nodejs / postject

Easily inject arbitrary read-only resources into executable formats (Mach-O, PE, ELF) and use it at runtime.
Other
186 stars 14 forks source link

Adding multiple sections to the `__POSTJECT` segment causes a crash #1

Open RaisinTen opened 2 years ago

RaisinTen commented 2 years ago

OS

Intel macOS Monterey Version 12.4

$ uname -a
Darwin Darshans-MacBook-Pro.local 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:22 PDT 2022; root:xnu-8020.121.3~4/RELEASE_X86_64 x86_64

Repro

$ echo "int main() {}" | clang -x c -
$ postject.py --macho-segment-name __POSTJECT a.out NODE_JS_CODE <(shuf -n 100 /usr/share/dict/words | fmt -w 72)
$ postject.py --macho-segment-name __POSTJECT a.out NODE_JS_BOOTSTRAP <(shuf -n 100 /usr/share/dict/words | fmt -w 72)

Crash report

```py ------------------------------------- Translated Report (Full Report Below) ------------------------------------- Process: Python [13660] Path: /usr/local/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python Identifier: org.python.python Version: 3.9.12 (3.9.12) Code Type: X86-64 (Native) Parent Process: zsh [12922] Responsible: iTerm2 [748] User ID: 501 Date/Time: 2022-07-13 15:45:24.4525 +0530 OS Version: macOS 12.4 (21F79) Report Version: 12 Bridge OS Version: 6.5 (19P5071) Anonymous UUID: CDD9CBE9-BEC3-A09F-0243-7CB482668B13 Sleep/Wake UUID: F873FF55-8F77-43B0-9FFA-77CB2BE2243F Time Awake Since Boot: 16000 seconds Time Since Wake: 1529 seconds System Integrity Protection: enabled Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: UNKNOWN_0xD at 0x0000000000000000 Exception Codes: 0x000000000000000d, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Termination Reason: Namespace SIGNAL, Code 11 Segmentation fault: 11 Terminating Process: exc handler [13660] VM Region Info: 0 is not in any region. Bytes before following region: 4415893504 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> __TEXT 107353000-107357000 [ 16K] r-x/r-x SM=COW .../MacOS/Python Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 Python 0x107976785 collect + 199 1 Python 0x10797655c collect_with_callback + 75 2 Python 0x1079779c7 PyGC_Collect + 107 3 Python 0x10794f097 Py_FinalizeEx + 413 4 Python 0x107952805 Py_Exit + 13 5 Python 0x1079561cf handle_system_exit + 35 6 Python 0x107955bd6 _PyErr_PrintEx + 42 7 Python 0x10795539c pyrun_simple_file + 455 8 Python 0x1079551af PyRun_SimpleFileExFlags + 67 9 Python 0x107974bfb pymain_run_file + 326 10 Python 0x107974469 Py_RunMain + 993 11 Python 0x1079757c4 Py_BytesMain + 42 12 dyld 0x11135d51e start + 462 Thread 0 crashed with X86 Thread State (64-bit): rax: 0x6261737365737361 rbx: 0x0000000107482030 rcx: 0xa1bdc985c185b082 rdx: 0x6261737365737361 rdi: 0x00007fc40a009698 rsi: 0x0000000000000000 rbp: 0x00007ff7b8bac1c0 rsp: 0x00007ff7b8bac100 r8: 0x0000000107dc3540 r9: 0xffffffff00000000 r10: 0x0000000000000400 r11: 0x0000000000000206 r12: 0x0000000000000002 r13: 0x00007fc40a0096b0 r14: 0x0000000000000003 r15: 0x0000000000000002 rip: 0x0000000107976785 rfl: 0x0000000000010293 cr2: 0x000000010794f3ec Logical CPU: 4 Error Code: 0x00000000 Trap Number: 13 Thread 0 instruction stream: 00 00 41 8d 47 01 4c 63-f0 83 f8 03 4c 89 bd 68 ..A.G.Lc....L..h ff ff ff 0f 8d 39 07 00-00 4b 8d 04 76 ff 84 c3 .....9...K..v... 94 02 00 00 45 85 ff 0f-89 25 07 00 00 4d 63 e7 ....E....%...Mc. 4b 8d 04 64 4c 8d ac c3-80 02 00 00 41 83 ff 02 K..dL.......A... 4b 8d 04 76 48 8d 84 c3-80 02 00 00 49 0f 4d c5 K..vH.......I.M. 48 89 45 98 49 8b 5d 00-49 39 dd 74 45 48 89 d8 H.E.I.].I9.tEH.. [48]8b 48 10 48 8b 10 48-8b 70 08 83 e6 01 48 8d H.H.H..H.p....H. <== 4c 8e 02 48 89 48 08 48-89 d0 49 39 d5 75 e1 4c L..H.H.H..I9.u.L 8d 35 ee 0f 00 00 48 8d-7b 10 48 8b 43 18 4c 89 .5....H.{.H.C.L. f6 48 89 fa ff 90 b8 00-00 00 48 8b 1b 49 39 dd .H........H..I9. 75 e4 4c 89 65 b8 48 8d-45 a0 48 89 40 08 48 89 u.L.e.H.E.H.@.H. 00 49 8b 5d 00 4d 89 ec-49 39 dd 74 79 4c 8d 7d .I.].M..I9.tyL.} Binary Images: 0x1077b9000 - 0x107a74fff org.python.python (3.9.12, (c) 2001-2021 Python Software Foundation.) /usr/local/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/Python 0x111358000 - 0x1113c3fff dyld (*) /usr/lib/dyld External Modification Summary: Calls made by other processes targeting this process: task_for_pid: 0 thread_create: 0 thread_set_state: 0 Calls made by this process: task_for_pid: 0 thread_create: 0 thread_set_state: 0 Calls made by all processes on this machine: task_for_pid: 0 thread_create: 0 thread_set_state: 0 VM Region Summary: ReadOnly portion of Libraries: Total=160.4M resident=0K(0%) swapped_out_or_unallocated=160.4M(100%) Writable regions: Total=580.1M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=580.1M(100%) VIRTUAL REGION REGION TYPE SIZE COUNT (non-coalesced) =========== ======= ======= Kernel Alloc Once 8K 1 MALLOC 173.8M 23 MALLOC guard page 16K 4 MALLOC_LARGE (reserved) 384K 1 reserved VM address space (unallocated) MALLOC_NANO (reserved) 384.0M 1 reserved VM address space (unallocated) ObjC additional data 15K 1 STACK GUARD 4K 1 Stack 16.0M 1 VM_ALLOCATE 5896K 25 __DATA 771K 53 __DATA_CONST 3542K 49 __DATA_DIRTY 79K 24 __LINKEDIT 135.0M 13 __TEXT 25.4M 58 __UNICODE 592K 1 dyld private memory 1024K 1 shared memory 12K 2 =========== ======= ======= TOTAL 746.3M 259 TOTAL, minus reserved VM space 361.9M 259 ----------- Full Report ----------- {"app_name":"Python","timestamp":"2022-07-13 15:45:24.00 +0530","app_version":"3.9.12","slice_uuid":"04d90438-f1c2-3624-9931-dbecf8989ee4","build_version":"3.9.12","platform":1,"bundleID":"org.python.python","share_with_app_devs":1,"is_first_party":0,"bug_type":"309","os_version":"macOS 12.4 (21F79)","incident_id":"2DB42710-A91D-4518-AA34-7A22586154AB","name":"Python"} { "uptime" : 16000, "procLaunch" : "2022-07-13 15:45:24.3640 +0530", "procRole" : "Unspecified", "version" : 2, "userID" : 501, "deployVersion" : 210, "modelCode" : "MacBookPro16,2", "procStartAbsTime" : 16957191655990, "coalitionID" : 726, "osVersion" : { "train" : "macOS 12.4", "build" : "21F79", "releaseType" : "User" }, "captureTime" : "2022-07-13 15:45:24.4525 +0530", "incident" : "2DB42710-A91D-4518-AA34-7A22586154AB", "bug_type" : "309", "pid" : 13660, "procExitAbsTime" : 16957279541644, "cpuType" : "X86-64", "procName" : "Python", "procPath" : "\/usr\/local\/Cellar\/python@3.9\/3.9.12\/Frameworks\/Python.framework\/Versions\/3.9\/Resources\/Python.app\/Contents\/MacOS\/Python", "bundleInfo" : {"CFBundleShortVersionString":"3.9.12","CFBundleVersion":"3.9.12","CFBundleIdentifier":"org.python.python"}, "storeInfo" : {"deviceIdentifierForVendor":"41426303-7475-557B-B1A1-DF62F151AC4C","thirdParty":true}, "parentProc" : "zsh", "parentPid" : 12922, "coalitionName" : "com.googlecode.iterm2", "crashReporterKey" : "CDD9CBE9-BEC3-A09F-0243-7CB482668B13", "responsiblePid" : 748, "responsibleProc" : "iTerm2", "wakeTime" : 1529, "bridgeVersion" : {"build":"19P5071","train":"6.5"}, "sleepWakeUUID" : "F873FF55-8F77-43B0-9FFA-77CB2BE2243F", "sip" : "enabled", "vmRegionInfo" : "0 is not in any region. Bytes before following region: 4415893504\n REGION TYPE START - END [ VSIZE] PRT\/MAX SHRMOD REGION DETAIL\n UNUSED SPACE AT START\n---> \n __TEXT 107353000-107357000 [ 16K] r-x\/r-x SM=COW ...\/MacOS\/Python", "isCorpse" : 1, "exception" : {"codes":"0x000000000000000d, 0x0000000000000000","rawCodes":[13,0],"type":"EXC_BAD_ACCESS","signal":"SIGSEGV","subtype":"UNKNOWN_0xD at 0x0000000000000000"}, "termination" : {"flags":0,"code":11,"namespace":"SIGNAL","indicator":"Segmentation fault: 11","byProc":"exc handler","byPid":13660}, "vmregioninfo" : "0 is not in any region. Bytes before following region: 4415893504\n REGION TYPE START - END [ VSIZE] PRT\/MAX SHRMOD REGION DETAIL\n UNUSED SPACE AT START\n---> \n __TEXT 107353000-107357000 [ 16K] r-x\/r-x SM=COW ...\/MacOS\/Python", "extMods" : {"caller":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"system":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"targeted":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"warnings":0}, "faultingThread" : 0, "threads" : [{"triggered":true,"id":172215,"instructionState":{"instructionStream":{"bytes":[0,0,65,141,71,1,76,99,240,131,248,3,76,137,189,104,255,255,255,15,141,57,7,0,0,75,141,4,118,255,132,195,148,2,0,0,69,133,255,15,137,37,7,0,0,77,99,231,75,141,4,100,76,141,172,195,128,2,0,0,65,131,255,2,75,141,4,118,72,141,132,195,128,2,0,0,73,15,77,197,72,137,69,152,73,139,93,0,73,57,221,116,69,72,137,216,72,139,72,16,72,139,16,72,139,112,8,131,230,1,72,141,76,142,2,72,137,72,8,72,137,208,73,57,213,117,225,76,141,53,238,15,0,0,72,141,123,16,72,139,67,24,76,137,246,72,137,250,255,144,184,0,0,0,72,139,27,73,57,221,117,228,76,137,101,184,72,141,69,160,72,137,64,8,72,137,0,73,139,93,0,77,137,236,73,57,221,116,121,76,141,125],"offset":96}},"threadState":{"r13":{"value":140479958128304},"rax":{"value":7089074227918369633},"rflags":{"value":66195},"cpu":{"value":4},"r14":{"value":3},"rsi":{"value":0},"r8":{"value":4426839360},"cr2":{"value":4422169580},"rdx":{"value":7089074227918369633},"r10":{"value":1024},"r9":{"value":18446744069414584320},"r15":{"value":2},"rbx":{"value":4417134640},"trap":{"value":13},"err":{"value":0},"r11":{"value":518},"rip":{"value":4422330245,"matchesCrashFrame":1},"rbp":{"value":140701932896704},"rsp":{"value":140701932896512},"r12":{"value":2},"rcx":{"value":11654692987019309186},"flavor":"x86_THREAD_STATE","rdi":{"value":140479958128280}},"queue":"com.apple.main-thread","frames":[{"imageOffset":1824645,"symbol":"collect","symbolLocation":199,"imageIndex":0},{"imageOffset":1824092,"symbol":"collect_with_callback","symbolLocation":75,"imageIndex":0},{"imageOffset":1829319,"symbol":"PyGC_Collect","symbolLocation":107,"imageIndex":0},{"imageOffset":1663127,"symbol":"Py_FinalizeEx","symbolLocation":413,"imageIndex":0},{"imageOffset":1677317,"symbol":"Py_Exit","symbolLocation":13,"imageIndex":0},{"imageOffset":1692111,"symbol":"handle_system_exit","symbolLocation":35,"imageIndex":0},{"imageOffset":1690582,"symbol":"_PyErr_PrintEx","symbolLocation":42,"imageIndex":0},{"imageOffset":1688476,"symbol":"pyrun_simple_file","symbolLocation":455,"imageIndex":0},{"imageOffset":1687983,"symbol":"PyRun_SimpleFileExFlags","symbolLocation":67,"imageIndex":0},{"imageOffset":1817595,"symbol":"pymain_run_file","symbolLocation":326,"imageIndex":0},{"imageOffset":1815657,"symbol":"Py_RunMain","symbolLocation":993,"imageIndex":0},{"imageOffset":1820612,"symbol":"Py_BytesMain","symbolLocation":42,"imageIndex":0},{"imageOffset":21790,"symbol":"start","symbolLocation":462,"imageIndex":1}]}], "usedImages" : [ { "source" : "P", "arch" : "x86_64", "base" : 4420505600, "CFBundleShortVersionString" : "3.9.12, (c) 2001-2021 Python Software Foundation.", "CFBundleIdentifier" : "org.python.python", "size" : 2867200, "uuid" : "c9129da7-ee5b-3a6f-8129-d7a5b32b7a9c", "path" : "\/usr\/local\/Cellar\/python@3.9\/3.9.12\/Frameworks\/Python.framework\/Versions\/3.9\/Python", "name" : "Python", "CFBundleVersion" : "3.9.12" }, { "source" : "P", "arch" : "x86_64", "base" : 4583686144, "size" : 442368, "uuid" : "b70ce1ec-b902-3852-8268-05de00bfa8d5", "path" : "\/usr\/lib\/dyld", "name" : "dyld" } ], "sharedCache" : { "base" : 140703181619200, "size" : 15220686848, "uuid" : "398acfb4-57f6-31e0-bc82-e9959e5c92ce" }, "vmSummary" : "ReadOnly portion of Libraries: Total=160.4M resident=0K(0%) swapped_out_or_unallocated=160.4M(100%)\nWritable regions: Total=580.1M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=580.1M(100%)\n\n VIRTUAL REGION \nREGION TYPE SIZE COUNT (non-coalesced) \n=========== ======= ======= \nKernel Alloc Once 8K 1 \nMALLOC 173.8M 23 \nMALLOC guard page 16K 4 \nMALLOC_LARGE (reserved) 384K 1 reserved VM address space (unallocated)\nMALLOC_NANO (reserved) 384.0M 1 reserved VM address space (unallocated)\nObjC additional data 15K 1 \nSTACK GUARD 4K 1 \nStack 16.0M 1 \nVM_ALLOCATE 5896K 25 \n__DATA 771K 53 \n__DATA_CONST 3542K 49 \n__DATA_DIRTY 79K 24 \n__LINKEDIT 135.0M 13 \n__TEXT 25.4M 58 \n__UNICODE 592K 1 \ndyld private memory 1024K 1 \nshared memory 12K 2 \n=========== ======= ======= \nTOTAL 746.3M 259 \nTOTAL, minus reserved VM space 361.9M 259 \n", "legacyInfo" : { "threadTriggered" : { "queue" : "com.apple.main-thread" } }, "trialInfo" : { "rollouts" : [ { "rolloutId" : "61301e3a61217b3110231469", "factorPackIds" : { "SIRI_FIND_MY_CONFIGURATION_FILES" : "6216ae152a40e71046e16225" }, "deploymentId" : 240000016 }, { "rolloutId" : "6112e14f37f5d11121dcd519", "factorPackIds" : { "SIRI_TEXT_TO_SPEECH" : "62c4376c87beda2658c8f47d" }, "deploymentId" : 240000176 } ], "experiments" : [ ] } } Model: MacBookPro16,2, BootROM 1731.120.10.0.0 (iBridge: 19.16.15071.0.0,0), 4 processors, Quad-Core Intel Core i5, 2 GHz, 16 GB, SMC Graphics: Intel Iris Plus Graphics, Intel Iris Plus Graphics, Built-In Display: Color LCD, 2560 x 1600 Retina, Main, MirrorOff, Online Memory Module: BANK 0/ChannelA-DIMM0, 8 GB, LPDDR4X, 3733 MHz, Samsung, K4UBE3D4AA-MGCL Memory Module: BANK 2/ChannelB-DIMM0, 8 GB, LPDDR4X, 3733 MHz, Samsung, K4UBE3D4AA-MGCL AirPort: spairport_wireless_card_type_wifi (0x14E4, 0x7BF), wl0: Jul 12 2021 18:02:56 version 9.30.464.0.32.5.76 FWID 01-c081cfed Bluetooth: Version (null), 0 services, 0 devices, 0 incoming serial ports Network Service: Wi-Fi, AirPort, en0 USB Device: USB31Bus USB Device: USB31Bus USB Device: T2Bus USB Device: Touch Bar Backlight USB Device: Touch Bar Display USB Device: Apple Internal Keyboard / Trackpad USB Device: Headset USB Device: Ambient Light Sensor USB Device: FaceTime HD Camera (Built-in) USB Device: Apple T2 Controller Thunderbolt Bus: MacBook Pro, Apple Inc., 86.0 Thunderbolt Bus: MacBook Pro, Apple Inc., 86.0 ```
RaisinTen commented 2 years ago

