X86 assembly language learning incoming (3) (reproduced)

xiaoxiao2021-03-06  18

X86 assembly language learning Notes (3) Author: Badcoffee Email: blog.oliver@gmail.com December 2004 ORIGINAL: http://blog.9cbs.net/yayong Copyright: be sure to identify the form of hyperlinks reprint The original source of the article, the author information and this statement this is the study notes in the process of learning the X86 assembly, which is inevitable to have errors and omissions. Welcome to correct. Strictly speaking, the content involved in this document is not limited to the X86 assembly area, with respect to the ELF file format, C language, compiler, and other related knowledge, also refer to the relevant documentation. The authors will update the feedback to the wrong form on their own Blog site. In X86 Assembly Language Learning Intention (1) (2), you can see the stack as a temporary storage area of ​​data during the process execution, usually contains the following types of data: the entry of the returned address function called by the local variable function call Parameter STP Stack Frame Pointer (can be removed by compiler optimization option) This chapter will continue to pass experiments, understand how global variables and static variables are stored and assigned in the process. Note: Different CALLING CONVENTIONs have a difference in the provisions of the entrance parameters, and the function call entry parameters may also pass the registers. For example, IBM's Power PC and AMD's Opteron, all of the port parameters of the function are passed through registers.

1. The overall variable and global constant experiment have been continued, give a simple C program, which is divided into three species: the global variable of the initialized global variable is not initialized #vi test5.c Int i = 1; int K = 3; INT L, M; INT N; const = 8; const INT = 8; const Int q = 9; int main () {l = 4; M = 5; n = 6; return i j k l m n o p q;} # gcc test5.c -o test5 # mdb test5 loading modules: [libc.so.1]> main :: Dis main: pushl% EBP; Main to main 1, create Stack Frame Main 1: MOVL% ESP,% EBP Main 3: Subl $ 8,% ESP Main 6: Andl $ 0xF0,% ESP Main 9 : MOVL $ 0,% EAX Main 0xE: Subl% Eax,% ESP; Main 3 to Main 0xe, to reserve stack space for local variables, and ensure that the stack 16 bytes MAIN 0x10: MOVL $ 4,0x8060948; l = 4 Main 0x1a: MOVL $ 5,0X806094c; m = 5 main 0x24: MOVL $ 6,0x8060950; n = 6 main 0x2e: MOVL 0X8060908,% EAX Main 0x33: AddL 0x8060904,% EAX Main 0x39: addl 0x806090c ,% eax main 0x3f: addl 0x8060948,% eax main 0x45: addl 0x806094c,% eax main 0x4b: addl 0x8060950,% eax main 0x51: addl 0x8050808,% eax main 0x57: addl 0x805080c,% eax main 0x5D: addl 0x8050810,% EAX; main 0x2e to main 0x5d, i j k L M N O P Q main 0x63: Leave; revoke Stack frame main 0x64: Ret; main function Return now, let us in the whole game The variable is initialized after setting breakpoints, observes the values ​​of these global variables:> main 0x2e: b; set breakpoint>: r; Run program MDB: Stop at Main 0x2e MDB: Target Stopped At: Main 0x2e: MOVL 0X8060908,% EAX> 0x8060904, 03 / NAP; Value of global variables I, J, K TEST5`I: Test5`i: Test5`i: 1 test5`j: 2 Test5`k: 3> 0x8060948, 03 / NAP; Test5`l: Test5`l: Test5`l: Test5`l: Test5`l: 4 Test5`m: 5 Test5`n: 6> 0x8050808, 03 / NAP; view global variable O, P , Q value o: o: 7: 8 Q: 9> Concept:

Process Address Space -------------------- ----> 0xfffffff (4GB) | | | | KERNEL SPACE | | | -------------------- ----> _kernel_base (0xE0000000) | | | l b |::::::::::::: | | ------- --------------- | Data Section | | LIB C Library |:::: ---------------- ------ | | | |::: # Up::: | | | ---------------------- | BSS | | | | | | | | ---------------------- | | | | | | ----- ---------------- ----> 0x08050000 | | | | | | | | | | --- ----------------- --> 0 Figure 3-1 Solaris Process Address Space on IA32 As shown in Figure 3-1, Solaris's process on IA32 The address space and Linux are similar, in the 4GB address space of the user process: kernel is always mapped to the highest end of the user address space, from the macro definition _kernel_base to 0xFfffffFFFFFF's area user process relied on the Kernel mapping At the high end of the user address space, the code segment of the low-end shared library of the user's process address space is stored, and the binary executable machine command is stored, which is the code segment map of the library ELF file to the virtual space. The attribute is the data segment of the read / exec / share, and the global variable required to execute the program execution is the data segment map of the ELF file to the virtual space, the attribute is the READ / WRITE / PRIVATE user code segment. , Stored the executable machine instructions of binary forms, is the data segment of the code segment map of the ELF file, the attribute is the data segment, and the program is stored The global variables required by the row are the data segment map of the ELF file to the virtual space, the attribute is a stack, as a stack, as a temporary data area of ​​the process, is KERNEL Put an anonymous memory map to the false space, the property is a heap (HEAP) on the READ / WRITE / EXEC user data segment, and when the malloc is called, the anonymous memory Map to the virtual space, the attribute is Read / WRITE / EXEC Note The differences and contacts of Stack and HEAP: The same points: 1. All comes from the anonymous memory allocation of Kernel, and independent of the ELF file on the disk. The allocation of the stack is generally caused by the local variable, the call function is caused by the declaration of local variables; the allocation of the heap is transparent to the user through the explicit call (malloc). The release of the stack is transparent to the user. The user does not need to care, and the corresponding instructions generated by the C compiler are depleted; the heap needs explicit call (free) to release 3. The growth direction of the stack space is from the high address to the low address;

The growth direction of the heap space is from the low address to the high address 4. The stack is in the address space of any process; the stack does not have the layout of the user address space without call Malloc, and the CPU and OS are different. There is a difference, and the above is discussed based on the X86 CPU on the Solaris OS.

