JeffBla
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # How ELF exec ## Explore ELF test.c is as following: ```c #include <stdio.h> #include <unistd.h> #define THREAD_INTERVAL 500 #define cr_start() \ static int __s = 0; \ switch (__s) { \ case 0: #define cr_yield \ { \ __s = __LINE__; \ return; \ case __LINE__:; \ } #define cr_end() \ } \ __s = 0; static int condition = 1; static void user_thread_1() { cr_start(); for (;;) { /* do something */ printf("Run %s\n", __FUNCTION__); cr_yield; } cr_end(); } static void user_thread_2() { cr_start(); for (;;) { if (condition) { /* do something conditional */ printf("Run %s - (1)\n", __FUNCTION__); cr_yield; } /* do something */ printf("Run %s - (2)\n", __FUNCTION__); condition = !condition; cr_yield; } cr_end(); } int main() { for (;;) { user_thread_1(); user_thread_2(); } return 0; } ``` test is an elf file compiled by gcc. use `objdump`, we can see it is essentially a binary code file from asssembly code. ```shell $ objdump -d test ``` :::spoiler output ```bash test 檔案格式 elf64-x86-64 .init 區段的反組譯: 0000000000001000 <_init>: 1000: f3 0f 1e fa endbr64 1004: 48 83 ec 08 sub $0x8,%rsp 1008: 48 8b 05 d9 2f 00 00 mov 0x2fd9(%rip),%rax # 3fe8 <__gmon_start__@Base> 100f: 48 85 c0 test %rax,%rax 1012: 74 02 je 1016 <_init+0x16> 1014: ff d0 call *%rax 1016: 48 83 c4 08 add $0x8,%rsp 101a: c3 ret .plt 區段的反組譯: 0000000000001020 <.plt>: 1020: ff 35 9a 2f 00 00 push 0x2f9a(%rip) # 3fc0 <_GLOBAL_OFFSET_TABLE_+0x8> 1026: ff 25 9c 2f 00 00 jmp *0x2f9c(%rip) # 3fc8 <_GLOBAL_OFFSET_TABLE_+0x10> 102c: 0f 1f 40 00 nopl 0x0(%rax) 1030: f3 0f 1e fa endbr64 1034: 68 00 00 00 00 push $0x0 1039: e9 e2 ff ff ff jmp 1020 <_init+0x20> 103e: 66 90 xchg %ax,%ax .plt.got 區段的反組譯: 0000000000001040 <__cxa_finalize@plt>: 1040: f3 0f 1e fa endbr64 1044: ff 25 ae 2f 00 00 jmp *0x2fae(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5> 104a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) .plt.sec 區段的反組譯: 0000000000001050 <printf@plt>: 1050: f3 0f 1e fa endbr64 1054: ff 25 76 2f 00 00 jmp *0x2f76(%rip) # 3fd0 <printf@GLIBC_2.2.5> 105a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) .text 區段的反組譯: 0000000000001060 <_start>: 1060: f3 0f 1e fa endbr64 1064: 31 ed xor %ebp,%ebp 1066: 49 89 d1 mov %rdx,%r9 1069: 5e pop %rsi 106a: 48 89 e2 mov %rsp,%rdx 106d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 1071: 50 push %rax 1072: 54 push %rsp 1073: 45 31 c0 xor %r8d,%r8d 1076: 31 c9 xor %ecx,%ecx 1078: 48 8d 3d ba 01 00 00 lea 0x1ba(%rip),%rdi # 1239 <main> 107f: ff 15 53 2f 00 00 call *0x2f53(%rip) # 3fd8 <__libc_start_main@GLIBC_2.34> 1085: f4 hlt 1086: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) 108d: 00 00 00 0000000000001090 <deregister_tm_clones>: 1090: 48 8d 3d 81 2f 00 00 lea 0x2f81(%rip),%rdi # 4018 <__TMC_END__> 1097: 48 8d 05 7a 2f 00 00 lea 0x2f7a(%rip),%rax # 4018 <__TMC_END__> 109e: 48 39 f8 cmp %rdi,%rax 10a1: 74 15 je 10b8 <deregister_tm_clones+0x28> 10a3: 48 8b 05 36 2f 00 00 mov 0x2f36(%rip),%rax # 3fe0 <_ITM_deregisterTMCloneTable@Base> 10aa: 48 85 c0 test %rax,%rax 10ad: 74 09 je 10b8 <deregister_tm_clones+0x28> 10af: ff e0 jmp *%rax 10b1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 10b8: c3 ret 10b9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 00000000000010c0 <register_tm_clones>: 10c0: 48 8d 3d 51 2f 00 00 lea 0x2f51(%rip),%rdi # 4018 <__TMC_END__> 10c7: 48 8d 35 4a 2f 00 00 lea 0x2f4a(%rip),%rsi # 4018 <__TMC_END__> 10ce: 48 29 fe sub %rdi,%rsi 10d1: 48 89 f0 mov %rsi,%rax 10d4: 48 c1 ee 3f shr $0x3f,%rsi 10d8: 48 c1 f8 03 sar $0x3,%rax 10dc: 48 01 c6 add %rax,%rsi 10df: 48 d1 fe sar $1,%rsi 10e2: 74 14 je 10f8 <register_tm_clones+0x38> 10e4: 48 8b 05 05 2f 00 00 mov 0x2f05(%rip),%rax # 3ff0 <_ITM_registerTMCloneTable@Base> 10eb: 48 85 c0 test %rax,%rax 10ee: 74 08 je 10f8 <register_tm_clones+0x38> 10f0: ff e0 jmp *%rax 10f2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 10f8: c3 ret 10f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 0000000000001100 <__do_global_dtors_aux>: 1100: f3 0f 1e fa endbr64 1104: 80 3d 09 2f 00 00 00 cmpb $0x0,0x2f09(%rip) # 4014 <completed.0> 110b: 75 2b jne 1138 <__do_global_dtors_aux+0x38> 110d: 55 push %rbp 110e: 48 83 3d e2 2e 00 00 cmpq $0x0,0x2ee2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5> 1115: 00 1116: 48 89 e5 mov %rsp,%rbp 1119: 74 0c je 1127 <__do_global_dtors_aux+0x27> 111b: 48 8b 3d e6 2e 00 00 mov 0x2ee6(%rip),%rdi # 4008 <__dso_handle> 1122: e8 19 ff ff ff call 1040 <__cxa_finalize@plt> 1127: e8 64 ff ff ff call 1090 <deregister_tm_clones> 112c: c6 05 e1 2e 00 00 01 movb $0x1,0x2ee1(%rip) # 4014 <completed.0> 1133: 5d pop %rbp 1134: c3 ret 1135: 0f 1f 00 nopl (%rax) 1138: c3 ret 1139: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 0000000000001140 <frame_dummy>: 1140: f3 0f 1e fa endbr64 1144: e9 77 ff ff ff jmp 10c0 <register_tm_clones> 0000000000001149 <user_thread_1>: 1149: f3 0f 1e fa endbr64 114d: 55 push %rbp 114e: 48 89 e5 mov %rsp,%rbp 1151: 8b 05 c1 2e 00 00 mov 0x2ec1(%rip),%eax # 4018 <__TMC_END__> 1157: 85 c0 test %eax,%eax 1159: 74 05 je 1160 <user_thread_1+0x17> 115b: 83 f8 1c cmp $0x1c,%eax 115e: 75 2a jne 118a <user_thread_1+0x41> 1160: 48 8d 05 c9 0e 00 00 lea 0xec9(%rip),%rax # 2030 <__FUNCTION__.2> 1167: 48 89 c6 mov %rax,%rsi 116a: 48 8d 05 97 0e 00 00 lea 0xe97(%rip),%rax # 2008 <_IO_stdin_used+0x8> 1171: 48 89 c7 mov %rax,%rdi 1174: b8 00 00 00 00 mov $0x0,%eax 1179: e8 d2 fe ff ff call 1050 <printf@plt> 117e: c7 05 90 2e 00 00 1c movl $0x1c,0x2e90(%rip) # 4018 <__TMC_END__> 1185: 00 00 00 1188: eb 0a jmp 1194 <user_thread_1+0x4b> 118a: c7 05 84 2e 00 00 00 movl $0x0,0x2e84(%rip) # 4018 <__TMC_END__> 1191: 00 00 00 1194: 5d pop %rbp 1195: c3 ret 0000000000001196 <user_thread_2>: 1196: f3 0f 1e fa endbr64 119a: 55 push %rbp 119b: 48 89 e5 mov %rsp,%rbp 119e: 8b 05 78 2e 00 00 mov 0x2e78(%rip),%eax # 401c <__s.1> 11a4: 83 f8 2f cmp $0x2f,%eax 11a7: 74 10 je 11b9 <user_thread_2+0x23> 11a9: 83 f8 2f cmp $0x2f,%eax 11ac: 7f 7f jg 122d <user_thread_2+0x97> 11ae: 85 c0 test %eax,%eax 11b0: 74 08 je 11ba <user_thread_2+0x24> 11b2: 83 f8 29 cmp $0x29,%eax 11b5: 74 38 je 11ef <user_thread_2+0x59> 11b7: eb 74 jmp 122d <user_thread_2+0x97> 11b9: 90 nop 11ba: 8b 05 50 2e 00 00 mov 0x2e50(%rip),%eax # 4010 <condition> 11c0: 85 c0 test %eax,%eax 11c2: 74 2a je 11ee <user_thread_2+0x58> 11c4: 48 8d 05 75 0e 00 00 lea 0xe75(%rip),%rax # 2040 <__FUNCTION__.0> 11cb: 48 89 c6 mov %rax,%rsi 11ce: 48 8d 05 3b 0e 00 00 lea 0xe3b(%rip),%rax # 2010 <_IO_stdin_used+0x10> 11d5: 48 89 c7 mov %rax,%rdi 11d8: b8 00 00 00 00 mov $0x0,%eax 11dd: e8 6e fe ff ff call 1050 <printf@plt> 11e2: c7 05 30 2e 00 00 29 movl $0x29,0x2e30(%rip) # 401c <__s.1> 11e9: 00 00 00 11ec: eb 49 jmp 1237 <user_thread_2+0xa1> 11ee: 90 nop 11ef: 48 8d 05 4a 0e 00 00 lea 0xe4a(%rip),%rax # 2040 <__FUNCTION__.0> 11f6: 48 89 c6 mov %rax,%rsi 11f9: 48 8d 05 1e 0e 00 00 lea 0xe1e(%rip),%rax # 201e <_IO_stdin_used+0x1e> 1200: 48 89 c7 mov %rax,%rdi 1203: b8 00 00 00 00 mov $0x0,%eax 1208: e8 43 fe ff ff call 1050 <printf@plt> 120d: 8b 05 fd 2d 00 00 mov 0x2dfd(%rip),%eax # 4010 <condition> 1213: 85 c0 test %eax,%eax 1215: 0f 94 c0 sete %al 1218: 0f b6 c0 movzbl %al,%eax 121b: 89 05 ef 2d 00 00 mov %eax,0x2def(%rip) # 4010 <condition> 1221: c7 05 f1 2d 00 00 2f movl $0x2f,0x2df1(%rip) # 401c <__s.1> 1228: 00 00 00 122b: eb 0a jmp 1237 <user_thread_2+0xa1> 122d: c7 05 e5 2d 00 00 00 movl $0x0,0x2de5(%rip) # 401c <__s.1> 1234: 00 00 00 1237: 5d pop %rbp 1238: c3 ret 0000000000001239 <main>: 1239: f3 0f 1e fa endbr64 123d: 55 push %rbp 123e: 48 89 e5 mov %rsp,%rbp 1241: b8 00 00 00 00 mov $0x0,%eax 1246: e8 fe fe ff ff call 1149 <user_thread_1> 124b: b8 00 00 00 00 mov $0x0,%eax 1250: e8 41 ff ff ff call 1196 <user_thread_2> 1255: 90 nop 1256: eb e9 jmp 1241 <main+0x8> .fini 區段的反組譯: 0000000000001258 <_fini>: 1258: f3 0f 1e fa endbr64 125c: 48 83 ec 08 sub $0x8,%rsp 1260: 48 83 c4 08 add $0x8,%rsp 1264: c3 ret ``` ::: <hr/> ![image](https://hackmd.io/_uploads/B14sdjh0kx.png) As shown in the above image, the kernel does the following: 1. Validates the ELF format. 2. Parses the ELF header to determine sections like .text, .data, .bss, etc. 3. Configures the new process’s memory layout (including setting up virtual memory mappings for each section). 4. If the ELF is dynamically linked (which most binaries are), it identifies the interpreter from the ELF header (PT_INTERP segment), typically /lib64/ld-linux-x86-64.so.2. then the dynamic linker -> C runtime(CRT). in the elf header, there is info parsed and used to be loaded into the mem: ```shell $ readelf test -e ``` :::spoiler output ```bash ELF 檔頭: 魔術位元組: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 類別: ELF64 資料: 2 的補數,小尾序(little endian) Version: 1 (current) OS/ABI: UNIX - System V ABI 版本: 0 類型: DYN (Position-Independent Executable file) 系統架構: Advanced Micro Devices X86-64 版本: 0x1 進入點位址: 0x1060 程式標頭起點: 64 (檔案內之位元組) 區段標頭起點: 15424 (檔案內之位元組) 旗標: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 13 Size of section headers: 64 (bytes) Number of section headers: 37 Section header string table index: 36 區段標頭: [號] 名稱 類型 位址 偏移量 大小 全體大小 旗標 連結 資訊 對齊 [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .interp PROGBITS 0000000000000318 00000318 000000000000001c 0000000000000000 A 0 0 1 [ 2] .note.gnu.pr[...] NOTE 0000000000000338 00000338 0000000000000030 0000000000000000 A 0 0 8 [ 3] .note.gnu.bu[...] NOTE 0000000000000368 00000368 0000000000000024 0000000000000000 A 0 0 4 [ 4] .note.ABI-tag NOTE 000000000000038c 0000038c 0000000000000020 0000000000000000 A 0 0 4 [ 5] .gnu.hash GNU_HASH 00000000000003b0 000003b0 0000000000000024 0000000000000000 A 6 0 8 [ 6] .dynsym DYNSYM 00000000000003d8 000003d8 00000000000000a8 0000000000000018 A 7 1 8 [ 7] .dynstr STRTAB 0000000000000480 00000480 000000000000008f 0000000000000000 A 0 0 1 [ 8] .gnu.version VERSYM 0000000000000510 00000510 000000000000000e 0000000000000002 A 6 0 2 [ 9] .gnu.version_r VERNEED 0000000000000520 00000520 0000000000000030 0000000000000000 A 7 1 8 [10] .rela.dyn RELA 0000000000000550 00000550 00000000000000c0 0000000000000018 A 6 0 8 [11] .rela.plt RELA 0000000000000610 00000610 0000000000000018 0000000000000018 AI 6 24 8 [12] .init PROGBITS 0000000000001000 00001000 000000000000001b 0000000000000000 AX 0 0 4 [13] .plt PROGBITS 0000000000001020 00001020 0000000000000020 0000000000000010 AX 0 0 16 [14] .plt.got PROGBITS 0000000000001040 00001040 0000000000000010 0000000000000010 AX 0 0 16 [15] .plt.sec PROGBITS 0000000000001050 00001050 0000000000000010 0000000000000010 AX 0 0 16 [16] .text PROGBITS 0000000000001060 00001060 00000000000001f8 0000000000000000 AX 0 0 16 [17] .fini PROGBITS 0000000000001258 00001258 000000000000000d 0000000000000000 AX 0 0 4 [18] .rodata PROGBITS 0000000000002000 00002000 000000000000004e 0000000000000000 A 0 0 8 [19] .eh_frame_hdr PROGBITS 0000000000002050 00002050 0000000000000044 0000000000000000 A 0 0 4 [20] .eh_frame PROGBITS 0000000000002098 00002098 00000000000000e8 0000000000000000 A 0 0 8 [21] .init_array INIT_ARRAY 0000000000003db8 00002db8 0000000000000008 0000000000000008 WA 0 0 8 [22] .fini_array FINI_ARRAY 0000000000003dc0 00002dc0 0000000000000008 0000000000000008 WA 0 0 8 [23] .dynamic DYNAMIC 0000000000003dc8 00002dc8 00000000000001f0 0000000000000010 WA 7 0 8 [24] .got PROGBITS 0000000000003fb8 00002fb8 0000000000000048 0000000000000008 WA 0 0 8 [25] .data PROGBITS 0000000000004000 00003000 0000000000000014 0000000000000000 WA 0 0 8 [26] .bss NOBITS 0000000000004014 00003014 000000000000000c 0000000000000000 WA 0 0 4 [27] .comment PROGBITS 0000000000000000 00003014 000000000000002b 0000000000000001 MS 0 0 1 [28] .debug_aranges PROGBITS 0000000000000000 0000303f 0000000000000030 0000000000000000 0 0 1 [29] .debug_info PROGBITS 0000000000000000 0000306f 0000000000000162 0000000000000000 0 0 1 [30] .debug_abbrev PROGBITS 0000000000000000 000031d1 00000000000000e5 0000000000000000 0 0 1 [31] .debug_line PROGBITS 0000000000000000 000032b6 000000000000009d 0000000000000000 0 0 1 [32] .debug_str PROGBITS 0000000000000000 00003353 0000000000000113 0000000000000001 MS 0 0 1 [33] .debug_line_str PROGBITS 0000000000000000 00003466 0000000000000036 0000000000000001 MS 0 0 1 [34] .symtab SYMTAB 0000000000000000 000034a0 0000000000000408 0000000000000018 35 25 8 [35] .strtab STRTAB 0000000000000000 000038a8 000000000000022c 0000000000000000 0 0 1 [36] .shstrtab STRTAB 0000000000000000 00003ad4 000000000000016a 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), D (mbind), l (large), p (processor specific) 程式標頭: 類型 偏移量 虛擬位址 實體位址 檔案大小 記憶大小 旗標 對齊 PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000002d8 0x00000000000002d8 R 0x8 INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318 0x000000000000001c 0x000000000000001c R 0x1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000628 0x0000000000000628 R 0x1000 LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000 0x0000000000000265 0x0000000000000265 R E 0x1000 LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000 0x0000000000000180 0x0000000000000180 R 0x1000 LOAD 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8 0x000000000000025c 0x0000000000000268 RW 0x1000 DYNAMIC 0x0000000000002dc8 0x0000000000003dc8 0x0000000000003dc8 0x00000000000001f0 0x00000000000001f0 RW 0x8 NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000030 0x0000000000000030 R 0x8 NOTE 0x0000000000000368 0x0000000000000368 0x0000000000000368 0x0000000000000044 0x0000000000000044 R 0x4 GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338 0x0000000000000030 0x0000000000000030 R 0x8 GNU_EH_FRAME 0x0000000000002050 0x0000000000002050 0x0000000000002050 0x0000000000000044 0x0000000000000044 R 0x4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10 GNU_RELRO 0x0000000000002db8 0x0000000000003db8 0x0000000000003db8 0x0000000000000248 0x0000000000000248 R 0x1 區段到節區映射中: 節區段… 00 01 .interp 02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 03 .init .plt .plt.got .plt.sec .text .fini 04 .rodata .eh_frame_hdr .eh_frame 05 .init_array .fini_array .dynamic .got .data .bss 06 .dynamic 07 .note.gnu.property 08 .note.gnu.build-id .note.ABI-tag 09 .note.gnu.property 10 .eh_frame_hdr 11 12 .init_array .fini_array .dynamic .got ``` ::: Notly, INTERP is where the dynamic linker performs and be requested. ## Examine with `strace` `stace` 關注於 child process 因此不會記錄 fork 與親代配置 child process 等過程,稍後利用 `bpftrace` 追蹤此類系統呼叫。 ```shell $ stace ls /tmp ``` ```bash= execve("/usr/bin/ls", ["ls", "/tmp/"], 0x7ffd2e161198 /* 49 vars */) = 0 ←- 在 child process 執行 execve 系統呼叫 / 用 $PATH 找到 file system 系統的紀錄 (inode) brk(NULL) = 0x5b2dab683000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7e58f85c4000 mmap(NULL, 105367, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7e58f85aa000 close(3) = 0 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 ⇒ 所以 /usr/bin/ls 是動態連結的 ELF read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\243\2\0\0\0\0\0"..., 832) = 832 pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784 fstat(3, {st_mode=S_IFREG|0755, st_size=2125328, ...}) = 0 pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784 mmap(NULL, 2170256, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7e58f8200000 ⇒ mmap? 為何執行程式時需要配置記憶體空間? stack vs. heap (motivation) ``` 從第六行可以發現 ls 會讀取並配置 `libc.so.6` (動態連結),所以 /usr/bin/ls 是動態連結的 ELF。 若在 gcc 編譯時提供 `--static` 則不會出現該動態連結檔。 ### 為何 stack 空間小於 heap?(motivation) 觀察 PID=1 (init) 的行程的記憶體映射狀況 ```shell $ sudo cat /proc/1/maps ``` ```bash ba55ec796000-ba55ecad7000 rw-p 00000000 00:00 0 [heap] ffffd8184000-ffffd81a5000 rw-p 00000000 00:00 0 [stack] ``` 其中可以發現 `[heap]` 在略高地址,而 `[stack]` 在高地址,且 `[heap]` $\rightarrow$ $ba55ec796000-ba55ecad7000 = (-3,411,968)_{10}$ `[stack]` $\rightarrow$ $ffffd8184000-ffffd81a5000 = (-135,168)_{10}$ `[heap]` 空間較大,而 `[stack]` 較小。 #### 如果 heap 和 stack 在相同記憶體空間? ```bash [---------- /usr/bin/ls —-------] [--- heap + stack —] ELF image 額外 (runtime overhead) ``` :::info function call 過程中需要額外的空間去保存 stack frame malloc / free 過程中需要額外空間 ::: 則當 stack overflow 時,還原時就有可能會釋放到其他空間,甚至沒有其他呼叫可以使用,如輸出,還原等,因為使用呼叫需要 function call。 #### ==為何 stack 空間小於 heap?(motivation)== 為了讓 stack overflow 及早被發現,對於系統設計者,不希望開發者寫出很差的程式,讓 stack overflow 就算發生,早點發生,反之,不知道程式碼怎麼被寫,希望讓開發者有較多空間配置記憶體、從系統要記憶體,設定 stack 是對開發者有限制。就如同 kernel 的 stack 空間很小,其犯錯空間很小,也就是犯錯很容易被發現。 ## Use `bpftrace` to 在 aarch64 上執行 利用 python 觀察 `stace ls` ```python from bcc import BPF # Define the eBPF program bpf_program = """ #include <uapi/linux/ptrace.h> int trace_execve(struct pt_regs *ctx) { bpf_trace_printk("execve called\\n"); return 0; } int trace_mmap(struct pt_regs *ctx) { bpf_trace_printk("mmap called\\n"); return 0; } int trace_fork(struct pt_regs *ctx) { bpf_trace_printk("fork called\\n"); return 0; } """ # Load and attach probes b = BPF(text=bpf_program) b.attach_kprobe(event="__arm64_sys_execve", fn_name="trace_execve") b.attach_kprobe(event="__arm64_sys_mmap", fn_name="trace_mmap") b.attach_kprobe(event="__arm64_sys_fork", fn_name="trace_fork") b.attach_kprobe(event="__arm64_sys_clone", fn_name="trace_fork") print("Tracing... Ctrl-C to end.") try: b.trace_print() except KeyboardInterrupt: pass ``` :::spoiler output ```bash Tracing... Ctrl-C to end. b' bash-1511871 [003] d..21 1295829.603542: bpf_trace_printk: fork called' b'' b' bash-14565 [002] d..21 1295829.604759: bpf_trace_printk: execve called' b'' b' bash-14565 [002] d..21 1295829.606079: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.606219: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.606329: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.606348: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.606472: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.606526: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.609314: bpf_trace_printk: mmap called' b'' b' bash-14565 [002] d..21 1295829.609892: bpf_trace_printk: fork called' b'' b' strace-14565 [002] d..21 1295829.610613: bpf_trace_printk: fork called' b'' b' strace-14565 [002] d..21 1295829.611975: bpf_trace_printk: fork called' b'' b' strace-14568 [000] d..21 1295829.613332: bpf_trace_printk: execve called' b'' b' strace-14568 [000] d..21 1295829.615507: bpf_trace_printk: mmap called' b'' b' strace-14565 [001] d..21 1295829.616501: bpf_trace_printk: mmap called' b'' b' strace-14565 [001] d..21 1295829.616731: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.618575: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.620229: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.620482: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.621413: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.621697: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.622946: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.623163: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.623869: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.624183: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.625580: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.625852: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.626607: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.627150: bpf_trace_printk: mmap called' b'' b' ls-14568 [000] d..21 1295829.632824: bpf_trace_printk: mmap called' b'' ``` :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully