I'm trying to learn more about how kernel's and executables work. To do this I'm starting with some basic experiments in regards to static and dynamic binaries compiled with aarch64 and x86_64 targets for macOS (Darwin), Linux, and Windows NT. All code and hex dumps for this issue can be found in this git repo. I have the following C program
#include <stdio.h>
int main() {
printf("This is the message.");
return 0;
}
I have compiled the code as is, renamed the output to b.out
, then I changed the end of the printed string from a "." to a "!" just to use as a reference later. When I run a.out
and b.out
I get the expected output:
a.out
This is the message.
b.out
This is the message!
I then attempted to change the last character in the printed string to "!" in .a.out
and saved the result as a binary to c.out
. But when I run it I get the following output:
c.out
zsh: killed ./c.out
Which appears to be a kernel kill rather than a zsh kill or anything programmed within the executable. When I look at the kernel logs I do see the following error:
-------------------------------------
Translated Report (Full Report Below)
-------------------------------------
Incident Identifier: 20C3E121-ED70-4F38-8795-D8CD6ED08F36
CrashReporter Key: 3BBE0F5E-25FE-9F02-ED42-03CD4C637157
Hardware Model: Mac14,6
Process: c.out [3352]
Path: /Users/USER/Documents/*/c.out
Identifier: c.out
Version: ???
Code Type: ARM-64 (Native)
Role: Unspecified
Parent Process: zsh [2823]
Coalition: com.apple.Terminal [3459]
Responsible Process: Terminal [2821]
Date/Time: 2024-02-09 09:35:57.9854 -0500
Launch Time: 2024-02-09 09:35:57.9160 -0500
OS Version: macOS 14.3.1 (23D60)
Release Type: User
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))
Exception Subtype: UNKNOWN_0x32 at 0x0000000102d44000
Exception Codes: 0x0000000000000032, 0x0000000102d44000
VM Region Info: 0x102d44000 is in 0x102d44000-0x102d48000; bytes after start: 0 bytes before end: 16383
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
---> __TEXT 102d44000-102d48000 [ 16K] r-x/r-x SM=COW
__DATA_CONST 102d48000-102d4c000 [ 16K] rw-/rw- SM=COW
Termination Reason: CODESIGNING 2 Invalid Page
Triggered by Thread: 0
Thread 0 Crashed:
0 0x102f0e204 dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 52
1 0x102f102ac dyld3::MachOFile::forEachSupportedPlatform(void (dyld3::Platform, unsigned int, unsigned int) block_pointer) const + 160
2 0x102f662e4 dyld3::MachOFile::isBuiltForSimulator() const + 124
3 0x102f11b88 start + 992
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000102d44000 x1: 0x000000016d0bb4d8 x2: 0x000000016d0bb480 x3: 0x0000000102f0de44
x4: 0x0000000000000070 x5: 0x0000000000000073 x6: 0x0000000000000000 x7: 0x0000000000000ca0
x8: 0x000000016d0bb4b8 x9: 0x0000000102fa75f8 x10: 0x0000000102f8f000 x11: 0x0000000102f9c7af
x12: 0x0000000000000065 x13: 0x0000000000000073 x14: 0x0000000000058a70 x15: 0x0000000000000000
x16: 0x0000000102f1034c x17: 0x6ae100016d0bb480 x18: 0x0000000000000000 x19: 0x000000016d0bb4d8
x20: 0x0000000102d44000 x21: 0x000000016d0bb480 x22: 0x0000000102f0c000 x23: 0x000000016d0bb638
x24: 0x000000016d0bb610 x25: 0x0000000000000000 x26: 0x0000000000000000 x27: 0x0000000000000000
x28: 0x0000000000000000 fp: 0x000000016d0bb470 lr: 0x2056000102f102ac
sp: 0x000000016d0bb3e0 pc: 0x0000000102f0e204 cpsr: 0x80001000
far: 0x0000000102d44000 esr: 0x92000007 (Data Abort) byte read Translation fault
Binary Images:
0x102f0c000 - 0x102fa3fff (*) <50746901-db0e-39a0-b391-baaa6b82ad0f> ???
0x102d44000 - 0x102d47fff (*) <8a6e71e1-eed6-3905-9bb4-9258440c0fe2> ???
0x0 - 0xffffffffffffffff ??? (*) <00000000-0000-0000-0000-000000000000> ???
Error Formulating Crash Report:
dyld_process_snapshot_get_shared_cache failed
EOF
-----------
Full Report
-----------
{"app_name":"c.out","timestamp":"2024-02-09 09:35:58.00 -0500","app_version":"","slice_uuid":"8a6e71e1-eed6-3905-9bb4-9258440c0fe2","build_version":"","platform":0,"share_with_app_devs":0,"is_first_party":1,"bug_type":"309","os_version":"macOS 14.3.1 (23D60)","roots_installed":0,"incident_id":"20C3E121-ED70-4F38-8795-D8CD6ED08F36","name":"c.out"}
{
"uptime" : 4500,
"procRole" : "Unspecified",
"version" : 2,
"userID" : 501,
"deployVersion" : 210,
"modelCode" : "Mac14,6",
"coalitionID" : 3459,
"osVersion" : {
"train" : "macOS 14.3.1",
"build" : "23D60",
"releaseType" : "User"
},
"captureTime" : "2024-02-09 09:35:57.9854 -0500",
"codeSigningMonitor" : 1,
"incident" : "20C3E121-ED70-4F38-8795-D8CD6ED08F36",
"pid" : 3352,
"translated" : false,
"cpuType" : "ARM-64",
"roots_installed" : 0,
"bug_type" : "309",
"procLaunch" : "2024-02-09 09:35:57.9160 -0500",
"procStartAbsTime" : 110142542836,
"procExitAbsTime" : 110144134578,
"procName" : "c.out",
"procPath" : "\/Users\/USER\/Documents\/*\/c.out",
"parentProc" : "zsh",
"parentPid" : 2823,
"coalitionName" : "com.apple.Terminal",
"crashReporterKey" : "3BBE0F5E-25FE-9F02-ED42-03CD4C637157",
"responsiblePid" : 2821,
"responsibleProc" : "Terminal",
"codeSigningID" : "a.out",
"codeSigningTeamID" : "",
"codeSigningFlags" : 587334144,
"codeSigningValidationCategory" : 0,
"codeSigningTrustLevel" : 4294967295,
"instructionByteStream" : {"beforePC":"+mcFqfhfBqn2Vwep9E8Iqf17Can9QwKR9QMCqvMDAar0AwCq\/\/8AOQ==","atPC":"CABAuelZn1Kp3b9yHwEJa+AAAFTJWZ9Sqd2\/ch8BCWthAQBUiQOAUg=="},
"wakeTime" : 4394,
"sleepWakeUUID" : "6725BB24-D686-433E-A28E-9F055451A803",
"sip" : "enabled",
"vmRegionInfo" : "0x102d44000 is in 0x102d44000-0x102d48000; bytes after start: 0 bytes before end: 16383\n REGION TYPE START - END [ VSIZE] PRT\/MAX SHRMOD REGION DETAIL\n UNUSED SPACE AT START\n---> __TEXT 102d44000-102d48000 [ 16K] r-x\/r-x SM=COW \n __DATA_CONST 102d48000-102d4c000 [ 16K] rw-\/rw- SM=COW ",
"exception" : {"codes":"0x0000000000000032, 0x0000000102d44000","rawCodes":[50,4342431744],"type":"EXC_BAD_ACCESS","signal":"SIGKILL (Code Signature Invalid)","subtype":"UNKNOWN_0x32 at 0x0000000102d44000"},
"termination" : {"flags":0,"code":2,"namespace":"CODESIGNING","indicator":"Invalid Page"},
"vmregioninfo" : "0x102d44000 is in 0x102d44000-0x102d48000; bytes after start: 0 bytes before end: 16383\n REGION TYPE START - END [ VSIZE] PRT\/MAX SHRMOD REGION DETAIL\n UNUSED SPACE AT START\n---> __TEXT 102d44000-102d48000 [ 16K] r-x\/r-x SM=COW \n __DATA_CONST 102d48000-102d4c000 [ 16K] rw-\/rw- SM=COW ",
"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":77191,"threadState":{"x":[{"value":4342431744},{"value":6124451032},{"value":6124450944},{"value":4344307268},{"value":112},{"value":115},{"value":0},{"value":3232},{"value":6124451000},{"value":4344935928,"symbolLocation":0,"symbol":"__block_descriptor_tmp.61"},{"value":4344836096,"symbolLocation":20,"symbol":"objc_visitor::ProtocolList::getProtocolField(objc_visitor::Visitor const&, unsigned long long) const (.cold.2)"},{"value":4344891311},{"value":101},{"value":115},{"value":363120},{"value":0},{"value":4344316748,"symbolLocation":0,"symbol":"invocation function for block in dyld3::MachOFile::forEachSupportedPlatform(void (dyld3::Platform, unsigned int, unsigned int) block_pointer) const"},{"value":7701436843904709760},{"value":0},{"value":6124451032},{"value":4342431744},{"value":6124450944},{"value":4344299520},{"value":6124451384},{"value":6124451344},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":2330049861555126956},"cpsr":{"value":2147487744},"fp":{"value":6124450928},"sp":{"value":6124450784},"esr":{"value":2449473543,"description":"(Data Abort) byte read Translation fault"},"pc":{"value":4344308228,"matchesCrashFrame":1},"far":{"value":4342431744}},"frames":[{"imageOffset":8708,"symbol":"dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const","symbolLocation":52,"imageIndex":0},{"imageOffset":17068,"symbol":"dyld3::MachOFile::forEachSupportedPlatform(void (dyld3::Platform, unsigned int, unsigned int) block_pointer) const","symbolLocation":160,"imageIndex":0},{"imageOffset":369380,"symbol":"dyld3::MachOFile::isBuiltForSimulator() const","symbolLocation":124,"imageIndex":0},{"imageOffset":23432,"symbol":"start","symbolLocation":992,"imageIndex":0}]}],
"usedImages" : [
{
"source" : "P",
"arch" : "arm64e",
"base" : 4344299520,
"size" : 622592,
"uuid" : "50746901-db0e-39a0-b391-baaa6b82ad0f",
"name" : ""
},
{
"source" : "P",
"arch" : "arm64",
"base" : 4342431744,
"size" : 16384,
"uuid" : "8a6e71e1-eed6-3905-9bb4-9258440c0fe2",
"name" : ""
},
{
"size" : 0,
"source" : "A",
"base" : 0,
"uuid" : "00000000-0000-0000-0000-000000000000"
}
],
"vmSummary" : "ReadOnly portion of Libraries: Total=1008K resident=0K(0%) swapped_out_or_unallocated=1008K(100%)\nWritable regions: Total=8176K written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=8176K(100%)\n\n VIRTUAL REGION \nREGION TYPE SIZE COUNT (non-coalesced) \n=========== ======= ======= \nSTACK GUARD 56.0M 1 \nStack 8176K 1 \n__DATA 16K 1 \n__DATA_CONST 48K 2 \n__DATA_DIRTY 16K 1 \n__LINKEDIT 384K 2 \n__TEXT 624K 2 \n=========== ======= ======= \nTOTAL 65.1M 10 \n",
"legacyInfo" : {
"threadTriggered" : {
}
},
"logWritingSignature" : "f13fb427e44496b8a2cba53558762cf657744a7e",
"trialInfo" : {
"rollouts" : [
{
"rolloutId" : "64b21a7351cbb02ce3442e4e",
"factorPackIds" : {
"REMINDERS_GROCERY" : "65542c604a6560536bdb1d22"
},
"deploymentId" : 240000032
},
{
"rolloutId" : "6425c75e4327780c10cc4252",
"factorPackIds" : {
"SIRI_HOME_AUTOMATION_INTENT_SELECTION_CACHE" : "642600a457e7664b1698eb32"
},
"deploymentId" : 240000004
}
],
"experiments" : [
]
},
"reportNotes" : [
"dyld_process_snapshot_get_shared_cache failed"
]
}
Which leads me to believe there is a crypto mechanism that is causing the kernel to have a problem with the executable. After some searching I found references to MACH-EXECUTE object files having a checksum, and when comparing found the following set of characters which based on the length I assume to be a MD5 hash:
00000378: 1b00 0000 1800 0000 8a6e 71e1 eed6 3905 9bb4 9258 440c 0fe2
So I start by trying to update that hash found in c.out
with the contents of b.out
's hash, so that the result looks like this:
00000378: 1b00 0000 1800 0000 e92b 09d1 5e12 30a5 b9f2 f0c1 8b21 a74d
I tried to execute the binary again and the same kernel error occurs. The only other difference which I've not been able to identify is found at the bottom of the hex dump which could be the problem, but I'm not sure what it is:
a.out
00008160: 0000 0034 0000 0000 0000 0001 612e 6f75 7400 a099 e717 e474
00008178: e85d 7190 c6bb 2c0a 0f08 56e5 e1cc d752 c26c a377 9142 1c4b
00008190: a6e2 ad7f acb2 586f c6e9 66c0 04d7 d1d1 6b02 4f58 05ff 7cb4
000081a8: 7c7a 85da bd8b 4889 2ca7 ad7f acb2 586f c6e9 66c0 04d7 d1d1
000081c0: 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889 2ca7 b263 8efb 717d
000081d8: ee06 21e4 651a ecb1 09bc 2aba 80db 7c57 5aca a99a a5ff 987e
000081f0: a3b5 dfd5 eb86 f195 6603 a12c 0636 f463 1f66 f10d 0bb8 d4ee
00008208: a3d2 5b82 e0e5 9202 b4ed ad7f acb2 586f c6e9 66c0 04d7 d1d1
00008220: 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889 2ca7 ad7f acb2 586f
00008238: c6e9 66c0 04d7 d1d1 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889
00008250: 2ca7 ad7f acb2 586f c6e9 66c0 04d7 d1d1 6b02 4f58 05ff 7cb4
00008268: 7c7a 85da bd8b 4889 2ca7 521e 9e92 c0d7 f140 79c7 e903 71dc
00008280: b96b ebb4 dca7 c209 1dba 1d71 6bf4 aea0 2586 0000 0000 0000
b.out
00008160: 0000 0034 0000 0000 0000 0001 612e 6f75 7400 fca1 75f4 4ef7
00008178: c187 a241 56d2 9d13 7ba4 7060 3e95 4111 900e 2364 644a 5cc1
00008190: a785 ad7f acb2 586f c6e9 66c0 04d7 d1d1 6b02 4f58 05ff 7cb4
000081a8: 7c7a 85da bd8b 4889 2ca7 ad7f acb2 586f c6e9 66c0 04d7 d1d1
000081c0: 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889 2ca7 1a07 1b89 4002
000081d8: ab65 ddc7 6901 1a11 cec2 5d81 b1ef f3eb 6a62 f1fb eeae eaa1
000081f0: a9da dfd5 eb86 f195 6603 a12c 0636 f463 1f66 f10d 0bb8 d4ee
00008208: a3d2 5b82 e0e5 9202 b4ed ad7f acb2 586f c6e9 66c0 04d7 d1d1
00008220: 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889 2ca7 ad7f acb2 586f
00008238: c6e9 66c0 04d7 d1d1 6b02 4f58 05ff 7cb4 7c7a 85da bd8b 4889
00008250: 2ca7 ad7f acb2 586f c6e9 66c0 04d7 d1d1 6b02 4f58 05ff 7cb4
00008268: 7c7a 85da bd8b 4889 2ca7 521e 9e92 c0d7 f140 79c7 e903 71dc
00008280: b96b ebb4 dca7 c209 1dba 1d71 6bf4 aea0 2586 0000 0000 0000
assuming by the error I'm guessing that it's a encrypted digest of some sort? But what algorithm and am I even right? And when I update the last set of segments with the ending binary of b.out
I still get the same SIGKIKLL?
The actual question: What am I doing wrong here if I want to be able to execute the updated binary?
You need to codesign c.out
, since your crash report indicates an invalid code signature:
Exception Type: EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))
To codesign the binary ad-hoc first remove any extended attributes:
$ xattr -c c.out
Then codesign it:
$ sudo codesign -f -s - c.out
You'll need a legit certificate if you intend to run the modified binary on other machines.