Although Postject v1.0.0-alpha.3 doesn't crash while adding multiple resources, I have a test case for which the resultant binary still crashes. I'm using the official release of Node.js v14.18.2 on my Intel macOS for this example:

cp $(command -v node) sea
postject sea NODE_JS_CODE <(shuf -n 100 /usr/share/dict/words | fmt -w 72)
postject sea NODE_JS_BOOTSTRAP <(shuf -n 100 /usr/share/dict/words | fmt -w 72)
./sea

Reason for crash keeps changing every time.

LLDB logs:

``` $ lldb -- ./sea (lldb) target create "./sea" Current executable set to '/Users/raisinten/Desktop/temp/project/trash/sea' (x86_64). (lldb) run Process 4459 launched: '/Users/raisinten/Desktop/temp/project/trash/sea' (x86_64) Process 4459 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) frame #0: 0x000000010002fb41 sea`_GLOBAL__sub_I_cares_wrap.cc + 1 Target 0: (sea) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) * frame #0: 0x000000010002fb41 sea`_GLOBAL__sub_I_cares_wrap.cc + 1 (lldb) ^D ```
``` $ lldb -- ./sea (lldb) target create "./sea" Current executable set to '/Users/raisinten/Desktop/temp/project/trash/sea' (x86_64). (lldb) run Process 4174 launched: '/Users/raisinten/Desktop/temp/project/trash/sea' (x86_64) Process 4174 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1) frame #0: 0x00000001000164eb sea`node::AsyncWrap::MakeCallback(v8::Local, int, v8::Local*) + 43 sea`node::AsyncWrap::MakeCallback: -> 0x1000164eb <+43>: movq %rax, (%rdi) 0x1000164ee <+46>: testq %rdx, %rdx 0x1000164f1 <+49>: je 0x100016579 ; <+185> 0x1000164f7 <+55>: movq %rdx, %r15 Target 0: (sea) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1) * frame #0: 0x00000001000164eb sea`node::AsyncWrap::MakeCallback(v8::Local, int, v8::Local*) + 43 frame #1: 0x000000000000001b frame #2: 0x000000010002fb53 sea`_GLOBAL__sub_I_cares_wrap.cc + 19 frame #3: 0x00000001043bb911 dyld`invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 129 frame #4: 0x00000001043b2e26 dyld`invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 557 frame #5: 0x0000000104381db3 dyld`dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 129 frame #6: 0x00000001043b2bb7 dyld`dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 179 frame #7: 0x00000001043bb342 dyld`dyld3::MachOAnalyzer::forEachInitializerPointerSection(Diagnostics&, void (unsigned int, unsigned int, unsigned char const*, bool&) block_pointer) const + 118 frame #8: 0x00000001043bb5b4 dyld`dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 386 frame #9: 0x0000000104394d82 dyld`dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 144 frame #10: 0x0000000104394f0e dyld`dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array&) const + 178 frame #11: 0x0000000104394fb2 dyld`dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const + 108 frame #12: 0x00000001043a8826 dyld`dyld4::APIs::runAllInitializersForMain() + 222 frame #13: 0x000000010438638d dyld`dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 3443 frame #14: 0x00000001043854e4 dyld`start + 388 (lldb) ^D ```

I'm guessing the binary gets corrupted?