Lors de l'exécution d'un programme dynamiquement linké celui ci va être mené à faire appel à des fonctions de librairies externes. Pour se faire il va faire ce qu'on appelle le lazy loading. C'est à dire qu'il va résoudre les fonctions nécessaires de la libc pour mettre l'adresse d'une fonction dns son entrée dans la GOT.
Lors de l'appel d'une fonction via la PLT le programme va tout d'abord regarder si l'entrée de GOT de la fonction est vide ou contient déjà l'adresse de la fonction résolue de la libc.
Un symbole représente une fonction ou une variable globale et est identifiée par un nom. Chaque symbole est décrit à l'aide de sa structure Elf32_Sym.
typedef struct elf32_rel {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
- r_offset : address of GOT entry where the resolved function will be stored
- r_info (ex: 0x107):
* 0x1 -> Index into Symbol Table (SYMTAB)
* 0x7 -> Function lookup value
struct elf32_sym {
Elf32_Word st_name; // Symbol name (index into String Table -> STRTAB)
Elf32_Addr st_value; // Value or address associated with the symbol
Elf32_Word st_size; // Size of the symbol
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
Elf32_Half st_shndx; // Which section (header table index) it's defined in
} Elf32_Sym;
#define DT_NULL 0 /* Marks end of dynamic section */
#define DT_NEEDED 1 /* Name of needed library */
#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
#define DT_PLTGOT 3 /* Processor defined value */
#define DT_HASH 4 /* Address of symbol hash table */
#define DT_STRTAB 5 /* Address of string table */
#define DT_SYMTAB 6 /* Address of symbol table */
#define DT_RELA 7 /* Address of Rela relocs */
#define DT_RELASZ 8 /* Total size of Rela relocs */
#define DT_RELAENT 9 /* Size of one Rela reloc */
#define DT_STRSZ 10 /* Size of string table */
#define DT_SYMENT 11 /* Size of one symbol table entry */
#define DT_INIT 12 /* Address of init function */
#define DT_FINI 13 /* Address of termination function */
#define DT_SONAME 14 /* Name of shared object */
#define DT_RPATH 15 /* Library search path */
#define DT_SYMBOLIC 16/* Start symbol search here */
#define DT_REL 17 /* Address of Rel relocs */
#define DT_RELSZ 18 /* Total size of Rel relocs */
#define DT_RELENT 19 /* Size of one Rel reloc */
#define DT_PLTREL 20 /* Type of reloc in PLT */
#define DT_DEBUG 21 /* For debugging; unspecified */
#define DT_TEXTREL 22 /* Reloc might modify .text */
#define DT_JMPREL 23 /* Address of PLT relocs */
typedef struct {
Elf32_Sword d_tag; // Dynamic entry type
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un; // Address of table
} Elf32_Dyn;
0xf7feadd0 <+0>: push eax
0xf7feadd1 <+1>: push ecx
0xf7feadd2 <+2>: push edx
0xf7feadd3 <+3>: mov edx,DWORD PTR [esp+0x10] ; reloc_offset
0xf7feadd7 <+7>: mov eax,DWORD PTR [esp+0xc] ; link_map structure (index of Elf32_Rel structure from JMPREL section)
0xf7feaddb <+11>: call 0xf7fe4f10 <_dl_fixup>
0xf7feade0 <+16>: pop edx
0xf7feade1 <+17>: mov ecx,DWORD PTR [esp]
0xf7feade4 <+20>: mov DWORD PTR [esp],eax
0xf7feade7 <+23>: mov eax,DWORD PTR [esp+0x4]
0xf7feadeb <+27>: ret 0xc
0xf7fe4f10 <+0>: push ebp
0xf7fe4f11 <+1>: push edi
0xf7fe4f12 <+2>: push esi
0xf7fe4f13 <+3>: push ebx
0xf7fe4f14 <+4>: call 0xf7ff18b3 <__x86.get_pc_thunk.di>
; EDI = GOT address of ld
0xf7fe4f19 <+9>: add edi,0x180e7
0xf7fe4f1f <+15>: sub esp,0x2c
; store link_map->l_info[DT_STRTAB] "Address of string table Elf32_Dyn at index 5" in ECX (STRTAB addr)
; https://code.woboq.org/userspace/glibc/elf/elf.h.html#854
0xf7fe4f22 <+18>: mov ecx,DWORD PTR [eax+0x34]
; store link_map->l_info[DT_SYMTAB] "Address of string table Elf32_Dyn at index 6" in EBX (SYMTAB addr)
0xf7fe4f25 <+21>: mov ebx,DWORD PTR [eax+0x38]
; save ld GOT address on stack
0xf7fe4f28 <+24>: mov DWORD PTR [esp+0x8],edi
; get STRTAB address (Elf32_Dyn->d_ptr) and store in ESI
0xf7fe4f2c <+28>: mov esi,DWORD PTR [ecx+0x4]
; store link_map->l_info[DT_JMPREL] "Address of plt reloc table Elf32_Dyn at index 23" in ECX (JMPREL addr)
0xf7fe4f2f <+31>: mov ecx,DWORD PTR [eax+0x7c]
; get JMPREL address (Elf32_Dyn->d_ptr) and add it in EDX which contained reloc_offset passed as argument
0xf7fe4f32 <+34>: add edx,DWORD PTR [ecx+0x4]
; store on stack STRTAB address
0xf7fe4f35 <+37>: mov DWORD PTR [esp+0xc],esi
; save in EBP JMPREL address
0xf7fe4f39 <+41>: mov ebp,edx
; At this moment, EDX contains the address of our Elf32_Rel structure.
; get Elf32_Rel->r_info and store it in EDX
0xf7fe4f3b <+43>: mov edx,DWORD PTR [edx+0x4]
; get Elf32_Rel->r_offset and store it in EDI
0xf7fe4f3e <+46>: mov edi,DWORD PTR [ebp+0x0]
; save in ESI (Elf32_Rel->r_info >> 0x8) which is the index in Symbol Table
0xf7fe4f41 <+49>: mov esi,edx
0xf7fe4f43 <+51>: shr esi,0x8
; save in ECX ((Elf32_Rel->r_info >> 0x8) << 0x4)
0xf7fe4f46 <+54>: mov ecx,esi
0xf7fe4f48 <+56>: shl ecx,0x4
; store in ECX (Elf32_Dyn->d_ptr + ECX) which points to the start of Elf32_Sym
; structure relative to the Elf32_Rel stucture.
0xf7fe4f4b <+59>: add ecx,DWORD PTR [ebx+0x4]
; add link_map->l_addr to Elf32_Rel->r_info and store in EDI result
0xf7fe4f4e <+62>: mov ebx,DWORD PTR [eax]
0xf7fe4f50 <+64>: add edi,ebx
; check (Elf32_Rel->r_info & 0xff) == ELF_MACHINE_JMP_SLOT (7)
0xf7fe4f52 <+66>: cmp dl,0x7
; save on stack Elf32_Sym structure address
0xf7fe4f55 <+69>: mov DWORD PTR [esp+0x1c],ecx
; if (Elf32_Rel->r_info & 0xff) != ELF_MACHINE_JMP_SLOT (7) -> error
0xf7fe4f59 <+73>: jne 0xf7fe5064 <_dl_fixup+340>
0xf7fe4f5f <+79>: test BYTE PTR [ecx+0xd],0x3
; save in EBP Elf32_Rel->r_offset
0xf7fe4f63 <+83>: mov ebp,edi
0xf7fe4f65 <+85>: jne 0xf7fe5010 <_dl_fixup+256>
; store Elf32_Dyn address of VERSYM
0xf7fe4f6b <+91>: mov ebx,DWORD PTR [eax+0xe4]
0xf7fe4f71 <+97>: xor edx,edx
0xf7fe4f73 <+99>: test ebx,ebx
0xf7fe4f75 <+101>: je 0xf7fe4f9a <_dl_fixup+138>
; store VERSYM address in EDX
0xf7fe4f77 <+103>: mov edx,DWORD PTR [ebx+0x4]
0xf7fe4f7a <+106>: movzx edx,WORD PTR [edx+esi*2]
0xf7fe4f7e <+110>: and edx,0x7fff
0xf7fe4f84 <+116>: shl edx,0x4
0xf7fe4f87 <+119>: add edx,DWORD PTR [eax+0x170]
0xf7fe4f8d <+125>: mov ebx,DWORD PTR [edx+0x4]
0xf7fe4f90 <+128>: test ebx,ebx
0xf7fe4f92 <+130>: mov ebx,0x0
0xf7fe4f97 <+135>: cmove edx,ebx
0xf7fe4f9a <+138>: mov esi,DWORD PTR gs:0xc
0xf7fe4fa1 <+145>: test esi,esi
0xf7fe4fa3 <+147>: mov ebx,0x1
0xf7fe4fa8 <+152>: jne 0xf7fe5018 <_dl_fixup+264>
; prepare arguments for _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope, version, ELF_RTYPE_CLASS_PLT, flags, NULL);
0xf7fe4faa <+154>: push 0x0 ; NULL
0xf7fe4fac <+156>: push ebx ; flags
0xf7fe4fad <+157>: push 0x1 ; ELF_RTYPE_CLASS_PLT
0xf7fe4faf <+159>: push edx ; version
0xf7fe4fb0 <+160>: push DWORD PTR [eax+0x1cc] ; link_map->l_scope
0xf7fe4fb6 <+166>: lea edx,[esp+0x30]
0xf7fe4fba <+170>: push edx ; &sym
0xf7fe4fbb <+171>: push eax ; link_map
0xf7fe4fbc <+172>: mov edi,DWORD PTR [esp+0x28]
0xf7fe4fc0 <+176>: add edi,DWORD PTR [ecx]
0xf7fe4fc2 <+178>: push edi ; strtab + sym->st_name
0xf7fe4fc3 <+179>: call 0xf7fdfec0 <_dl_lookup_symbol_x>
; just write at Elf32_Rel->r_offset address the function that was looked up
0xf7fe4fc8 <+184>: mov edi,eax
0xf7fe4fca <+186>: mov eax,gs:0xc
0xf7fe4fd0 <+192>: add esp,0x20
0xf7fe4fd3 <+195>: test eax,eax
0xf7fe4fd5 <+197>: jne 0xf7fe5030 <_dl_fixup+288>
0xf7fe4fd7 <+199>: mov ecx,DWORD PTR [esp+0x1c]
0xf7fe4fdb <+203>: xor eax,eax
0xf7fe4fdd <+205>: test ecx,ecx
0xf7fe4fdf <+207>: je 0xf7fe4ff6 <_dl_fixup+230>
0xf7fe4fe1 <+209>: test edi,edi
0xf7fe4fe3 <+211>: je 0xf7fe4fe7 <_dl_fixup+215>
0xf7fe4fe5 <+213>: mov eax,DWORD PTR [edi]
0xf7fe4fe7 <+215>: movzx edx,BYTE PTR [ecx+0xc]
0xf7fe4feb <+219>: add eax,DWORD PTR [ecx+0x4]
0xf7fe4fee <+222>: and edx,0xf
0xf7fe4ff1 <+225>: cmp dl,0xa
0xf7fe4ff4 <+228>: je 0xf7fe5060 <_dl_fixup+336>
0xf7fe4ff6 <+230>: mov esi,DWORD PTR [esp+0x8]
0xf7fe4ffa <+234>: mov edx,DWORD PTR [esi-0x6d0]
0xf7fe5000 <+240>: test edx,edx
0xf7fe5002 <+242>: jne 0xf7fe5007 <_dl_fixup+247>
0xf7fe5004 <+244>: mov DWORD PTR [ebp+0x0],eax
0xf7fe5007 <+247>: add esp,0x2c
0xf7fe500a <+250>: pop ebx
0xf7fe500b <+251>: pop esi
0xf7fe500c <+252>: pop edi
0xf7fe500d <+253>: pop ebp
0xf7fe500e <+254>: ret
0xf7fe500f <+255>: nop
0xf7fe5010 <+256>: mov eax,ebx
0xf7fe5012 <+258>: jmp 0xf7fe4fe7 <_dl_fixup+215>
0xf7fe5014 <+260>: lea esi,[esi+eiz*1+0x0]
0xf7fe5018 <+264>: mov DWORD PTR gs:0x1c,0x1
0xf7fe5023 <+275>: mov ebx,0x5
0xf7fe5028 <+280>: jmp 0xf7fe4faa <_dl_fixup+154>
0xf7fe502a <+282>: lea esi,[esi+0x0]
0xf7fe5030 <+288>: xor esi,esi
0xf7fe5032 <+290>: mov eax,esi
0xf7fe5034 <+292>: xchg DWORD PTR gs:0x1c,eax
0xf7fe503b <+299>: cmp eax,0x2
0xf7fe503e <+302>: jne 0xf7fe4fd7 <_dl_fixup+199>
0xf7fe5040 <+304>: mov ebx,DWORD PTR gs:0x8
0xf7fe5047 <+311>: mov eax,0xf0
0xf7fe504c <+316>: add ebx,0x1c
0xf7fe504f <+319>: mov ecx,0x81
0xf7fe5054 <+324>: mov edx,0x1
0xf7fe5059 <+329>: int 0x80
0xf7fe505b <+331>: jmp 0xf7fe4fd7 <_dl_fixup+199>
0xf7fe5060 <+336>: call eax
0xf7fe5062 <+338>: jmp 0xf7fe4ff6 <_dl_fixup+230>
0xf7fe5064 <+340>: mov edi,DWORD PTR [esp+0x8]
0xf7fe5068 <+344>: lea eax,[edi-0x7acc]
0xf7fe506e <+350>: push eax
0xf7fe506f <+351>: lea eax,[edi-0x9cf3]
0xf7fe5075 <+357>: push 0x50
0xf7fe5077 <+359>: push eax
0xf7fe5078 <+360>: lea eax,[edi-0x7b3c]
0xf7fe507e <+366>: push eax
0xf7fe507f <+367>: call 0xf7feeb00 <__GI___assert_fail>
sra op_1, op_2, shift : op_1 = op_2 >> shift sll op_1, op_2, shift : op_1 = op_2 << shift sb op_1, (op_2) :
Jun 12, 2022General Mathematics Quadratic equation Given a quadratic equation of form : $ax^2+bx+c = 0$ We compute the determinant : $$\Delta = b^2-4ac$$ If $\Delta >= 0$ then the quadratic equation admits 2 solutions : $$x = {-b \pm \sqrt{\Delta} \over 2a}$$Else, if $\Delta = 0$ then the quadratic equation admits only 1 solution : $$x = {-b \over 2a}$$If $\Delta < 0$ then the quadratic equation admits no solutions in $\Bbb{R}$ but in $\Bbb{C}$ we have :
Apr 18, 2022VPTR (ou Virtual Pointer) est un pointeur qui pointe vers l'entrée d'un tableau de pointeur sur fonction d'une classe. Ces pointeurs sur fonction pointent eux-mêmes vers les méthodes relative à la classe. Il y a une VTABLE pour chaque classe et donc un VPTR pour chaque VTABLE. Reprennons un bout de code du chall C++ de Root-Me pour montrer un exemple : class UpperFormatter: public formatter { public : virtual int RTTI( ) { return 1; };
Mar 2, 2022or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up