Using the PMAP command, you can observe the address space distribution of the specified process in the system. Here is an example of watching the Bash process with PMAP: # pmap 1030 1030: -bash 08045000 12k rw --- [stack]; bash's stack 08050000 444K rx - / usr / bin / bash; bash text section 080CE000 72K rwx - / usr / bin / bash; bash's data segment 080e0000 156k rwx-- [HEAP]; BASH Punch DD8C0000 8K RX - / USR / LIB / LOCALE / ZH_CN.GB18030 / Methods_zh_cn.gb18030.so.2; Shared library text segment DD8D1000 4K rwx - /usr/lib/locale/en_cn.gb18030/methods_zh_cn.gb18030.so.2; Shared library data segment DD8E0000 324K rx - /usr/lib/locale/en_cn.gb18030/en_cn.gb18030.so.2 DD940000 8K rwx - /usr/lib/locale/en_cn.gb18030/en_cn.gb18030.so.2 DD950000 4K RWX- - [Anon]; Anonymous memory, DD960000 12K rx-- /usr/lib/libmp.so.2 dd973000 4k rwx-- /usr/lib/libmp.so.2 dd980000 628k RX - /usR/LIB/LIBC.SO.1 DDA2D000 24K rwx - /usr/lib/libc.so.1 DDA33000 4K rwx - /usr/lib/libc.so.1 DDA50000 4K RWX - [Anon ] DDA60000 548k rx - /usr/lib/libnsl.so.1 DDAF9000 20K rwx - /usr/lib/libnsl.so.1 DDAFE000 32K RWX - /usr/lib/libnsl.so.1 DDB10000 44K RX- - /usr/lib/libsocket.so.1 DDB2B000 4K RW X- /usr/lib/libsocket.so.1 ddb30000 152k rx - /usr/lib/libcurses.so.1 ddb66000 28k rwx - /usr/lib/libcurses.so.1 DDB6D000 8K RWX - / USR /LIB/LIBCURS.SO.1 DDB80000 4K rx - /usr/lib/libdl.so.1 DDB90000 292K RX - /USR/LIB/ld.so.1 DDBE9000 16K RWX - / USR / LIB / LD. SO.1 DDBED000 8K RWX - /usr/lib/ld.so.1 Total 2864K Problem: Global Variables and Global Constants Location in the Process Address Space? Obviously, according to the previous description, global variables are in the user's data segment, then the global constant is the data segment? Similarly, you can use MDB to hang the test5 process, then use the PMAP command to verify: # mdb test5 loading modules: [libc.so.1]> :: sysbp _exit; set breakpoint in the system call _exit Running program MDB: Stop on entry to _exit mdb: target stopped at: libc.so.1`exit 0x2b: jae 0x15 > At this time,

After the program is running, you can use the PMAP to view the address space of the test5 process in another terminal: # ps -ef | grep test5 root 1387 1386 0 02:23:53 PTS / 1 0:00 Test5 root 1399 1390 0 02:25:03 PTS / 3 0:00 Grep test5 root 1386 1338 0 02:23:41 PTS / 1 0:00 mdb test5 # pmap -f 1387; mandatory with PMAP 1387: Test5 08044000 16K rwx- - [stack]; TEST5 Stack 08050000 4K RX - / EXPORT / HOME / ASM / L3 / TEST5; TEST5 code segment, start address is 0x08050000 08060000 4K RWX - / Export / Home / ASM / L3 / TEST5; Test5 data segment, start address is 0x08060000 DDAC0000 628K RX - /USR/LIB/LIBC.SO.1 DDB6D000 24K rwx - /usr/lib/libc.so.1 DDB73000 4K RWX - / USR / LIB / Libc.so.1 DDB80000 4K rx - /usr/lib/libdl.so.1 ddb90000 292k rx - /usr/lib/ld.so.1 DDBE9000 16K RWX - /usr/lib/ld.so.1 DDBED000 8K rwx - /usr/lib/ld.so.1 Total 1000K can be seen that since the Test5 program does not use Malloc to apply for memory, there is no HEAP mapping with MDB to observe the initialization value of these global variables and constants, Their addresss are: global variables I, J, K: 0x8060904 start 12-byte global variables L, M, N: 0x8060948 start 12-byte global constant O, P, Q: 0x8050808 starting 12 words The section is clear, according to the address of these variables, we can initially determine which paragraph belongs to these variables: Since the Test5 data segment start address is 0x08060000, we conclude: global variables I, J, K, L, M, N belong to data The starting address of the TEST5 code segment is 0x08050000, we conclude: global constant O, P, Q belong to code segment It is indeed an accident that this conclusion is indeed: the global constant is actually in the code segment. But it seems that in the reason: the attribute after the data segment memory is R / W / X, and the constant requirement is read-only attribute, so it is reasonable in the code segment (R-X). Question: Why is these global variable addresses not continuous? It is easy to note that global variables I, J, K and L, M, N, and global constant O, P, Q are continuous declarations, but the address is actually discontinuous, but at 3 segments continuous 12-byte address on.

Of course, the global constant is a code segment, so the address and global variable are separated; then why global variables are not continuous? The data segment is actually mapped from the ELF format to the address space of the process, by analyzing the ELF file format: # file test5 test5: Elf 32-bit lsb executable 80386 Version 1, DynamicalLinked NOT STRIPPED # Elfdump test5 Elf Header; ELF header information Total 52 (0x34) byte Elfdata2lsb; 32-bit ELF file, small end (LSB) encoding E_MACHINE: EM_386 E_VERSION: EV_CURRENT; Intel 80386, version 1 E_TYPE: ET_EXEC; executable E_FLAGS: 0 E_EHSIZE: 0X8050600 E_EHSIZE: 52 E_SHSTRNDX: 27; program entry point _ start address 0x8050600 e_shoff: 0x1584 e_shentsize: 40 e_shnum: 29; Section header table size is 29 * 40 e_phoff: 0x34 e_phentsize: 32 e_phnum: 5 Program header [0]:; description Program header table how itself is mapped p_vaddr in memory : 0x8050034 p_flags: [pf_x pf_r] p_paddr: 0 p_type: [PT_phdr] p_filesz: 0xA0 p_memsz: 0xA0 p_offset: 0x34 p_align: 0 Program Header [1]:; Description Program loader path name (.interp section) stored in file Position P_vaddr: 0 p_flags: [PF_R] p_paddr: 0 p_type: [PT_INTERP] P_Filesz: 0x11 p_memsz: 0 p_offset: 0xd4 p_align: 0 Program Header [2]:; Describe how to map, start addresses in memory 0x8050000, the size of 0x814 p_vaddr: 0x8050000 p_flags: [PF_X PF_R] p_paddr: 0 p_type: [PT_LOAD] p_filesz: 0x814 p_memsz: 0x814 p_offset: 0 p_align: 0x10000 Program Header [3]:; description data segments how to map in the memory, start address 0x8060814, the size of 0x144 p_vaddr: 0x8060814 p_flags: [PF_X PF_W PF_R] p_paddr: 0 p_type: [PT_LOAD] p_filesz: 0x118 p_memsz: 0x144 p_offset: 0x814 p_align: 0x10000 Program Header [4]:; described dynamic linking information ( .dynamic section) how to map memory p_vaddr: 0x8060848 p_flags: [PF_X PF_W PF_R] p_paddr: 0 p_type: [PT_DYNAMIC] p_filesz: 0xb8 p_memsz: 0 p_offset: 0x848 p_align: 0 Section Header [1]: sh_name: .interp;

