Memory Analysis
The commands here provide a better analysis of memory segments and the registers.
elf-info
elf-info
(elf
for short) provides basic information about the ELF file. This is most useful for viewing memory segments, the entry point, and the ELF header.
gef➤ elf-info Magic : 7f 45 4c 46 Class : 0x1 - ELF_32_BITS Endianness : 0x1 - LITTLE_ENDIAN Version : 0x1 OS ABI : 0x0 - SYSTEMV ABI Version : 0x0 Type : 0x2 - ET_EXEC Machine : 0x3 - X86_32 Program Header Table : 0x00000034 Section Header Table : 0x00003628 Header Table : 0x00000034 ELF Version : 0x1 Header size : 52 (0x34) Entry point : 0x08049090 ──────────────────────────────────────────────── Program Header ──────────────────────────────────────────────── [ #] Type Offset Virtaddr Physaddr FileSiz MemSiz Flags Align [ 0] PT_PHDR 0x34 0x8048034 0x8048034 0x160 0x160 PF_R 0x4 [ 1] PT_INTERP 0x194 0x8048194 0x8048194 0x13 0x13 PF_R 0x1 [ 2] PT_LOAD 0x0 0x8048000 0x8048000 0x388 0x388 PF_R 0x1000 [ 3] PT_LOAD 0x1000 0x8049000 0x8049000 0x270 0x270 None 0x1000 [ 4] PT_LOAD 0x2000 0x804a000 0x804a000 0x160 0x160 PF_R 0x1000 [ 5] PT_LOAD 0x2f08 0x804bf08 0x804bf08 0x120 0x124 None 0x1000 [ 6] PT_DYNAMIC 0x2f10 0x804bf10 0x804bf10 0xe8 0xe8 None 0x4 [ 7] PT_NOTE 0x1a8 0x80481a8 0x80481a8 0x44 0x44 PF_R 0x4 [ 8] PT_GNU_EH_FRAME 0x2038 0x804a038 0x804a038 0x44 0x44 PF_R 0x4 [ 9] PT_GNU_STACK 0x0 0x0 0x0 0x0 0x0 None 0x10 [10] PT_GNU_RELRO 0x2f08 0x804bf08 0x804bf08 0xf8 0xf8 PF_R 0x1 ──────────────────────────────────────────────── Section Header ──────────────────────────────────────────────── [ #] Name Type Address Offset Size EntSiz Flags Link Info Align [ 0] UNKN 0x0 0x0 0x0 0x0 UNKNOWN_FLAG 0x0 0x0 0x0 [ 1] .interp SHT_PROGBITS 0x8048194 0x194 0x13 0x0 ALLOC 0x0 0x0 0x1 [ 2] .note.gnu.build-id SHT_NOTE 0x80481a8 0x1a8 0x24 0x0 ALLOC 0x0 0x0 0x4 [ 3] .note.ABI-tag SHT_NOTE 0x80481cc 0x1cc 0x20 0x0 ALLOC 0x0 0x0 0x4 [ 4] .gnu.hash SHT_GNU_HASH 0x80481ec 0x1ec 0x20 0x4 ALLOC 0x5 0x0 0x4 [ 5] .dynsym SHT_DYNSYM 0x804820c 0x20c 0x90 0x10 ALLOC 0x6 0x1 0x4 [ 6] .dynstr SHT_STRTAB 0x804829c 0x29c 0x6f 0x0 ALLOC 0x0 0x0 0x1 [ 7] .gnu.version SHT_GNU_versym 0x804830c 0x30c 0x12 0x2 ALLOC 0x5 0x0 0x2 [ 8] .gnu.version_r SHT_GNU_verneed 0x8048320 0x320 0x30 0x0 ALLOC 0x6 0x1 0x4 [ 9] .rel.dyn SHT_REL 0x8048350 0x350 0x10 0x8 ALLOC 0x5 0x0 0x4 [10] .rel.plt SHT_REL 0x8048360 0x360 0x28 0x8 UNKNOWN_FLAG 0x5 0x16 0x4 [11] .init SHT_PROGBITS 0x8049000 0x1000 0x24 0x0 UNKNOWN_FLAG 0x0 0x0 0x4 [12] .plt SHT_PROGBITS 0x8049030 0x1030 0x60 0x4 UNKNOWN_FLAG 0x0 0x0 0x10 [13] .text SHT_PROGBITS 0x8049090 0x1090 0x1c8 0x0 UNKNOWN_FLAG 0x0 0x0 0x10 [14] .fini SHT_PROGBITS 0x8049258 0x1258 0x18 0x0 UNKNOWN_FLAG 0x0 0x0 0x4 [15] .rodata SHT_PROGBITS 0x804a000 0x2000 0x37 0x0 ALLOC 0x0 0x0 0x4 [16] .eh_frame_hdr SHT_PROGBITS 0x804a038 0x2038 0x44 0x0 ALLOC 0x0 0x0 0x4 [17] .eh_frame SHT_PROGBITS 0x804a07c 0x207c 0xe4 0x0 ALLOC 0x0 0x0 0x4 [18] .init_array SHT_INIT_ARRAY 0x804bf08 0x2f08 0x4 0x4 UNKNOWN_FLAG 0x0 0x0 0x4 [19] .fini_array SHT_FINI_ARRAY 0x804bf0c 0x2f0c 0x4 0x4 UNKNOWN_FLAG 0x0 0x0 0x4 [20] .dynamic SHT_DYNAMIC 0x804bf10 0x2f10 0xe8 0x8 UNKNOWN_FLAG 0x6 0x0 0x4 [21] .got SHT_PROGBITS 0x804bff8 0x2ff8 0x8 0x4 UNKNOWN_FLAG 0x0 0x0 0x4 [22] .got.plt SHT_PROGBITS 0x804c000 0x3000 0x20 0x4 UNKNOWN_FLAG 0x0 0x0 0x4 [23] .data SHT_PROGBITS 0x804c020 0x3020 0x8 0x0 UNKNOWN_FLAG 0x0 0x0 0x4 [24] .bss SHT_NOBITS 0x804c028 0x3028 0x4 0x0 UNKNOWN_FLAG 0x0 0x0 0x1 [25] .comment SHT_PROGBITS 0x0 0x3028 0x2d 0x1 UNKNOWN_FLAG 0x0 0x0 0x1 [26] .symtab SHT_SYMTAB 0x0 0x3058 0x2b0 0x10 UNKNOWN_FLAG 0x1b 0x12 0x4 [27] .strtab SHT_STRTAB 0x0 0x3308 0x21f 0x0 UNKNOWN_FLAG 0x0 0x0 0x1 [28] .shstrtab SHT_STRTAB 0x0 0x3527 0x101 0x0 UNKNOWN_FLAG 0x0 0x0 0x1
got
The got
command prints the GOT table.
gef➤ got GOT protection: Partial RelRO | GOT functions: 5 [0x804c00c] __libc_start_main@GLIBC_2.34 → 0xf7c21560 [0x804c010] fflush@GLIBC_2.0 → 0xf7c71410 [0x804c014] gets@GLIBC_2.0 → 0x8049066 [0x804c018] puts@GLIBC_2.0 → 0xf7c732a0 [0x804c01c] system@GLIBC_2.0 → 0x8049086
got
can apply filters to the output. You can filter by symbol name and can also use more than one filter.
gef➤ got puts GOT protection: Partial RelRO | GOT functions: 5 [0x804c018] puts@GLIBC_2.0 → 0xf7c732a0 gef➤ got puts system GOT protection: Partial RelRO | GOT functions: 5 [0x804c018] puts@GLIBC_2.0 → 0xf7c732a0 [0x804c01c] system@GLIBC_2.0 → 0x8049086
got
at runtime.heap
The heap
command provides information on the heap chunks.
Use heap arenas
to view the heap arenas.
gef➤ heap arenas Arena(base=0x7ffff7e19c80, top=0x5555555596d0, last_remainder=0x0, next=0x7ffff7e19c80)
Use heap chunks
to view the heap chunks.
gef➤ heap chunks Chunk(addr=0x555555559010, size=0x290, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) [0x0000555555559010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................] Chunk(addr=0x5555555592a0, size=0x30, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) [0x00005555555592a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................] Chunk(addr=0x5555555592d0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) [0x00005555555592d0 45 6e 74 65 72 20 74 68 65 20 66 6c 61 67 20 68 Enter the flag h] Chunk(addr=0x5555555596e0, size=0x20930, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← top chunk
…yet.
dereference
The dereference
(deref
for short) command provides similar output to the Stack section of context
. It takes three optional arguments:
- A start address, symbol, or register (by default,
$sp
) - The number of consecutive addresses to reference
- The base location for offset (by default, the start address)
gef➤ deref 0xffffd640│+0x0000: 0xffffd658 → 0xf7c184be → "_dl_audit_preinit" ← $esp 0xffffd644│+0x0004: 0x00000000 0xffffd648│+0x0008: 0x01000000 0xffffd64c│+0x000c: 0x080491fb → <read_in+12> add ebx, 0x2e05 0xffffd650│+0x0010: 0xf7fc4540 → <__kernel_vsyscall+0> push ecx 0xffffd654│+0x0014: 0x00000000 0xffffd658│+0x0018: 0xf7c184be → "_dl_audit_preinit" 0xffffd65c│+0x001c: 0xf7e2a054 → 0xf7fdde10 → <_dl_audit_preinit+0> endbr32 0xffffd660│+0x0020: 0xf7fbe4a0 → 0xf7c00000 → 0x464c457f 0xffffd664│+0x0024: 0xf7fd6f90 → mov edi, eax
With arguments:
gef➤ deref $esp -l 7 -r $ebp 0xffffd640│-0x0048: 0xffffd658 → 0xf7c184be → "_dl_audit_preinit" ← $esp 0xffffd644│-0x0044: 0x00000000 0xffffd648│-0x0040: 0x01000000 0xffffd64c│-0x003c: 0x080491fb → <read_in+12> add ebx, 0x2e05 0xffffd650│-0x0038: 0xf7fc4540 → <__kernel_vsyscall+0> push ecx 0xffffd654│-0x0034: 0x00000000 0xffffd658│-0x0030: 0xf7c184be → "_dl_audit_preinit"
registers
The registers
command is a wrapper for info registers
. It shows the current state of the registers in the same format it is printed in context
.
gef➤ registers $eax : 0xffffd228 → 0xf7c184be → "_dl_audit_preinit" $ebx : 0x0804c000 → 0x0804bf10 → <_DYNAMIC+0> add DWORD PTR [eax], eax $ecx : 0x6c0 $edx : 0xf7e2b9b4 → 0x00000000 $esp : 0xffffd210 → 0xffffd228 → 0xf7c184be → "_dl_audit_preinit" $ebp : 0xffffd258 → 0xffffd268 → 0xf7ffd020 → 0xf7ffda40 → 0x00000000 $esi : 0xffffd324 → 0xffffd4ea → "/ironforge/args" $edi : 0xf7ffcb80 → 0x00000000 $eip : 0x0804922e → 0xfffe2de8 → 0x00000000 $eflags: [zero carry PARITY ADJUST SIGN trap INTERRUPT direction overflow resume virtualx86 identification] $cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x00 $gs: 0x63
Like info registers
, you can filter by register.
gef➤ registers $eip $esi $eip : 0x0804922e → 0xfffe2de8 → 0x00000000 $esi : 0xffffd324 → 0xffffd4ea → "/ironforge/args"
vmmap
vmmap
performs an extended function to info proc mappings
. It shows all loaded memory segments.
gef➤ vmmap [ Legend: Code | Heap | Stack ] Start End Offset Perm Path 0x08048000 0x08049000 0x00000000 r-- /ironforge/args 0x08049000 0x0804a000 0x00001000 r-x /ironforge/args 0x0804a000 0x0804b000 0x00002000 r-- /ironforge/args 0x0804b000 0x0804c000 0x00002000 r-- /ironforge/args 0x0804c000 0x0804d000 0x00003000 rw- /ironforge/args 0xf7c00000 0xf7c20000 0x00000000 r-- /usr/lib/i386-linux-gnu/libc.so.6 0xf7c20000 0xf7da2000 0x00020000 r-x /usr/lib/i386-linux-gnu/libc.so.6 0xf7da2000 0xf7e27000 0x001a2000 r-- /usr/lib/i386-linux-gnu/libc.so.6 0xf7e27000 0xf7e28000 0x00227000 --- /usr/lib/i386-linux-gnu/libc.so.6 0xf7e28000 0xf7e2a000 0x00227000 r-- /usr/lib/i386-linux-gnu/libc.so.6 0xf7e2a000 0xf7e2b000 0x00229000 rw- /usr/lib/i386-linux-gnu/libc.so.6 0xf7e2b000 0xf7e35000 0x00000000 rw- 0xf7fbe000 0xf7fc0000 0x00000000 rw- 0xf7fc0000 0xf7fc4000 0x00000000 r-- [vvar] 0xf7fc4000 0xf7fc6000 0x00000000 r-x [vdso] 0xf7fc6000 0xf7fc7000 0x00000000 r-- /usr/lib/i386-linux-gnu/ld-linux.so.2 0xf7fc7000 0xf7fec000 0x00001000 r-x /usr/lib/i386-linux-gnu/ld-linux.so.2 0xf7fec000 0xf7ffb000 0x00026000 r-- /usr/lib/i386-linux-gnu/ld-linux.so.2 0xf7ffb000 0xf7ffd000 0x00034000 r-- /usr/lib/i386-linux-gnu/ld-linux.so.2 0xf7ffd000 0xf7ffe000 0x00036000 rw- /usr/lib/i386-linux-gnu/ld-linux.so.2 0xfffdd000 0xffffe000 0x00000000 rwx [stack]
vmmap
also takes an optional argument. It takes an address and resolves it to a certain memory segment.
gef➤ x/wx $ebp-0x30 0xffffd228: 0xf7c18400 gef➤ vmmap 0xffffd228 [ Legend: Code | Heap | Stack ] Start End Offset Perm Path 0xfffdd000 0xffffe000 0x00000000 rwx [stack]
scan
scan
searches for addresses of one memory region inside another region. This is also known as needle-in-haystack scanning.
gef➤ scan stack libc [+] Searching for addresses in 'stack' that point to 'libc' [stack]: 0x00007fffffffd6a8│+0x1f6a8: 0x00007ffff77cf482 → "__tunable_get_val" [stack]: 0x00007fffffffd6b0│+0x1f6b0: 0x00007ffff77bff78 → 0x0000001200001ab2 [stack]: 0x00007fffffffd758│+0x1f758: 0x00007ffff77cd9d0 → 0x6c5f755f72647800 [stack]: 0x00007fffffffd778│+0x1f778: 0x00007ffff77bda6c → 0x0000090900000907 [stack]: 0x00007fffffffd7d8│+0x1f7d8: 0x00007ffff77cd9d0 → 0x6c5f755f72647800 [...]
You can check mappings without a path associated using an address range.
gef➤ scan 0x555555554000-0x555555555000 libc [+] Searching for addresses in '0x555555554000-0x555555555000' that point to 'libc'