Skip to content

Instantly share code, notes, and snippets.

@merryhime
Last active April 11, 2025 01:16

Revisions

  1. @MerryMage MerryMage revised this gist Jul 25, 2019. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions text.md
    Original file line number Diff line number Diff line change
    @@ -81,9 +81,7 @@ Edit: [@shuffle2](https://twitter.com/shuffle2) has a useful post on using fs he

    ## macOS

    Fuck you.

    Edit: [This](https://gist.github.com/aras-p/5389747) looks half-promising.
    [This](https://gist.github.com/aras-p/5389747) looks half-promising.

    That syscall is a MDEP syscall intended for the internal use of pthread to set gsbase. Looking at the [mdep syscall table](https://github.com/opensource-apple/xnu/blob/53c5e2e62fc4182595609153d4b99648da577c39/osfmk/i386/machdep_call.c#L63) shows that it is the only valid mdep syscall on x64, and the [rest of the code](https://github.com/opensource-apple/xnu/blob/53c5e2e62fc4182595609153d4b99648da577c39/osfmk/i386/pcb_native.c#L480-L486) shows it does what you'd expect.

  2. @MerryMage MerryMage revised this gist Jul 21, 2019. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion text.md
    Original file line number Diff line number Diff line change
    @@ -89,4 +89,6 @@ That syscall is a MDEP syscall intended for the internal use of pthread to set g

    Scouering the rest of the publicly available kernel sourcecode doesn't reveal any method of setting fsbase.

    If one is absolutely desperate, one could use [Hypervisor.framework](https://developer.apple.com/reference/hypervisor) which would provide you with absolute control over a vCPU.
    If one is absolutely desperate, one could use [Hypervisor.framework](https://developer.apple.com/reference/hypervisor) which would provide you with absolute control over a vCPU.

    Edit 2: If you really really need to use `fs` for some reason, see [this hack](https://nuxi.nl/blog/2016/05/10/cloudabi-for-mac-part-3.html), which rewrites all fs accesses to gs accesses.
  3. @MerryMage MerryMage revised this gist Apr 3, 2017. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion text.md
    Original file line number Diff line number Diff line change
    @@ -87,4 +87,6 @@ Edit: [This](https://gist.github.com/aras-p/5389747) looks half-promising.

    That syscall is a MDEP syscall intended for the internal use of pthread to set gsbase. Looking at the [mdep syscall table](https://github.com/opensource-apple/xnu/blob/53c5e2e62fc4182595609153d4b99648da577c39/osfmk/i386/machdep_call.c#L63) shows that it is the only valid mdep syscall on x64, and the [rest of the code](https://github.com/opensource-apple/xnu/blob/53c5e2e62fc4182595609153d4b99648da577c39/osfmk/i386/pcb_native.c#L480-L486) shows it does what you'd expect.

    Scouering the rest of the publicly available kernel sourcecode doesn't reveal any method of setting fsbase.
    Scouering the rest of the publicly available kernel sourcecode doesn't reveal any method of setting fsbase.

    If one is absolutely desperate, one could use [Hypervisor.framework](https://developer.apple.com/reference/hypervisor) which would provide you with absolute control over a vCPU.
  4. @MerryMage MerryMage revised this gist Apr 3, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion text.md
    Original file line number Diff line number Diff line change
    @@ -83,4 +83,8 @@ Edit: [@shuffle2](https://twitter.com/shuffle2) has a useful post on using fs he

    Fuck you.

    Edit: [This](https://gist.github.com/aras-p/5389747) looks half-promising. Untested.
    Edit: [This](https://gist.github.com/aras-p/5389747) looks half-promising.

    That syscall is a MDEP syscall intended for the internal use of pthread to set gsbase. Looking at the [mdep syscall table](https://github.com/opensource-apple/xnu/blob/53c5e2e62fc4182595609153d4b99648da577c39/osfmk/i386/machdep_call.c#L63) shows that it is the only valid mdep syscall on x64, and the [rest of the code](https://github.com/opensource-apple/xnu/blob/53c5e2e62fc4182595609153d4b99648da577c39/osfmk/i386/pcb_native.c#L480-L486) shows it does what you'd expect.

    Scouering the rest of the publicly available kernel sourcecode doesn't reveal any method of setting fsbase.
  5. @MerryMage MerryMage revised this gist Apr 3, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions text.md
    Original file line number Diff line number Diff line change
    @@ -82,3 +82,5 @@ Edit: [@shuffle2](https://twitter.com/shuffle2) has a useful post on using fs he
    ## macOS

    Fuck you.

    Edit: [This](https://gist.github.com/aras-p/5389747) looks half-promising. Untested.
  6. @MerryMage MerryMage revised this gist Apr 3, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions text.md
    Original file line number Diff line number Diff line change
    @@ -77,6 +77,8 @@ Presence of this feature can be detected using `IsProcessorFeaturePresent(PF_RDW

    I currently do not know if `wrfsbase` is available for use.

    Edit: [@shuffle2](https://twitter.com/shuffle2) has a useful post on using fs here: http://ghettohaxxx-blog.azurewebsites.net/executing-bsd-elfs-in-windows/

    ## macOS

    Fuck you.
  7. @MerryMage MerryMage revised this gist Apr 3, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion text.md
    Original file line number Diff line number Diff line change
    @@ -79,4 +79,4 @@ I currently do not know if `wrfsbase` is available for use.

    ## macOS

    Fuck you, apparently.
    Fuck you.
  8. @MerryMage MerryMage created this gist Apr 3, 2017.
    82 changes: 82 additions & 0 deletions text.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    # GSBASE and FSBASE

    When you're running out of registers while writing a JIT, you might resort to more unconventional methods for memory access. You might choose to resort to segment registers if you need a fixed register for memory offsets.

    Instructions such as:

    lea rax,gs:[rcx+rdx*8]
    mov rax,gs:[rcx+rdx*8]

    would then be available for your use.

    This document documents what I have found about fs and gs on modern operating systems.

    ## Linux

    Doesn't care. Do what you want with `gs`.

    #include <asm/prctl.h>
    static int arch_prctl(int func, void *ptr) {
    return syscall(__NR_arch_prctl, func, ptr);
    }

    arch_prctl(ARCH_SET_FS, (void*)fsbase);
    arch_prctl(ARCH_SET_GS, (void*)gsbase);

    ## FreeBSD

    Doesn't care.

    amd64_set_fsbase((void*)fsbase);
    amd64_set_gsbase((void*)gsbase);

    ## NetBSD

    Doesn't care.

    sysarch(X86_64_SET_FSBASE, (void*)fsbase);
    sysarch(X86_64_SET_GSBASE, (void*)gsbase);

    ## Windows (32-bit)

    The 32 bit ABI for Windows allows you to modify the equivalent of gsbase using an LDT entry.

    int (*NtSetLdtEntries)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
    *(FARPROC*)(&NtSetLdtEntries) = GetProcAddress(LoadLibrary("ntdll.dll"), "NtSetLdtEntries");

    DWORD base = /* ... */;
    DWORD limit = /* ... */;

    LDT_ENTRY ll;
    ll.BaseLow = base & 0xFFFF;
    ll.HighWord.Bytes.BaseMid = base >> 16;
    ll.HighWord.Bytes.BaseHi = base >> 24;
    ll.LimitLow = limit & 0xFFFF;
    ll.HighWord.Bits.LimitHi = limit >> 16;
    ll.HighWord.Bits.Granularity = 0;
    ll.HighWord.Bits.Default_Big = 1;
    ll.HighWord.Bits.Reserved_0 = 0;
    ll.HighWord.Bits.Sys = 0;
    ll.HighWord.Bits.Pres = 1;
    ll.HighWord.Bits.Dpl = 3;
    ll.HighWord.Bits.Type = 0x13;

    int ret = NtSetLdtEntries(0x80, *(DWORD*)&ll, *((DWORD*)(&ll)+1), 0, 0, 0);
    assert(ret >= 0);

    // Then use assembly to set gs to refer to the LDT entry

    ## Windows (64-bit)

    Win 8.1 onwards enables `fsgsbase` instructions when they are available. This requires the application to be non-UMS.

    Win 8.1 onwards explicitly allows you to use the `wrgsbase` instruction to directly write gsbase for user-level threading.
    However, the kernel checks for a valid TEB and may modify your gsbase if it doesn't point to a valid one.

    Presence of this feature can be detected using `IsProcessorFeaturePresent(PF_RDWRFSGSBASE_AVAILABLE)`.

    I currently do not know if `wrfsbase` is available for use.

    ## macOS

    Fuck you, apparently.