This section holds the interpreter program (Interpreter) path sh_addr: 0x80500d4 sh_flags: [SHF_ALLOC] sh_size: 0x11 sh_type: [SHT_PROGBITS] sh_offset: 0xd4 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 Section Header [2]: sh_name: .hash; this section holds a symbol hash table sh_addr: 0x80500e8 sh_flags: [SHF_ALLOC] sh_size: 0x104 sh_type: [SHT_HASH] sh_offset: 0xe8 sh_entsize: 0x4 sh_link: 3 sh_info: 0 sh_addralign: 0x4 Section Header [3 ]: sh_name: .dynsym; this section holds the dynamic symbol table sh_addr: 0x80501ec sh_flags: [SHF_ALLOC] sh_size: 0x200 sh_type: [SHT_DYNSYM] sh_offset: 0x1ec sh_entsize: 0x10 sh_link: 4 sh_info: 1 sh_addralign: 0x4 Section Header [4] : sh_name: .dynstr; string section holds the required dynamic connection sh_addr: 0x80503ec sh_flags: [SHF_ALLOC SHF_STRINGS] sh_size: 0x11a sh_type: [SHT_STRTAB] sh_offset: 0x3ec sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 Section Header [5]: SH_NAME: .SUNW_VERSION; this section is Sun extension, save version information sh_addr: 0x8050508 sh_flags: [shf_alloc] sh_size: 0x20 sh_type: [sht_sunw_verneed] sh_offset: 0x 508 sh_entsize: 0 sh_link: 4 sh_info: 1 sh_addralign: 0x4 Section Header [6]: sh_name: .rel.got; This section holds relocation section .got information symbol portion sh_addr: 0x8050528 sh_flags: [SHF_ALLOC SHF_INFO_LINK] sh_size : 0x18 sh_type: [SHT_REL] SH_EFFSET: 0X528 SH_ENTSIZE: 0x8 sh_link: 3 sh_info: 14 sh_addralign: 0x4 section header [7]: sh_name: .rel.bss; this section saves. BSS section Some symbols SH_ADDR : 0x8050540 sh_flags: [SHF_ALLOC SHF_INFO_LINK] sh_size: 0x8 sh_type: [SHT_REL] sh_offset: 0x540 sh_entsize: 0x8 sh_link: 3 sh_info: 22 sh_addralign: 0x4 Section Header [8]: sh_name: .rel.plt;

This section holds .plt section relocation information symbol portion sh_addr: 0x8050548 sh_flags: [SHF_ALLOC SHF_INFO_LINK] sh_size: 0x38 sh_type: [SHT_REL] sh_offset: 0x548 sh_entsize: 0x8 sh_link: 3 sh_info: 9 sh_addralign: 0x4 Section Header [9 ]: sh_name: .plt; this section holds the connection table procedure (procedure Linkage table) sh_addr: 0x8050580 sh_flags: [SHF_ALLOC SHF_EXECINSTR] sh_size: 0x80 sh_type: [SHT_PROGBITS] sh_offset: 0x580 sh_entsize: 0x10 sh_link: 0 sh_info: 0 sh_addralign: 0x4 section Header [10]: sh_name: .text; section holds the body of the program, to execute instructions sh_addr: 0x8050600 sh_flags: [SHF_ALLOC SHF_EXECINSTR] sh_size: 0x1ec sh_type: [SHT_PROGBITS] sh_offset: 0x600 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [11]: sh_name: .init; this section holds executable instructions, which constitutes the initialization code sh_addr process: 0x80507ec sh_flags: [SHF_ALLOC SHF_EXECINSTR] sh_size: 0xd sh_type: [SHT_PROGBITS] SH_OFFSET: 0X7EC SH_ENTSIZE: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 section Header [12]: sh_name: .fini; This section saves executable instructions, which constitutes the termination code of the process sh_addr: 0x80507f9 s h_flags: [SHF_ALLOC SHF_EXECINSTR] sh_size: 0x8 sh_type: [SHT_PROGBITS] sh_offset: 0x7f9 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 Section Header [13]: sh_name: .rodata; This section holds read-only data sh_addr: 0x8050804 sh_flags: [SHF_ALLOC] sh_size: 0x10 sh_type: [SHT_PROGBITS] sh_offset: 0x804 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [14]: sh_name: .got; this section holds the global offset table sh_addr : 0x8060814 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x34 sh_type: [SHT_PROGBITS] sh_offset: 0x814 sh_entsize: 0x4 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [15]: sh_name: .dynamic;

This section holds dynamic linking information sh_addr: 0x8060848 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0xb8 sh_type: [SHT_DYNAMIC] sh_offset: 0x848 sh_entsize: 0x8 sh_link: 4 sh_info: 0 sh_addralign: 0x4 Section Header [16]: sh_name: .data ; the sections holds initialized data sh_addr: 0x8060900 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x10 sh_type: [SHT_PROGBITS] sh_offset: 0x900 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [17]: sh_name:. ctors sh_addr: 0x8060910 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x8 sh_type: [SHT_PROGBITS] sh_offset: 0x910 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [18]: sh_name: .dtors sh_addr: 0x8060918 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x8 sh_type: [SHT_PROGBITS] sh_offset: 0x918 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [19]: sh_name: .eh_frame sh_addr: 0x8060920 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x4 sh_type: [ SHT_PROGBITS] SH_OFFSET: 0x920 SH_ENTSIZE: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [20]: sh_name: .jcr sh_addr: 0x8060924 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x4 sh_type: [SHT_PROGBITS] sh_offset: 0x924 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [21]: sh_name : .data.rel.local sh_addr: 0x8060928 sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x4 sh_type: [SHT_PROGBITS] sh_offset: 0x928 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [22]: sh_name: .bss; the sectiopn holds uninitialized data sh_addr: 0x806092c sh_flags: [SHF_WRITE SHF_ALLOC] sh_size: 0x2c sh_type: [SHT_NOBITS]; indicates not occupy ELF space sh_size is memory size sh_offset: 0x92c sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section header [23]: SH_NAME: .SYMTAB

This section holds a symbol table sh_addr: 0 sh_flags: 0 sh_size: 0x540 sh_type: [SHT_SYMTAB] sh_offset: 0x92c sh_entsize: 0x10 sh_link: 24 sh_info: 53 sh_addralign: 0x4 Section Header [24]: sh_name: .strtab; This section holds string table sh_addr: 0 sh_flags: [SHF_STRINGS] sh_size: 0x20b sh_type: [SHT_STRTAB] sh_offset: 0xe6c sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 Section Header [25]: sh_name: .comment; section holds versioning information sh_addr: 0 sh_flags: 0 sh_size: 0x24d sh_type: [SHT_PROGBITS] sh_offset: 0x1077 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 Section Header [26]: sh_name: .stab.index sh_addr: 0 sh_flags: 0 sh_size: 0x24 sh_type: [SHT_PROGBITS] sh_offset: 0x12c4 sh_entsize: 0xc sh_link: 0 sh_info: 0 sh_addralign: 0x4 Section Header [27]: sh_name: .shstrtab; section holds the section name sh_addr: 0 sh_flags: [SHF_STRINGS] sh_size: 0xDC SH_TYPE: [SHT_STRTAB] SH_OFFSET: 0X12E8 SH_ENTSIZE: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 section header [28]: sh_name: .stab.indexstr sh_addr: 0 sh_flag s: 0 sh_size: 0x1c0 sh_type: [SHT_STRTAB] sh_offset: 0x13c4 sh_entsize: 0 sh_link: 0 sh_info: 0 sh_addralign: 0x1 Interpreter: /usr/lib/ld.so.1 Version Needed Section: .SUNW_version file version libc.so. 1 sysvabi_1.3 Symbol Table: .dynsym;

