Memory Layout in Program Execution α׷ ޸ By Fr??ick Giasson fred@decatomb.com http://www.decatomb.com October 2001 Copyrights, 2001, Fr??ick Giasson ó : http://web.textfiles.com/computers/memorylayout.txt ==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+ : 赿(dskim@mail.hau.ac.kr), Network Security Lab(http://nslab.hau.ac.kr) /* ְų ñ ּ */ : mutacker, mutacker@mail.hau.ac.kr ==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+ Table of Contents: ------------------ Preface Introduction Introduction Chapter 1: 1:... Program execution: The route map. 1.1:.... The pseudo-shell code. 1.2:.... Create a child Process. 1.2.1:..... FORKS system call: the nine steps. 1.3:.... Execute the program. 1.3.1:..... C run-time, start-off procedure. 1.3.2:..... EXEC system call, the nine steps. Chapter 2: 2:... Memory layout in executed program. 2.1:.... Dissection of the ELF executable file. Chapter 3: 3:... The Stack and the Heap. 3.1:.... Where are they? 3.2:.... How to know what's the size of the user stack frame at compilation? 3.3:.... Registers. 3.3.1:..... Generals Registers. 3.3.2:..... Segments register. 3.3.3:..... Offsets Registers. 3.4:.... The stack. 3.4.2:..... Stack management during procedure calling. 3.4.2.1:...... The call. 3.4.2.2:...... The Prologue. 3.4.2.3:...... The return. 3.5:.... The Heap. Conclusion Annex 1 Annex 2 Annex 3 Bibliography Preface: -------- ̰ ù ° ̴. ʺڳ ߰ ý , α׷, Ŀ , ̷ , Ǵ ִ ǻͱ ̴. Ƿ¿ ؼ ϰ, Ǽ ߰Ѵٸ Ⲩ ϰ ˷ֽŴٸ, ۿ ̴. ٸ ڵ Բ ϱ⸦ ϴٸ, ؼ Ư Ͽ ֱ⸦ ٶ. - http://www.decatomb.com/forums/viewforum.php?forum=29 Ұ: ----- ޸  ü ߿ ̴. ̰ ý ߿ ڿ̸ ɽ ٷ ʿ䰡 ִ. ޸ ý ٷ ̴. ƴ, 츮 ޸ ýۿ ̴. 츮 α׷  Ǵ ׸ ޸𸮷  Ǵ ̴. , ޸ ýۿ ٸ κ ִ: , ޸, ü ˰, ׸̼ . ׷ ü ޸ ý μ() ϱ Ѵٸ, ׷ ڼ ⸦ ٶ. ű⿡ /н ̴н ޸ ýۿ ڿ ִ.  μ ۵Ǵ ϱ ؼ ̴н ޸ ý ̿ ̴. ̰ NetBSD, FreeBSD ELF A-32 ü Ű̴. α׷ Ͽ GCC ̰, ο(low) ȯ濡 츮 α׷  ϴ ſ ֱ 츮 α׷ ϱ ؼ GDB ̴. Chapter 1: Program execution: The route map: --------------------------------------------- α׷  ޸𸮿 εǴ ƴ ̷ο ̴. ׷ ̰(α׷)  Ǿ°? ù ° κп (route map) ôϵ ν α׷ ü μ  Ǵ ſ ̴. ڰ α׷ ̸ Ÿϰ ̴. ܰ α׷ ޸𸮿 εǾ غ ̴. ------ [Root@Seldon prog]# helloworld < Enter > Hello World! ------ ~, (helloworld) ϴ α׷ ̸ ŸϿ, Enter Ű . ġ ð ܼ â "Hello World" Ʈ Ÿ ̿ ߰Ǵ°? ̰ ΰ? ƴϴ! 1.1: The pseudo-shell code: --------------------------- ſ ⺻ α׷ ǻ-ڵ尡 ִ. : ------ #define TRUE 1 ARRAY command ARRAY parameters while(TRUE) { read_command_line(command,parameters); /* We are waiting to read an input from the terminal. In our example, command = "helloworld" and parameters = "" */ pid_t = fork(); /* pid_t contain the process ID of the child process */ if( pid_t != 0 ) /* If the PID isn't 0 then... { Note: The PID == 0 when it's the child's thread of execution. */ /* Parent code. */ waitpid(-1,&status,0); /* The program is waiting the end of the child execution ( -1 ) to continue the parent process }else{ ( the Shell ) */ /* Child Code. */ execve(command,parameters,0); /* Finally, we execute our helloworld program! */ } } ------ Ʈ 1: execve() Լ ڽ μ( fork() == 0 ) ȣǰ waitpid() θ μ ȣȴ( fork() == pid_t ) ------ ߴ°? . Ʒ ǻ- κ ſ ̴. 1.2: Create a child process: ---------------------------- , α׷ 츮 α׷ ϱ ο μ ϴ ʿ Ѵ. Minix Ͽ ̰ ϱ ִ. : ------ Minix: ------ do_fork() Linux: ------ fork() vfork() clone() ------ Ͽ fork() ó vfork() clone() Լ, μ 鿡 ణ . Լ . (man clone or man vfork). 츮 츮 fork()Լ ̴. fork()Լ ̴ Ѵ. Լ (file descriptions), , ͵, ͵ ϴ, θ μ Ȯ 繰 ̴. fork() ȣ , ڽμ θ μ ׵ и . fork() ȣÿ , Ŀ, θ ڽ ̰ ڽ μ θ𿡰, θ μ ڽ μ ġ ̴. θ ڽ μ ϰ ϴ ʴ ؽƮ(text) ̴. , FORK ý ȣ , ڽ μ Ǿ. fork() Լ , ý ȣ ڽ μ ĺ(PID) α׷ ȯ ̴. PID types.h ǵ ȣȭ ̴ : Ʈ 1: fork() ν FORK system call ̴. ̷ 信 ȥ . ------ Minix:Source: minix/include/sys/types.h -- typedef int pid_t; Linux:Source: /posix/sys/types.h -- ifndef __pid_t_defined typedef int __pid_t pid_t; ------ 1.2.1: FORKS system call: the nine steps: ----------------------------------------- FORK ý ȣ ϴ 9 ܰ谡 ִ: Ʈ 1: η(Annex) 1 ִ do_fork() ̷ ܰ ã ִ Ʈ 2: fork()Լ ڵ fork.c ľ glibcȿ ִ Ʈ 3: ̷ ܰ迡 ̴н ؼ 밡ϴ. ⺻ ؼ ϴ. ϰ ٸ Ŀο  μ Ǵ° ϴ ̴. 1- μ ̺ á üũ϶(η1 14ٿ 16) , μ ̺ ´ ΰ? μ ̺ Ŀ Ϻκ̴. ̺ Ǵ η 2 ִ. ̺ μ ͵, ޸ , ī(accounting), ׸ ۼؾ ޽ Ѵ. Ʈ 1: μ ̺ " /include/minix/config.h " ִ NR_PROCS ǵȴ. ------ #define NR_PROCS 32 ------ Ʈ 2: , μ ִ ½ũ ̴, Ʈ 512 Ʈ . 2- ڽ μ Ÿ ÿ ޸𸮸 Ҵϱ õѴ. 3- θ Ϳ ڽ ޸𸮷 Ѵ. 4- μ ã θ װ Ѵ. 5- μ ̺ ڽ ޸ ִ´ 6- ڽĿ PID Ѵ. Ʈ 1: , pid_t ݵ ȣȭ Ѵ 7- Ŀΰ ýۿ ڽĿ ؼ Ѵ FORK ý ȣ Ŀΰ ýۿ Ӱ μ ؼ ؾ ϴ°? ֳϸ ̴н μ , ޸ ׸ и ⿡ ؼ DZ ̴. ׷, μ ̺ 3κ ְ, ׷ κ װ ʿϴ ʵ带 . ޸ ϴ μ ̺ κ "/src/mm/mproc.h"ȿ ǵȴ ý ϴ μ ̺ κ "/src/fs/fproc.h" ǵȴ , Ŀο õ μ ̺ κ η 2 ǵȴ. 8- ڽ ޸ Ŀο Ѵ. 9- ޽ θ ڽĿ . Ʈ 1: ڽ μ 0̰ θ μ ڽ μ PID̴. 츮 ֵ,  κ ȣǴ ϳ α׷ ù° κ ׷ ʴ. FORK ý ȣ execve() ɿ ۵Ǿ 츮 ο α׷ ٷ ؼ ο μ ̴. ׷, μ ü , ý (μ ý, ½ũ, μ( ý, ޸ , Ʈũ), μ) 츮 do_fork() ȣ ȴ. ̰ ǥ ƴϱ 忡 ϱ ̴. 1.3: Execute the program: ------------------------- , 츮 ο μ ߴ. ; 츮 μ 츮 α׷ ϴµ ̴. execve()Լ "EXEC system call" ˷ ο ý ȣ ȣѴ. ý ȣ ϴ°? ̰ ޸ ̹ ο üϰ ο ޸ ̹ ο ¾Ų. ̴ Ͽ  α׷ Ű ִ. Minix: ------ do_exec() Ʈ 1: /src/mm/exec.c ̺귯ȿ . /src/fs/misc.c /src/kernel/system.c library ȿ ٸ do_exec() Լ ȿ ٸ Ϳ ؼ ̾߱ ̴. Linux: ------ execve() exec йи ν ٸ ִ, ڼ man pages : execl() execlp() execle() execv() execvp() , 츮 ޸𸮿 츮 ο ̹ ũ ִٰ ̴. EXEC ý ȣ⿡ α׷  Ǿ ̰, Ŀ do_exec() Լ ϴ ܰ踦 ̴. FOKR ý ȣ , Minix ü ؼ ȣȯǴ ̸, ׷ OSϿ ⺻ . EXEC ý ȣ , Ͽ Ŀ, ޸ , Ͻý ýۿ Ư ٸ Ư¡ õ ٸ ٷ , ϴ. 츮 츮 "mv hw pg" EXEC μ ϱ ޸ Ű ִ. Ʈ 1: "hw" "pr" ̸ ̴. Arrays passed to execve() ------------------------- execve() ޵Ǵ 迭 Argument Array --------------- | 0 | |---------------| | pr | |---------------| | hw | |---------------| | mv | --------------- ׸ 1.0 Environment Array --------------- | 0 | |---------------| | HOME=/root | --------------- ׸ 1.1 The stack build by execve() --------------------------- 3 2 1 0 --------------- 40 | \0| t | o | o | |---------------| 36 | r | / | = | E | |---------------| 32 | M | O | H | \0| |---------------| 28 | r | p | \0| w | |---------------| 24 | h | \0| v | m | |---------------| 20 | 0 | |---------------| 16 | 33 | |---------------| 12 | 0 | |---------------| 8 | 30 | |---------------| 4 | 27 | |---------------| 0 | 24 | --------------- Figure 1.2 The stack after relocation by the memory manager: (޸ ڿ Ҵ ): ------------------------------------------------- 3 2 1 0 --------------- 6532 | \0| t | o | o | |---------------| 6528 | r | / | = | E | |---------------| 6524 | M | O | H | \0| |---------------| 6520 | r | p | \0| w | |---------------| 6516 | h | \0| v | m | |---------------| 6512 | 0 | |---------------| 6508 | 6525 | |---------------| 6504 | 0 | |---------------| 6500 | 6522 | |---------------| 6496 | 6519 | |---------------| 6492 | 6516 | --------------- ׸ 1.3 The stack as it appears to main() at the start of execution: ( ۽ÿ main() Ÿ ) ------------------------------------------------------------- 3 2 1 0 --------------- 6532 | \0| t | o | o | |---------------| 6528 | r | / | = | E | |---------------| 6524 | M | O | H | \0| |---------------| 6520 | r | p | \0| w | |---------------| 6516 | h | \0| v | m | |---------------| 6512 | 0 | |---------------| 6508 | 6525 | |---------------| 6504 | 0 | |---------------| 6500 | 6522 | |---------------| 6496 | 6519 | |---------------| 6492 | 6516 | |---------------| 6488 | 6508 | <-- envp |---------------| 6484 | 6492 | <-- argv |---------------| 6480 | 3 | <-- argc |---------------| 6476 | return | --------------- ׸ 1.4 ̷ õ ǥ  ϴ ̰ ޸𸮿 εǴ 츮 α׷ EXEC ý ȣ ̴. EXEC μ ߿ 迭 ִ. ȯ 迭(׸1.0) μ 迭 (׸1.1)̴. ȯ 迭 Ʈ 迭̰, ̰ ο α׷ ȯν ޵ȴ. μ 迭 ο α׷ ޵Ǵ μ Ʈ 迭̴. ̷ ΰ 迭 NULL ("\0") Բ ʿ䰡 ִ. do_exec() ν ּ ȿ ʱ (׸1.2, η 3 49~56) ̴. , ν ޸ θ ̰ ̰ Ӱ ÿ ο ޸𸮸 Ҵ ̸ ų ̴.(Annex 3 lines 062 to 066) ν ͸ ġ (patch up)Ų Ŀ (Annex line 077) ׸ ׸1.2 ޸𸮴 ׸ 1.3 ޸ . , 츮 ʱ μ Ѵ(Annex line 077). ʱ μ ޸ ý ν ̺ κ̴. "/src/mm/mproc.h" Ͼȿ MPROC ȿ ʱ ÿ Ͱ ִ. ޸𸮴 ׸ 1.4 δ. ̰ ۽ÿ main() ν Ÿ ǥ̴. 1.3.1: C run-time, start-off procedure: --------------------------------------- , , α׷ εǾ Ǿ. ׷ 츮 ణ ִ. C Ϸ ؼ, main() Ǵٸ Լ ̴. Ϸ main()Լ 츮 α׷ Ѵ. ׷ Ϸ main() Լ ڵ ǥ C ȣ ʸ Ͽ, Ķ ù° Ķ Ѵ. 쿡, ּ 3 Ķ͸ ǰ( 2 ), ׷ ̰ 츮 ׸1.3 ƴϴ. 쿡, 츮  main() Լ 3 Ķ͸ ִ°? 츮 ڵ带 ϰ, ̰ 츮 α׷ Ӹ κп ԵǾ ̴. ڵ C -Ÿ, ŸƮ- ν, CRTSO ҷ, ڵ Ϲ ÿ 3 ̻ dwords ΰ, main()Լ ǥ ȣ ȣϱ ̴. -DWord 1: ARGC: The number of parameters passed to the function. Լ ޵Ǵ Ķ Type: Integer Note 1: Adress 0x6476 on Figure 1.4 -DWord 2: ARGV: Pointer on parameters array string. Ķ 迭 Ʈ Type: Pointer Note 1: Adress 0x6484 and pointer on 0x6492 on Figure 1.4 -DWord 3: ENVP: Pointer on the environment array string. ȯ 迭 Ʈ Type: Pointer Note 1: Adress 0x6488 and pointer on 0x6508 on Figure 1.4 ̷ dwords ׸ 1.4 ǥõǾ. , CRTSO ҷ ν ִ. ׷ μ ó ̴°? ϱ غ. GDB ! GDB 츮 ׽Ʈ α׷("crtso") . ----- (gdb) file crtso Reading symbols from crtso...done. ----- , , 츮 ã 𼭺 ؾ ؼ 𸥴. 쿡, 츮 0 , ̰ 츮 翡 ؼ ƴ ̴. ----- (gdb) disassemble main Dump of assembler code for function main: 0x80481e0
: push %ebp ... 0x80481eb : call 0x8048498 End of assembler dump. ----- CRTSO ġ . ̵ ִ. 츮 Լ ּ-1 dword ν α׷ ȿ װ ̴. 쿡, 츮 Լ ּҸ ̴. 츮 Լ ؼ ̰ Ѵٸ, 츮 Ʈ Լ, the CRTSO Ƹ ߰ ̴! ο غ. ----- (gdb) disassemble main-1 Dump of assembler code for function init_dummy: 0x80481d0 : push %ebp ... 0x80481da : lea 0x0(%esi),%esi End of assembler dump. ----- 츮 ּ 0x80481d0 -1 frame_dummy Լ ߰ߴ. ----- (gdb) disassemble init_dummy-1 Dump of assembler code for function frame_dummy: 0x80481a0 : push %ebp ... 0x80481c9 : lea 0x0(%esi,1),%esi End of assembler dump. ----- 츮 0x80481a0 -1 fini_dummy Լ ߰ߴ. ----- (gdb) disassemble frame_dummy-1 Dump of assembler code for function fini_dummy: 0x8048190 : push %ebp ... 0x804819a : lea 0x0(%esi),%esi End of assembler dump. ----- 츮 0x8048190 -1 the __do_global_dtors_aux Լ ߰ߴ. ----- (gdb) disassemble fini_dummy-1 Dump of assembler code for function __do_global_dtors_aux: 0x8048130 <__do_global_dtors_aux>: push %ebp ... 0x804818d <__do_global_dtors_aux+93>: lea 0x0(%esi),%esi End of assembler dump. ----- 0x8048130 -1 call_gmon_start Լ ߰ߴ. ----- (gdb) disassemble __do_global_dtors_aux-1 Dump of assembler code for function call_gmon_start: 0x8048104 : push %ebp ... 0x804812f : nop End of assembler dump. ----- 0x8048104 -1 _start Լ ãҴ. ..., ̰ ̷ο Լ̴, ׷ ʳ? 츮 ̰ ߰ߴ ! ----- (gdb) disassemble call_gmon_start-1 Dump of assembler code for function _start: 0x80480e0 <_start>: xor %ebp,%ebp 0x80480e2 <_start+2>: pop %esi 0x80480e3 <_start+3>: mov %esp,%ecx 0x80480e5 <_start+5>: and $0xfffffff0,%esp 0x80480e8 <_start+8>: push %eax 0x80480e9 <_start+9>: push %esp 0x80480ea <_start+10>: push %edx 0x80480eb <_start+11>: push $0x808e220 0x80480f0 <_start+16>: push $0x80480b4 0x80480f5 <_start+21>: push %ecx 0x80480f6 <_start+22>: push %esi 0x80480f7 <_start+23>: push $0x80481e0 0x80480fc <_start+28>: call 0x80481f0 <__libc_start_main> 0x8048101 <_start+33>: hlt 0x8048102 <_start+34>: mov %esi,%esi End of assembler dump. ----- CRTSO 3 Ǫ ν ÿ 3 Ķ͸ ̴.: 0x80480e8 <_start+8>: push %eax ! push argc ( integer ) 0x80480ea <_start+10>: push %edx ! push argv ( pointer ) 0x80480f5 <_start+21>: push %ecx ! push envp ( pointer ) CRTSO __libc_start_main function (visible in thelibc.so.6 library) Լ ̴. ׸, __libc_start_mainԼ the __libc_init_firstԼ ȣ ̰, Լ _initԼ ȣ ̴. ׸ α׷ ҷ _fini Ѵ. , 0x8048101 <_start+33>: hlt, а ϸ Ʈ ϱ ҷ. ̰ Ŀ, Ķ͵ ÿ ̰, 츮 α׷ main()Լ ׸ 1.4 ó ̷ Ķ͵ ׼ ̴. 1.3.2: EXEC system call, the nine steps: ---------------------------------------- , 츮 EXEC system ȣ ܰ踦 ̴. ޸ ȿ εǰ Ǿ α׷ 9 ߿ ܰ谡 ִ. 1- , ޸𸮿 డ üũѴ.( Lines 24 to 37 in Annex 3 ) MM 谡 ְ, MM MM ۾ 丮 ۾ ȯϱ tell_fs() ν FS ˸ ̴. α׷ MM allowed Լ ̴. 2- ׸Ʈ ũ⸦ д´( Lines 40 to 46 in Annex 3 ) 3- μ ȣڷκ ȯ ġ Ѵ( Lines 49 to 56 in Annex 3 ) 4- ο ޸𸮸 Ҵϰ ʿ ޸𸮸 Ų( Lines 62 to 66 in Annex 3 ) ̰ ϱ, 츮 , find_shared() ν Բ( line 59 in Annex 3 ), ؽƮ ޸𸮿 ̹ εǾ ʾҴ ٸ μ ִ üũ ̴. , 츮 new_mem()Լ ȣ ̴. Լ ޸𸮿 츮 ο ޸ ̹(װ, 츮 α׷ Ϳ , 츮 ޸𸮿 ϴ ٰ ؽƮ ã´ٸ) ū ã ޸𸮿 üũ ̴. , ޸ ʵ Ʈǰ sys_newmap() Լ Ŀο ȭ ̴. Ʈ 1: new_mem() ν ϳ, Ȥ ǿ ū ߰ ϸ α׷ ̴. ν ϱ Ѱ , ڵ, ؽƮ ٸ ġŰ װ͵ Բ ũŰ ̴. ׷ ̰ Minix ü ƴϴ. ׷Ƿ, ̰ ̴, , ǰ ڵ ٸ ޸ ִ. Ͽ μ μ ޸𸮶 Ҹ ޸ ̿ ߰ ޸ õ (intermediate memory heaven) ִٴ ̴. װ͵ vm_area_struct ü Բ Ǿ ִ. mm_struct Ϻκ̰ ̰ task_struct ( μ Բϴ vector) Ϻκ̴. ׷, ν "demand paging"̶ Ҹ ׷̵ȴ. demand paging μ ޸𸮰 μ ޸𸮸 Ϸ õ ޸𸮷 Ű. Ʈ 2: new_mem() Լ bss ׸Ʈ( ׸Ʈ ׸Ʈ Ϻκ̴. bss ʱȭ Ѵ. ׸Ʈ ؼ ޸𸮾ȿ α׷ ޸ ̾ƿ ؼ Ʒ ̴.), gap ׸Ʈ ȭѴ. Ʈ 2.1: gap bss ׸Ʈ ޸ ׸Ʈ̰, ̰ ޸𸮸 Ҵϰ ̴. ޸ ̾ƿ ׸Ʈ ؼ ̴. gap ־ ٸ ̸ ̴. 5- ο ޸𸮷 Ѵ.( lines 74 to 81 in Annex 3 ) ü ο ޸ , ޸ ̴. , patch_ptr()Լ (Line 077 Annex 3) ο ޸ Ҵ( ޸𸮿 ġ 0 ƴ) ϱ ͸ ġ ̴. , 츮 ׸ 1.2 ׸ 1.3 . 6- (׸ ؽƮ)׸Ʈ ο ޸ ̹ Ѵ.( Lines 84 to 89 in Annex 1 ) ؽƮ ׸Ʈ ϴ find_shared() Լ ̴. ޸𸮿 ̹ Ǵ 츮 Ͱ ϴ ؽƮ ׸Ʈ ٸ, NULL ̴. Ʈ 1: MPROC ü /src/mm/mproc.h Ͽ ǵǾ ִ. Ʈ 2: MPROCüȿ ϴ 3 ; ino_t mp_ino; /* inode number of file */ dev_t mp_dev; /* device number of file system */ time_t mp_ctime; /* inode changed time */ Ŀ, sh_mp (mproc) NULL̸, load_seg() ޸𸮿 ִ ؽƮ ׸Ʈ ε ̰ load_seg()ν Ŀ ȣ ̰ ޸𸮿 ִ ׸Ʈ ε ̴. 7- setuid, setgid Ʈ üũϰ ٷ.( Lines 100 to 109 in Annex 3 ) 8- μ ̺ Ʈ fix up()Ѵ. EXEC call 츮 μ ο ޸ Ҵ Բ MPROC ʵ带 ų ̴. 9- μ Ǵ Ŀο Ѵ. μ sys_exec() ϴ "/src/kernel/system.c" ִ do_exec() ν ˷ ̴. SYS_EXEC ޽ "/include/minix/com.h" ǵǾ ִ. ޽ EXEC ý ȣ Ŀ α׷ ī(PC) (SP) ̴. shell ȣ 츮 α׷(helloworld) Ȯϰ Ǿ ޸𸮿 εǾ. ,  α׷ ޸𸮿 εǴ ̴. Chapter 2: Memory Layout of an executed program: ------------------------------------------------ ϳ α׷ , , ׸ , ν ü Ǿ. ׷, װ͵ ޸𸮿  εǾ°?  ϴ°? Ʈ 1: ELF ˿ 밡( ) ̴. 쿡, Ʒ  ü OpenBSD, NetBSD,Ÿ ٸ IA-32 ELF ü 밡 ̴. ޸𸮿 ϳ α׷ ⺻ ̾ƿ ִ. --------------- | | | Arguments and | | environment | | variables | | | |---------------| | Stack |<--|-- |(grow downward)| | | | |User | | |Stack | | |Frame | | | | (grow upward) | |( Mind the Gap ) | Heap |<--|-- |---------------| | BSS | |---------------| | Data | |---------------| | Code | --------------- Figure 1.5 ϳ C ڵ尡 ִµ, ̰  ޸ εǴ ̴. varinmem.c ------------------- int iGlobalInit = 1; /* Global Initialized: .data */ int iGlobalUnInit; /* Global Uninitialized: .bss */ char *szGlobalP; /* Global Uninitialized: .bss */ void function(char cArgument) { int iLocalInit = 1; /* Local Initialized: stack */ int iLocalUnInit; /* Local Uninitialized: stack */ char szLocalP[12] = "Hello World!"; /* Local Initialized: stack */ szGlobalP = (char*)malloc( 12 * sizeof(char)); /* Dynamic Variable: heap */ strncpy(szGlobalP,"Hello World!",12); } int main(void) { function(0); /* Function call: new environment */ } ------ ڵ带 GDB Բ ̴. [root@Seldon prog]# gcc -o varinmem -ggdb -static varinmem.c Ʈ 1: α׷ ̷ Ķ͵ ̴. 2.1: The dissection of the ELF executable file: ----------------------------------------------- 츮 varinmem α׷ ִ : [root@Seldon prog]# readelf -e varinmem ... Table 1: -------- Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .init PROGBITS 080480b4 0000b4 000018 00 AX 0 0 4 [ 2] .text PROGBITS 080480e0 0000e0 046220 00 AX 0 0 32 [ 3] .fini PROGBITS 0808e300 046300 00001e 00 AX 0 0 4 [ 4] .rodata PROGBITS 0808e320 046320 00da80 00 A 0 0 32 [ 5] __libc_subinit PROGBITS 0809bda0 053da0 000008 00 A 0 0 4 [ 6] __libc_subfreeres PROGBITS 0809bda8 053da8 00003c 00 A 0 0 4 [ 7] __libc_atexit PROGBITS 0809bde4 053de4 000004 00 A 0 0 4 [ 8] .data PROGBITS 0809ce00 053e00 001220 00 WA 0 0 32 [ 9] .eh_frame PROGBITS 0809e020 055020 000d40 00 WA 0 0 4 [10] .ctors PROGBITS 0809ed60 055d60 000008 00 WA 0 0 4 [11] .dtors PROGBITS 0809ed68 055d68 000008 00 WA 0 0 4 [12] .got PROGBITS 0809ed70 055d70 000010 04 WA 0 0 4 [13] .sbss PROGBITS 0809ed80 055d80 000000 00 W 0 0 1 [14] .bss NOBITS 0809ed80 055d80 000f44 00 WA 0 0 32 [15] .stab PROGBITS 00000000 055d80 0cf030 0c 16 0 4 [16] .stabstr STRTAB 00000000 124db0 059911 00 0 0 1 [17] .comment PROGBITS 00000000 17e6c1 002e9e 00 0 0 1 [18] .debug_aranges PROGBITS 00000000 18155f 000020 00 0 0 1 [19] .debug_pubnames PROGBITS 00000000 18157f 000058 00 0 0 1 [20] .debug_info PROGBITS 00000000 1815d7 000198 00 0 0 1 [21] .debug_abbrev PROGBITS 00000000 18176f 0000c0 00 0 0 1 [22] .debug_line PROGBITS 00000000 18182f 00007e 00 0 0 1 [23] .note.ABI-tag NOTE 08048094 000094 000020 00 A 0 0 4 [24] .note NOTE 00000000 1818ad 001144 00 0 0 1 [25] .shstrtab STRTAB 00000000 1829f1 000103 00 0 0 1 [26] .symtab SYMTAB 00000000 182f54 005aa0 10 27 26d 4 [27] .strtab STRTAB 00000000 1889f4 004b48 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) ... Table 2: -------- Description of most important sections -------------------------------------- ߿ .interp <-----| Path name for a program interpreter α׷ ؼ⿡ .hash <-----| Symbol hash table ɺ ؽ ̺ .dynsym <-----| Dynamic Linking symbol table ŷ ɺ ̺ .dynstr <-----| Strings needed for dynamic linking ŷ ʿ Ʈ .init <-----| Process initialisation code μ ʱȭ ڵ .plt <-----| Procedure linkage table μ Ű ̺ .text <-----| Executable instructions డ ɾ .fini <-----| Process termination code μ ڵ .rodata <-----| read-only data б .data <-----| Initialised data present in process image μ ̹ ǥõǴ ʱȭ .got <-----| Global offset table ۷ι ̺ .dynamic <-----| Dynamic linking information ŷ .bss <-----| Uninitialised data present in process image μ ̹ ǥõǴ ʱȭ .stabstr <-----| Usually names associated with symbol table entries ɺ ̺ Ʈ ̸ .comment <-----| Version control informations Ʈ .note <-----| File notes Ʈ -------- 츮 츮 α׷ ߿ Բ . , 츮 ̷ ϴ ڼ 캼 ̴. ̰ Ͽ GDB ̴. .init Ǻ غ: ----- [root@Seldon prog]# readelf -x 1 varinmem Hex dump of section '.init': 0x080480b4 0000dbe8 90000000 45e808ec 83e58955 U......E........ 0x080480c4 c3c90004 61b6e800 ...a.... ----- readelf α׷ 츮 츮 varinmem α׷ .init 16 ش. , ̷ Ϸκ Ǿ. ׷, 츮 ̷ 16 ׸Ʈ ߰ ? 츮 ּҿ .init ڵ忡 츮 ִ GDB Ͽ ̴: 0x080440b4 ----- (gdb) file varinmem Reading symbols from varinmem...done. (gdb) disassemble 0x080480b4 Dump of assembler code for function _init: 0x80480b4 <_init>: push %ebp 0x80480b5 <_init+1>: mov %esp,%ebp 0x80480b7 <_init+3>: sub $0x8,%esp 0x80480ba <_init+6>: call 0x8048104 0x80480bf <_init+11>: nop 0x80480c0 <_init+12>: call 0x80481a0 0x80480c5 <_init+17>: call 0x808e280 <__do_global_ctors_aux> 0x80480ca <_init+22>: leave 0x80480cb <_init+23>: ret End of assembler dump. ----- 츮 ˾Ƴ´! .init ׸Ʈ _init Լ Ǿ. , ̰ CRTSO ƴϸ, ƾ 츮 α׷ ʱȭ ϰ ʴ´. 쿡, ׸Ʈ _start ν ġ ִ°? ----- (gdb) disassemble _start Dump of assembler code for function _start: 0x80480e0 <_start>: xor %ebp,%ebp ... 0x8048102 <_start+34>: mov %esi,%esi End of assembler dump. ----- _start Լ ڵ ּ0x80480e0 ۵ȴ. , 츮 (ǥ2) ƿͼ ּҿ ġϴ : ----- [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 2] .text PROGBITS 080480e0 0000e0 046220 00 AX 0 0 32 ----- , ϴ ּҰ ! 츮 ߰ߴ! CRTSO ν .text ù° ν̴. , 츮 .data ׸Ʈ 캼 ̴. װ μ ̹ ʱȭ Ͱ ȴ. ----- [root@Seldon prog]# readelf -x 8 varinmem Hex dump of section '.data': 0x0809ce00 00000000 0809ed6c 00000000 00000000 ........l....... 0x0809ce10 00000000 00000000 0809edc0 00000001 ................ ... 0x0809e010 00000000 0000003f 3f783020 65707974 type 0x??....... ----- (gdb) disassemble 0x0809ce10 Dump of assembler code for function iGlobalInit: 0x809ce10 : add %eax,(%eax) 0x809ce12 : add %al,(%eax) End of assembler dump. ----- 츮 .data ù° ּҸ Ѵٸ, 츮 data_start ν ̴. ׷, ּҷ( 0x809ce12 ) Ѵٸ, 츮 ̷ο ͵ ̴. ű⿡ 1(memorylayout.c ) ʱȭ 츮 iGlobalInit ִ°? ׷! 츮 츮 α׷ ʱȭ ִ ġ ٷ ߰Ͽ! , ׷, 츮 iGlobalInit zGlobalP ִ°? ..Tap...Tap...Tap...Tap...Arg...Tap...Tap...cant find it...Tap...Tap... many many time later... Tap...Tap...Tap........ ..Tap...Tap...Tap...Tap...Arg...Tap...Tap...װ ߰ ...Tap...Tap... ڿ .... ..Tap...Tap...Tap........ ..Tap...Tap...Tap.....Tap...Tap...Tap... no ã 簡? ſ ִ GDB Ǵٸ Ư ִ: ----- (gdb) file varinmem Reading symbols from varinmem...done. (gdb) list 1 1 int iGlobalInit = 1; 2 int iGlobalUnInit; 3 char *szGlobalP; ----- (gdb) print &szGlobalP $1 = (char **) 0x809f7a4 ----- (gdb) info symbol 0x809f7a4 szGlobalP in section .bss ----- (gdb) disassemble 0x809f7a4 Dump of assembler code for function szGlobalP: 0x809f7a4 : add %al,(%eax) 0x809f7a6 : add %al,(%eax) End of assembler dump. ----- (gdb) disassemble 0x809f7a4-1 Dump of assembler code for function iGlobalUnInit: 0x809f7a0 : add %al,(%eax) 0x809f7a2 : add %al,(%eax) End of assembler dump. ----- 츮 ˾Ƴ´! ù°, 츮 α׷ ҽڵ带 Ͽ. α׷ szGlobalP ޸ "&" ɺ Բ print GDB Ͽ.(print ɿ ڼ "help print" ϶) Ŀ, ɺ ǥõǴ ƴ ˱ Ͽ "info symbol" Ͽ. szGlobalP .bss ǿ Ÿ ߰Ͽ. Ŀ szGlobalP ּҿ ڵ带 װ  ִ Ͽ Ͽ. szGlobalP ߰Ͽ! Ŀ, ּ Ǿ ˱ Ͽ. szGlobalP ּ ּҸ Ͽ ̴. Ե, iGlobalUnInit ʱȭ ߰Ͽ! , ð̶ Ѵ. , ٸ ǵ ߰ϱ⸦ Ѵٸ, Ͽ. ׸Ʈ ϰ ߴ ˱ "readelf"α׷ ϰ GDB α׷( α׷ GDB Բ ϵǾ ʿ䰡 ִ)  ׸Ʈ ּҸ 𽺾϶! ̿Ͱ ڵ ν ̷ο ߰ ȮѴ. Chapter 3: The Stack and the Heap: ---------------------------------- ΰ ִ. . ̷ ذå α׷ κ̴. ð .( gap ϴ°?) ʱȭ ʱȭ ϶ ó .data .bss ġʴ°? ̰ α׷ ޸ ν εŰ ʴ° ̴.(1.3-EXEC step 4 -Ʈ 4 ) ν Ǵ Ŵ α׷ ٸ, ν ߿, ̷ ν 10 Ȥ 20 Ѵ. 쿡 õ ʱȭ ̰, ̰͵ α׷ ߿ ᵵ ̴. ϳ α׷ ޸ ߿ н ϴ°? ũ̼ǿ 5 Ȥ 10 α׷ ̰ ׷ ̰ ģ ̴! ̰ ̷ 鿡 ؼ Ϸ ޸𸮸 Ҵ ʴ ֵ ̴. 쿡, ġϰ Ǵ°? ̰ ̴. 츮 Լ(, ) ޸𸮿  εǴ 캼 ̴. Ϳ 鿡 ؼ ణ ̴. , ʹ IA-32 PCũ̼ ޸𸮿 32Ʈ ּҸ ǥѴ. 쿡, Ϳ õǴ ޸ ǥϰ, ʹ ̴ּ! GDB ̿ Ϳ  ϴ ̴. ----- (gdb) list 8 int iLocalUnInit; 9 char szLocalP[12] = "Hello World!"; 10 11 szGlobalP = (char*)malloc( 12 * sizeof(char)); 12 strncpy(szGlobalP,"Hello World!",12); 13 } (gdb) break 13 Breakpoint 1 at 0x8048231: file memorylayout.c, line 13. ----- ʱȭ 극ũƮ ʿ䰡 ִ ˱ ҽ ǥϿ. Ŀ, 13 극ũ͸ ξ. ----- (gdb) run Starting program: /root/prog/varinmem Breakpoint 1, function (cArgument=0 '\000') at varinmem.c:13 13 } ----- α׷ Ŀ, α׷ 극ũƮ Ǿ. ----- (gdb) print szGlobalP $1 = 0x809ff88 "Hello World!" ----- , "Hello World!" Ʈ ּ 0x809ff88 . ޸ Ǵ ˱ üũ ̴. ----- (gdb) info symbol 0x809ff88 No symbol matches 0x809ff88. ----- , ּҿ ǵ ɺ ! ----- (gdb) print &szGlobalP $2 = (char **) 0x809f7a4 ----- , ּҸ ߰ߴ. ----- (gdb) info symbol 0x809f7a4 szGlobalP in section .bss ----- ʹ ׻ .bss ׸Ʈ ִ. 츮 0x809ff88ּҰ "Hello World!" Ʈ ִ Ŭ̶ ȴ. װ ̰(Hello world) ǵ ɺ ƴϱ ̴. ̰ Ϳ õǴ ޸ ִ ̰, ʹ ּҿ ִ. Ʈ 1: 3.5 Ե ó, ̷ ޸ Ŭʹ ҴǾ ִ. 3.1: Where are they? -------------------- ˴ٽ, " "̶ Ҹ ޸ ġϰ ȴ. Ǿ. ,  κ ̰ ϳ Լ ǰų κ() ٴ() ʰԵ ̴. ȣ Լ ȯ, ڿ ؼ, USF Ǿ. USF ݴ, ǿ Ǿ. 3.2: How to know what's the size of the user stack frame at compilation? ------------------------------------------------------------------------ 8088 ο μ ϰ ִٸ, ϵ ÷ο츦 ϱ Ʈ ý ִ. , α׷ ӿ  縸ŭ Ҵ Žð ׷ ̻ ڶٸ, ü Ʈ ߻ ̰, ϴٸ ü ÿ Ǵٸ ޸ ҴϷ õ ̴. 3.3: Registers: --------------- ð ϱ , ͵ ϰ ſ ̴. ʹ μ κ, ϴ ̴. װ͵ μ ޸𸮻̿ ũ̴. 3.3.1: General Registers: ----------------------- ̷ ͵ ͸ ϰ ϱ ؼ Ǿ ׵߿   ½ũ Ǿ. A 32bit general registers representation: (32Ʈ ǥ) ---------------------------------------- ------------------------------------------ | Low | High | | | | | | | 8 | 8 | | | Bits | Bits | | | | | | ------------------------------------------ ^ ^ ^ | First 16 bits | Extended 16 Bits | Figure 1.6 %EBX ǥ : ---------------------------- ------------------------------------------ | %BL | %BH | | |------------------------------------------| | %BX | | |------------------------------------------| | %EBX | ------------------------------------------ ׸ 3.0 ο 32Ʈ ũ μ 386 Բ Ȩ ǻ ־. 16Ʈ μ 16Ʈ(%BX) ̸ ͸ . ̷ 16Ʈ 8Ʈ Ǿ. 8Ʈ(%BL) 8Ʈ(%BH) ִ. ׷, ӵ ο , ͵ ο 16Ʈ ȮǾ ü ʹ %EBX Ҹ. "E" "Extended" ǹѴ. %EAX: No specialisation. Ưȭ . %EBX: Specialized for the index addressing management. ε 巹 Ưȭ %ECX: Specialized for loops management. Ưȭ EX: MOV %ECX,10 EXLOOP: ADD %EAX,10 LOOP EXLOOP ;ECX = ECX-1; The loop will stop when %EXC == 0 %EDX: Specialized in multiplication/division of unsigned numbers. ȣ / Ưȭ 3.3.2: Segments registers: -------------------------- %CS: ̰ ڵ ׸Ʈ̴. ̰ α׷ డ ڵ忡 ̴. ̰ CALL, JMP, Jxx Ȥ POP %CS ɿ ɼ ִ. %SS: ̰ ׸Ʈ̴. ׸Ʈ SP BP׸Ʈ õǾִ. ʹ ʹ Լ ȣ 쿡 ũμ ͸ Ͻ ̴. %ES: ̰ Ʈ ׸Ʈ̴. ̰ Ʈ μ Ǿ. 쿡, ES DI ּҸ ̴. %DS: ̰ ׸Ʈ SP, BP, IP ٸ ׸Ʈ ȴ. %FS: ES . %GS: ES . (: ̷ ͵ Context switch Selector Ǿ. Ŀκκп ϱ ٶ) 3.3.3: Offset Registers: ------------------------ %ESP: Ȯ , ̰ 츮 κ̴. %EBP: Ȯ ̽ , Լ ȯ ų ̴. %EDI: Ȯ ε, ޸ ϴ ۷̼ǿ Ѵ. %ESI: Ȯ ҽ ε, ۷̼ ̰ ޸ ۺκ ̴. %EIP: Ȯ νƮ() , ּҸ Ų. 3.4: The stack: --------------- Լ ȣɶ, 츮 ÿ Լ ο ȯ ؾ ʿ䰡 ̴. 츮 ĶͿ ̴. , Լ ٽ ǰ Ǵ ̷ κ̴. Լ ( ɾ) .text ǿ ִ. Լ, Ȥ ȣ ð ϱ Ʒ ڵ带 ̴. funcinmem.c ----------- int iGlobalInit = 1; int iGlobalUnInit; char *szGlobalP; void function(char *cParameter, int iParameter) { int iLocalInit = 1; int iLocalUnInit; char szHelloString[12] = "Hello World!"; char *szLocalP; iParameter = 5; iLocalUnInit = iParameter; iGlobalUnInit = iLocalUnInit+1; szGlobalP = (char*)malloc( 12 * sizeof(char)); strncpy(szGlobalP,"Hello World!",12); szLocalP = (char*)malloc( 12 * sizeof(char)); strncpy(szLocalP,"Hello World!",12); return; } int main(int argc, char **argv) { int iMainLocalInit = 2; function("test",0); iMainLocalInit += 1; iGlobalInit += iMainLocalInit; printf("iMainLocalInit = %d\n",iMainLocalInit); } ------ 3.4.2: Stack management when calling a procedure: ------------------------------------------------- Լ 3 ⺻ κе : 1- Լ ȣ: Ķ͵ ÿ Ǫõǰ ɾ (IP) 츮 Լ ȣ Ŀ ɾ μ ϱ Ǿ. 2- ѷα: Լ ۽ÿ, 츮 Լ ϱ Ÿ Ͱ ¸ ̴. Ŀ, 츮 츮 Լ ȣ⿡ ޸ ¸ ̴. 3- Լ : Լ ȣDZ Ÿ ó ´. , main() function()ν 𽺾 Ʈ1: 忡 ̷ û(listening) ׻ ̴. װ͵ 캸µ ------ (gdb) disassemble main Dump of assembler code for function main: 0x8048270
: push %ebp 0x8048271 : mov %esp,%ebp 0x8048273 : sub $0x8,%esp 0x8048276 : movl $0x2,0xfffffffc(%ebp) 0x804827d : sub $0x8,%esp 0x8048280 : push $0x0 0x8048282 : push $0x808e3d5 0x8048287 : call 0x80481e0 0x804828c : add $0x10,%esp 0x804828f : lea 0xfffffffc(%ebp),%eax 0x8048292 : incl (%eax) 0x8048294 : mov 0xfffffffc(%ebp),%eax 0x8048297 : add %eax,0x809cef0 0x804829d : sub $0x8,%esp 0x80482a0 : pushl 0xfffffffc(%ebp) 0x80482a3 : push $0x808e3da 0x80482a8 : call 0x804872c 0x80482ad : add $0x10,%esp 0x80482b0 : leave 0x80482b1 : ret End of assembler dump. ------ ------ (gdb) file funcinmem Reading symbols from funcinmem...done. (gdb) disassemble function Dump of assembler code for function function: 0x80481e0 : push %ebp 0x80481e1 : mov %esp,%ebp 0x80481e3 : push %edi 0x80481e4 : push %esi 0x80481e5 : sub $0x30,%esp 0x80481e8 : movl $0x1,0xfffffff4(%ebp) 0x80481ef : lea 0xffffffd8(%ebp),%edi 0x80481f2 : mov $0x808e3c8,%esi 0x80481f7 : cld 0x80481f8 : mov $0x3,%ecx 0x80481fd : repz movsl %ds:(%esi),%es:(%edi) 0x80481ff : movl $0x5,0xc(%ebp) 0x8048206 : mov 0xc(%ebp),%eax 0x8048209 : mov %eax,0xfffffff0(%ebp) 0x804820c : mov 0xfffffff0(%ebp),%eax 0x804820f : inc %eax 0x8048210 : mov %eax,0x809f8c4 0x8048215 : sub $0xc,%esp 0x8048218 : push $0xc 0x804821a : call 0x8048d78 <__libc_malloc> 0x804821f : add $0x10,%esp 0x8048222 : mov %eax,%eax 0x8048224 : mov %eax,0x809f8c8 0x8048229 : sub $0x4,%esp 0x804822c : push $0xc 0x804822e : push $0x808e3c8 0x8048233 : pushl 0x809f8c8 0x8048239 : call 0x804cbdc 0x804823e : add $0x10,%esp 0x8048241 : sub $0xc,%esp 0x8048244 : push $0xc 0x8048246 : call 0x8048d78 <__libc_malloc> 0x804824b : add $0x10,%esp 0x804824e : mov %eax,%eax 0x8048250 : mov %eax,0xffffffd4(%ebp) 0x8048253 : sub $0x4,%esp 0x8048256 : push $0xc 0x8048258 : push $0x808e3c8 0x804825d : pushl 0xffffffd4(%ebp) 0x8048260 : call 0x804cbdc 0x8048265 : add $0x10,%esp 0x8048268 : lea 0xfffffff8(%ebp),%esp 0x804826b : pop %esi 0x804826c : pop %edi 0x804826d : pop %ebp 0x804826e : ret End of assembler dump. ------ 3.4.2.1: The call: ------------------ ̰ 츮 Լ ȣ ڵ̴: ----------------------------------------------- 0x8048280 : push $0x0 0x8048282 : push $0x808e3d5 0x8048287 : call 0x80481e0 ------ Լȣ ν ȣǾ Լ ťƮ ̰ ȣ Լ Ŀ α׷ ϱ ؼ ȣǾ Լ ϴ ּҸ޸(%EIP) ̴. , GDB ɾ: ------ (gdb) break *0x8048280 Breakpoint 1 at 0x8048280: file funcinmem.c, line 30. (gdb) run Starting program: /root/prog/funcinmem Breakpoint 1, 0x08048280 in main (argc=1, argv=0xbffffa84) at funcinmem.c:30 warning: Source file is more recent than executable. 30 function("test",0); (gdb) info register esp esp 0xbffffa08 0xbffffa08 (gdb) stepi 0x08048282 30 function("test",0); (gdb) info register esp esp 0xbffffa04 0xbffffa04 (gdb) stepi 0x08048287 30 function("test",0); (gdb) info register esp esp 0xbffffa00 0xbffffa00 ------ , 츮 ¸ ð GDB ߱ "push $0x0" 극ũ͸ ξ. , 츮 "functinmem" α׷ Ͽ. "call" "push"ɾ 츮 ťƮ ÿ ̴. %ESP ʹ ׸ 2 dwordŭ Ʒ Ű ̴. | | | | | | | | | | | | |---------------| |---------------| X | | <-- %ebp 0xbffffa18| | <-- %ebp |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffffa08| | |---------------| |---------------| | 0 | 0xbffffa04| 0x0 | |---------------| |---------------| | test | <-- %esp 0xbffffa00| 0x808e3d5 | <-- %esp |---------------| |---------------| | | | | | | | | | | | | ------ ׸ 3.1 ------ (gdb) x/4c 0x808e3d5 0x808e3d5 <_IO_stdin_used+17>: 116 't' 101 'e' 115 's' 116 't' (gdb) info symbol 0x808e3d5 _IO_stdin_used + 17 in section .rodata ------ ޸𸮿 ּҰ ñߴ. װ ּҿ ޸𸮸 ˻߰ ޸𸮿 "test" ƱԸƮ Ʈ ϴ Ұ ִٴ Ȯ߱ ̴. Ʈ ELF .rodata(read only dat) ǿ ִٴ ߰ߴ! ------ (gdb) stepi function (cParameter=0x1
, iParameter=-1073743228) at funcinmem.c:6 6 { (gdb) info register esp esp 0xbffff9fc 0xbffff9fc (gdb) info register eip eip 0x80481e0 0x80481e0 (gdb) info register esp esp 0xbffff9fc 0xbffff9fc (gdb) x 0xbffff9fc 0xbffff9fc: 0x0804828c (gdb) x 0x0804828c 0x804828c : 0x8d10c483 (gdb) disassemble main+28 ... 0x8048287 : call 0x80481e0 0x804828c : add $0x10,%esp ... ------ , 츮 "call 0x80481e0 " Ͽ. %EIP "function" ν Ŀ 츮 α׷ ϱ ÿ ǪõǾ. , 츮 ν (0x80481e0 (push %ebp)) ù° %EIP . , װͿ Ǿ. %ESP ޸ ٸ dword Ʒ Űܠµ, ? ּ 0xbffff9fc 츮 %ESP ޸ ּҸ ˻Ͽ. 0x8d10c483 ޸ ּҿ ּ ͸ ߰ߴ. ּҰ 츮 Լ "add $0x10,%esp" ּ ߰ϱ ޸𸮸 𽺾Ͽ. ˾Ƴ´! ̰ 츮 "function" ν Ŀ Ǿ ̴ּ! %EIP ʹ 0x80481e0 ҴDZ "call"ɿ ÿ ǪõǾ. | | | | | | | | | | | | |---------------| |---------------| X | | <-- %ebp 0xbffffa18| | <-- %ebp |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffffa08| | |---------------| |---------------| | 0 | 0xbffffa04| 0x0 | |---------------| |---------------| | test | 0xbffffa00| 0x808e3d5 | |---------------| |---------------| | Z | <-- %esp 0xbffff9fc| 0x0804828c | <-- %esp |---------------| |---------------| | | | | | | | | z= α׷ ϱ ν ȣ (pop)ϱ ּ ------ ׸ 3.2 ------ 3.4.2.2: The Prologue: ---------------------- ̰ 츮 ѷα ڵ̴: ------------------------------------------ 0x80481e0 : push %ebp 0x80481e1 : mov %esp,%ebp 0x80481e3 : push %edi 0x80481e4 : push %esi 0x80481e5 : sub $0x30,%esp ------ , GDB ɾ: ------ (gdb) break *0x80481e0 Breakpoint 1 at 0x80481e0: file funcinmem.c, line 6. (gdb) run Starting program: /root/prog/funcinmem Breakpoint 1, function (cParameter=0x1
, iParameter=-1073743228) at funcinmem.c:6 6 { ------ , 츮 ѷα ڵ ù°ο 극ũƮ ξ α׷ ߴ. α׷ 츮 ù° 극ũƮ , "push %ebp"(϶, Ǫ ȣ ʰ, 극ũƮ Ǫ Ŀ ȣǾ) ------ (gdb) info register ebp ebp 0xbffffa18 0xbffffa18 (gdb) info register esp esp 0xbffff9fc 0xbffff9fc ------ 츮 X ޸ ּҿ %EBP Ϳ Y ޸ ּҿ %ESP ִ. ------ | | | | | | | | | | | | |---------------| |---------------| X | | <-- %ebp 0xbffffa18| | <-- %ebp |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | <-- %esp 0xbffff9fc| | <-- %esp |---------------| |---------------| | | | | | | | | | | | | | | | | | | | | ------ Figure 3.3 ------ (gdb) stepi 0x080481e1 6 { (gdb) info register ebp ebp 0xbffffa18 0xbffffa18 (gdb) info register esp esp 0xbffff9f8 0xbffff9f8 ------ 츮 "stepi" GDB ɰ Բ (push %ebp) Ͽ. 츮 %EBP ġ Ǫν ȯ ̴. ׸ , %ESP ʹ dword ε ֳϸ %EBP ÿ Ǫ߱ ̴. ̰ "push %ebp" ȣĿ %ESP ġ ȭ ֱ ̴: 0xbffff9fc - 0xbffff9f8 ---------- 0x00000004 ( A dword ) ------ | | | | | | | | | | | | |---------------| |---------------| X | | <-- %ebp 0xbffffa18| | <-- %ebp |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %esp 0xbffff9f8| 0xbffffa18 | <-- %esp |---------------| |---------------| | | | | | | | | | | | | ------ Figure 3.4 ------ (gdb) stepi 0x080481e3 in function (cParameter=0x808e3d5 "test", iParameter=0) at funcinmem.c:6 6 { (gdb) info register ebp ebp 0xbffff9f8 0xbffff9f8 (gdb) info register esp esp 0xbffff9f8 0xbffff9f8 ------ "stepi" GDB ȣν "mov %esp,%ebp" Ǿ. ̰ %EBP ͸ %ESP ͷ ű ̴. ̰ 츮 ȣ ν ο ȯ ̴. %ESP %EBP Ѵ ȯ ּһ󿡼 ο ȯ ̴. ------ | | | | | | | | | | | | |---------------| |---------------| X | | 0xbffffa18| | |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %esp 0xbffff9f8| 0xbffffa18 | <-- %esp |---------------| |-%ebp |---------------| |-%ebp | | | | | | | | | | | | ------ Figure 3.5 ------ (gdb) stepi 0x080481e4 6 { (gdb) info register esp esp 0xbffff9f4 0xbffff9f4 (gdb) stepi 0x080481e5 6 { (gdb) info register esp esp 0xbffff9f0 0xbffff9f0 ------ 츮 %EDI %ESI ÿ Ǫν װ͵ ¸ Ѵ. | | | | | | | | | | | | |---------------| |---------------| X | | 0xbffffa18| | |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %ebp 0xbffff9f8| 0xbffffa18 | <-- %ebp |---------------| |---------------| | V | 0xbffff9f4| 0x1 | |---------------| |---------------| | W | <-- %esp 0xbffff9f0| 0xbffffa84 | <-- %esp |---------------| |---------------| | | | | | | | | | | | | | | | | ------ V = %EDI W = %ESI Figure 3.6 ------ Ʒ ΰ dword еν Ϸ ĵ Ŀ ̾ƿ̴. (gdb) break *0x8048265 Breakpoint 3 at 0x8048265 (gdb) run Starting program: /root/prog/funcinmem Breakpoint 1, 0x08048265 in function (cParameter=0x808e3d5 "test", iParameter=5) at funcinmem.c:21 21 strncpy(szLocalP,"Hello World!",12); (gdb) info register ebp ebp 0xbffff9f8 0xbffff9f8 (gdb) info register esp esp 0xbffff9b0 0xbffff9b0 (gdb) x 0xbffff9f8 0xbffff9f8: 0xbffffa18 ------ 츮 main()Լ ȯ ------ (gdb) x 0xbffff9f4 0xbffff9f4: 0x00000001 ------ Saved %EDI %EDI ------ (gdb) x 0xbffff9f0 0xbffff9f0: 0xbffffa84 ------ %ESI ------ (gdb) x 0xbffff9ec 0xbffff9ec: 0x00000001 ------ iLocalInit ------ (gdb) x 0xbffff9e8 0xbffff9e8: 0x00000005 ------ iLocalUnInit = iParameter; ------ (gdb) x 0xbffff9e4 0xbffff9e4: 0x00000000 ------ Padding ------ (gdb) x 0xbffff9e0 0xbffff9e0: 0x00000000 ------ Padding ------ (gdb) x 0xbffff9dc 0xbffff9dc: 0x00000000 ------ Padding ------ (gdb) x 0xbffff9d8 0xbffff9d8: 0x21646c72 ------ szHelloString ( First DWord ) ------ (gdb) x 0xbffff9d4 0xbffff9d4: 0x6f57206f ------ szHelloString ( Second DWord ) ------ (gdb) x 0xbffff9d0 0xbffff9d0: 0x6c6c6548 ------ szHelloString ( Last DWord ) ------ (gdb) x 0xbffff9cc 0xbffff9cc: 0x080a00d8 ------ szLocalP ------ (gdb) x 0xbffff9c8 0xbffff9c8: 0x00000000 ------ Padding ------ (gdb) x 0xbffff9c4 0xbffff9c4: 0x00000000 ------ Padding ------ (gdb) x 0xbffff9c0 0xbffff9c0: 0x00000000 ------ Padding ------ ΰ dword еν Ϸ ĵ Ŀ ̴. 0x80481e5 : sub $0x30,%esp ɿ , 츮 츮 ֱ ÿ 12 dword ̴. , dword(4Ʈ Ȥ 32Ʈ) Ǿ. dword ä , Ʈ 0x0 ҴǾ. | | | | | | | | | | | | |---------------| |---------------| X | | 0xbffffa18| | |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %ebp 0xbffff9f8| 0xbffffa18 | <-- %ebp |---------------| |---------------| | V | 0xbffff9f4| 0x1 | |---------------| |---------------| | W | 0xbffff9f0| 0xbffffa84 | |---------------| |---------------| | Allocated | 0xbffff9ec| | |---------------| |---------------| | Allocated | 0xbffff9e8| | |---------------| |---------------| | Allocated | 0xbffff9e4| | |---------------| |---------------| | Allocated | 0xbffff9e0| | |---------------| |---------------| | Allocated | 0xbffff9dc| | |---------------| |---------------| | Allocated | 0xbffff9d8| | |---------------| |---------------| | Allocated | 0xbffff9d4| | |---------------| |---------------| | Allocated | 0xbffff9d0| | |---------------| |---------------| | Allocated | 0xbffff9cc| | |---------------| |---------------| | Allocated | 0xbffff9c8| | |---------------| |---------------| | Allocated | 0xbffff9c4| | |---------------| |---------------| | Allocated | <-- %esp 0xbffff9c0| | <-- %esp |---------------| |---------------| V = %EDI W = %ESI ------ Figure 3.7 , ޸ Ҵ, 츮 װ͵ȿ 츮 ̴. ޸ : | | | | | | | | | | | | |---------------| |---------------| X | | 0xbffffa18| | |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %ebp 0xbffff9f8| 0xbffffa18 | <-- %ebp |---------------| |---------------| | V | 0xbffff9f4| 0x1 | |---------------| |---------------| | W | 0xbffff9f0| 0xbffffa84 | |---------------| |---------------| | iLocalInit | 0xbffff9ec| 0x00000001 | |---------------| |---------------| | iLocalUnInit | 0xbffff9e8| 0x00000005 | |---------------| |---------------| | [Padding] | 0xbffff9e4| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9e0| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9dc| 0x00000000 | |---------------| |---------------| | szHelloString | 0xbffff9d8| 0x21646c72 | "!dlr" |---------------| |---------------| | szHelloString | 0xbffff9d4| 0x6f57206f | "oW o" |---------------| |---------------| | szHelloString | 0xbffff9d0| 0x6c6c6548 | "lleH" |---------------| |---------------| | szLocalP | 0xbffff9cc| 0x080a00d8 | |---------------| |---------------| | [Padding] | 0xbffff9c8| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9c4| 0x00000000 | |---------------| |---------------| | [Padding] | <-- %esp 0xbffff9c0| 0x00000000 | <-- %esp |---------------| |---------------| V = %EDI W = %ESI ------ Figure 3.8 , ű⿡ 츮 ణ ʿϴ. 츮 ̷ : ------ int iLocalInit = 1; /* Will take 1 dword in the stack */ int iLocalUnInit; /* Will take 1 dword in the stack */ char szHelloString[12] = "Hello World!"; /* Will take 4 dwords in the stack In reality, 3 dwords + 1 byte but, don't forgot, the stack is devised in dwords not in bytes. */ char *szLocalP; /* Will take 1 dword in the stack */ ------ 쿡, %ESP 12 ƴ϶ 7 dwordŭ ҵǾ ȴ. ̰ ̷ δ ̷ ʴ. Ҵ ̴ Ϸ, ü, ȭ ̴. , Ϸ е ̴. ̰ 츮 0x00000000 е 5 dwords ̴. : stdint.h ȣȭ 32Ʈ(int32_t) ƴ϶ 16Ʈ(int16_t) ǵǾ, 츮 ʰ ϳ dwordȿ 2 ȣȭ Ƽ ̴. 3.4.2.3: The return: -------------------- ν 츮 α׷ Լ ȣ ǥǾ ȯ ̴. 츮 , 츮 main() ν ȯ function() ν ȣ ͵Ǿ ̴. ν ڵ尡 ִ: --------------------------------------------------- 0x8048268 : lea 0xfffffff8(%ebp),%esp 0x804826b : pop %esi 0x804826c : pop %edi 0x804826d : pop %ebp 0x804826e : ret ------ , ٸ ð GDB ɾ! ------ (gdb) break *0x8048268 Breakpoint 1 at 0x8048268: file funcinmem.c, line 24. (gdb) run Starting program: /root/prog/funcinmem Breakpoint 1, function (cParameter=0x808e3d5 "test", iParameter=5) at funcinmem.c:24 warning: Source file is more recent than executable. 24 } (gdb) info register ebp ebp 0xbffff9f8 0xbffff9f8 (gdb) info register esp esp 0xbffff9c0 0xbffff9c0 ------ , "lea 0xfffffff8(%ebp),%esp" ɾ 극ũƮ ɾ. %ESP %EBP ¸ üũϿ. ------ (gdb) stepi 0x0804826b 24 } (gdb) info register ebp ebp 0xbffff9f8 0xbffff9f8 (gdb) info register esp esp 0xbffff9f0 0xbffff9f0 ------ "stepi" gdb Ͽ "lea" Ͽ. %ESP %EBP ¸ ٽ üũϿ. %ESP ߴ. ÿ Ͽ. δ: | | | | | | | | | | | | |---------------| |---------------| X | | 0xbffffa18| | |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %ebp 0xbffff9f8| 0xbffffa18 | <-- %ebp |---------------| |---------------| | V | 0xbffff9f4| 0x1 | |---------------| |---------------| | W | <-- %esp 0xbffff9f0| 0xbffffa84 | <-- %esp |---------------| |---------------| | iLocalInit | 0xbffff9ec| 0x00000001 | |---------------| |---------------| | iLocalUnInit | 0xbffff9e8| 0x00000005 | |---------------| |---------------| | [Padding] | 0xbffff9e4| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9e0| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9dc| 0x00000000 | |---------------| |---------------| | szHelloString | 0xbffff9d8| 0x21646c72 | "!dlr" |---------------| |---------------| | szHelloString | 0xbffff9d4| 0x6f57206f | "oW o" |---------------| |---------------| | szHelloString | 0xbffff9d0| 0x6c6c6548 | "lloH" |---------------| |---------------| | szLocalP | 0xbffff9cc| 0x080a00d8 | |---------------| |---------------| | [Padding] | 0xbffff9c8| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9c4| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9c0| 0x00000000 | |---------------| |---------------| V = %EDI W = %ESI ------ Figure 3.9 , 츮 %ESP 12 dwordsŭ Ҵ! 츮 װ ̾ƿ, 鿡 ޸ Ҵ , ȸѴ. ------ (gdb) info register edi edi 0xbffff9dc -1073743396 (gdb) info register esi esi 0x808e3d4 134800340 (gdb) info register esp esp 0xbffff9f0 0xbffff9f0 (gdb) stepi 0x0804826c 24 } (gdb) info register edi edi 0xbffff9dc -1073743396 (gdb) info register esi esi 0xbffffa84 -1073743228 (gdb) info register esp esp 0xbffff9f4 0xbffff9f4 (gdb) stepi 0x0804826d 24 } (gdb) info register edi edi 0x1 1 (gdb) info register esi esi 0xbffffa84 -1073743228 (gdb) info register esp esp 0xbffff9f8 0xbffff9f8 ------ , %ESI κ ˵Ǿ, ׸, %ESP ÿ dwordŭ Ǿ. , %EDI ÿ ˵Ǿ, ׸ , %ESP Ǵٸ dwordŭ ÿ Ǿ. ׷, %ESI %EDI function() ν ȣ main() ν ȯ濡 ִ . δ: | | | | | | | | | | | | |---------------| |---------------| X | | 0xbffffa18| | |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffff9fc| | |---------------| |---------------| | X | <-- %ebp 0xbffff9f8| 0xbffffa18 | <-- %ebp |---------------| |%esp |---------------| |%esp | V | 0xbffff9f4| 0x1 | |---------------| |---------------| | W | 0xbffff9f0| 0xbffffa84 | |---------------| |---------------| | iLocalInit | 0xbffff9ec| 0x00000001 | |---------------| |---------------| | iLocalUnInit | 0xbffff9e8| 0x00000005 | |---------------| |---------------| | [Padding] | 0xbffff9e4| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9e0| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9dc| 0x00000000 | |---------------| |---------------| | szHelloString | 0xbffff9d8| 0x21646c72 | "!dlr" |---------------| |---------------| | szHelloString | 0xbffff9d4| 0x6f57206f | "oW o" |---------------| |---------------| | szHelloString | 0xbffff9d0| 0x6c6c6548 | "lloH" |---------------| |---------------| | szLocalP | 0xbffff9cc| 0x080a00d8 | |---------------| |---------------| | [Padding] | 0xbffff9c8| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9c4| 0x00000000 | |---------------| |---------------| | [Padding] | 0xbffff9c0| 0x00000000 | |---------------| |---------------| V = %EDI W = %ESI ------ Figure 3.10 ------ (gdb) info register ebp ebp 0xbffff9f8 0xbffff9f8 (gdb) info register esp esp 0xbffff9f8 0xbffff9f8 (gdb) stepi 0x0804826e in function (cParameter=0x1
, iParameter=-1073743228) at funcinmem.c:24 24 } (gdb) info register ebp ebp 0xbffffa18 0xbffffa18 (gdb) info register esp esp 0xbffff9fc 0xbffff9fc ------ %ESP %EBP ʹ ޸ ּҿ ִ. %EBP κ ˵Ǿ. %EBP װ ޸ ġ Ű ̴. ɾ ؼ, %ESP ʹ ޸𸮿 1 dwordŭ Ǹ鼭 ̰ װ ޸ ּҸ Ų! ------ (gdb) info register esp esp 0xbffff9fc 0xbffff9fc (gdb) info register eip eip 0x804826e 0x804826e (gdb) stepi 0x0804828c in main (argc=1, argv=0xbffffa84) at funcinmem.c:30 30 function("test",0); (gdb) info register esp esp 0xbffffa00 0xbffffa00 (gdb) info register eip eip 0x804828c 0x804828c ------ 3.4.2.1 Ѹ, ȣ %EIP ÿ ǪѴ. ׷, "ret" %EIP ͸ "pop" ̴. ׸, %ESP ޸ ÿ Ǵٸ dwordŭ ǰ function() ν ù° ĶͿ õǰ ִ. , %EIP main()ν ϱ غǾ. | | | | | | | | | | | | |---------------| |---------------| X | | <-- %ebp 0xbffffa18| | <-- %ebp |---------------| |---------------| | | | | | | | | | | | | |---------------| |---------------| Y | | 0xbffffa08| | |---------------| |---------------| | 0 | 0xbffffa04| 0x0 | |---------------| |---------------| | test | 0xbffffa00| 0x808e3d5 | <-- %esp |---------------| |---------------| | Z | <-- %esp 0xbffff9fc| 0x0804828c | |---------------| |---------------| | | | | | | | | ------ Figure 3.11 3.5: The Heap: -------------- α׷ ҴǴ ޸ ̴. 츮 ˴ٽ, ʱȭ .bss ELF ǿ ǵǾ. ݴ, ʱȭ ÿ ǵǾ(츮 ҵ). ҴǾ ޸ ̰ Ͻÿ ˷ ʴ´ٸ Ÿ ̴. , ̴ Ͻÿ ˷. stdint.h װ ϸ, x86 ̴ 32Ʈ ̴. ׷, ʱȭ .bss׸Ʈ Ǿ ̰ ʱȭ 쿡, ÿ Ǿ ̴. ׷, ̰ ƴϴ. Ǹ ϶: Ϳ õǴ ޸ ̴. 츮 ̷ ΰ Ǹ Բ Ѵٸ, ̰ ̰, ֳϸ α׷ ߿ ְ, ޸𸮸 Ҵ ȭǾֱ ̴. ׷ , ʹ ޸ ޸𸮿 ִ ּ̰, ̴ 쿡, Ͻÿ(32Ʈ) ˷, ׻ .bss ( ) ǵǾ ̴. 츮 ʱȭ Ŀ .bss ó ִ. | | | Heap | 0x809fe04|---------------| | | <---- /// /// | | | | |---------------| | 0x809f8c8| szGlobalP | | BSS |---------------| | Segment 0x809f8c4| iGlobalUnInit | | |---------------| | | | | /// /// | | | <---- 0x809ee80|---------------| | Data | | | ------ Figure 3.12 츮 ʱȭ .bss ǿ ִ. ׷ , 츮 function()ν 츮 ʱȭ Ŀ ˱⸦ Ѵ. , ٸ Ÿӿ GDB ɾ: ϱ , ð Ʒ ڶ ʰ ڶٴ ο ʿ䰡 ִ. ------ (gdb) info symbol &szGlobalP szGlobalP in section .bss (gdb) print &szGlobalP $1 = (char **) 0x809f8c8 (gdb) print szGlobalP $2 = 0x80a00c8 "Hello World!\021" (gdb) x/4c 0x80a00c8 0x80a00c8: 72 'H' 101 'e' 108 'l' 108 'l' (gdb) x/4c 0x80a00cc 0x80a00cc: 111 'o' 32 ' ' 87 'W' 111 'o' (gdb) x/4c 0x80a00d0 0x80a00d0: 114 'r' 108 'l' 100 'd' 33 '!' (gdb) x/4c 0x80a00d4 0x80a00d4: 17 '\021' 0 '\000' 0 '\000' 0 '\000' (gdb) info symbol &szLocalP No symbol matches &szLocalP. (gdb) print &szLocalP $5 = (char **) 0xbffff9cc (gdb) print szLocalP $6 = 0x80a00d8 "Hello World!!\017" (gdb) x/4c 0x80a00d8 0x80a00d8: 72 'H' 101 'e' 108 'l' 108 'l' (gdb) x/4c 0x80a00dc 0x80a00dc: 111 'o' 32 ' ' 87 'W' 111 'o' (gdb) x/4c 0x80a00e0 0x80a00e0: 114 'r' 108 'l' 100 'd' 33 '!' (gdb) x/4c 0x80a00e4 0x80a00e4: 33 '!' 15 '\017' 0 '\000' 0 '\000' ------ Ʈ 1: szLocalP ǵ  ɺ µ ̴ ̰ ÿ ǵǾ ֱ ̴. , function() ν Ŀ ̿ δ. 3 2 1 0 | | | Stack | |---------------| | | /// /// | | |---------------| 0x80a00e4|0x0|0x0|0x0|017| <--|-- |---------------| | 0x80a00e0| ! | d | l | r | | |---------------| | szLocalP 0x80a00dc| o | W |\32| o | | |---------------| | 0x80a00d8| l | l | e | H | <--|-- |---------------| 0x80a00d4|0x0|0x0|0x0|021| <--|-- |---------------| | 0x80a00d0| ! | d | l | r | | |---------------| | szGlobalP 0x80a00cc| o | W |\32| o | | |---------------| | 0x80a00c8| l | l | e | H | <--|-- |---------------| | | /// /// | | 0x809fe08|---------------| | BSS | | | ------ Figure 3.13 극ũ Ʈν ޵Ǿ. ޸𸮸 ϴ ʿϴٸ, 극ũ Ʈ Űܾ ʿ䰡 ̴. ý ȣ α׷ ޸𸮸 ʿ Ѵٴ Ŀο ϴµ Ǿ. ׸, Ŀ ణ ƾ ε, BRK ý ȣ Ŀ, ̰ ޸𸮸 Ҵϱ ӿ 극ũƮ ű ִ ˱ ؼ̴. ̸, Ŀ μ ̺ ο ٲ ̰ ũ ӿ ̴. BRK û Ҵ翡 ޸𸮰 ٸ, ׷ Ŀ -1 ϰ α׷ ؼ ޸ Ҵ ̴. The Conclusion: -------------------------- , ؾ߸ ߴ ͵ д ̸ ⸦ ٶ. α׷ ޸𸮿  εǴ  Ǵ ϱ ǰ  α׷ ⺻ α׷  ۵Ǵ ϱ ִ. "" ϴµ ð̶ Ѵ.  α׷  ϴ,   Ϸ ϴ ׸  ϴ ϴµ ɾ. , 츮 ޸𸮿 εǴ ν ýۿ ȿ ִ. 츮 α׷ ϰ ǵ ɺ ִ ˻ν ýۿ  C Ÿ ϴ ִ. 츮 ũⰡ Ȥ , þ Ȥ , Ÿ ̴. α׷ ޸𸮿  εǴ ϴ° α׷  ϴ ϴ ̴.  , ڸƮ, ÷ Ȥ ˷ְ ִٸ, fred@decatomb.com ̸ ֱ ٶ.  , װ͵鿡 Ⲩ ֱ ϸ, ֱ ٶ ؽƮ ̴. ================================================================================ ================================================================================ Annex 1 : --------- do_fork() - Function Code - src/mm/forkexit.c --------------------------------------------- /*===========================================================================* * do_fork * *===========================================================================*/ 01 PUBLIC int do_fork() 02 { 03 /* The process pointed to by 'mp' has forked. Create a child process. */ 04 05 register struct mproc *rmp; /* pointer to parent */ 06 register struct mproc *rmc; /* pointer to child */ 07 int i, child_nr, t; 08 phys_clicks prog_clicks, child_base = 0; 09 phys_bytes prog_bytes, parent_abs, child_abs; /* Intel only */ 10 11 /* If tables might fill up during FORK, don't even start since recovery half 12 * way through is such a nuisance. 13 */ 14 rmp = mp; 15 if (procs_in_use == NR_PROCS) return(EAGAIN); 16 if (procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0)return(EAGAIN); 17 18 /* Determine how much memory to allocate. Only the data and stack need to 19 * be copied, because the text segment is either shared or of zero length. 20 */ 21 prog_clicks = (phys_clicks) rmp->mp_seg[S].mem_len; 22 prog_clicks += (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir); 23 #if (SHADOWING == 0) 24 prog_bytes = (phys_bytes) prog_clicks << CLICK_SHIFT; 25 #endif 26 if ( (child_base = alloc_mem(prog_clicks)) == NO_MEM) return(ENOMEM); 27 28 #if (SHADOWING == 0) 29 /* Create a copy of the parent's core image for the child. */ 30 child_abs = (phys_bytes) child_base << CLICK_SHIFT; 31 parent_abs = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT; 32 i = sys_copy(ABS, 0, parent_abs, ABS, 0, child_abs, prog_bytes); 33 if (i < 0) panic("do_fork can't copy", i); 34 #endif 35 36 /* Find a slot in 'mproc' for the child process. A slot must exist. */ 37 for (rmc = &mproc[0]; rmc < &mproc[NR_PROCS]; rmc++) 38 if ( (rmc->mp_flags & IN_USE) == 0) break; 39 40 /* Set up the child and its memory map; copy its 'mproc' slot from parent. */ 41 child_nr = (int)(rmc - mproc); /* slot number of the child */ 42 procs_in_use++; 43 *rmc = *rmp; /* copy parent's process slot to child's */ 44 45 rmc->mp_parent = who; /* record child's parent */ 46 rmc->mp_flags &= ~TRACED; /* child does not inherit trace status */ 47 #if (SHADOWING == 0) 48 /* A separate I&D child keeps the parents text segment. The data and stack 49 * segments must refer to the new copy. 50 */ 51 if (!(rmc->mp_flags & SEPARATE)) rmc->mp_seg[T].mem_phys = child_base; 52 rmc->mp_seg[D].mem_phys = child_base; 53 rmc->mp_seg[S].mem_phys = rmc->mp_seg[D].mem_phys + 54 (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir); 55 #endif 56 rmc->mp_exitstatus = 0; 57 rmc->mp_sigstatus = 0; 58 59 /* Find a free pid for the child and put it in the table. */ 60 do { 61 t = 0; /* 't' = 0 means pid still free */ 62 next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1); 63 for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) 64 if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) { 65 t = 1; 66 break; 67 } 68 rmc->mp_pid = next_pid; /* assign pid to child */ 69 } while (t); 70 /* Tell kernel and file system about the (now successful) FORK. */ 71 sys_fork(who, child_nr, rmc->mp_pid, child_base); /* child_base is 68K only*/ 72 tell_fs(FORK, who, child_nr, rmc->mp_pid); 73 74 #if (SHADOWING == 0) 75 /* Report child's memory map to kernel. */ 76 sys_newmap(child_nr, rmc->mp_seg); 77 #endif 78 79 /* Reply to child to wake it up. */ 80 reply(child_nr, 0, 0, NIL_PTR); 81 return(next_pid); /* child's pid */ 82 } ------ Annex 2 : --------- Process Table definition - src/kernel/proc.h -------------------------------------------- struct proc { struct stackframe_s p_reg; /* process' registers saved in stack frame */ #if (CHIP == INTEL) reg_t p_ldt_sel; /* selector in gdt giving ldt base and limit*/ struct segdesc_s p_ldt[2]; /* local descriptors for code and data */ /* 2 is LDT_SIZE - avoid include protect.h */ #endif /* (CHIP == INTEL) */ #if (CHIP == M68000) reg_t p_splow; /* lowest observed stack value */ int p_trap; /* trap type (only low byte) */ #if (SHADOWING == 0) char *p_crp; /* mmu table pointer (really struct _rpr *) */ #else phys_clicks p_shadow; /* set if shadowed process image */ int align; /* make the struct size a multiple of 4 */ #endif int p_nflips; /* statistics */ char p_physio; /* cannot be (un)shadowed now if set */ #if defined(FPP) struct fsave p_fsave; /* FPP state frame and registers */ int align2; /* make the struct size a multiple of 4 */ #endif #endif /* (CHIP == M68000) */ reg_t *p_stguard; /* stack guard word */ int p_nr; /* number of this process (for fast access) */ int p_int_blocked; /* nonzero if int msg blocked by busy task */ int p_int_held; /* nonzero if int msg held by busy syscall */ struct proc *p_nextheld; /* next in chain of held-up int processes */ int p_flags; /* P_SLOT_FREE, SENDING, RECEIVING, etc. */ struct mem_map p_map[NR_SEGS];/* memory map */ pid_t p_pid; /* process id passed in from MM */ clock_t user_time; /* user time in ticks */ clock_t sys_time; /* sys time in ticks */ clock_t child_utime; /* cumulative user time of children */ clock_t child_stime; /* cumulative sys time of children */ clock_t p_alarm; /* time of next alarm in ticks, or 0 */ struct proc *p_callerq; /* head of list of procs wishing to send */ struct proc *p_sendlink; /* link to next proc wishing to send */ message *p_messbuf; /* pointer to message buffer */ int p_getfrom; /* from whom does process want to receive? */ int p_sendto; struct proc *p_nextready; /* pointer to next ready process */ sigset_t p_pending; /* bit map for pending signals */ unsigned p_pendcount; /* count of pending and unfinished signals */ char p_name[16]; /* name of the process */ }; ------ Annex 3: -------- 001 /*===========================================================================* 002 * do_exec * 003 *===========================================================================*/ 004 PUBLIC int do_exec() 005 { 006 /* Perform the execve(name, argv, envp) call. The user library builds a 007 * complete stack image, including pointers, args, environ, etc. The stack 008 * is copied to a buffer inside MM, and then to the new core image. 009 */ 010 011 register struct mproc *rmp; 012 struct mproc *sh_mp; 013 int m, r, fd, ft, sn; 014 static char mbuf[ARG_MAX]; /* buffer for stack and zeroes */ 015 static char name_buf[PATH_MAX]; /* the name of the file to exec */ 016 char *new_sp, *basename; 017 vir_bytes src, dst, text_bytes, data_bytes, bss_bytes, stk_bytes, vsp; 018 phys_bytes tot_bytes; /* total space for program, including gap */ 019 long sym_bytes; 020 vir_clicks sc; 021 struct stat s_buf; 022 vir_bytes pc; 023 /* Do some validity checks. */ 024 rmp = mp; 025 stk_bytes = (vir_bytes) stack_bytes; 026 if (stk_bytes > ARG_MAX) return(ENOMEM); /* stack too big */ 027 if (exec_len <= 0 || exec_len > PATH_MAX) return(EINVAL); 028 029 /* Get the exec file name and see if the file is executable. */ 030 src = (vir_bytes) exec_name; 031 dst = (vir_bytes) name_buf; 032 r = sys_copy(who, D, (phys_bytes) src, 033 MM_PROC_NR, D, (phys_bytes) dst, (phys_bytes) exec_len); 034 if (r != OK) return(r); /* file name not in user data segment */ 035 tell_fs(CHDIR, who, FALSE, 0); /* switch to the user's FS environ. */ 036 fd = allowed(name_buf, &s_buf, X_BIT); /* is file executable? */ 037 if (fd < 0) return(fd); /* file was not executable */ 038 039 /* Read the file header and extract the segment sizes. */ 040 sc = (stk_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT; 041 m = read_header(fd, &ft, &text_bytes, &data_bytes, &bss_bytes, 042 &tot_bytes, &sym_bytes, sc, &pc); 043 if (m < 0) { 044 close(fd); /* something wrong with header */ 045 return(ENOEXEC); 046 } 047 048 /* Fetch the stack from the user before destroying the old core image. */ 049 src = (vir_bytes) stack_ptr; 050 dst = (vir_bytes) mbuf; 051 r = sys_copy(who, D, (phys_bytes) src, 052 MM_PROC_NR, D, (phys_bytes) dst, (phys_bytes)stk_bytes); 053 if (r != OK) { 054 close(fd); /* can't fetch stack (e.g. bad virtual addr) */ 055 return(EACCES); 056 } 057 058 /* Can the process' text be shared with that of one already running? */ 059 sh_mp = find_share(rmp, s_buf.st_ino, s_buf.st_dev, s_buf.st_ctime); 060 061 /* Allocate new memory and release old memory. Fix map and tell kernel. */ 062 r = new_mem(sh_mp, text_bytes, data_bytes, bss_bytes, stk_bytes, tot_bytes); 063 if (r != OK) { 064 close(fd); /* insufficient core or program too big */ 065 return(r); 066 } 067 068 /* Save file identification to allow it to be shared. */ 069 rmp->mp_ino = s_buf.st_ino; 070 rmp->mp_dev = s_buf.st_dev; 071 rmp->mp_ctime = s_buf.st_ctime; 072 073 /* Patch up stack and copy it from MM to new core image. */ 074 vsp = (vir_bytes) rmp->mp_seg[S].mem_vir << CLICK_SHIFT; 075 vsp += (vir_bytes) rmp->mp_seg[S].mem_len << CLICK_SHIFT; 076 vsp -= stk_bytes; 077 patch_ptr(mbuf, vsp); 078 src = (vir_bytes) mbuf; 079 r = sys_copy(MM_PROC_NR, D, (phys_bytes) src, 080 who, D, (phys_bytes) vsp, (phys_bytes)stk_bytes); 081 if (r != OK) panic("do_exec stack copy err", NO_NUM); 082 083 /* Read in text and data segments. */ 084 if (sh_mp != NULL) { 085 lseek(fd, (off_t) text_bytes, SEEK_CUR); /* shared: skip text */ 086 } else { 087 load_seg(fd, T, text_bytes); 088 } 089 load_seg(fd, D, data_bytes); 090 091 #if (SHADOWING == 1) 092 if (lseek(fd, (off_t)sym_bytes, SEEK_CUR) == (off_t) -1) ; /* error */ 093 if (relocate(fd, (unsigned char *)mbuf) < 0) ; /* error */ 094 pc += (vir_bytes) rp->mp_seg[T].mem_vir << CLICK_SHIFT; 095 #endif 096 097 close(fd); /* don't need exec file any more */ 098 099 /* Take care of setuid/setgid bits. */ 100 if ((rmp->mp_flags & TRACED) == 0) { /* suppress if tracing */ 101 if (s_buf.st_mode & I_SET_UID_BIT) { 102 rmp->mp_effuid = s_buf.st_uid; 103 tell_fs(SETUID,who, (int)rmp->mp_realuid, (int)rmp->mp_effuid); 104 } 105 if (s_buf.st_mode & I_SET_GID_BIT) { 106 rmp->mp_effgid = s_buf.st_gid; 107 tell_fs(SETGID,who, (int)rmp->mp_realgid, (int)rmp->mp_effgid); 108 } 109 } 110 111 * Save offset to initial argc (for ps) */ 112 rmp->mp_procargs = vsp; 113 114 /* Fix 'mproc' fields, tell kernel that exec is done, reset caught sigs. */ 115 for (sn = 1; sn <= _NSIG; sn++) { 116 if (sigismember(&rmp->mp_catch, sn)) { 117 sigdelset(&rmp->mp_catch, sn); 118 rmp->mp_sigact[sn].sa_handler = SIG_DFL; 119 sigemptyset(&rmp->mp_sigact[sn].sa_mask); 120 } 121 } 122 123 rmp->mp_flags &= ~SEPARATE; /* turn off SEPARATE bit */ 124 rmp->mp_flags |= ft; /* turn it on for separate I & D files */ 125 new_sp = (char *) vsp; 126 127 tell_fs(EXEC, who, 0, 0); /* allow FS to handle FD_CLOEXEC files */ 128 129 /* System will save command line for debugging, ps(1) output, etc. */ 130 basename = strrchr(name_buf, '/'); 131 if (basename == NULL) basename = name_buf; else basename++; 132 sys_exec(who, new_sp, rmp->mp_flags & TRACED, basename, pc); 133 return(OK); 134 } ------ Bibliography: ------------- -Andrew S. Tanenbaum and Albert S. Woodhull, "Operating System, Design and Implementation. Second Edition", Prentice Hall, Upper Saddle River, New Jersy 07458, 1997, p.939. -David A Rusling, "The Linux Kernel", http://www.linuxdoc.org/LDP/tlk/tlk-title.html, 1999. -George F. Corliss,"Minix_book",http://www.mscs.mu.edu/~georgec/Classes/207.1998/14Minix_book/, 1998. Minix source snippets are: Copyright (c) 1987,1997, Prentice Hall. All rights reserved. (c) Copyright 2001 Fr??ick Giasson, All Rights Reserved