64 lines · c
1#include <mach-o/loader.h>2#include <mach/machine.h>3#include <stdlib.h>4#include <string.h>5#include <uuid/uuid.h>6 7int main() {8 int size_of_load_cmds =9 sizeof(struct segment_command_64) + sizeof(struct uuid_command);10 uint8_t *macho_buf =11 (uint8_t *)malloc(sizeof(struct mach_header_64) + size_of_load_cmds);12 uint8_t *p = macho_buf;13 struct mach_header_64 mh;14 mh.magic = MH_MAGIC_64;15 mh.cputype = CPU_TYPE_ARM64;16 mh.cpusubtype = 0;17 mh.filetype = MH_EXECUTE;18 mh.ncmds = 2;19 mh.sizeofcmds = size_of_load_cmds;20 mh.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_TWOLEVEL | MH_PIE;21 22 memcpy(p, &mh, sizeof(mh));23 p += sizeof(mh);24 25 struct segment_command_64 seg;26 seg.cmd = LC_SEGMENT_64;27 seg.cmdsize = sizeof(seg);28 strcpy(seg.segname, "__TEXT");29 seg.vmaddr = 0x5000;30 seg.vmsize = 0x1000;31 seg.fileoff = 0;32 seg.filesize = 0;33 seg.maxprot = 0;34 seg.initprot = 0;35 seg.nsects = 0;36 seg.flags = 0;37 38 memcpy(p, &seg, sizeof(seg));39 p += sizeof(seg);40 41 struct uuid_command uuid;42 uuid.cmd = LC_UUID;43 uuid.cmdsize = sizeof(uuid);44 uuid_clear(uuid.uuid);45 uuid_parse("1b4e28ba-2fa1-11d2-883f-b9a761bde3fb", uuid.uuid);46 47 memcpy(p, &uuid, sizeof(uuid));48 p += sizeof(uuid);49 50 // If this needs to be debugged, the memory buffer can be written51 // to a file with52 // (lldb) mem rea -b -o /tmp/t -c `p - macho_buf` macho_buf53 // (lldb) platform shell otool -hlv /tmp/t54 // to verify that it is well formed.55 56 // And inside lldb, it should be inspectable via57 // (lldb) script print(lldb.frame.locals["macho_buf"][0].GetValueAsUnsigned())58 // 10555316240396859 // (lldb) process plugin packet send60 // 'jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[105553162403968]}]'61 62 return 0; // break here63}64