Dynamic parsing and link required Symbol table index value size type bind os ver sh-size [0] 0x00000000 0x00000000 NOTY LOCL D 0 undef [1] 0x080507ec 0x0000000D Func Glob D 0 .init _init [2] 0x08050804 0x00000004 Objt Glob D 0. rodata _lib_version [3] 0x08050580 0x00000000 OBJT GLOB D 0 .plt _PROCEDURE_LINKAGE_TABLE_ [4] 0x08050600 0x00000075 FUNC GLOB D 0 .text _start [5] 0x08060900 0x00000000 OBJT GLOB D 0 .data __dso_handle [6] 0x08060848 0x00000000 OBJT GLOB D 0 .dynamic _DYNAMIC [7] 0x00000000 0x00000000 nOTY WEAK D 0 UNDEF __deregister_frame_info_bases [8] 0x08050814 0x00000000 OBJT GLOB D 0 .rodata _etext [9] 0x08060958 0x00000000 OBJT GLOB D 0 .bss _end [10] 0x08050590 0x00000000 FUNC WEAK D 0 UNDEF _cleanup [11] 0x08050675 0x00000001 FUNC WEAK D 0 .text _mcount [12] 0x08060904 0x00000004 OBJT GLOB D 0 .data i [13] 0x08060908 0x00000004 OBJT GLOB D 0 .data j [14] 0x0806090c 0x00000004 OBJT GLOB D 0 .data k [15] 0x08060948 0x00000004 OBJT Glob D 0 .bss L [16] 0x08060954 0x00000004 Objt Glob D 0 .bss_ENVIRO n [17] 0x08060814 0x00000000 OBJT GLOB D 0 .got _GLOBAL_OFFSET_TABLE_ [18] 0x0806094c 0x00000004 OBJT GLOB D 0 .bss m [19] 0x0806092c 0x00000000 OBJT GLOB D 0 .data.rel.l _edata [20] 0x08060954 0x00000004 OBJT WEAK D 0 .bss environ [21] 0x080507f9 0x00000008 FUNC GLOB D 0 .fini _fini [22] 0x080505a0 0x00000000 FUNC GLOB D 0 UNDEF atexit [23] 0x08060950 0x00000004 OBJT GLOB D 0 .bss n [24] 0x08050808 0x00000004 OBJT GLOB D 0 .rodata o [25] 0x0805080c 0x00000004 OBJT GLOB D 0 .rodata p [26] 0x00000000 0x00000000 nOTY WEAK D 0 UNDEF _Jv_RegisterClasses [27] 0x08050810 0x00000004 OBJT GLOB D 0 .rodata q [28] 0x080505b0 0x00000000 FUNC GLOB D 0 UNDEF __fpstart [29] 0x08050753 0x00000065 Func Glob D 0 .Text Main [30] 0x00000000 0x00000000 NOTY W

EAK D 0 UNDEF __register_frame_info_bases [31] 0x080505c0 0x00000000 FUNC GLOB D 0 UNDEF exit Symbol Table: .symtab; desired program chain symbol table index value size type bind oth ver shndx name [0] 0x00000000 0x00000000 NOTY LOCL D 0 UNDEF [1 ] 0x00000000 0x00000000 FILE LOCL D 0 ABS test5 [2] 0x080500d4 0x00000000 SECT LOCL D 0 .interp [3] 0x080500e8 0x00000000 SECT LOCL D 0 .hash [4] 0x080501ec 0x00000000 SECT LOCL D 0 .dynsym [5] 0x080503ec 0x00000000 SECT LOCL D 0. DynStr [6] 0x08050508 0x00000000 SECT LOCL D 0.SUNW_VERSI [7] 0x08050528 0x00000000 SECT LOCL D 0 .rel.got [8] 0x08050540 0x00000000 SECT LOCL D 0 .rel.bss [9] 0x08050548 0x00000000 SECT LOCL D 0. Rel.plt [10] 0x08050580 0x00000000 SECT LOCL D 0 .plt [11] 0x08050600 0x00000000 SECT LOCL D 0 .Text [12] 0x080507ec 0x00000000 SECT LOCL D 0 .init [13] 0x080507f9 0x00000000 SECT LOCL D 0 .fini [14] 0x08050804 0x00000000 SECT LOCL D 0 .RODATA [15] 0x08060814 0x00000000 SECT LOCL D 0 .got [16] 0x08060848 0x00000000 SECT LOCL D 0 .Dynamic [17] 0x0 8060900 0x00000000 SECT LOCL D 0 .data [18] 0x08060910 0x00000000 SECT LOCL D 0 .ctors [19] 0x08060918 0x00000000 SECT LOCL D 0 .dtors [20] 0x08060920 0x00000000 SECT LOCL D 0 .eh_frame [21] 0x08060924 0x00000000 SECT LOCL D 0 .jcr [22] 0x08060928 0x00000000 SECT LOCL D 0 .DATA.REL.L [23] 0x0806092c 0x00000000 SECT LOCL D 0 .BS [24] 0x00000000 0x00000000 SECT LOCL D 0.SYMTAB [25] 0x00000000 0x00000000 SECT LOCL D 0 .STRTAB [26] 0x00000000 0x00000000 SECT LOCL D 0 .comment [27] 0x0000000000 0x00000000 SECT LOCL D 0 .stab.index [28] 0x00000000 0x00000000 SECT LOCL D 0 .shstRTAB [29] 0x00000000 0x00000000 SECT LOCL D 0 .stab.index [30 ] 0x08050000 0x00000000 Objt LoCl D 0 .Interp _Start_ [31] 0x08060958 0x00000000 Objt LoCl D 0 .bss _end_ [32]

