åå ã¯ããå
¥éã»ãã¥ãªãã£ã³ã³ãã¹ãã¼ã¼CTFã解ããªããå¦ã¶å®æ¦æè¡ããèªãã§ãCTF ã®åã¸ã£ã³ã«ãã¨ã«ä½¿ããã¦ããæè¡ããã¼ã«ã«ã¤ãã¦ã調ã¹ãããå®éã«ä½¿ã£ã¦ã¿ãããã¾ããã
ä»åã¯ãx86-64 ELFï¼Linuxï¼ã®ã¢ã»ã³ãã©ãç解ãã¦ããã¾ããã¾ãããã使ã GDBã³ãã³ããããã¤ããªã«å¯¾ãã¦ãã使ãã³ãã³ããx86-64 ã®ãã使ãå½ä»¤ãæ¸ãã¨ãã¦ãããã¨æãã¾ãã
ããã§ã¯ããã£ã¦ããã¾ãã
åèæç®
Ghidra ã®è§£èª¬ã主ã§ãããåé ã«ãx86ãx86-64 ã®ã¢ã¼ããã¯ãã£ãã¢ã»ã³ãã©ã解説ããã¦ãã¾ããä»åã¯ããã®è§£èª¬ããã¨ã«æ¸ãã¦ãã¾ãã
GDB ã®æ¬ã¯å°ãªãã®ã§ãããCQåºçã®å¤ãæ¸ç±ã¯ãããã¾ã¨ã¾ã£ã¦ããã¨æãã¾ããGDB ã®ã³ãã³ãã«ã¤ãã¦ããããç¨åº¦ãæ¸ãã¦ããã¦ããã®ã§ãããç縮çãæ¸ãã¦ã¦ã»ããã£ãã§ãã
ã¯ããã«
ãã»ãã¥ãªãã£ãã®è¨äºä¸è¦§ã§ããè¯ãã£ããåèã«ãã¦ãã ããã
ã»ãã¥ãªãã£ã®è¨äºä¸è¦§
æ®éã® GDB ã¯ãããã°ããã«ã¯ä¸ä¾¿ãªã®ã§ãæåã« gdb-peda ãå°å
¥ãã¦ããã¾ãï¼ç¾å¨ã¯ããã¼ãé åã確èªã§ãã pwndbg ã«ç§»è¡æ¸ã¿ã§ãï¼ã
ç°å¢ã¯ãVirtualBoxï¼ParrotOS 6.1 ã§ãã
ããã§ã¯ããã£ã¦ããã¾ãã
gdb-pedaã®å°å
¥æ¹æ³
gdb-peda ã®å
¬å¼ã® GitHub ã¯ä»¥ä¸ã§ãã
github.com
Installation ã«ãå°å
¥æ¹æ³ãæ¸ããã¦ãã¾ãã®ã§ãããã«å¾ãã¾ãï¼ã¤ã³ã¹ãã¼ã«å
ã¯å¤æ´ãã¦ãã¾ãï¼ã
$ git clone https://github.com/longld/peda.git
$ echo "source ~/Downloads/peda/peda.py" >> ~/.gdbinit
ã§ã¯ãgdb-peda ãå°å
¥ããç¶æ
ã§ãGDB ãèµ·åãã¦ã¿ã¾ãã
$ gdb -q exec_me_revenge
ãã®å¾ãstart ãå®è¡ããã¨ã以ä¸ã®ããã«ãã¬ã¸ã¹ã¿ãã³ã¼ããã¹ã¿ãã¯ã常ã«è¡¨ç¤ºãããããã«ãªãã¾ããã¨ã¦ã便å©ã§ããã
gdb-peda ã®å°å
¥æ¹æ³ã¯ä»¥ä¸ã§ãã
pwndbgã®å°å
¥æ¹æ³
gdb-peda ã§ã¯ããã¼ãé åã®æ
å ±ã表示ã§ãã¾ããã§ããï¼ç§ã®ç°å¢ã ãããããã¾ããï¼ãããã§ãããèã pwndbg ãå°å
¥ãããã¨æãã¾ãã
pwndbg ã®å
¬å¼ãµã¤ãã¯ä»¥ä¸ã§ãã
github.com
å
¬å¼ãµã¤ãã®å°å
¥æé éãã«å°å
¥ãã¦ã¿ã¾ãã
ããããã¤ã³ã¹ãã¼ã«ãããããã«è¦ãã¾ãã
$ git clone https://github.com/pwndbg/pwndbg
$ cd pwndbg/
$ ./setup
å®äºããã®ã§ãæ©é GDB ãèµ·åãã¦ã¿ã¾ããããã¨ã©ã¼ãåºã¾ããgdb-pedaã¨ã®ä½µç¨ã¯ã§ããªãããã§ãã.gdbinit ãç·¨éãã¾ããgdb-peda 㨠pwndbg ã¯ä¸¡æ¹ã¨ãã.gdbinit ã« 1è¡ãã¤æ¸ãè¾¼ãã§ããã ããªã®ã§ãgdb-peda ã®æ¹ã® source ãã³ã¡ã³ãã¢ã¦ããã¾ãããããã¨ãã¨ã©ã¼ã¯åºãªããªãã¾ããã
$ nano ~/.gdbinit
$ cat ~/.gdbinit
source /home/user/Downloads/pwndbg/gdbinit.py
å°ã使ã£ã¦ã¿ã¾ãããããã®ã¾ã¾ã ã¨ãTeraTerm ã§ä½¿ãã«ã¯å³ããã§ãããASCIIã³ã¼ã以å¤ã®æåã使ããã¦ããã®ã§ããããã¨ããã§ãï¼ã«ãªãã¾ããASCIIã³ã¼ãã ãã§è¡¨ç¤ºããæ¹æ³ãããã¨æãã®ã§ãããã¡ãã£ã¨èª¿ã¹ã¦ã¿ã¾ãã
å¾æ¥ã調ã¹ã¾ãããTeraTermã®ãã¼ã¸ã§ã³5以éã使ãã¨ãä¸ã® ? ã«ãªã£ã¦ãã¾ãåé¡ã¯è§£æ¶ãã¾ããTeraTerm ã®å
¬å¼ãµã¤ãã«ããã¨ãUnicode ã¸ã®å¯¾å¿ãé²ãã ããã§ããããã«ãããâ?
ã¨ãªã£ã¦ããã¨ããããââ¸
ã¨æå³éãã«è¡¨ç¤ºã§ããããã«ãªã£ãã®ã ã¨æãã¾ãã
ç°¡åãªããã°ã©ã ã§x86-64 ELFãGDBã§ãããã°ãéå§ãã¦ã¿ã
ç°¡å㪠Cè¨èªã®ããã°ã©ã ãèªåã§æ¸ãã¦ã¿ã¾ãããããã使ã£ã¦ãGDB ã§åãããªãããx86-64 ELF ã®åä½ãç解ãã¦ããã¾ãã
使ç¨ããç°¡åãªCè¨èªããã°ã©ã
mainé¢æ°ãããsubé¢æ°ãå¼ã³åºããsubé¢æ°ã®ä¸ã§ãprintfé¢æ°ãå®è¡ãscanfé¢æ°ãå®è¡ãã¦ãæ°å¤ãåãåããæ»ãå¤ã§mainé¢æ°ã«è¿ãã¾ããmainé¢æ°ã¯ãæ»ãå¤ã 0 è¶
ãªãã·ã¹ãã ã« 0 ãè¿ãããã以å¤ãªã 1 ãè¿ãã¾ãã
#include <stdio.h>
int sub( void )
{
int data;
printf( "input data: " );
scanf( "%d", &data );
return data;
}
int main( int argc, void *argv[] )
{
int ret;
ret = sub();
if( ret > 0 )
return 0;
else
return 1;
}
ç°¡åã«å®è¡ãã¦ã¿ã¾ãã
$ gcc -g -o hello_world.out hello_world.c
$ ./hello_world.out
input data: 0
$ echo $?
1
$ ./hello_world.out
input data: 1
$ echo $?
0
æ³å®ãã¦ããéãã«åä½ãã¦ããããã§ãã
ããã°ã©ã ã®æ¦è¦ã調ã¹ã
GDB ã§åä½ã確èªããåã«ãããã°ã©ã ã®æ¦è¦ã調ã¹ã¾ãã
ELFãããã«ããã¨ãã¨ã³ããªãã¤ã³ãã¯ã0x1060 ã§ããã»ã¯ã·ã§ã³ãããã® textã»ã¯ã·ã§ã³ãã0x1060 ããå§ã¾ã£ã¦ãã¾ãã
$ file hello_world.out
hello_world.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=89d00684582cd697b573c0fd49c38d4f17146450, for GNU/Linux 3.2.0, with debug_info, not stripped
$ readelf -h hello_world.out
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2 s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1060
Start of program headers: 64 (bytes into file)
Start of section headers: 15088 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 37
Section header string table index: 36
$ readelf -l hello_world.out
Elf file type is DYN (Position-Independent Executable file)
Entry point 0x1060
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318 0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000670 0x0000000000000670 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 0x00000000000001b9 0x00000000000001b9 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000 0x0000000000000114 0x0000000000000114 R 0x1000
LOAD 0x0000000000002dd0 0x0000000000003dd0 0x0000000000003dd0 0x0000000000000250 0x0000000000000258 RW 0x1000
DYNAMIC 0x0000000000002de0 0x0000000000003de0 0x0000000000003de0 0x00000000000001e0 0x00000000000001e0 RW 0x8
NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358 0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x0000000000002014 0x0000000000002014 0x0000000000002014 0x0000000000000034 0x0000000000000034 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002dd0 0x0000000000003dd0 0x0000000000003dd0 0x0000000000000230 0x0000000000000230 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .plt.got .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.gnu.property
08 .note.gnu.build-id .note.ABI-tag
09 .note.gnu.property
10 .eh_frame_hdr
11
12 .init_array .fini_array .dynamic .got
$ readelf -S hello_world.out
There are 37 section headers, starting at offset 0x3af0:
Section Headers:
[Nr] Name Type Address Offset Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000318 00000318 000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.pr[...] NOTE 0000000000000338 00000338 0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.bu[...] NOTE 0000000000000358 00000358 0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000000037c 0000037c 0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0 0000000000000024 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000000003c8 000003c8 00000000000000c0 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000488 00000488 00000000000000a8 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000000530 00000530 0000000000000010 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 0000000000000540 00000540 0000000000000040 0000000000000000 A 7 1 8
[10] .rela.dyn RELA 0000000000000580 00000580 00000000000000c0 0000000000000018 A 6 0 8
[11] .rela.plt RELA 0000000000000640 00000640 0000000000000030 0000000000000018 AI 6 24 8
[12] .init PROGBITS 0000000000001000 00001000 0000000000000017 0000000000000000 AX 0 0 4
[13] .plt PROGBITS 0000000000001020 00001020 0000000000000030 0000000000000010 AX 0 0 16
[14] .plt.got PROGBITS 0000000000001050 00001050 0000000000000008 0000000000000008 AX 0 0 8
[15] .text PROGBITS 0000000000001060 00001060 0000000000000150 0000000000000000 AX 0 0 16
[16] .fini PROGBITS 00000000000011b0 000011b0 0000000000000009 0000000000000000 AX 0 0 4
[17] .rodata PROGBITS 0000000000002000 00002000 0000000000000014 0000000000000000 A 0 0 4
[18] .eh_frame_hdr PROGBITS 0000000000002014 00002014 0000000000000034 0000000000000000 A 0 0 4
[19] .eh_frame PROGBITS 0000000000002048 00002048 00000000000000cc 0000000000000000 A 0 0 8
[20] .init_array INIT_ARRAY 0000000000003dd0 00002dd0 0000000000000008 0000000000000008 WA 0 0 8
[21] .fini_array FINI_ARRAY 0000000000003dd8 00002dd8 0000000000000008 0000000000000008 WA 0 0 8
[22] .dynamic DYNAMIC 0000000000003de0 00002de0 00000000000001e0 0000000000000010 WA 7 0 8
[23] .got PROGBITS 0000000000003fc0 00002fc0 0000000000000028 0000000000000008 WA 0 0 8
[24] .got.plt PROGBITS 0000000000003fe8 00002fe8 0000000000000028 0000000000000008 WA 0 0 8
[25] .data PROGBITS 0000000000004010 00003010 0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000004020 00003020 0000000000000008 0000000000000000 WA 0 0 1
[27] .comment PROGBITS 0000000000000000 00003020 000000000000001f 0000000000000001 MS 0 0 1
[28] .debug_aranges PROGBITS 0000000000000000 0000303f 0000000000000030 0000000000000000 0 0 1
[29] .debug_info PROGBITS 0000000000000000 0000306f 000000000000012d 0000000000000000 0 0 1
[30] .debug_abbrev PROGBITS 0000000000000000 0000319c 00000000000000eb 0000000000000000 0 0 1
[31] .debug_line PROGBITS 0000000000000000 00003287 000000000000006c 0000000000000000 0 0 1
[32] .debug_str PROGBITS 0000000000000000 000032f3 00000000000000bc 0000000000000001 MS 0 0 1
[33] .debug_line_str PROGBITS 0000000000000000 000033af 000000000000003f 0000000000000001 MS 0 0 1
[34] .symtab SYMTAB 0000000000000000 000033f0 0000000000000390 0000000000000018 35 18 8
[35] .strtab STRTAB 0000000000000000 00003780 0000000000000200 0000000000000000 0 0 1
[36] .shstrtab STRTAB 0000000000000000 00003980 000000000000016a 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
GDBã§ãããã°ãéå§ãã¦ã¿ã
ã§ã¯ãæ©éèµ·åãã¦ã¿ã¾ããèµ·åããã¨ã以ä¸ã®ããã«ãå
¥åå¾
ã¡ã®ç¶æ
ã«ãªãã¾ãã
$ gdb -q hello_world.out
no key sequence terminator:
Reading symbols from hello_world.out...
gdb-peda$
ããã§ãã·ã³ãã«ãæ®ã£ã¦ãï¼mainé¢æ°ãåããï¼å ´åã¯ãstart ãå®è¡ãã㨠mainé¢æ°ã®å
é ã§æ¢ã¾ã£ã¦ããã¾ããä¸æ¹ãrun ãå®è¡ããã¨ãmainé¢æ°ã§ã¯æ¢ã¾ããããã¬ã¼ã¯ãã¤ã³ãã§æ¢ã¾ãããããã¯ãããã°ã©ã ã®æå¾ã¾ã§å®è¡ããã¾ãã
start ãå®è¡ãã¦ã¿ã¾ããæ
å ±éå¤ãã§ããã
Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled off'.
Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled on'.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[----------------------------------registers-----------------------------------]
RAX: 0x555555555185 (<main>: push rbp)
RBX: 0x7fffffffe358 --> 0x7fffffffe5da ("/home/user/svn/experiment/c/hello_world.out")
RCX: 0x555555557dd8 --> 0x555555555100 (<__do_global_dtors_aux>: endbr64)
RDX: 0x7fffffffe368 --> 0x7fffffffe606 ("SHELL=/bin/bash")
RSI: 0x7fffffffe358 --> 0x7fffffffe5da ("/home/user/svn/experiment/c/hello_world.out")
RDI: 0x1
RBP: 0x7fffffffe240 --> 0x1
RSP: 0x7fffffffe220 --> 0x7fffffffe358 --> 0x7fffffffe5da ("/home/user/svn/experiment/c/hello_world.out")
RIP: 0x555555555194 (<main+15>: call 0x555555555149 <sub>)
R8 : 0x0
R9 : 0x7ffff7fcf680 (<_dl_fini>: push rbp)
R10: 0x7ffff7fcb878 --> 0xc00120000000e
R11: 0x7ffff7fe1930 (<_dl_audit_preinit>: mov eax,DWORD PTR [rip+0x1b4e2]
R12: 0x0
R13: 0x7fffffffe368 --> 0x7fffffffe606 ("SHELL=/bin/bash")
R14: 0x555555557dd8 --> 0x555555555100 (<__do_global_dtors_aux>: endbr64)
R15: 0x7ffff7ffd020 --> 0x7ffff7ffe2e0 --> 0x555555554000 --> 0x10102464c457f
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x555555555189 <main+4>: sub rsp,0x20
0x55555555518d <main+8>: mov DWORD PTR [rbp-0x14],edi
0x555555555190 <main+11>: mov QWORD PTR [rbp-0x20],rsi
=> 0x555555555194 <main+15>: call 0x555555555149 <sub>
0x555555555199 <main+20>: mov DWORD PTR [rbp-0x4],eax
0x55555555519c <main+23>: cmp DWORD PTR [rbp-0x4],0x0
0x5555555551a0 <main+27>: jle 0x5555555551a9 <main+36>
0x5555555551a2 <main+29>: mov eax,0x0
No argument
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe220 --> 0x7fffffffe358 --> 0x7fffffffe5da ("/home/user/svn/experiment/c/hello_world.out")
0008| 0x7fffffffe228 --> 0x100000000
0016| 0x7fffffffe230 --> 0x0
0024| 0x7fffffffe238 --> 0x0
0032| 0x7fffffffe240 --> 0x1
0040| 0x7fffffffe248 --> 0x7ffff7df124a (<__libc_start_call_main+122>: mov edi,eax)
0048| 0x7fffffffe250 --> 0x0
0056| 0x7fffffffe258 --> 0x555555555185 (<main>: push rbp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Temporary breakpoint 1, main (argc=0x1, argv=0x7fffffffe358) at hello_world.c:18
18 ret = sub();
gdb-peda$
GDB ã§ã¯ãASLRï¼Address Space Layout Randomizationï¼ã¯ãããã©ã«ãã§ç¡å¹ã«ãªã£ã¦ããï¼æå¹ã«ãããã¨ãã§ããï¼ã®ã§ãæ¯ååãã¢ãã¬ã¹é
ç½®ã«ãªãã¾ãã
ã¾ããæå¾ã¾ã§å®è¡ããç¶æ
ã§ãããä¸åº¦ãrun ãªã©ãå®è¡ããã¨ãåå®è¡ãããã¨ãåºæ¥ã¾ãã
x86-64ã®åºæ¬çãªåä½ãç解ãã
主è¦ãªã¬ã¸ã¹ã¿ã®ç解
ã¾ããã¬ã¸ã¹ã¿ã«ã¤ãã¦ç°¡åã«ç解ãã¦ããã¾ãã
ã¬ã¸ã¹ã¿å |
æ¦è¦ |
ç¨é |
RIP |
ããã°ã©ã ã«ã¦ã³ã¿ |
ç¾å¨ã®ããã°ã©ã ã®ä½ç½®ã¢ãã¬ã¹ |
RSP |
ã¹ã¿ãã¯ãã¤ã³ã¿ |
ç¾å¨ã®ã¹ã¿ãã¯ãã¤ã³ã¿ã®ã¢ãã¬ã¹ |
RBP |
ãã¼ã¹ãã¤ã³ã¿ |
é¢æ°å
ã§ã¹ã¿ãã¯é åãæ±ãåºæºã¨ãªãã¢ãã¬ã¹ |
x86-64 ã§ã¯ãé¢æ°å¼ã³åºãã§ã¯ã以ä¸ã®åä½ãè¡ãã¾ãã
- callå½ä»¤ã§ã¯ãcallå½ä»¤ã®æ¬¡ã®å½ä»¤ã®ã¢ãã¬ã¹ãã¹ã¿ãã¯ã« push ãã¦ãRIP ãé¢æ°ã®å
é ã¢ãã¬ã¹ã«ã»ãããã
- å¼ã³åºãå
ã§ä½¿ç¨ãã¦ãã RBP ãã¹ã¿ãã¯ã« push ãã
- ç¾å¨ã® RSP ã RBP ã«ã»ãããã
ãã®å¾ãé¢æ°ã®å
é¨ã§ã¯ãRBP ãåºæºã¨ãã¦ã¹ã¿ãã¯ãæ±ãã¾ãã
ã¾ããé¢æ°ã®æå¾ã§ã¯ä»¥ä¸ã®åä½ãè¡ãã¾ãã1. 㨠2. 㯠leaveå½ä»¤ã§ãåãåä½ã«ãªãã¾ãã
- RBP ã RSP ã«ã»ããããï¼RSP ã¯ä¸ã®é¢æ°å¼ã³åºãã® 3. ã«æ»ãï¼
- ã¹ã¿ãã¯ã RBP ã« pop ããï¼RBP ãé¢æ°å¼ã³åºãæã®ç¶æ
ã«æ»ãï¼
- retå½ä»¤ã§ã¯ãç¾å¨ã®ã¹ã¿ãã¯ï¼ä¸ã®é¢æ°å¼ã³åºãã® 1. ã§ä¿åãã¦ãã callå½ä»¤ã®æ¬¡ã®å½ä»¤ã®ã¢ãã¬ã¹ï¼ã pop ã㦠RIP ã«ã»ãããã
ããã«ãããé¢æ°ã®å¼ã³åºãå
ã§ã¯ãcallå½ä»¤ã®å®è¡åã¨å®è¡å¾ã§ãRSPãRBP ãåãç¶æ
ãä¿æããã¾ãã
ã¹ã¿ãã¯
大ããã¢ãã¬ã¹ããå°ããã¢ãã¬ã¹ã«åãã£ã¦ãã¹ã¿ãã¯ã¯ä½¿ããã¦ããã¾ãã
é¢æ°ã®å¼ã³åºãè¦ç´
x86-64 ã®é¢æ°ã®å¼ã³åºãè¦ç´ã¯ãx86 ã¨ç°ãªãã¾ãã
x86 ã¯ãå¼æ°ã¯éé ï¼3ã¤ã®å¼æ°ã®ã¨ãã第3å¼æ°â第2å¼æ°â第1å¼æ°ã®é ï¼ã§ãå
¨ã¦ã¹ã¿ãã¯ã«ç©ã¾ãã¾ããæ»ãå¤ã¯ EAX ã«æ ¼ç´ãããé¢æ°ã®å¼ã³åºãå
ãã¹ã¿ãã¯ã解æ¾ãã¾ãã
x86-64 ã§ã¯ãå¼æ°ã¯ç¬¬6å¼æ°ã¾ã§ã¬ã¸ã¹ã¿ã§æ¸¡ããããã以éã¯ã¹ã¿ãã¯ã«ç©ã¾ãã¾ããã¬ã¸ã¹ã¿ã®é ã¯ã以ä¸ã®éãã§ãã
第1å¼æ° |
第2å¼æ° |
第3å¼æ° |
第4å¼æ° |
第5å¼æ° |
第6å¼æ° |
RDI |
RSI |
RDX |
RCX |
R8 |
R9 |
æ»ãå¤ã¯ RAX ã«æ ¼ç´ããã¾ãã
ã·ã¹ãã ã³ã¼ã«ã®å ´åã¯ãå°ãç°ãªãã以ä¸ã®ããã«ãªã£ã¦ãã¾ãã
ã¢ã¼ããã¯ã㣠|
å½ä»¤ |
çªå· |
第1å¼æ° |
第2å¼æ° |
第3å¼æ° |
第4å¼æ° |
第5å¼æ° |
第6å¼æ° |
x86 |
int 0x80 |
eax |
ebx |
ecx |
edx |
esi |
edi |
ebp |
x86-64 |
syscall |
RAX |
RDI |
RSI |
RDX |
r10 |
r8 |
r9 |
ç ´å£ï¼æ®çºæ§ï¼ã¬ã¸ã¹ã¿ã¨éç ´å£ï¼ä¸æ®çºæ§ï¼ã¬ã¸ã¹ã¿
- ç ´å£ï¼æ®çºæ§ï¼ã¬ã¸ã¹ã¿ï¼RAXãRCXãRDXãR8ï½R11ãXMM0ï½XMM5
- éç ´å£ï¼ä¸æ®çºæ§ï¼ã¬ã¸ã¹ã¿ï¼RBXãRBPãRDIãRSIãRSPãR12ï½R15ãXMM6ï½XMM15
ç°¡åãªããã°ã©ã ã§x86-64 ELFãGDBã§ãããã°ãã¦ã¿ã
ããã¾ã§ãè¸ã¾ãã¦ãç解ããã¢ã»ã³ãã©ã®å
容ãæ¸ãã¦ããã¾ãã
mainé¢æ°ã®ã¢ã»ã³ãã©ã®å
容
ã¾ããmainé¢æ°ã§ãã
æåã®2è¡ã¯ãmainé¢æ°ã§ãã£ã¦ããã決ã¾ãã®2è¡ã§ãããã®å¾ã® sub rsp,0x20
ã¯ãmainé¢æ°ã§ä½¿ç¨ãããã¼ã«ã«å¤æ°ã®ããã«ãã¹ã¿ãã¯ã確ä¿ãã¦ãã¾ãã
mov DWORD PTR [rbp-0x14],edi
㨠mov QWORD PTR [rbp-0x20],rsi
ã¯ã確ä¿ããã¹ã¿ãã¯ã«ã¬ã¸ã¹ã¿ã®å¤ãéé¿ãã¦ããã®ã ã¨æãã¾ãããçç±ã¯åããã¾ãããRDI 㨠RSI ã¯ãéç ´å£ã¬ã¸ã¹ã¿ãªã®ã§ãä¸ä½ã§ã±ã¢ããå¿
è¦ã¯ãªãã¯ãã§ããã¾ããmainé¢æ°ã¨ãã¦éé¿ãã¦ãã®ãã¨æãã¾ãããã使ç¨ãã¦ããªãã®ã§å¿
è¦ãªãã¯ãã§ãã
callå½ä»¤ã§ãsubé¢æ°ãå¼ã³åºãããã®å¾ãæ»ãå¤ã EAX ã«å
¥ã£ã¦ãã®ã§ã確ä¿ããã¹ã¿ãã¯ã«æ ¼ç´ãã¦ãã¾ããcmpå½ä»¤ã§ 0 ã¨æ¯è¼ãã¦ãjleå½ä»¤ã§åå²ãã¾ãã
cmpå½ä»¤ã¨ testå½ä»¤ã¯ã¹ãã¼ã¿ã¹ã¬ã¸ã¹ã¿ã«çµæãåæ ããã ãã§çµæã¯ã¬ã¸ã¹ã¿ã«ä¿åãã¾ãããjleå½ä»¤ã¯ãæåã« Jump ã® J ãä»ãã¦ãã®ã§ãã¸ã£ã³ãå½ä»¤ã§ãle ã¯ï¼ãã¶ãã§ããï¼less than equal ãªã®ã§ãå°ãããçããå ´åã«ã¸ã£ã³ããã¾ãã
ã¤ã¾ããsubé¢æ°ã®æ»ãå¤ãã0 ã¨æ¯ã¹ã¦ãå°ããããããã¯ãçããå ´åã« main+36ï¼1 ãè¿ãæ¹ï¼ã«ã¸ã£ã³ããã¾ããããã§ãªããã°ã0 ãè¿ãæ¹ãéããmain+41 ã«ã¸ã£ã³ããã¾ãã
æå¾ã¯ããã¡ãããmainé¢æ°ã§ãã£ã¦ããã決ã¾ãã®2è¡ã§ãã
gdb-peda$ disas main
Dump of assembler code for function main:
0x0000555555555185 <+0>: push rbp
0x0000555555555186 <+1>: mov rbp,rsp
0x0000555555555189 <+4>: sub rsp,0x20
0x000055555555518d <+8>: mov DWORD PTR [rbp-0x14],edi
0x0000555555555190 <+11>: mov QWORD PTR [rbp-0x20],rsi
=> 0x0000555555555194 <+15>: call 0x555555555149 <sub>
0x0000555555555199 <+20>: mov DWORD PTR [rbp-0x4],eax
0x000055555555519c <+23>: cmp DWORD PTR [rbp-0x4],0x0
0x00005555555551a0 <+27>: jle 0x5555555551a9 <main+36>
0x00005555555551a2 <+29>: mov eax,0x0
0x00005555555551a7 <+34>: jmp 0x5555555551ae <main+41>
0x00005555555551a9 <+36>: mov eax,0x1
0x00005555555551ae <+41>: leave
0x00005555555551af <+42>: ret
End of assembler dump.
subé¢æ°ã®ã¢ã»ã³ãã©ã®å
容
ç¶ãã¦ãsubé¢æ°ã§ããä¸ã§èª¬æãããã®ã¯çç¥ãã¾ãã
lea rax,[rip+0xeac] # 0x555555556004
ã¯ãRIP+0xEAC ã®ã¢ãã¬ã¹ã RAX ã«è¨å®ãã¾ããRIP ã¯ã1ã¤é²ãã ã¨ããï¼0x0000555555555158ï¼ã«ãªãã¾ããã³ã¡ã³ãã®éããçµæã¯ã0x555555556004
ã«ãªãã¾ããGDB ã§ããã®ã¢ãã¬ã¹ãè¦ã¦ã¿ã¾ãããprintfé¢æ°ã®å¼æ°ãå
¥ã£ã¦ãã¾ããã
gdb-peda$ x/s 0x555555556004
0x555555556004: "input data: "
å¼æ°ã RDI ã«æ ¼ç´ãã¦ãprintfé¢æ°ãå¼ã³åºãã¦ãã¾ãããã®å¾ãscanfé¢æ°ãå¼ã³åºãããã«ãã¾ã leaå½ä»¤ãããã¾ãã第2å¼æ°ããæºåãã¦ãã¾ããã¹ã¿ãã¯ã®ã¢ãã¬ã¹ï¼ãã¼ã«ã«å¤æ°ï¼ã RSI ã«ã»ãããã¦ãã¾ãã第1å¼æ°ã«ã¤ãã¦ã¯ãä¸å¿å
容ã確èªãã¦ããã¾ããæ£ããã%d
ãå
¥ã£ã¦ãã¾ããã
$ x/s 0x555555556011
0x555555556011: "%d"
ãã¨ã¯ãsubé¢æ°ã®æ»ãå¤ã¨ãã¦ãscanfé¢æ°ã®çµæã®ç¬¬2å¼æ°ã®å¤ãæ»ãå¤ã® EAX ã«ã»ãããã¦çµäºã§ãã
gdb-peda$ disas sub
Dump of assembler code for function sub:
0x0000555555555149 <+0>: push rbp
0x000055555555514a <+1>: mov rbp,rsp
0x000055555555514d <+4>: sub rsp,0x10
0x0000555555555151 <+8>: lea rax,[rip+0xeac]
0x0000555555555158 <+15>: mov rdi,rax
0x000055555555515b <+18>: mov eax,0x0
0x0000555555555160 <+23>: call 0x555555555030 <printf@plt>
0x0000555555555165 <+28>: lea rax,[rbp-0x4]
0x0000555555555169 <+32>: mov rsi,rax
0x000055555555516c <+35>: lea rax,[rip+0xe9e]
0x0000555555555173 <+42>: mov rdi,rax
0x0000555555555176 <+45>: mov eax,0x0
0x000055555555517b <+50>: call 0x555555555040 <__isoc99_scanf@plt>
0x0000555555555180 <+55>: mov eax,DWORD PTR [rbp-0x4]
0x0000555555555183 <+58>: leave
0x0000555555555184 <+59>: ret
End of assembler dump.
ç°¡åãªããã°ã©ã ãstripãã¦GDBã§ãããã°ãã¦ã¿ã
ããã¾ã§ã¯ãstrip ããã¦ããªãï¼ãããã°æ
å ±ãæ®ã£ã¦ããï¼ããã°ã©ã ãæ±ã£ã¦ãã¾ããããæ®é㯠strip ããã¦ããï¼ãããã°æ
å ±ã¯æ®ã£ã¦ããªãï¼ã¨æãã¾ããããããã¯ãå
ã»ã©ã®ããã°ã©ã ã strip ãã¦ãGDB ã§ãããã°ãã¦ã¿ã¾ãã
$ cp hello_world.out hello_world_strip.out
$ strip hello_world_strip.out
$ ll hello_world.out hello_world_strip.out
-rwxr-xr-x 1 user user 18K Sep 7 22:19 hello_world.out*
-rwxr-xr-x 1 user user 15K Sep 8 17:59 hello_world_strip.out*
ããã°ã©ã ã®æ¦è¦ã調ã¹ã
strip ãã¦ããªãããããã°æ
å ±ã®ããããã°ã©ã ã§ã¯ãreadelf ã®æ
å ±ã使ããªãã¦ããããã°åºæ¥ã¾ããããstrip ãããããã°ã©ã ã®å ´åã¯ããã®æ
å ±ãéè¦ã«ãªãã¾ãã
ã¨ã³ããªãã¤ã³ãã¯ãå
ã»ã©ã¨åãã§ã0x1060 ããå§ã¾ã£ã¦ãã¾ãã
$ file hello_world_strip.out
hello_world_strip.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=89d00684582cd697b573c0fd49c38d4f17146450, for GNU/Linux 3.2.0, stripped
$ readelf -h hello_world_strip.out
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2 s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1060
Start of program headers: 64 (bytes into file)
Start of section headers: 12624 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 29
Section header string table index: 28
$ readelf -l hello_world_strip.out
Elf file type is DYN (Position-Independent Executable file)
Entry point 0x1060
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318 0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000670 0x0000000000000670 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 0x00000000000001b9 0x00000000000001b9 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000 0x0000000000000114 0x0000000000000114 R 0x1000
LOAD 0x0000000000002dd0 0x0000000000003dd0 0x0000000000003dd0 0x0000000000000250 0x0000000000000258 RW 0x1000
DYNAMIC 0x0000000000002de0 0x0000000000003de0 0x0000000000003de0 0x00000000000001e0 0x00000000000001e0 RW 0x8
NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358 0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x0000000000002014 0x0000000000002014 0x0000000000002014 0x0000000000000034 0x0000000000000034 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000002dd0 0x0000000000003dd0 0x0000000000003dd0 0x0000000000000230 0x0000000000000230 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .plt.got .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.gnu.property
08 .note.gnu.build-id .note.ABI-tag
09 .note.gnu.property
10 .eh_frame_hdr
11
12 .init_array .fini_array .dynamic .got
$ readelf -S hello_world_strip.out
There are 29 section headers, starting at offset 0x3150:
Section Headers:
[Nr] Name Type Address Offset Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000318 00000318 000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.pr[...] NOTE 0000000000000338 00000338 0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.bu[...] NOTE 0000000000000358 00000358 0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000000037c 0000037c 0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0 0000000000000024 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000000003c8 000003c8 00000000000000c0 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000488 00000488 00000000000000a8 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000000530 00000530 0000000000000010 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 0000000000000540 00000540 0000000000000040 0000000000000000 A 7 1 8
[10] .rela.dyn RELA 0000000000000580 00000580 00000000000000c0 0000000000000018 A 6 0 8
[11] .rela.plt RELA 0000000000000640 00000640 0000000000000030 0000000000000018 AI 6 24 8
[12] .init PROGBITS 0000000000001000 00001000 0000000000000017 0000000000000000 AX 0 0 4
[13] .plt PROGBITS 0000000000001020 00001020 0000000000000030 0000000000000010 AX 0 0 16
[14] .plt.got PROGBITS 0000000000001050 00001050 0000000000000008 0000000000000008 AX 0 0 8
[15] .text PROGBITS 0000000000001060 00001060 0000000000000150 0000000000000000 AX 0 0 16
[16] .fini PROGBITS 00000000000011b0 000011b0 0000000000000009 0000000000000000 AX 0 0 4
[17] .rodata PROGBITS 0000000000002000 00002000 0000000000000014 0000000000000000 A 0 0 4
[18] .eh_frame_hdr PROGBITS 0000000000002014 00002014 0000000000000034 0000000000000000 A 0 0 4
[19] .eh_frame PROGBITS 0000000000002048 00002048 00000000000000cc 0000000000000000 A 0 0 8
[20] .init_array INIT_ARRAY 0000000000003dd0 00002dd0 0000000000000008 0000000000000008 WA 0 0 8
[21] .fini_array FINI_ARRAY 0000000000003dd8 00002dd8 0000000000000008 0000000000000008 WA 0 0 8
[22] .dynamic DYNAMIC 0000000000003de0 00002de0 00000000000001e0 0000000000000010 WA 7 0 8
[23] .got PROGBITS 0000000000003fc0 00002fc0 0000000000000028 0000000000000008 WA 0 0 8
[24] .got.plt PROGBITS 0000000000003fe8 00002fe8 0000000000000028 0000000000000008 WA 0 0 8
[25] .data PROGBITS 0000000000004010 00003010 0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000004020 00003020 0000000000000008 0000000000000000 WA 0 0 1
[27] .comment PROGBITS 0000000000000000 00003020 000000000000001f 0000000000000001 MS 0 0 1
[28] .shstrtab STRTAB 0000000000000000 0000303f 000000000000010a 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
Ghidraã使ã£ã¦mainé¢æ°ã®ã¢ãã¬ã¹ãç¹å®ãã
hello_world_strip.out ã«ã¤ãã¦ãGhidra ã使ã£ã¦è§£æãã¾ãã
Ghidra ã®ç°å¢æ§ç¯ã¨ä½¿ãæ¹ã«ã¤ãã¦ã¯ã以ä¸ãåç
§ãã¦ãã ããã
daisuke20240310.hatenablog.com
daisuke20240310.hatenablog.com
Ghidra ãèµ·åãã¦ãhello-world-strip ã¨ããååã§ããã¸ã§ã¯ããä½ããhello_world_strip.out ã解æããã¾ãã解æãçµããã¨ãentry ã表示ããã¾ããããªããWindow â Memory Map ãéãã家ã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãBase Image Address ã¯ã0 ã«å¤æ´ãã¾ããã
éã³ã³ãã¤ã«ç»é¢ãè¦ãã¨ã__libc_start_main()
ãè¦ãã¾ãã第1å¼æ°ã mainé¢æ°ãªã®ã§ãFUN_00001185
ãããã«ã¯ãªãã¯ãã¾ãã
ããã¨ãmainé¢æ°ã表示ããã¾ãããmainé¢æ°ã¨ã¯æ¸ãã¦ã¾ããããå
ã»ã©ã¨åãã¢ã»ã³ãã©ã³ã¼ãã並ãã§ãã¾ãã
mainé¢æ°ã®å
é ã¢ãã¬ã¹ã¯ããã¡ã¤ã«ã®å
é ãã 0x1185 ã«ãããã¨ãåããã¾ããã
GDBã§ãããã°ãéå§ãã¦ã¿ã
ã§ã¯ãGDB ãèµ·åãã¦ã¿ã¾ããå
ã»ã©ã¨éã£ã¦ãã·ã³ãã«æ
å ±ãèªã¿è¾¼ã¾ãã¾ããã§ããã
$ gdb -q hello_world_strip.out
no key sequence terminator:
Reading symbols from hello_world_strip.out...
(No debugging symbols found in hello_world_strip.out)
gdb-peda$
ã¾ããå
ã»ã©ã¨åãããã«ãstart ãå®è¡ãã¦ã¿ã¾ãã_start
ã§æ¢ã¾ã£ã¦ããã¾ããã
gdb-peda$ start
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x0
RCX: 0x0
RDX: 0x0
RSI: 0x0
RDI: 0x0
RBP: 0x0
RSP: 0x7fffffffe340 --> 0x1
RIP: 0x7ffff7fe5a40 (<_start>: mov rdi,rsp)
R8 : 0x0
R9 : 0x0
R10: 0x0
R11: 0x0
R12: 0x0
R13: 0x0
R14: 0x0
R15: 0x0
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x7ffff7fe5a35 <_dl_help+1285>: call 0x7ffff7fd1120 <_dl_init_paths>
0x7ffff7fe5a3a <_dl_help+1290>: jmp 0x7ffff7fe5560 <_dl_help+48>
0x7ffff7fe5a3f: nop
=> 0x7ffff7fe5a40 <_start>: mov rdi,rsp
0x7ffff7fe5a43 <_start+3>: call 0x7ffff7fe6640 <_dl_start>
0x7ffff7fe5a48 <_dl_start_user>: mov r12,rax
0x7ffff7fe5a4b <_dl_start_user+3>: mov rdx,QWORD PTR [rsp]
0x7ffff7fe5a4f <_dl_start_user+7>: mov rsi,rdx
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe340 --> 0x1
0008| 0x7fffffffe348 --> 0x7fffffffe5ce ("/home/user/svn/experiment/c/hello_world_strip.out")
0016| 0x7fffffffe350 --> 0x0
0024| 0x7fffffffe358 --> 0x7fffffffe600 ("SHELL=/bin/bash")
0032| 0x7fffffffe360 --> 0x7fffffffe610 ("NMAP_PRIVILEGED=")
0040| 0x7fffffffe368 --> 0x7fffffffe621 ("PWD=/home/user/svn/experiment/c")
0048| 0x7fffffffe370 --> 0x7fffffffe641 ("LOGNAME=user")
0056| 0x7fffffffe378 --> 0x7fffffffe64e ("XDG_SESSION_TYPE=tty")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Temporary breakpoint 1, 0x00007ffff7fe5a40 in _start () from /lib64/ld-linux-x86-64.so.2
gdb-peda$
ããã§ãããã»ã¹ã®ãããã調ã¹ã¾ããhello_world_strip.out ã¯ã0x555555554000 ã«ãã¼ãããã¦ãããã¨ãåããã¾ããå
ã»ã©ãmainé¢æ°ã®ä½ç½®ã¯ãå
é ãã 0x1185 ã¨åãã£ãã®ã§ããããã足ãã¨ã0x555555551185 ã« mainé¢æ°ãåå¨ãã¦ããã¯ãã§ãã
gdb-peda$ i proc map
process 81015
Mapped address spaces:
Start Addr End Addr Size Offset Perms objfile
0x555555554000 0x555555555000 0x1000 0x0 r--p /home/user/svn/experiment/c/hello_world_strip.out
0x555555555000 0x555555556000 0x1000 0x1000 r-xp /home/user/svn/experiment/c/hello_world_strip.out
0x555555556000 0x555555557000 0x1000 0x2000 r--p /home/user/svn/experiment/c/hello_world_strip.out
0x555555557000 0x555555559000 0x2000 0x2000 rw-p /home/user/svn/experiment/c/hello_world_strip.out
0x7ffff7fc5000 0x7ffff7fc9000 0x4000 0x0 r--p [vvar]
0x7ffff7fc9000 0x7ffff7fcb000 0x2000 0x0 r-xp [vdso]
0x7ffff7fcb000 0x7ffff7fcc000 0x1000 0x0 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7fcc000 0x7ffff7ff1000 0x25000 0x1000 r-xp /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ff1000 0x7ffff7ffb000 0xa000 0x26000 r--p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffff7ffb000 0x7ffff7fff000 0x4000 0x30000 rw-p /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
gdb-peda$
mainé¢æ°ã表示ãã¦ã¿ã¾ããç¡äºã«ãmainé¢æ°ã表示ããã¾ããã
gdb-peda$ x/10i 0x555555555185
0x555555555185: push rbp
0x555555555186: mov rbp,rsp
0x555555555189: sub rsp,0x20
0x55555555518d: mov DWORD PTR [rbp-0x14],edi
0x555555555190: mov QWORD PTR [rbp-0x20],rsi
0x555555555194: call 0x555555555149
0x555555555199: mov DWORD PTR [rbp-0x4],eax
0x55555555519c: cmp DWORD PTR [rbp-0x4],0x0
0x5555555551a0: jle 0x5555555551a9
0x5555555551a2: mov eax,0x0
ãã¨ã¯ãmainé¢æ°ã«ãã¬ã¼ã¯ãã¤ã³ããè¨å®ãã¦ãå®è¡ããã°ãå
ã»ã©ã¨åãããã«ãããã°ãåºæ¥ã¾ãã
$ b *0x555555555185
Breakpoint 2 at 0x555555555185
gdb-peda$ i b
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000555555555185
gdb-peda$ c
Continuing.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[----------------------------------registers-----------------------------------]
RAX: 0x555555555185 (push rbp)
RBX: 0x7fffffffe348 --> 0x7fffffffe5ce ("/home/user/svn/experiment/c/hello_world_strip.out")
RCX: 0x555555557dd8 --> 0x555555555100 (endbr64)
RDX: 0x7fffffffe358 --> 0x7fffffffe600 ("SHELL=/bin/bash")
RSI: 0x7fffffffe348 --> 0x7fffffffe5ce ("/home/user/svn/experiment/c/hello_world_strip.out")
RDI: 0x1
RBP: 0x1
RSP: 0x7fffffffe238 --> 0x7ffff7df124a (<__libc_start_call_main+122>: mov edi,eax)
RIP: 0x555555555185 (push rbp)
R8 : 0x0
R9 : 0x7ffff7fcf680 (<_dl_fini>: push rbp)
R10: 0x7ffff7fcb878 --> 0xc00120000000e
R11: 0x7ffff7fe1930 (<_dl_audit_preinit>: mov eax,DWORD PTR [rip+0x1b4e2]
R12: 0x0
R13: 0x7fffffffe358 --> 0x7fffffffe600 ("SHELL=/bin/bash")
R14: 0x555555557dd8 --> 0x555555555100 (endbr64)
R15: 0x7ffff7ffd020 --> 0x7ffff7ffe2e0 --> 0x555555554000 --> 0x10102464c457f
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x555555555180: mov eax,DWORD PTR [rbp-0x4]
0x555555555183: leave
0x555555555184: ret
=> 0x555555555185: push rbp
0x555555555186: mov rbp,rsp
0x555555555189: sub rsp,0x20
0x55555555518d: mov DWORD PTR [rbp-0x14],edi
0x555555555190: mov QWORD PTR [rbp-0x20],rsi
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe238 --> 0x7ffff7df124a (<__libc_start_call_main+122>: mov edi,eax)
0008| 0x7fffffffe240 --> 0x0
0016| 0x7fffffffe248 --> 0x555555555185 (push rbp)
0024| 0x7fffffffe250 --> 0x100000000
0032| 0x7fffffffe258 --> 0x7fffffffe348 --> 0x7fffffffe5ce ("/home/user/svn/experiment/c/hello_world_strip.out")
0040| 0x7fffffffe260 --> 0x7fffffffe348 --> 0x7fffffffe5ce ("/home/user/svn/experiment/c/hello_world_strip.out")
0048| 0x7fffffffe268 --> 0x3c24da9e3bd1cf39
0056| 0x7fffffffe270 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 2, 0x0000555555555185 in ?? ()
gdb-peda$
strip ãããããã°ã©ã ã GDB ã§ãããã°ããæ¹æ³ã¯ä»¥ä¸ã§ãã
ç¾æç¹ã§åãã£ã¦ãªããã¨
- leaå½ä»¤ãªã©ã§ãRAX ã«è¨å®ããå¾ãä»ã®ã¬ã¸ã¹ã¿ã« mov ãã¦ãããæåããä»ã®ã¬ã¸ã¹ã¿ã対象㫠leaå½ä»¤ãå®è¡ã§ããªãã®ãï¼
- ããé¢æ°ã§ããã¼ã«ã«å¤æ°ã¨ãã¦ã¹ã¿ãã¯ã 4byte ãã使ã£ã¦ããªãã®ã«ãã¹ã¿ãã¯ã¯ 16byte 確ä¿ããã¦ãããããªããï¼ï¼8byteã§ããã®ã§ã¯ï¼ï¼
- é¢æ°å¼ã³åºãæã« EAX ãã¼ãã¯ãªã¢ãã¦ããé¢æ°ãå¼ã³åºãã¦ãããããªããï¼
- RDI 㨠RSI ã¯ãéç ´å£ã¬ã¸ã¹ã¿ãªã®ã«ãä¸ä½ã§éé¿ãã¦ããã®ã¯ãªããï¼
ãããã°ã³ã³ã½ã¼ã«ã§ãã使ãGDBã³ãã³ã
GDB ã§ã¯ãç¾å¨ã®ã¬ã¸ã¹ã¿ã®å¤ãè¦ãããéã¢ã»ã³ãã©ã³ã¼ããè¦ãããã¹ãããå®è¡ãããããã¨ãã«ãGDBã®ã³ãã³ããä¸è¦§ã«ãã¦ããã¾ããVSCode ã§ãGDBã³ãã³ããå®è¡ããã«ã¯ããããã°ã³ã³ã½ã¼ã«ãéãã¦ãã-exec GDBã³ãã³ããã¨å
¥åãã¾ãã
ä¾ãã°ãinfo registers ã®ã³ãã³ããå®è¡ãããå ´åã¯ãã-exec info registersãã¨å
¥åãã¦ãªã¿ã¼ã³ãã¼ãæ¼ãã¨å®è¡ã§ãã¾ãããã¡ãããç縮形ã®ã-exec i rãã§ãåããã¨ãåºæ¥ã¾ãã
以ä¸ã®è¡¨ã§ã¯ã-exec
ã¯çç¥ãã¦ãã¾ããã¾ãããªãã¹ãç縮形ã®æ¹ãæ¸ãã¦ããã¾ãã
ã³ãã³ã |
å
容 |
start |
å®è¡éå§ããï¼ã·ã³ãã«æ
å ±ãããã°mainé¢æ°ã§æ¢ã¾ãï¼ |
rï¼runï¼ |
å®è¡éå§ããï¼mainé¢æ°ã§æ¢ã¾ããªãï¼ |
cï¼continueï¼ |
å®è¡ãåéãã |
sï¼stepï¼ |
Cè¨èªã®ã¹ãããå®è¡ããã |
si |
ã¢ã»ã³ãã©ã®ã¹ãããå®è¡ããã |
nï¼nextï¼ |
Cè¨èªã®ã¹ããããªã¼ãã¼ï¼é¢æ°ã«å
¥ããªãï¼å®è¡ããã |
ni |
ã¢ã»ã³ãã©ã®ã¹ããããªã¼ãã¼ï¼é¢æ°ã«å
¥ããªãï¼å®è¡ããã |
finï¼finishï¼ |
é¢æ°ãæããã¾ã§å¦çãå®è¡ãã |
b é¢æ°åï¼breakï¼ |
æå®ããé¢æ°ã«ãã¬ã¼ã¯ãã¤ã³ããè¨å®ãã |
b *ã¢ãã¬ã¹ |
æå®ããã¢ãã¬ã¹ã«ãã¬ã¼ã¯ãã¤ã³ããè¨å®ãã |
tb *ã¢ãã¬ã¹ï¼tbreakï¼ |
æå®ããã¢ãã¬ã¹ã«1度ã ãæå¹ãªãã¬ã¼ã¯ãã¤ã³ããè¨å®ãã |
i bï¼info breakpointsï¼ |
ãã¬ã¼ã¯ãã¤ã³ãã®ä¸è¦§ã表示ãã |
d åé¤ãããã¬ã¼ã¯ãã¤ã³ãçªå·ï¼deleteï¼ |
ä¸ã®ãã¬ã¼ã¯ãã¤ã³ãã®ä¸è¦§ã§åé¤ãããçªå·ãæå®ããã¨ãã¬ã¼ã¯ãã¤ã³ããåé¤ã§ãã |
i rï¼info registersï¼ |
æ´æ°ã®ã¬ã¸ã¹ã¿ãå
¨ã¦è¡¨ç¤ºãã |
i r $sp |
ã¹ã¿ãã¯ãã¤ã³ã¿ã®ã¬ã¸ã¹ã¿ã表示ãã |
i r $x0 $x1 |
x0 㨠x1 ã®ã¬ã¸ã¹ã¿ã表示ãã |
i proc map |
ã¡ã¢ãªãããã表示ãã |
x/b $sp |
SPãæãã¦ããã¡ã¢ãªã1ãã¤ã表示ãã |
x/xb $sp |
SPãæãã¦ããã¡ã¢ãªã®1ãã¤ãã16é²æ°ã§è¡¨ç¤ºãã |
x/xw $sp |
SPãæãã¦ããã¡ã¢ãªã®1ã¯ã¼ãï¼4byteï¼ã16é²æ°ã§è¡¨ç¤ºãã |
x/4xw $sp |
SPãæãã¦ããã¡ã¢ãªã®4ã¯ã¼ãï¼4byteÃ4ï¼ã16é²æ°ã§è¡¨ç¤ºãã |
x/xg $sp |
SPãæãã¦ããã¡ã¢ãªã®8ãã¤ãã16é²æ°ã§è¡¨ç¤ºãã |
x/s $sp |
SPãæãã¦ããã¡ã¢ãªã®æååã表示ãã |
x/10i ã¢ãã¬ã¹ |
æå®ããã¢ãã¬ã¹ã®ã³ã¼ãã表示ãã |
set $rax=0x10 |
æå®ã®ã¬ã¸ã¹ã¿ã«å¤ãæ¸ãè¾¼ã |
以éã¯ãpwndbg ãå°å
¥ããå ´åã«ä½¿ããã³ãã³ãã§ãã
ã³ãã³ã |
å
容 |
tele |
ã¡ã¢ãªãããæãã«è¡¨ç¤ºãã¦ããããããã©ã«ãã¯ãã¤ã表示ãã¦ããã¦ãã [ STACK ] ã表示ããã |
tele rsp 20 |
ã¹ã¿ãã¯ï¼rspï¼ãå
é ã¨ãã¦20ååã®å
容ãããæãã«è¡¨ç¤ºãã¦ããã |
nearpc |
éã¢ã»ã³ãã©ã表示ãããããã©ã«ãã¯ãã¤ã表示ãã¦ããã¦ããéã¢ã»ã³ãã© |
nearpc 20 |
éã¢ã»ã³ãã©ã20è¡å表示ãã |
elfheader |
ã»ã¯ã·ã§ã³ã®ã¢ãã¬ã¹è¡¨ç¤º |
got |
GOTé åã®è¡¨ç¤º |
vmmap |
ã¡ã¢ãªãããã®è¡¨ç¤º |
retaddr |
ãªã¿ã¼ã³ã¢ãã¬ã¹ã®è¡¨ç¤º |
heap |
ãã¼ãé åã®ãã£ã³ã¯ã表示ããã |
arena |
arenaã®æ
å ±ã®è¡¨ç¤º |
bins |
binsã®æ
å ±ã®è¡¨ç¤º |
fastbins |
fastbinsã®æ
å ±ã®è¡¨ç¤º |
tcachebins |
tcachebinsã®æ
å ±ã®è¡¨ç¤º |
unsortedbin |
unsortedbinã®æ
å ±ã®è¡¨ç¤º |
largebins |
largebinsã®æ
å ±ã®è¡¨ç¤º |
smallbins |
smallbinsã®æ
å ±ã®è¡¨ç¤º |
ãã¤ããªãæ±ãã³ãã³ãã®ã¾ã¨ã
ãã使ããã¤ããªãæ±ãã³ãã³ããåæãã¾ãã
objdump ã«ããéã¢ã»ã³ãã©ã®åºåã¯ãä½ãæå®ããªãå ´åã¯ãAT&Tè¨æ³ã¨å¼ã°ãããã©ã¼ãããã¨ãªãã¾ããããã¯ãGDBãGhidra ã§è¦ããã Intelè¨æ³ã¨ã¯ãã½ã¼ã¹ã¨ãã¹ãã£ãã¼ã·ã§ã³ãå
¥ãæ¿ãããããå
¨ãç°ãªãã¾ãã常ã«ã-M intel
ãæå®ããã®ãããããã§ãã
ã³ãã³ã |
å
容 |
file a.out |
a.outã®ãã¡ã¤ã«ã®æ¦è¦ã表示ãã |
strings a.out |
a.outã«å«ã¾ããæååã®ãã¡ã¤ã«ã®æ¦è¦ã表示ããï¼ããã©ã«ãï¼å¯èªé¨åã4æå以ä¸é£ç¶ï¼ |
strip a.out |
a.outã«å«ã¾ããã·ã³ãã«æ
å ±ãä¸é¨ãæ®ãã¦åé¤ãã |
objdump -M intel -d a.out > a.s |
éã¢ã»ã³ãã©ãåºåãã |
objdump -M intel -d -j .plt a.out |
ç¹å®ã®ã»ã¯ã·ã§ã³ã®éã¢ã»ã³ãã©ãåºåãã |
readelf -h a.out |
ELFããããåºåãã |
readelf -l a.out |
ããã°ã©ã ããããåºåãã |
readelf -S a.out |
ã»ã¯ã·ã§ã³ããããåºåãã |
readelf -s a.out |
ã·ã³ãã«ãã¼ãã«ãåºåãã |
readelf -r a.out |
ãªãã±ã¼ã·ã§ã³æ
å ±ãåºåãã |
checksec --file=a.out |
ã»ãã¥ãªãã£æ©æ§ãåºåãã |
x86-64ã®å½ä»¤ã¾ã¨ã
ãã使ã x86-64 ã®å½ä»¤ãã¾ã¨ãã¦ããã¾ãã
å½ä»¤ |
å
容 |
mov dest, src |
src ã dest ã«ã³ãã¼ãã |
push value |
value ãã¹ã¿ãã¯ã«ä¿åãRSP 㯠-8 |
pop dest |
ã¹ã¿ãã¯ã®å¤ã dest ã«åå¾ãRSP 㯠+8 |
add dest, src |
dest 㨠src ãå ç®ã㦠dest ã«ä¿å |
sub dest, src |
dest ãã src ãæ¸ç®ã㦠dest ã«ä¿å |
mul src |
RAX 㨠src ãä¹ç®ãã¦ä¸ä½32bitã RDX ã«ä¸ä½32bitã RAX ã«ä¿åï¼RDX:RAXï¼ â»8bitå士ã®ä¹ç®ã¯ AX ã«ä¿åãã㦠RDX ã¯å½±é¿ãåããªããããã以å¤ã¯ RDX ã¯æ¸ãè¾¼ã¾ãããã¨ã«æ³¨æ |
imul src |
ãªãã©ã³ãã 1ã¤ã®å ´å㯠mul ã®ç¬¦å·ä»çã§ããªãã©ã³ãã2ã¤ã3ã¤ã®å ´åã¯çµæã RAX ã«ä¿åãããRDX ã¯å½±é¿ãåããªã |
div src |
ä¸ä½32bitã RDX ã«ä¸ä½32bitã RAXï¼RDX:RAXï¼ã src ã§é¤ç®ãã¦åã RAX ã«ä½ã RDX ã«ä¿å |
xor dest, src |
dest 㨠src ãæä»çè«çåã㦠dest ã«ä¿å |
call function |
é¢æ°å¼ã³åºã |
ret |
é¢æ°ããå¼ã³åºãå
ã«æ»ã |
shl dest, src |
dest ã src ã ãå·¦è«çã·ããã㦠dest ã«ä¿å |
cmp src1, src2 |
src1 㨠src2 ãæ¯è¼ãã¦çµæã EFLAGSã¬ã¸ã¹ã¿ã«ã»ãã |
jmp address |
address ã«ç¡æ¡ä»¶ã¸ã£ã³ã |
jz address |
ã¼ãã®å ´åï¼ZF=1ï¼ã¯ address ã«ã¸ã£ã³ã |
jnz address |
ã¼ãã§ãªãå ´åï¼ZF=0ï¼ã¯ address ã«ã¸ã£ã³ã |
jl address |
å°ããå ´åï¼SF=0ï¼ã¯ address ã«ã¸ã£ã³ã |
jle address |
å°ãããã¾ãã¯ãçããå ´å㯠address ã«ã¸ã£ã³ã |
jg address |
大ããå ´å㯠address ã«ã¸ã£ã³ã |
jge |
大ãããã¾ãã¯ãçããå ´å㯠address ã«ã¸ã£ã³ã |
ãããã«
ä»åã¯ãPC Linux ã®ã¢ã»ã³ãã©ãç解ãã¦ã¿ã¾ãããx86-64 ã®ã¢ã»ã³ãã©ã¯ä»ååãã¦ã§ããããARM ã¨ããã¾ã§éãã¨ããããã§ã¯ãªãã£ãã®ã§ãä½ã¨ãç°¡åãªã¨ããã¯ç解ã§ããã¨æãã¾ãã
æåæ°ã¯ 4ä¸æåãè¶
ãã¾ãããã ãã¶éãã§ãï¼ç¬ï¼ã
ä»åã¯ä»¥ä¸ã§ãã
æå¾ã«ãªãã¾ããããã¨ã³ã¸ãã¢ã°ã«ã¼ãã®ã©ã³ãã³ã°ã«åå ä¸ã§ãã
æ°æ¥½ã«ãããã¨ãããããé¡ããããã¾ãð
ä»åã¯ä»¥ä¸ã§ãï¼
æå¾ã¾ã§ãèªã¿ããã ãããããã¨ããããã¾ããã