The gs
/fs
segment can be used for thread local storage similar to what you have encountered in Windows. Variable specific to a thread such as errno
, stack canary etc are usually stored here in Linux.
According to this, your first example is to save canary to the stack from fs:0x28
. You can see some hacks here and read more here
Canary check from an example binary
$ tail x.c
#include <stdio.h>
int main(int argc, char **argv)
{
char s[32];
scanf("%s", s);
return 0;
}
$ gcc -no-pie -fno-pic x.c -o z64
$ gcc -m32 -no-pie -fno-pic x.c -o z32
$ r2 -AA z32 -qc "pdf @ sym.main"
;-- main:
┌ (fcn) sym.main 86
....
│ 0x080484bf 65a114000000 mov eax, dword gs:[0x14] ; [0x14:4]=-1 ; 20
│ 0x080484c5 8945f4 mov dword [local_ch], eax
│ 0x080484c8 31c0 xor eax, eax
....
│ 0x080484e3 8b55f4 mov edx, dword [local_ch]
│ 0x080484e6 653315140000. xor edx, dword gs:[0x14]
│ ┌─< 0x080484ed 7405 je 0x80484f4
│ │ 0x080484ef e85cfeffff call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
....
$ r2 -AA z64 -qc "pdf @ sym.main"
;-- main:
┌ (fcn) sym.main 79
....
│ 0x00400586 64488b042528. mov rax, qword fs:[0x28] ; [0x28:8]=-1 ; '(' ; 40
│ 0x0040058f 488945f8 mov qword [local_8h], rax
│ 0x00400593 31c0 xor eax, eax
....
│ 0x004005b0 488b55f8 mov rdx, qword [local_8h]
│ 0x004005b4 644833142528. xor rdx, qword fs:[0x28]
│ ┌─< 0x004005bd 7405 je 0x4005c4
│ │ 0x004005bf e8acfeffff call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
....
Also for your second request, yes that is pthread_t
at offset 0 in fs
/gs
.
$ tail -n 30 x.c
#ifdef __x86_64__
#define val_t uint64_t
#define INSN_READ "movq %%fs:0, %0;"
#define FMT "Found val: %#lx\n"
#elif __i386__
#define val_t uint32_t
#define INSN_READ "movl %%gs:0, %0;"
#define FMT "Found val: %#x\n"
#endif
val_t read_val()
{
val_t val = 0;
__asm__(INSN_READ
: "=r"(val)
:
:);
return val;
}
int main(int argc, char **argv)
{
printf(FMT, read_val());
printf(FMT, (val_t)pthread_self());
return 0;
}
$ gcc -no-pie -fno-pic x.c -o zm64
$ gcc -m32 -no-pie -fno-pic x.c -o zm32
$ ./zm32
Found val: 0xf7f800c0
Found val: 0xf7f800c0
$ ./zm64
Found val: 0x7fd50119f4c0
Found val: 0x7fd50119f4c0
I tried to look for your second snippet in my libc
but couldn't find it. SO can't answer for sure what it contains at 0x44
. While debugging I only got 0s at that offset.
$ r2 /lib/x86_64-linux-gnu/libc.so.6
-- There is only one binary, and we are all just reversing pieces of it.
[0x00021cb0]> /x `!rasm2 -a x86.as -b 64 "mov rax, fs:[0]"`
Searching 9 bytes in [0x0-0x1e6aa0]
hits: 7
Searching 9 bytes in [0x3e7620-0x3f0ae0]
hits: 0
0x000e18c9 hit0_0 64488b042500000000
0x000e1d8a hit0_1 64488b042500000000
0x00105cff hit0_2 64488b042500000000
0x00105e50 hit0_3 64488b042500000000
0x00105f21 hit0_4 64488b042500000000
0x00106865 hit0_5 64488b042500000000
0x0014a18a hit0_6 64488b042500000000
[0x00021cb0]> pd10 @@ hit0_*
;-- hit0_0:
0x000e18c9 64488b042500. mov rax, qword fs:[0]
0x000e18d2 31db xor ebx, ebx
0x000e18d4 48c744241800. mov qword [rsp + 0x18], 0
0x000e18dd 4c8b25849530. mov r12, qword [0x003eae68] ; [0x3eae68:8]=0
0x000e18e4 48890424 mov qword [rsp], rax
0x000e18e8 488d442450 lea rax, [rsp + 0x50] ; "@" ; 'P'
0x000e18ed 4889442430 mov qword [rsp + 0x30], rax
0x000e18f2 488d442460 lea rax, [rsp + 0x60] ; '`'
0x000e18f7 4889442420 mov qword [rsp + 0x20], rax
0x000e18fc 488d442458 lea rax, [rsp + 0x58] ; "@" ; 'X'
;-- hit0_1:
0x000e1d8a 64488b042500. mov rax, qword fs:[0]
0x000e1d93 31db xor ebx, ebx
0x000e1d95 48c744242800. mov qword [rsp + 0x28], 0
0x000e1d9e 4c8b25c39030. mov r12, qword [0x003eae68] ; [0x3eae68:8]=0
0x000e1da5 4889442410 mov qword [rsp + 0x10], rax
0x000e1daa 488d442460 lea rax, [rsp + 0x60] ; '`'
0x000e1daf 4889442440 mov qword [rsp + 0x40], rax
0x000e1db4 488d442470 lea rax, [rsp + 0x70] ; 'p'
0x000e1db9 4889442430 mov qword [rsp + 0x30], rax
0x000e1dbe 488d442468 lea rax, [rsp + 0x68] ; 'h'
;-- hit0_2:
0x00105cff 64488b042500. mov rax, qword fs:[0]
0x00105d08 488b1d41512e. mov rbx, qword [0x003eae50] ; [0x3eae50:8]=0
0x00105d0f 4c8b2d52512e. mov r13, qword [0x003eae68] ; [0x3eae68:8]=0
0x00105d16 4c8d3c18 lea r15, [rax + rbx]
0x00105d1a 48898560feff. mov qword [rbp - 0x1a0], rax
0x00105d21 4c89e7 mov rdi, r12
0x00105d24 e807060600 call sym._dl_mcount_wrapper_check
0x00105d29 488b8560feff. mov rax, qword [rbp - 0x1a0]
0x00105d30 4883ec08 sub rsp, 8
0x00105d34 498b4e08 mov rcx, qword [r14 + 8] ; sym.__resp ; [0x8:8]=0
;-- hit0_3:
0x00105e50 64488b042500. mov rax, qword fs:[0]
0x00105e59 4c8b2d08502e. mov r13, qword [0x003eae68] ; [0x3eae68:8]=0
0x00105e60 4c8dbd98feff. lea r15, [rbp - 0x168]
0x00105e67 488b1de24f2e. mov rbx, qword [0x003eae50] ; [0x3eae50:8]=0
0x00105e6e 48c78598feff. mov qword [rbp - 0x168], 0
0x00105e79 48898560feff. mov qword [rbp - 0x1a0], rax
0x00105e80 4c01e8 add rax, r13 ; 'o'
0x00105e83 48898508feff. mov qword [rbp - 0x1f8], rax
0x00105e8a 660f1f440000 nop word [rax + rax]
0x00105e90 4c89e7 mov rdi, r12
;-- hit0_4:
0x00105f21 64488b042500. mov rax, qword fs:[0]
0x00105f2a 4c8b2d374f2e. mov r13, qword [0x003eae68] ; [0x3eae68:8]=0
0x00105f31 4c8dbd98feff. lea r15, [rbp - 0x168]
0x00105f38 488b1d114f2e. mov rbx, qword [0x003eae50] ; [0x3eae50:8]=0
0x00105f3f 48c78598feff. mov qword [rbp - 0x168], 0
0x00105f4a 48898560feff. mov qword [rbp - 0x1a0], rax
0x00105f51 4c01e8 add rax, r13 ; 'o'
0x00105f54 48898508feff. mov qword [rbp - 0x1f8], rax
0x00105f5b 0f1f440000 nop dword [rax + rax]
0x00105f60 4c89e7 mov rdi, r12
;-- hit0_5:
0x00106865 64488b042500. mov rax, qword fs:[0]
0x0010686e 488db5c0feff. lea rsi, [rbp - 0x140]
0x00106875 4c8b0dd4452e. mov r9, qword [0x003eae50] ; [0x3eae50:8]=0
0x0010687c 488b8d20feff. mov rcx, qword [rbp - 0x1e0]
0x00106883 ba00010000 mov edx, 0x100
0x00106888 4885ff test rdi, rdi
0x0010688b 490f44fd cmove rdi, r13
0x0010688f 4901c1 add r9, rax ; '#'
0x00106892 480305cf452e. add rax, qword [0x003eae68]
0x00106899 4989c0 mov r8, rax
;-- hit0_6:
0x0014a18a 64488b042500. mov rax, qword fs:[0]
0x0014a193 4c89fb mov rbx, r15
0x0014a196 4889442440 mov qword [rsp + 0x40], rax
0x0014a19b 488d442460 lea rax, [rsp + 0x60] ; '`'
0x0014a1a0 4889442408 mov qword [rsp + 8], rax
0x0014a1a5 488b4500 mov rax, qword [rbp]
0x0014a1a9 488b7c2458 mov rdi, qword [rsp + 0x58] ; [0x58:8]=64 ; 'X'
0x0014a1ae 4889442410 mov qword [rsp + 0x10], rax
0x0014a1b3 488b03 mov rax, qword [rbx]
0x0014a1b6 4889442418 mov qword [rsp + 0x18], rax
[0x00021cb0]>