0x0000000000 0x00000000 File LoCl D 0 ABS CRT1.S [33] 0x00000000 0x00000000 File LoCl D 0 Abs Crti.s [34] 0x00000000 0x00000000 File LoCl D 0 ABS VALUES-XA.C [35] 0x00000000 0x00000000 File LOCL D 0 ABS CRTSTUFF. c [36] 0x08060910 0x00000000 OBJT LOCL D 0 .ctors __CTOR_LIST__ [37] 0x08060918 0x00000000 OBJT LOCL D 0 .dtors __DTOR_LIST__ [38] 0x08060920 0x00000000 OBJT LOCL D 0 .eh_frame __EH_FRAME_BEGIN__ [39] 0x08060924 0x00000000 OBJT LOCL D 0 .jcr __JCR_LIST__ [ 40] 0x08060928 0x00000000 OBJT LOCL D 0 .data.rel.l p.0 [41] 0x0806092c 0x00000001 OBJT LOCL D 0 .bss completed.1 [42] 0x08050678 0x00000000 FUNC LOCL D 0 .text __do_global_dtors_aux [43] 0x08060930 0x00000018 OBJT LOCL D 0 .bss object.2 [44] 0x080506e4 0x00000000 FUNC LOCL D 0 .text frame_dummy [45] 0x00000000 0x00000000 FILE LOCL D 0 ABS test5.c [46] 0x00000000 0x00000000 FILE LOCL D 0 ABS crtstuff.c [47] 0x08060914 0x00000000 Objt LOCL D 0 .ctors __ctor_nd__ [48] 0x0806091c 0x00000000 Objt LOCL D 0 .dttors __dtor_end__ [49] 0 x08060920 0x00000000 OBJT LOCL D 0 .eh_frame __FRAME_END__ [50] 0x08060924 0x00000000 OBJT LOCL D 0 .jcr __JCR_END__ [51] 0x080507b8 0x00000000 FUNC LOCL D 0 .text __do_global_ctors_aux [52] 0x00000000 0x00000000 FILE LOCL D 0 ABS crtn.o [53] 0x080507ec 0x0000000d FUNC GLOB D 0 .init _init [54] 0x08050804 0x00000004 OBJT GLOB D 0 .rodata _lib_version [55] 0x08050580 0x00000000 OBJT GLOB D 0 .plt _PROCEDURE_LINKAGE_TABLE_ [56] 0x08050600 0x00000075 FUNC GLOB D 0 .text _start [57] 0x08060900 0x00000000 OBJT GLOB D 0 .data __dso_handle [58] 0x08060848 0x00000000 OBJT GLOB D 0 .dynamic _DYNAMIC [59] 0x00000000 0x00000000 nOTY WEAK D 0 UNDEF __deregister_frame_info_bases [60] 0x08050814 0x00000000 OBJT GLOB D 0 .rodata _etext [61] 0x08060958 0x0

0000000 OBJT GLOB D 0 .bss _end [62] 0x08050590 0x00000000 FUNC WEAK D 0 UNDEF _cleanup [63] 0x08050675 0x00000001 FUNC WEAK D 0 .text _mcount [64] 0x08060904 0x00000004 OBJT GLOB D 0 .data i [65] 0x08060908 0x00000004 OBJT GLOB D 0 .data j [66] 0x0806090c 0x00000004 OBJT GLOB D 0 .data k [67] 0x08060948 0x00000004 OBJT GLOB D 0 .bss l [68] 0x08060954 0x00000004 OBJT GLOB D 0 .bss _environ [69] 0x08060814 0x00000000 OBJT GLOB D 0 .got _GLOBAL_OFFSET_TABLE_ [70] 0x0806094c 0x00000004 OBJT GLOB D 0 .bss m [71] 0x0806092c 0x00000000 OBJT GLOB D 0 .data.rel.l _edata [72] 0x08060954 0x00000004 OBJT WEAK D 0 .bss environ [73] 0x080507f9 0x00000008 FUNC GLOB D 0 .fini _fini [74] 0x080505a0 0x00000000 FUNC GLOB D 0 UNDEF atexit [75] 0x08060950 0x00000004 OBJT GLOB D 0 .bss n [76] 0x08050808 0x00000004 OBJT GLOB D 0 .rodata o [77] 0x0805080c 0x00000004 OBJT GLOB D 0. Rodata P [78] 0x00000000 0x00000000 NOTY Weak D 0 undef _JV_REGISTERCLASSES [79] 0x08050810 0x00000004 Objt Glob D 0 .Rodata Q [8 0] 0x080505b0 0x00000000 FUNC GLOB D 0 UNDEF __fpstart [81] 0x08050753 0x00000065 FUNC GLOB D 0 .text main [82] 0x00000000 0x00000000 NOTY WEAK D 0 UNDEF __register_frame_info_bases [83] 0x080505c0 0x00000000 FUNC GLOB D 0 UNDEF exit Hash Section: .hash bucket Symndx Name 0 [1] _INIT 1 [2] _LIB_Version [3] _Procedure_Linkage_Table_ 2 [4] _Start [5] __dso_handle 4 [6] _Dynamic 9 [7] __deregister_frame_info_bases [8] _text 10 [9] _end 12 [10] _cleanup [ 11] _MCOUNT [12] i 13 [13] J 14 [14] K 15 [15] L 16 [16] _ENVIRON [17] _Global_offset_table_ [18] m [19] _eData [20] environ 17 [21] _fini [22 ] Atexit [23] N 18 [24] O 19 [25] P 20 [26] _JV_REGISTERCLASS [27] q 25 [28] __fpstart 26 [29] main 29 [30] __register_frame_info_bases [31] exit 13 B

uckets contain 0 symbols 10 buckets contain 1 symbols 5 buckets contain 2 symbols 2 buckets contain 3 symbols 1 buckets contain 5 symbols 31 buckets 31 symbols (globals) Global Offset Table: 13 entries ndx addr value reloc addend symbol [00000] 08060814 08060848 R_386_NONE 00000000 [00001] 08060818 00000000 R_386_NONE 00000000 [00002] 0806081c 00000000 R_386_NONE 00000000 [00003] 08060820 08050596 R_386_JMP_SLOT 00000000 _cleanup [00004] 08060824 080505a6 R_386_JMP_SLOT 00000000 atexit [00005] 08060828 080505b6 R_386_JMP_SLOT 00000000 __fpstart [00006] 0806082c 080505c6 R_386_JMP_SLOT 00000000 exit [00007] 08060830 00000000 R_386_GLOB_DAT 00000000 __deregister_frame_info_bases [00008] 08060834 080505d6 R_386_JMP_SLOT 00000000 __deregister_frame_info_bases [00009] 08060838 00000000 R_386_GLOB_DAT 00000000 __register_frame_info_bases [00010] 0806083c 00000000 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses [00011] 08060840 080505e6 R_386_JMP_SLOT 00000000 _Jv_RegisterClasses [00012] 08060844 080505f6 R_386_JMP_SLOT 00000000 __register_frame_info_bases Relocation: .rel.got type offset section with respect to R_386_GLOB_DAT 0x8060830 .rel.got __deregister_frame_info_bases R_386_GLOB_DAT 0x8060838 .rel.got __register_frame_info_bases R_386_GLOB_DAT 0x806083c .rel.got _Jv_RegisterClasses Relocation: .rel.bss type offset section with respect to R_386_COPY 0x8060954 .rel.bss _environ Relocation: .rel.plt type offset section with respect to R_386_JMP_SLOT 0x8060820 .rel.plt _cleanup R_386_JMP_SLOT 0x8060824 .rel.plt atexit R_386_JMP_SLOT 0x8060828 .rel.plt __fpstart R_386_JMP_SLOT 0x806082c .rel.plt exit R_386_JMP_SLOT 0x8060834 .rel .plt __deregister_frame_inco_bases r_386_jmp_slot 0x8060840.REL.PLT _JV_REGISTERCLASS R_386_JMP_SLO

T 0x8060844 .rel.plt __register_frame_info_bases Dynamic Section: .dynamic index tag value [0] NEEDED 0x104 libc.so.1 [1] INIT 0x80507ec [2] FINI 0x80507f9 [3] HASH 0x80500e8 [4] STRTAB 0x80503ec [5] STRSZ 0x11a [6] symtab 0x80501ec [7] Syment 0x10 [8] checksum 0x6a10 [9] verneed 0x8050508 [10] VerneedNum 0x1 [11] Pltrelsz 0x38 [12] pltrel 0x11 [13] jmprel 0x8050548 [14] rel 0x8050528 [15] RELSZ 0x58 [16] relent 0x8 [17] debug 0 [18] feature_1 0x1 [Parinit] [19] Flags 0 0 [20] Flags_1 0 0 [21] Pltgot 0x8060814 Using Elfdump You can view more details of the ELF file format, you can in the symbol table .DYNSYM and .SYMTAB find global variables and global constants defined in the program: i, j, k in .data section L, M, N in .bss section O, P, Q in. RODATA Section concept: ELF (Executable and Linking Format) Executable Connection Format ELF Format is developed and published as an application binary interface (USL) as an application binary interface (ABI). At present, the ELF format is one of the most widely used binary industrial standards on the UNIX / Linux platform. The general format of the ELF file is given from different perspectives: the Linking view execution angle ============================================================================================================================================================================================================================= ============ Elf Header Elf Header program header table (optional) Program Header Table section 1 Segment 1 ... segment 2 section n ... section Header Table Section Header Table (Optional) Figure 3 -2 ELF file format Excerpable and Linkable Format (ELF) You can draw the contents of TEST5 according to the information of the files in the version of the version of the Test5 ELF file: Entry Name starting file offset actual size = Next entry start offset ----------------------------------------------------------------------------------------------------- ------------ Elf Header 0x0 0x34 = 0x34 Program Header 0x34 0xA0 = 0xD4 section 1 .Interp 0xD4 0x11 = 0xE5 000 0xE5 0x3 = 0xE8 Section 2 .hash 0xe8 0x104 = 0x1ec Section 3 .dynsym 0x1ec 0x200 = 0x3ec section 4 .dynstr 0x3ec 0x11a = 0x506 00 0x506 0x2 = 0x508 section 5.sun

W_version 0x508 section 6.rel.got 0x528 0x18 = 0x540 section 7.rel.bss 0x540 0x8 = 0x548 section 8.rel.plt 0x548 0x38 = 0x580 section 9 .plt 0x580 0x80 = 0x600 section 10 .text 0x600 0x1ec = 0x7ec Section 11 .init 0x7ec 0xd = 0x7f9 Section 12 .fini 0x7f9 0x8 = 0x801 000 0x801 0x3 = 0x804 Section 13 .rodata 0x804 0x10 = 0x814 Section 14 .got 0x814 0x34 = 0x848 Section 15 .dynamic 0x848 0xb8 = 900 Section 16 .data 0x900 0x10 = 0x910 Section 17 .ctors 0x910 0x8 = 0x918 Section 18 .dtors 0x918 0x8 = 0x920 Section 19 .eh_frame 0x920 0x4 = 0x924 Section 20 .jcr 0x924 0x4 = 0x928 Section 21 .data.rel.local 0x928 0x4 = 0x92c Section 22 .bss 0x92c 0x0 = 0x958 Section 23 .symtab 0x92c 0x540 = 0xe6c Section 24 .strtab 0xe6c 0x20b = 1077 Section 25 .comment 0x1077 0x24d = 0x12c4 Section 26 .stab.index 0x12c4 0x24 = 0x12e8 Section 27 .shstrtab 0x12e8 0xdc = 0x13c4 Section 28 .stab.indexstr 0x13c4 0x1c0 = 0x1584 Section header table 0x1584 0x488 = 0x1a0c; 29x40 = 1160 = 0x488 which is based on Elf header information --------------------------------------- ------------- Figure 3-3 TEST5 ELF file format # ls -al test5 -rwxr-xr-x 1 root other 6668 2004-12-19 06:56 Test5 can see TEST5 The size is 0x1a0c byte, namely 6688 bytes. It can be seen that .bss section is used to save uninitialized global variables, so do not occupy the ELF file space; the ELF file is loaded, followed by the related properties of the .bsss in section, for .BSS mapping corresponding size Memory space, and initialization to 0 ELF file Program HEADER TABLE describes how to put ELF into memory: Program Header 2 describes the starting address and size of the user code segment: 0x8050000 0x814 = 0x8050814 Program HEADER 3 describes the user data segment Start Address and Size: 0x8060814 0x144 = 0x8060958 Question: Why is the result of the previous PMAP is the data segment starts from 0x8060000, while the ELF file PROG

Is Ram HEADER 3 starting from 0x8060814? If you check the format specification of the ELF file, you can find the answer: Program Header [2]: p_vaddr: 0x8050000 p_flags: [PF_X PF_R] p_paddr: 0 p_type: [PT_LOAD] P_Filesz: 0x814 p_memsz: 0x814 p_offset: 0 p_align: 0x10000 ; designated 64K page-aligned Program Header [3]: p_vaddr: 0x8060814 p_flags: [PF_X PF_W PF_R] p_paddr: 0 p_type: [PT_LOAD] p_filesz: 0x118 p_memsz: 0x144 p_offset: 0x814 p_align: 0x10000; designated page 64K aligned p_align specify the mapping When the code segment and data segment, you must follow the 64K page aligned mode, that is, the start mapping address must be ended at 0000. The start address of the code segment is just satisfying the condition. If the data segment does not consider the page alignment, you should start with the next byte of the code segment, that is, 0x8050814. However, it is only starting from the 64K page alignment, only the 64K page closest to 0x8050814 is started with the address 0x8060000. In fact, when mapping the ELF is mapping, the size of TEST5 is 0x1a0c, less than 1 page size, code segment and data segment are on page 1. When the mapping occurs, first map the code segment of this page 1 to 0x8050000, attribute READ / EXEC; reproduce this page to 0x8060000, attribute READ / WRITE / EXEC. In this way, the actual data segment start addresses are 0x8060000 0x814 = 0x8060814 Question: Why do you want pages to Qie Page Align? First, memory mapping is a page minimum unit because Solaris's memory management is page-style memory management (which is currently most modern OS); second, code segment and data segment due to different authority requirements (code Segment requires only read only), therefore must be mapped; in the end, it is the efficiency of efficiency; although the mapping of the ELF file is completed in the Solaris kernel, it is still possible to call MMAP (2) through the system. Memory mapping common sense. For other systems, such as Linux situations are similar. Then why is this example request 64k page? The answer is: this is also the page of Solaris on SPARC. Qi Qi Requirements Concept: ELF File Loading Depending on Program HEADER TABLE and Section HEADER TABLE Pictures the internal situation of TEST5 code segments and data segments: Entry Name start address actual size = Next entry start address ================= User text ========================= ==== 0x8050000 Elf Header 0x8050000 0x34 = 0x8050034 program header 0x8050034 0xa0 = 0x80500d4 section 1 .Interp 0x80500d4 &

# 43; 0x11 = 0x80500e5 0 0x80500e5 0x3 = 0x80500e8; 3 padding bytes 0 Section 2 .hash 0x80500e8 0x104 = 0x80501ec Section 3 .dynsym 0x80501ec 0x200 = 0x80503ec Section 4 .dynstr 0x80503ec 0x11a = 0x8050506 0 0x8050506 0x2 = 0x8050508; 2-byte 0 is filled Section 5 .SUNW_version 0x8050508 0x20 = 0x8050528 Section 6 .rel.got 0x8050528 0x18 = 0x8050540 Section 7 .rel.bss 0x8050540 0x8 = 0x8050548 Section 8 .rel.plt 0x8050548 0x38 = 0x8050580 Section 9 .plt 0x8050580 0x80 = 0x8050600 Section 10 .text 0x8050600 0x1ec = 0x80507ec Section 11 .init 0x80507ec 0xd = 0x80507f9 Section 12 .fini 0x80507f9 0x8 = 0x8050801 0 0x8050801 0x3 = 0x8050804; 3 padding bytes 0 Section 13. Rodata 0x8050804 0x10 = 0x8050814; o, p, q in code segment. Rodata section ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------- Section 14 .got 0x8050814 0x34 = 0x8050848; this is the first page of the code segment is also the last page, section 15.dynamic 0x8050848 0xb8 = 8050900; so the contents of the data segment is appended to an end of the last code segment section 16 .data 0x8050900 0x10 = 0x8050910 section 17 .ctors 0x8050910 0x8 = 0x8050918 section 18 .dtors 0x8050918 0x8 = 0x8050920 section 19. EH_FRAME 0x8050920 0x4 = 0x8050924 Section 20 .jcr 0x8050924 0x4 = 0x8050928 Section 21 .data.rel.local 0x8050928 0x4 = 0x805092c Section 22 .bss 0x805092c 0x2c = 0x8050958 pending data 0x8050958 0x6a8 = 8051000; Last byte is 0x6a8 Fill ================================================= ===== no mapping ==========--

1; ======= User data ============================ 0x8060000 Elf header 0x8060000 0x34 = 0x8060034; this is The last page of the data segment is also the first page, Program Header 0x8060034 0xA0 = 0x80600d4; Therefore, the content of the code segment will append to the first page of the data segment before section 1.Interp 0x80600d4 0x11 = 0x80600E5 0 0x80600E5 0x3 = 0x80600E8; 3 byte 0 is filled Section 2 .hash 0x80600e8 0x104 = 0x80601ec Section 3 .dynsym 0x80601ec 0x200 = 0x80603ec Section 4 .dynstr 0x80603ec 0x11a = 0x8060506 0 0x8060506 0x2 = 0x8060508; 2-byte 0 is filled Section 5 .SUNW_version 0x8060508 0x20 = 0x8060528 Section 6 .rel.got 0x8060528 0x18 = 0x8060540 Section 7 .rel.bss 0x8060540 0x8 = 0x8060548 Section 8 .rel.plt 0x8060548 0x38 = 0x8060580 Section 9 .plt 0x8060580 0x80 = 0x8060600 Section 10 .text 0x8060600 0x1ec = 0x80607ec Section 11 .init 0x80607ec 0xd = 0x80607f9 Section 12 .fini 0x80607f9 0x8 = 0x8060801 0 0x8060801 0x3 = 0x8060804; 3 padding bytes 0 Section 13 .rodata 0x8060804 0x10 = 0x8060814 -------- -------------------------------------------- Section 14.got 0x8060814 0x34 = 0x8060848 section 15.dynamic 0x8060848 0xB8 = 8060900 section 16.Data 0x8 060900 0x10 = 0x8060910; i, j, k .data section in the data segment Section 17 .ctors 0x8060910 0x8 = 0x8060918 Section 18 .dtors 0x8060918 0x8 = 0x8060920 Section 19 .eh_frame 0x8060920 0x4 = 0x8060924 Section 20 .jcr 0x8060924 0x4 = 0x8060928 section 21 .data.rel.local 0x8060928 0x4 = 0x806092c section 22 .bss 0x806092c 0x2c = 0x8060958; l, m, n .bss section in the data segment 0 0x8060958 0x6a8 = 8061000; Last Is 0x6A8 byte 0 Fill &

# 61; ================================================ ======= Figure 3-4 Test5 code segment and data segment internal structure The following sections is not included in the section header table does not contain SHF_alloc, so it is not mapped to memory: section 23.symtab symbol table, no Map to memory, the strip command can remove the section 24.strtab string table, mainly saved and .symtab's name string, other strings, not mapped to memory, Strip commands can remove the section 25 .Comment saves the binary Information, the format content determines that the binary itself is not mapped to the memory, the strip command retains the section section 26.stab.index saves the information related to the binary, and the format content is determined in the binary itself, not mapped to memory, Strip The command can remove the section 27 .shstrtab string table, only saving section name, not mapped to memory, Strip command keeps the section section 28.stab.indexstr string table, not mapped to memory, Strip command can remove Figure 3- 4, you can clearly find global variables and global constants in the accurate position of the data segment and code segment, you can answer the previous question: global constant O, P, Q belong to the code segment. Rodata section, this section It belongs to the code segment and has read-only properties, used to save read-only data global variables I, J, K belong to the data segment, which is used to save the initial value of global variables, this section is also occupied in the ELF file and memory. Spatial global variables L, M, N belong to the code segment. BSS section, used to save uninitialized global variables, this section occupies the memory space without occupying the ELF file space due to each of the different sections, the address space must not continuous The load of the ELF file is summarized below: * The first code segment page contains the Elf Header, Program Header Table, and other information * The last code segment page append a copy of the copy * The first data segment page The previous data segment page will contain the file information that is not related to the running process 2. The ELF file is loaded with the effect of the ELF file itself can directly use the tool to observe the binaries, the following life Order can be observed. Information section related content: BASH-2.05 # od -a x -c -j 0x1077 -n 0x24d test5 0000000 gNUC CRT 1. S / 0 as: 0000010 F Orte D EvelOper 0000020 7 C ompiler c omm 0000030 ON 7. 0 IA 3 2 - ITEA 0000040 M 2 0 0 1/1 2/1 2/0 gnu 0000050 C CRTI. S / 0 AS: F 0000060 RTE D Evel

Oper 7 0000070 C OMPILER C OMMON 0000080 7. 0 IA 3 2 - ITEAM 2 0000090 0 0 1/1 2/1 2/0/0 @ (#) s 00000a0 uns 5. 9 g ENERIC 00000B0 _ 1 1 2 2 3 4 - 0 3 n Ovem 00000c0 BER 2 0 0 2/0 GCC: (g 00000d0 Nu) 3. 3. 2/0 as: f OMMon 0000100 7. 0 IA 3 2 - ITEAM 2 0000110 0 0 1/1 2/1 2/0 GCC: (0000120 GNU) 3. 3. 2/0 as: f 0000130 ORTE D Eveloper 7 0000140 C ompiler c ommon 0000150 7. 0 IA 3 2 - Iteam 0000160 2 0 0 1/1 2/1 2/0 GCC: 0000170 (GNU) 3. 3. 2/0 as: 0000180 F Orte D Eveloper 0000190 7 C omp ompiler c ommo 00001a0 N 7. 0 IA 3 2 - ITEAM 00001B0 2 0 0 1/1 2/1 2/0 gnu 00001c0 c Crtn. O / 0 AS: F or 00001D0 TE D Eveloper 7 c 00001D OMPILER C OMMON 7 00001F0. 0 IA 3 2 - ITEAM 2 0 0000200 0 1/1 2/1 2/0 ld: s = 0000210 Tware G ENERATION 0000220 U t i l i t i e S - S O L 0000230 a R I S L i N k E d I t O r 0000240 S: 5. 9 - 1. 2 7 6/0 000024D Obviously, the contents of .comment section is the version information of the compiler and linker. Observing that the ELF is loaded after memory, the process of the ELF program is required to hang in the system to read the relevant content. With MDB, you can view the code segment and data segment values ​​loaded in memory. The following verifies Figure 3-4: # MDB Test5 Loading Modules: [libc.so.1]> main :: dis be: pushl% EBP Main 1: MOVL% ESP,% EBP Main 3: Subl $ 8,% ESP Main 6: Andl $ 0xF0,% ESP Main 9: MOVL $ 0,% EAX Main 0xE: Subl% EAX,% ESP Main 0x10: movl $ 4,0x8060948 main 0x1a: movl $ 5,0x806094c main 0x24: movl $ 6,0x8060950 main 0x2e: movl 0x8060908,% eax main 0x33: addl 0x8060904,% eax main 0x39: addl 0x806090c,% eax main 0x3f: addl 0x8060948,% EAX Main 0x45: AddL 0x806094c,% EAX Main & # 4

3; 0x4b: addl 0x8060950,% eax main 0x51: addl 0x8050808,% eax main 0x57: addl 0x805080c,% eax main 0x5d: addl 0x8050810,% EAX main 0x63: Leave main 0x64: Ret> main 0x2e : b; Set breakpoint>: r; Run MDB: Stop at main 0x2e mdb: target stopped at: main 0x2e: MOVL 0x8060908,% EAX> 0x8050000, 0x4 / NAB; view Elf Header head 4 byte 0x8050000: 0x8050000 : 7F 0x8050002: 4C 0x8050003: 46> 0x8050003: 46> 0x8050000, 0x4 / NAC; view Elf Header head 4 byte 0x8050000: 0x8050000: 0x8050001: E 0x8050002: L 0x8050003: f> 0x80500d4 ,11 / c; view .INTERP section 0x80500d4 : /usr/lib/ld.so.1> 0x8050600 :: Dis; View .Text Section's first process, also ELF's entry point _Start: Pushl $ 0 _Start 2: Pushl $ 0 _Start 4: MOVL% ESP ,% EBP _START 6: Pushl% EDX _Start 7: MOVL $ 0x8050590,% EAX _Start 0xc: testl% Eax,% EAX _Start 0xe: JE 0xF <_Start 0x1D> _Start 0x10: Pushl $ 0x8050590 _start_Start 0x15: Call -0x75 _Start 0x1a: add1 $ 4,% ESP _Start 0x1D: MOVL $ 0x8060848,% EAX _Start 0x22: testl% EAX,% EAX _Start 0x24: JE 7 <_Start 0x2B> _Start 0x26: Call -0x86 _Start 0x2b: Pushl $ 0x80507f9 _Start 0x30: Call -0x90 _Start 0x35: MOVL 8 (% EBP),% EAX _Start 0x38: LEAL 0x10 (% EBP,% EAX, 4),% EDX _Start 0x3c: MOVL% EDX, 0x8060954 _Start 0x42: Andl $ 0xf0,% ESP _Start 0x45: Subl $ 4,% ESP _Start 0x48: Pushl% EDX _Start 0x49: Leal 0xc (% EBP),% EDX _Start 0x4c: Pushl% EDX _Start 0x4D: Pushl% EAX _Start 0x4e: Call 0x19e <_init> _Start 0x53: Call -0xa3 _Start 0x58: Call 0xfb

_Start

0x5D: AddL $ 0xc,% ESP _Start 0x60: Pushl% EAX _Start 0x61: Call -0xa1 _Start 0x66: Pushl $ 0 _Start 0x68: MOVL $ 1,% EAX _Start 0x6d: lcall $ 7, $ 0 _START 0X74: HLT> 0x8050804, 0x4 / nap; view. Rodata section, including real O, P, Q several global constants _LIB_Version: _lib_version: _lib_version: 1 o: 7 p: 8 Q: 9> 0x8050900, 0x4 / NAP; View Data Section after the code segment, this is actually invalid data 0x8050900: 0x805050900: 0 0x805050904: 1; global variable I 0x8050908: 2; global variable J 0x805090c: 3; global variable k> 0x8060000, 0x4 / NAB; View the Elf Header header header before the data segment, this is actually invalid 0x8060000: 0x8060000: 7F 0x8060001: 45 0x8060002: 4C 0x8060003: 46> 0x8060000, 0x4 / NAC; view fill to The ELF Header header before the data segment 4 bytes, this part is actually invalid 0x8060000: 0x8060000: 0x8060001: E 0x8060002: L 0x8060003: f> 0x8060804, 0x4 / nap; view fill to the data segment before. Rodata section, this section Actual is invalid 0x8060804: 0x8060808: 7; global constant O 0x806080c: 8; global constant P 0x8060810: 9; global constant Q> 0x8060900, 0x4 / nap; view .date section, including true I, J, K Several global variables 0x8060900: 0x8060900: 0 Test5`i: 1 test5`j: 2 Test5`k: 3> 0x806092c, 0xb / nap; view .bss section, including several global variables TEST5` COMP Leted.1: Test5`completed.1: Test5`completed.1: 0 Test5`Object.2: 0 Test5`Object.2 4: 0 Test5`Object.2 8: 0 Test5`Object.2 0xc: 0 Test5`Object.2 0x10: 0 Test5`Object.2 0x14: 0 Test5`l: 4 test5`m: 5 test5`n: 6 test5`Environ: 0x8047E00> 0x8060958, 0x6a8 / nab; view the end of the data segment Added 0x6A8 byte data, all 0 0x8060958: 0x8060958: 0 0x8060959: 0 0x806095a: 0 ........................ ..... 0x8060fff: 0> 0x8060fff, 2 / nab; verification page boundary data is mapped 0x8060ff: 0x8060000060ff: 0 MDB: Failed to read data from target: no mapping for address 0x8061000:> 0x8050fff, 2 / NAB Verification page

转载请注明原文地址:https://www.9cbs.com/read-67799.html

New Post(0)