├── .gitignore ├── AppController.h ├── AppController.mm ├── ArchiveLayout.h ├── ArchiveLayout.mm ├── Attach.h ├── Attach.mm ├── CRTFootPrints.h ├── CRTFootPrints.mm ├── Common.h ├── DataController.h ├── DataController.mm ├── DataSources.h ├── DataSources.mm ├── Document.h ├── Document.mm ├── DyldInfo.h ├── DyldInfo.mm ├── English.lproj ├── Credits.rtf ├── InfoPlist.strings ├── Layout.xib ├── MainMenu.xib └── Preferences.xib ├── Exceptions.h ├── Exceptions.mm ├── FatLayout.h ├── FatLayout.mm ├── Info.plist ├── Layout.h ├── Layout.mm ├── LinkEdit.h ├── LinkEdit.mm ├── LoadCommands.h ├── LoadCommands.mm ├── MachOLayout.h ├── MachOLayout.mm ├── ObjC.h ├── ObjC.mm ├── PreferenceController.h ├── PreferenceController.mm ├── Prefix.pch ├── README ├── README.orig ├── ReadWrite.h ├── ReadWrite.mm ├── SectionContents.h ├── SectionContents.mm ├── capstone ├── LEB128.h ├── MCDisassembler.h ├── MCFixedLenDisassembler.h ├── MCInst.c ├── MCInst.h ├── MCInstrDesc.c ├── MCInstrDesc.h ├── MCRegisterInfo.c ├── MCRegisterInfo.h ├── MathExtras.h ├── SStream.c ├── SStream.h ├── arch │ ├── AArch64 │ │ ├── AArch64AddressingModes.h │ │ ├── AArch64BaseInfo.c │ │ ├── AArch64BaseInfo.h │ │ ├── AArch64Disassembler.c │ │ ├── AArch64Disassembler.h │ │ ├── AArch64GenAsmWriter.inc │ │ ├── AArch64GenDisassemblerTables.inc │ │ ├── AArch64GenInstrInfo.inc │ │ ├── AArch64GenRegisterInfo.inc │ │ ├── AArch64GenSubtargetInfo.inc │ │ ├── AArch64InstPrinter.c │ │ ├── AArch64InstPrinter.h │ │ ├── AArch64Mapping.c │ │ ├── AArch64Mapping.h │ │ └── AArch64Module.c │ ├── ARM │ │ ├── ARMAddressingModes.h │ │ ├── ARMBaseInfo.h │ │ ├── ARMDisassembler.c │ │ ├── ARMDisassembler.h │ │ ├── ARMGenAsmWriter.inc │ │ ├── ARMGenDisassemblerTables.inc │ │ ├── ARMGenInstrInfo.inc │ │ ├── ARMGenRegisterInfo.inc │ │ ├── ARMGenSubtargetInfo.inc │ │ ├── ARMInstPrinter.c │ │ ├── ARMInstPrinter.h │ │ ├── ARMMapping.c │ │ ├── ARMMapping.h │ │ └── ARMModule.c │ ├── PowerPC │ │ ├── PPCDisassembler.c │ │ ├── PPCDisassembler.h │ │ ├── PPCGenAsmWriter.inc │ │ ├── PPCGenDisassemblerTables.inc │ │ ├── PPCGenInstrInfo.inc │ │ ├── PPCGenRegisterInfo.inc │ │ ├── PPCGenSubtargetInfo.inc │ │ ├── PPCInstPrinter.c │ │ ├── PPCInstPrinter.h │ │ ├── PPCMapping.c │ │ ├── PPCMapping.h │ │ ├── PPCModule.c │ │ └── PPCPredicates.h │ └── X86 │ │ ├── X86ATTInstPrinter.c │ │ ├── X86BaseInfo.h │ │ ├── X86Disassembler.c │ │ ├── X86Disassembler.h │ │ ├── X86DisassemblerDecoder.c │ │ ├── X86DisassemblerDecoder.h │ │ ├── X86DisassemblerDecoderCommon.h │ │ ├── X86GenAsmWriter.inc │ │ ├── X86GenAsmWriter1.inc │ │ ├── X86GenAsmWriter1_reduce.inc │ │ ├── X86GenAsmWriter_reduce.inc │ │ ├── X86GenDisassemblerTables.inc │ │ ├── X86GenDisassemblerTables_reduce.inc │ │ ├── X86GenInstrInfo.inc │ │ ├── X86GenInstrInfo_reduce.inc │ │ ├── X86GenRegisterInfo.inc │ │ ├── X86InstPrinter.h │ │ ├── X86IntelInstPrinter.c │ │ ├── X86Mapping.c │ │ ├── X86Mapping.h │ │ └── X86Module.c ├── cs.c ├── cs_priv.h ├── include │ ├── arm.h │ ├── arm64.h │ ├── capstone.h │ ├── mips.h │ ├── platform.h │ ├── ppc.h │ ├── sparc.h │ ├── systemz.h │ ├── x86.h │ └── xcore.h ├── inttypes.h ├── myinttypes.h ├── osxkernel_inttypes.h ├── utils.c └── utils.h ├── createdmg ├── greenApple.icns ├── mach-o ├── arch.h ├── arm │ └── reloc.h ├── arm64 │ └── reloc.h ├── compact_unwind_encoding.h ├── fat.h ├── loader.h ├── nlist.h ├── ranlib.h ├── reloc.h ├── swap.h └── x86_64 │ └── reloc.h ├── mach └── machine.h ├── machoview.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── junzhan.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── junzhan.xcuserdatad │ └── xcschemes │ ├── MachOView.xcscheme │ └── xcschememanagement.plist ├── main.mm ├── redApple.icns └── stop.png /.gitignore: -------------------------------------------------------------------------------- 1 | .svn/* 2 | build/* 3 | English.lproj/.svn/all-wcprops 4 | English.lproj/.svn/entries 5 | English.lproj/.svn/text-base/InfoPlist.strings.svn-base 6 | English.lproj/.svn/text-base/Layout.xib.svn-base 7 | English.lproj/.svn/text-base/MainMenu.xib.svn-base 8 | English.lproj/.svn/text-base/Preferences.xib.svn-base 9 | mach-o/.svn/all-wcprops 10 | mach-o/.svn/entries 11 | mach-o/.svn/text-base/arch.h.svn-base 12 | mach-o/.svn/text-base/compact_unwind_encoding.h.svn-base 13 | mach-o/.svn/text-base/fat.h.svn-base 14 | mach-o/.svn/text-base/loader.h.svn-base 15 | mach-o/.svn/text-base/nlist.h.svn-base 16 | mach-o/.svn/text-base/ranlib.h.svn-base 17 | mach-o/.svn/text-base/reloc.h.svn-base 18 | mach-o/.svn/text-base/swap.h.svn-base 19 | mach-o/arm/.svn/all-wcprops 20 | mach-o/arm/.svn/entries 21 | mach-o/arm/.svn/text-base/reloc.h.svn-base 22 | mach-o/x86_64/.svn/all-wcprops 23 | mach-o/x86_64/.svn/entries 24 | mach-o/x86_64/.svn/text-base/reloc.h.svn-base 25 | machoview.xcodeproj/.svn/all-wcprops 26 | machoview.xcodeproj/.svn/entries 27 | machoview.xcodeproj/.svn/text-base/project.pbxproj.svn-base 28 | otool_disasm/.svn/all-wcprops 29 | otool_disasm/.svn/entries 30 | otool_disasm/.svn/text-base/arm_disasm.c.svn-base 31 | otool_disasm/.svn/text-base/arm_disasm.h.svn-base 32 | otool_disasm/.svn/text-base/bytesex.c.svn-base 33 | otool_disasm/.svn/text-base/i386_disasm.c.svn-base 34 | otool_disasm/.svn/text-base/i386_disasm.h.svn-base 35 | otool_disasm/.svn/text-base/ofile_print.h.svn-base 36 | otool_disasm/.svn/text-base/otool.h.svn-base 37 | otool_disasm/.svn/text-base/symbol.c.svn-base 38 | otool_disasm/disasm.xcodeproj/.svn/all-wcprops 39 | otool_disasm/disasm.xcodeproj/.svn/entries 40 | otool_disasm/disasm.xcodeproj/.svn/text-base/project.pbxproj.svn-base 41 | -------------------------------------------------------------------------------- /AppController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AppController.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 15/06/2010. 6 | * 7 | */ 8 | 9 | #import 10 | 11 | @class MVPreferenceController; 12 | 13 | @interface MVAppController : NSObject 14 | { 15 | MVPreferenceController * preferenceController; 16 | } 17 | 18 | - (IBAction)showPreferencePanel:(id)sender; 19 | - (IBAction)attach:(id)sender; 20 | 21 | @end 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ArchiveLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ArchiveLayout.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 18/03/2011. 6 | * 7 | */ 8 | 9 | #import "Layout.h" 10 | 11 | @interface MVObjectInfo : NSObject 12 | { 13 | NSString * name; 14 | uint32_t length; 15 | MVLayout * __weak layout; 16 | } 17 | 18 | @property (nonatomic) NSString * name; 19 | @property (nonatomic) uint32_t length; 20 | @property (nonatomic,weak) MVLayout * layout; 21 | 22 | @end 23 | 24 | @interface ArchiveLayout : MVLayout 25 | { 26 | NSMutableDictionary * objectInfoMap; // <(NSNumber)object offset,MVObjectInfo> 27 | } 28 | 29 | + (ArchiveLayout *) layoutWithDataController:(MVDataController *)dc rootNode:(MVNode *)node; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Attach.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Attach.h 3 | * MachOView 4 | * 5 | * Created by fG! on 08/09/13. 6 | * reverser@put.as 7 | * 8 | */ 9 | 10 | #ifndef machoview_Attach_h 11 | #define machoview_Attach_h 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | int64_t get_image_size(mach_vm_address_t address, pid_t pid, uint64_t *vmaddr_slide); 19 | kern_return_t find_main_binary(pid_t pid, mach_vm_address_t *main_address); 20 | kern_return_t dump_binary(mach_vm_address_t address, pid_t pid, uint8_t *buffer, uint64_t aslr_slide); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /Attach.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Attach.mm 3 | * MachOView 4 | * 5 | * Created by fG! on 08/09/13. 6 | * reverser@put.as 7 | * 8 | * Contains functions for the attach to process feature. 9 | * 10 | */ 11 | 12 | #include "Attach.h" 13 | 14 | #include 15 | 16 | /* local functions */ 17 | static kern_return_t readmem(mach_vm_offset_t *buffer, mach_vm_address_t address, mach_vm_size_t size, pid_t pid, vm_region_basic_info_data_64_t *info); 18 | 19 | #pragma mark Public functions 20 | 21 | /* 22 | * find main binary by iterating memory region 23 | * assumes there's only one binary with filetype == MH_EXECUTE 24 | */ 25 | kern_return_t 26 | find_main_binary(pid_t pid, mach_vm_address_t *main_address) 27 | { 28 | vm_map_t targetTask = 0; 29 | kern_return_t kr = 0; 30 | if (task_for_pid(mach_task_self(), pid, &targetTask)) 31 | { 32 | NSLog(@"[ERROR] Can't execute task_for_pid! Do you have the right permissions/entitlements?\n"); 33 | return KERN_FAILURE; 34 | } 35 | 36 | vm_address_t iter = 0; 37 | while (1) 38 | { 39 | struct mach_header mh = {0}; 40 | vm_address_t addr = iter; 41 | vm_size_t lsize = 0; 42 | uint32_t depth; 43 | mach_vm_size_t bytes_read = 0; 44 | struct vm_region_submap_info_64 info; 45 | mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; 46 | if (vm_region_recurse_64(targetTask, &addr, &lsize, &depth, (vm_region_info_t)&info, &count)) 47 | { 48 | break; 49 | } 50 | kr = mach_vm_read_overwrite(targetTask, (mach_vm_address_t)addr, (mach_vm_size_t)sizeof(struct mach_header), (mach_vm_address_t)&mh, &bytes_read); 51 | if (kr == KERN_SUCCESS && bytes_read == sizeof(struct mach_header)) 52 | { 53 | /* only one image with MH_EXECUTE filetype */ 54 | if ( (mh.magic == MH_MAGIC || mh.magic == MH_MAGIC_64) && mh.filetype == MH_EXECUTE) 55 | { 56 | #if DEBUG 57 | NSLog(@"Found main binary mach-o image @ %p!\n", (void*)addr); 58 | #endif 59 | *main_address = addr; 60 | break; 61 | } 62 | } 63 | iter = addr + lsize; 64 | } 65 | return KERN_SUCCESS; 66 | } 67 | 68 | /* 69 | * we need to find the binary file size 70 | * which is taken from the filesize field of each segment command 71 | * and not the vmsize (because of alignment) 72 | * if we dump using vmaddresses, we will get the alignment space into the dumped 73 | * binary and get into problems :-) 74 | */ 75 | int64_t 76 | get_image_size(mach_vm_address_t address, pid_t pid, uint64_t *vmaddr_slide) 77 | { 78 | vm_region_basic_info_data_64_t region_info = {0}; 79 | // allocate a buffer to read the header info 80 | // NOTE: this is not exactly correct since the 64bit version has an extra 4 bytes 81 | // but this will work for this purpose so no need for more complexity! 82 | struct mach_header header = {0}; 83 | if (readmem((mach_vm_offset_t*)&header, address, sizeof(struct mach_header), pid, ®ion_info)) 84 | { 85 | NSLog(@"Can't read header!"); 86 | return -1; 87 | } 88 | 89 | if (header.magic != MH_MAGIC && header.magic != MH_MAGIC_64) 90 | { 91 | printf("[ERROR] Target is not a mach-o binary!\n"); 92 | return -1; 93 | } 94 | 95 | int64_t imagefilesize = -1; 96 | /* read the load commands */ 97 | uint8_t *loadcmds = (uint8_t*)malloc(header.sizeofcmds); 98 | uint16_t mach_header_size = sizeof(struct mach_header); 99 | if (header.magic == MH_MAGIC_64) 100 | { 101 | mach_header_size = sizeof(struct mach_header_64); 102 | } 103 | if (readmem((mach_vm_offset_t*)loadcmds, address+mach_header_size, header.sizeofcmds, pid, ®ion_info)) 104 | { 105 | NSLog(@"Can't read load commands"); 106 | free(loadcmds); 107 | return -1; 108 | } 109 | 110 | /* process and retrieve address and size of linkedit */ 111 | uint8_t *loadCmdAddress = 0; 112 | loadCmdAddress = (uint8_t*)loadcmds; 113 | struct load_command *loadCommand = NULL; 114 | struct segment_command *segCmd = NULL; 115 | struct segment_command_64 *segCmd64 = NULL; 116 | for (uint32_t i = 0; i < header.ncmds; i++) 117 | { 118 | loadCommand = (struct load_command*)loadCmdAddress; 119 | if (loadCommand->cmd == LC_SEGMENT) 120 | { 121 | segCmd = (struct segment_command*)loadCmdAddress; 122 | if (strncmp(segCmd->segname, "__PAGEZERO", 16) != 0) 123 | { 124 | if (strncmp(segCmd->segname, "__TEXT", 16) == 0) 125 | { 126 | *vmaddr_slide = address - segCmd->vmaddr; 127 | } 128 | imagefilesize += segCmd->filesize; 129 | } 130 | } 131 | else if (loadCommand->cmd == LC_SEGMENT_64) 132 | { 133 | segCmd64 = (struct segment_command_64*)loadCmdAddress; 134 | if (strncmp(segCmd64->segname, "__PAGEZERO", 16) != 0) 135 | { 136 | if (strncmp(segCmd64->segname, "__TEXT", 16) == 0) 137 | { 138 | *vmaddr_slide = address - segCmd64->vmaddr; 139 | } 140 | imagefilesize += segCmd64->filesize; 141 | } 142 | } 143 | // advance to next command 144 | loadCmdAddress += loadCommand->cmdsize; 145 | } 146 | free(loadcmds); 147 | return imagefilesize; 148 | } 149 | 150 | /* 151 | * dump the binary into the allocated buffer 152 | * we dump each segment and advance the buffer 153 | */ 154 | kern_return_t 155 | dump_binary(mach_vm_address_t address, pid_t pid, uint8_t *buffer, uint64_t aslr_slide) 156 | { 157 | vm_region_basic_info_data_64_t region_info = {0}; 158 | // allocate a buffer to read the header info 159 | // NOTE: this is not exactly correct since the 64bit version has an extra 4 bytes 160 | // but this will work for this purpose so no need for more complexity! 161 | struct mach_header header = {0}; 162 | if (readmem((mach_vm_offset_t*)&header, address, sizeof(struct mach_header), pid, ®ion_info)) 163 | { 164 | NSLog(@"Can't read header!"); 165 | return KERN_FAILURE; 166 | } 167 | 168 | if (header.magic != MH_MAGIC && header.magic != MH_MAGIC_64) 169 | { 170 | printf("[ERROR] Target is not a mach-o binary!\n"); 171 | exit(1); 172 | } 173 | 174 | // read the header info to find the LINKEDIT 175 | uint8_t *loadcmds = (uint8_t*)malloc(header.sizeofcmds); 176 | 177 | uint16_t mach_header_size = sizeof(struct mach_header); 178 | if (header.magic == MH_MAGIC_64) 179 | { 180 | mach_header_size = sizeof(struct mach_header_64); 181 | } 182 | // retrieve the load commands 183 | if (readmem((mach_vm_offset_t*)loadcmds, address+mach_header_size, header.sizeofcmds, pid, ®ion_info)) 184 | { 185 | NSLog(@"Can't read load commands"); 186 | return KERN_FAILURE; 187 | } 188 | 189 | // process and retrieve address and size of linkedit 190 | uint8_t *loadCmdAddress = 0; 191 | loadCmdAddress = (uint8_t*)loadcmds; 192 | struct load_command *loadCommand = NULL; 193 | struct segment_command *segCmd = NULL; 194 | struct segment_command_64 *segCmd64 = NULL; 195 | for (uint32_t i = 0; i < header.ncmds; i++) 196 | { 197 | loadCommand = (struct load_command*)loadCmdAddress; 198 | if (loadCommand->cmd == LC_SEGMENT) 199 | { 200 | segCmd = (struct segment_command*)loadCmdAddress; 201 | if (strncmp(segCmd->segname, "__PAGEZERO", 16) != 0) 202 | { 203 | #if DEBUG 204 | printf("[DEBUG] Dumping %s at %llx with size %x (buffer:%x)\n", segCmd->segname, segCmd->vmaddr+aslr_slide, segCmd->filesize, (uint32_t)*buffer); 205 | #endif 206 | readmem((mach_vm_offset_t*)buffer, segCmd->vmaddr+aslr_slide, segCmd->filesize, pid, ®ion_info); 207 | } 208 | buffer += segCmd->filesize; 209 | } 210 | else if (loadCommand->cmd == LC_SEGMENT_64) 211 | { 212 | segCmd64 = (struct segment_command_64*)loadCmdAddress; 213 | if (strncmp(segCmd64->segname, "__PAGEZERO", 16) != 0) 214 | { 215 | #if DEBUG 216 | printf("[DEBUG] Dumping %s at %llx with size %llx (buffer:%x)\n", segCmd64->segname, segCmd64->vmaddr+aslr_slide, segCmd64->filesize, (uint32_t)*buffer); 217 | #endif 218 | readmem((mach_vm_offset_t*)buffer, segCmd64->vmaddr+aslr_slide, segCmd64->filesize, pid, ®ion_info); 219 | } 220 | buffer += segCmd64->filesize; 221 | } 222 | // advance to next command 223 | loadCmdAddress += loadCommand->cmdsize; 224 | } 225 | free(loadcmds); 226 | return KERN_SUCCESS; 227 | } 228 | 229 | #pragma mark Local functions 230 | 231 | static kern_return_t 232 | readmem(mach_vm_offset_t *buffer, mach_vm_address_t address, mach_vm_size_t size, pid_t pid, vm_region_basic_info_data_64_t *info) 233 | { 234 | // get task for pid 235 | vm_map_t port; 236 | 237 | kern_return_t kr; 238 | //#if DEBUG 239 | // printf("[DEBUG] Readmem of address %llx to buffer %llx with size %llx\n", address, buffer, size); 240 | //#endif 241 | if (task_for_pid(mach_task_self(), pid, &port)) 242 | { 243 | fprintf(stderr, "[ERROR] Can't execute task_for_pid! Do you have the right permissions/entitlements?\n"); 244 | return KERN_FAILURE; 245 | } 246 | 247 | mach_msg_type_number_t info_cnt = sizeof (vm_region_basic_info_data_64_t); 248 | mach_port_t object_name; 249 | mach_vm_size_t size_info; 250 | mach_vm_address_t address_info = address; 251 | kr = mach_vm_region(port, &address_info, &size_info, VM_REGION_BASIC_INFO_64, (vm_region_info_t)info, &info_cnt, &object_name); 252 | if (kr) 253 | { 254 | fprintf(stderr, "[ERROR] mach_vm_region failed with error %d\n", (int)kr); 255 | return KERN_FAILURE; 256 | } 257 | 258 | /* read memory - vm_read_overwrite because we supply the buffer */ 259 | mach_vm_size_t nread; 260 | kr = mach_vm_read_overwrite(port, address, size, (mach_vm_address_t)buffer, &nread); 261 | if (kr) 262 | { 263 | fprintf(stderr, "[ERROR] vm_read failed! %d\n", kr); 264 | return KERN_FAILURE; 265 | } 266 | else if (nread != size) 267 | { 268 | fprintf(stderr, "[ERROR] vm_read failed! requested size: 0x%llx read: 0x%llx\n", size, nread); 269 | return KERN_FAILURE; 270 | } 271 | return KERN_SUCCESS; 272 | } 273 | -------------------------------------------------------------------------------- /CRTFootPrints.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CRTFootPrints.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 25/11/2010. 6 | * 7 | */ 8 | 9 | 10 | #import "MachOLayout.h" 11 | 12 | #define FOOTPRINT_STRIDE 16 13 | #define GAP(x) {00, x} // fake entry with zero length, second element is the size of bytes to skip 14 | 15 | typedef uint8_t AsmFootPrint[][FOOTPRINT_STRIDE]; 16 | 17 | @interface MachOLayout (CRTFootPrints) 18 | 19 | - (bool) matchAsmAtOffset:(uint32_t)offset 20 | asmFootPrint:(const AsmFootPrint)footprint 21 | lineCount:(NSUInteger)lineCount; 22 | 23 | - (void) determineRuntimeVersion; 24 | 25 | @end 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Common.h 3 | * MachOView 4 | * 5 | * Created by Peter Saghelyi on 10/09/2011. 6 | * 7 | */ 8 | 9 | 10 | //#define MV_NO_MULTITHREAD 11 | //#define MV_NO_ARCHIVER 12 | //#define MV_STATISTICS 13 | 14 | extern NSCondition * pipeCondition; 15 | extern int32_t numIOThread; 16 | extern int64_t nrow_total; // number of rows (loaded and empty) 17 | extern int64_t nrow_loaded; // number of loaded rows 18 | 19 | #define NSSTRING(C_STR) [NSString stringWithCString: (char *)(C_STR) encoding: [NSString defaultCStringEncoding]] 20 | #define CSTRING(NS_STR) [(NS_STR) cStringUsingEncoding: [NSString defaultCStringEncoding]] 21 | 22 | #define N_ELEMENTS(ARR) (sizeof(ARR)/sizeof(*(ARR))) 23 | #define FIRST_ELEM(ARR) (&(ARR)[0]) 24 | #define LAST_ELEM(ARR) (&(ARR)[N_ELEMENTS(ARR)-1]) -------------------------------------------------------------------------------- /DataController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DataController.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 15/06/2010. 6 | * 7 | */ 8 | 9 | #define OFFSET_COLUMN 0 10 | #define DATA_COLUMN 1 // use this with details 11 | #define DESCRIPTION_COLUMN 2 // use this with details 12 | #define VALUE_COLUMN 3 13 | 14 | #define DATA_LO_COLUMN 1 // use this with no details 15 | #define DATA_HI_COLUMN 2 // use this with no details 16 | 17 | extern NSString * const MVUnderlineAttributeName; 18 | extern NSString * const MVCellColorAttributeName; 19 | extern NSString * const MVTextColorAttributeName; 20 | extern NSString * const MVMetaDataAttributeName; 21 | 22 | extern NSString * const MVLayoutUserInfoKey; 23 | extern NSString * const MVNodeUserInfoKey; 24 | extern NSString * const MVStatusUserInfoKey; 25 | 26 | extern NSString * const MVDataTreeWillChangeNotification; 27 | extern NSString * const MVDataTreeDidChangeNotification; 28 | extern NSString * const MVDataTreeChangedNotification; 29 | extern NSString * const MVDataTableChangedNotification; 30 | extern NSString * const MVThreadStateChangedNotification; 31 | 32 | extern NSString * const MVStatusTaskStarted; 33 | extern NSString * const MVStatusTaskTerminated; 34 | 35 | struct MVNodeSaver; 36 | 37 | @protocol MVSerializing 38 | - (void)loadFromFile:(FILE *)pFile; 39 | - (void)saveToFile:(FILE *)pFile; 40 | - (void)clear; 41 | @end 42 | 43 | //---------------------------------------------------------------------------- 44 | @interface MVColoumns : NSObject 45 | { 46 | NSString * offsetStr; 47 | NSString * dataStr; 48 | NSString * descriptionStr; 49 | NSString * valueStr; 50 | } 51 | 52 | @property (nonatomic) NSString * offsetStr; 53 | @property (nonatomic) NSString * dataStr; 54 | @property (nonatomic) NSString * descriptionStr; 55 | @property (nonatomic) NSString * valueStr; 56 | 57 | +(MVColoumns *) coloumnsWithData:(NSString *)col0 :(NSString *)col1 :(NSString *)col2 :(NSString *)col3; 58 | 59 | @end 60 | 61 | //---------------------------------------------------------------------------- 62 | @interface MVRow : NSObject 63 | { 64 | MVColoumns * coloumns; 65 | NSDictionary * attributes; 66 | uint32_t offset; // for sorting if necessary 67 | uint32_t coloumnsOffset; // offset of coloumns 68 | uint32_t attributesOffset; // offset of attribues 69 | BOOL deleted; 70 | BOOL dirty; // eg. attributes has changed 71 | } 72 | 73 | @property (nonatomic) NSDictionary * attributes; 74 | @property (nonatomic) MVColoumns * coloumns; 75 | @property (nonatomic) uint32_t offset; 76 | @property (nonatomic) BOOL deleted; 77 | @property (nonatomic) BOOL dirty; 78 | 79 | -(NSString *)coloumnAtIndex:(NSUInteger)index; 80 | 81 | @end 82 | 83 | @class MVArchiver; 84 | 85 | //---------------------------------------------------------------------------- 86 | @interface MVTable : NSObject 87 | { 88 | NSMutableArray * rows; // array of MVRow * (host of all the rows) 89 | NSMutableArray * displayRows; // array of MVRow * (rows filtered by search criteria) 90 | MVArchiver * __weak archiver; 91 | FILE * swapFile; 92 | NSLock * tableLock; 93 | } 94 | 95 | @property (nonatomic) FILE * swapFile; 96 | 97 | - (NSUInteger) rowCountToDisplay; 98 | - (MVRow *) getRowToDisplay:(NSUInteger)rowIndex; 99 | 100 | - (void) popRow; 101 | - (void) appendRow:(id)col0 :(id)col1 :(id)col2 :(id)col3; 102 | - (void) insertRowWithOffset:(uint32_t)offset :(id)col0 :(id)col1 :(id)col2 :(id)col3; 103 | - (void) updateCellContentTo:(id)object atRow:(NSUInteger)rowIndex andCol:(NSUInteger)colIndex; 104 | 105 | - (NSUInteger) rowCount; 106 | - (void) setAttributes:(NSString *)firstArg, ... NS_REQUIRES_NIL_TERMINATION; 107 | - (void) setAttributesForRowIndex:(NSUInteger)index :(NSString *)firstArg, ... NS_REQUIRES_NIL_TERMINATION; 108 | - (void) setAttributesFromRowIndex:(NSUInteger)index :(NSString *)firstArg, ... NS_REQUIRES_NIL_TERMINATION; 109 | 110 | @end 111 | 112 | //---------------------------------------------------------------------------- 113 | @interface MVNode : NSObject 114 | { 115 | NSString * caption; 116 | MVNode * __weak parent; 117 | NSMutableArray * children; 118 | NSRange dataRange; 119 | MVTable * details; 120 | NSMutableDictionary * userInfo; 121 | uint32_t detailsOffset; 122 | } 123 | 124 | @property (nonatomic) NSString * caption; 125 | @property (nonatomic,weak) MVNode * parent; 126 | @property (nonatomic) NSRange dataRange; 127 | @property (nonatomic) MVTable * details; 128 | @property (nonatomic) NSMutableDictionary * userInfo; 129 | @property (nonatomic) uint32_t detailsOffset; 130 | 131 | - (NSUInteger) numberOfChildren; 132 | - (MVNode *) childAtIndex:(NSUInteger)n; 133 | - (MVNode *) insertChild:(NSString *)_caption location:(uint32_t)location length:(uint32_t)length; 134 | - (MVNode *) insertChildWithDetails:(NSString *)_caption location:(uint32_t)location length:(uint32_t)length saver:(MVNodeSaver &)saver; 135 | - (MVNode *) findNodeByUserInfo:(NSDictionary *)uinfo; 136 | - (void) openDetails; // open swap file for reading details on demand 137 | - (void) closeDetails; // close swap file 138 | - (void) sortDetails; 139 | - (void) filterDetails:(NSString *)filter; 140 | - (void) loadFromFile:(FILE *)pFile; 141 | - (void) saveToFile:(FILE *)pFile; 142 | 143 | @end 144 | 145 | //---------------------------------------------------------------------------- 146 | @interface MVDataController : NSObject 147 | { 148 | NSString * fileName; // path to the binary handled by this data controller 149 | NSMutableData * fileData; // content of the binary 150 | NSMutableData * realData; // patched content by relocs and bindings 151 | NSMutableArray * layouts; 152 | MVNode * rootNode; 153 | MVNode * __weak selectedNode; 154 | NSLock * treeLock; // semaphore for the node tree 155 | } 156 | 157 | @property (nonatomic) NSString * fileName; 158 | @property (nonatomic) NSMutableData * fileData; 159 | @property (nonatomic) NSMutableData * realData; 160 | @property (nonatomic,readonly) NSArray * layouts; 161 | @property (nonatomic,readonly) MVNode * rootNode; 162 | @property (nonatomic,weak) MVNode * selectedNode; 163 | @property (nonatomic,readonly) NSLock * treeLock; 164 | 165 | -(NSString *) getMachine:(cpu_type_t)cputype; 166 | -(NSString *) getARMCpu:(cpu_subtype_t)cpusubtype; 167 | 168 | - (void) createLayouts:(MVNode *)parent location:(uint32_t)location length:(uint32_t)length; 169 | - (void) updateTreeView: (MVNode *)node; 170 | - (void) updateTableView; 171 | - (void) updateStatus: (NSString *)status; 172 | 173 | @end 174 | 175 | //---------------------------------------------------------------------------- 176 | @interface MVArchiver : NSObject 177 | { 178 | NSString * swapPath; 179 | NSMutableArray * objectsToSave; // conforms MVSerializing 180 | NSThread * saverThread; 181 | NSLock * saverLock; 182 | } 183 | 184 | @property (nonatomic,readonly) NSString * swapPath; 185 | 186 | +(MVArchiver *) archiverWithPath:(NSString *)path; 187 | -(void) addObjectToSave:(id)object; 188 | -(void) suspend; 189 | -(void) resume; 190 | -(void) halt; 191 | 192 | @end 193 | 194 | //---------------------------------------------------------------------------- 195 | struct MVNodeSaver 196 | { 197 | MVNodeSaver(); 198 | ~MVNodeSaver(); 199 | 200 | void setNode(MVNode * node) { m_node = node; } 201 | 202 | private: 203 | MVNodeSaver(MVNodeSaver const &); 204 | MVNodeSaver & operator=(MVNodeSaver const &); 205 | 206 | MVNode * __weak m_node; 207 | }; 208 | 209 | 210 | -------------------------------------------------------------------------------- /DataSources.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSources.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 15/06/2010. 6 | * 7 | */ 8 | 9 | extern NSString * const MVScannerErrorMessage; 10 | 11 | @interface MVDataSourceTree : NSObject; 12 | @end 13 | 14 | 15 | @interface MVDataSourceDetails : NSObject; 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Document.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Document.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 15/06/2010. 6 | * 7 | */ 8 | 9 | @class MVDataController; 10 | 11 | @interface MVOutlineView : NSOutlineView 12 | { 13 | } 14 | @end 15 | 16 | @interface MVTableView : NSTableView 17 | { 18 | } 19 | @end 20 | 21 | @interface MVRightFormatter : NSFormatter 22 | { 23 | BOOL compound; // NO: plain hex; YES: groups of bytes (11 22 33 44 55) 24 | NSUInteger length; // size of hex value; number of bytes 25 | BOOL alignLeft; // NO: 12 --> 0012 YES: 12 --> 1200 26 | } 27 | @end 28 | 29 | 30 | @interface MVDocument : NSDocument 31 | { 32 | IBOutlet MVOutlineView * leftView; 33 | IBOutlet MVTableView * rightView; 34 | IBOutlet NSSearchField * searchField; 35 | IBOutlet NSTextField * statusText; 36 | IBOutlet NSProgressIndicator * progressIndicator; 37 | IBOutlet NSSegmentedControl * offsetModeSwitch; 38 | IBOutlet NSButton * stopButton; 39 | MVDataController * dataController; 40 | int32_t threadCount; 41 | } 42 | @property (nonatomic,readonly) MVDataController * dataController; 43 | 44 | - (IBAction)updateSearchFilter:(id)sender; 45 | - (IBAction)updateAddressingMode:(id)sender; 46 | - (IBAction)stopProcessing:(id)sender; 47 | - (BOOL)isRVA; 48 | 49 | + (NSString *)temporaryDirectory; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DyldInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DyldInfo.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 21/09/2010. 6 | * 7 | */ 8 | 9 | #import "MachOLayout.h" 10 | 11 | 12 | @interface DyldHelper : NSObject 13 | { 14 | NSMutableDictionary * externalMap; // external symbol name --> symbols index (negative number) 15 | } 16 | 17 | +(DyldHelper *) dyldHelperWithSymbols:(NSDictionary *)symbolNames is64Bit:(bool)is64Bit; 18 | 19 | @end 20 | 21 | 22 | @interface MachOLayout (DyldInfo) 23 | 24 | enum BindNodeType {NodeTypeBind, NodeTypeWeakBind, NodeTypeLazyBind}; 25 | 26 | - (MVNode *)createRebaseNode:(MVNode *)parent 27 | caption:(NSString *)caption 28 | location:(uint32_t)location 29 | length:(uint32_t)length 30 | baseAddress:(uint64_t)baseAddress; 31 | 32 | - (MVNode *)createBindingNode:(MVNode *)parent 33 | caption:(NSString *)caption 34 | location:(uint32_t)location 35 | length:(uint32_t)length 36 | baseAddress:(uint64_t)baseAddress 37 | nodeType:(BindNodeType)nodeType 38 | dyldHelper:(DyldHelper *)helper; 39 | 40 | - (MVNode *)createExportNode:(MVNode *)parent 41 | caption:(NSString *)caption 42 | location:(uint32_t)location 43 | length:(uint32_t)length 44 | baseAddress:(uint64_t)baseAddress; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /English.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Menlo-Regular;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\vieww9600\viewh8400\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 6 | 7 | \f0\b\fs24 \cf0 Engineering: 8 | \b0 \ 9 | Peter Saghelyi\ 10 | 11 | \f1\fs22 \CocoaLigature0 fG! 12 | \f0\fs24 \CocoaLigature1 \ 13 | \ 14 | 15 | \b Human Interface Design: 16 | \b0 \ 17 | ...\ 18 | \ 19 | 20 | \b Testing: 21 | \b0 \ 22 | ...\ 23 | \ 24 | 25 | \b Documentation: 26 | \b0 \ 27 | ...\ 28 | } -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /English.lproj/Preferences.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Exceptions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Exceptions.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 20/07/2010. 6 | * 7 | */ 8 | 9 | #import "MachOLayout.h" 10 | 11 | @interface MachOLayout (Exceptions) 12 | 13 | - (MVNode *)createCFINode:(MVNode *)parent 14 | caption:(NSString *)caption 15 | location:(uint32_t)location 16 | length:(uint32_t)length; 17 | 18 | 19 | - (MVNode *)createLSDANode:(MVNode *)parent 20 | caption:(NSString *)caption 21 | location:(uint32_t)location 22 | length:(uint32_t)length 23 | eh_frame_begin:(uint64_t)eh_frame_begin; 24 | 25 | - (MVNode *)createUnwindInfoHeaderNode:(MVNode *)parent 26 | caption:(NSString *)caption 27 | location:(uint32_t)location 28 | header:(struct unwind_info_section_header const *)unwind_info_section_header; 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /FatLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FatLayout.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 02/12/2011. 6 | * 7 | */ 8 | 9 | #import "Layout.h" 10 | 11 | @interface FatLayout : MVLayout; 12 | 13 | + (FatLayout *) layoutWithDataController:(MVDataController *)dc rootNode:(MVNode *)node; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /FatLayout.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * FatLayout.mm 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 02/12/2011. 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #import "Common.h" 16 | #import "FatLayout.h" 17 | #import "DataController.h" 18 | #import "MachOLayout.h" 19 | #import "ReadWrite.h" 20 | 21 | using namespace std; 22 | 23 | //============================================================================ 24 | @implementation FatLayout 25 | 26 | //----------------------------------------------------------------------------- 27 | - (id)initWithDataController:(MVDataController *)dc rootNode:(MVNode *)node 28 | { 29 | if (self = [super initWithDataController:dc rootNode:node]) 30 | { 31 | //further initialisations 32 | } 33 | return self; 34 | } 35 | 36 | //----------------------------------------------------------------------------- 37 | + (FatLayout *)layoutWithDataController:(MVDataController *)dc rootNode:(MVNode *)node 38 | { 39 | return [[FatLayout alloc] initWithDataController:dc rootNode:node]; 40 | } 41 | 42 | //---------------------------------------------------------------------------- 43 | - (MVNode *)createHeaderNode:(MVNode *)parent 44 | caption:(NSString *)caption 45 | location:(uint32_t)location 46 | fat_header:(struct fat_header const *)fat_header 47 | { 48 | MVNodeSaver nodeSaver; 49 | MVNode * node = [parent insertChildWithDetails:caption 50 | location:location 51 | length:sizeof(struct fat_header) + fat_header->nfat_arch * sizeof(struct fat_arch) 52 | saver:nodeSaver]; 53 | 54 | NSRange range = NSMakeRange(location,0); 55 | NSString * lastReadHex; 56 | 57 | uint32_t magic = [dataController read_uint32:range lastReadHex:&lastReadHex]; 58 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 59 | :lastReadHex 60 | :@"Magic Number" 61 | :magic == FAT_MAGIC ? @"FAT_MAGIC" : 62 | magic == FAT_CIGAM ? @"FAT_CIGAM" : @"???"]; 63 | 64 | [node.details setAttributes:MVCellColorAttributeName,[NSColor greenColor],nil]; 65 | 66 | [dataController read_uint32:range lastReadHex:&lastReadHex]; 67 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 68 | :lastReadHex 69 | :@"Number of Architecture" 70 | :[NSString stringWithFormat:@"%u",fat_header->nfat_arch]]; 71 | 72 | [node.details setAttributes:MVCellColorAttributeName,[NSColor greenColor], 73 | MVUnderlineAttributeName,@"YES",nil]; 74 | 75 | for (uint32_t nimg = 0; nimg < fat_header->nfat_arch; ++nimg) 76 | { 77 | // need to make copy for byte swapping 78 | struct fat_arch fat_arch; 79 | [dataController.fileData getBytes:&fat_arch range:NSMakeRange(NSMaxRange(range), sizeof(struct fat_arch))]; 80 | swap_fat_arch(&fat_arch, 1, NX_LittleEndian); 81 | 82 | [dataController read_uint32:range lastReadHex:&lastReadHex]; 83 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 84 | :lastReadHex 85 | :@"CPU Type" 86 | :fat_arch.cputype == CPU_TYPE_ANY ? @"CPU_TYPE_ANY" : 87 | fat_arch.cputype == CPU_TYPE_I386 ? @"CPU_TYPE_I386" : 88 | fat_arch.cputype == CPU_TYPE_X86_64 ? @"CPU_TYPE_X86_64" : 89 | fat_arch.cputype == CPU_TYPE_ARM ? @"CPU_TYPE_ARM" : 90 | fat_arch.cputype == CPU_TYPE_ARM64 ? @"CPU_TYPE_ARM64" : 91 | fat_arch.cputype == CPU_TYPE_POWERPC ? @"CPU_TYPE_POWERPC" : 92 | fat_arch.cputype == CPU_TYPE_POWERPC64 ? @"CPU_TYPE_POWERPC64" : 93 | @"???"]; 94 | 95 | [dataController read_uint32:range lastReadHex:&lastReadHex]; 96 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 97 | :lastReadHex 98 | :@"CPU SubType" 99 | :fat_arch.cputype == CPU_TYPE_POWERPC ? 100 | ((fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_ALL ? @"CPU_SUBTYPE_POWERPC_ALL" : 101 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_601 ? @"CPU_SUBTYPE_POWERPC_601" : 102 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_602 ? @"CPU_SUBTYPE_POWERPC_602" : 103 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_603 ? @"CPU_SUBTYPE_POWERPC_603" : 104 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_603e ? @"CPU_SUBTYPE_POWERPC_603e" : 105 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_603ev ? @"CPU_SUBTYPE_POWERPC_603ev" : 106 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_604 ? @"CPU_SUBTYPE_POWERPC_604" : 107 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_604e ? @"CPU_SUBTYPE_POWERPC_604e" : 108 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_620 ? @"CPU_SUBTYPE_POWERPC_620" : 109 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_750 ? @"CPU_SUBTYPE_POWERPC_750" : 110 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_7400 ? @"CPU_SUBTYPE_POWERPC_7400" : 111 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_7450 ? @"CPU_SUBTYPE_POWERPC_7450" : 112 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_POWERPC_970 ? @"CPU_SUBTYPE_POWERPC_970" : @"???") : 113 | fat_arch.cputype == CPU_TYPE_ARM ? 114 | ((fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_ALL ? @"CPU_SUBTYPE_ARM_ALL" : 115 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V4T ? @"CPU_SUBTYPE_ARM_V4T" : 116 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V6 ? @"CPU_SUBTYPE_ARM_V6" : 117 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V5TEJ ? @"CPU_SUBTYPE_ARM_V5TEJ" : 118 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_XSCALE ? @"CPU_SUBTYPE_ARM_XSCALE" : 119 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V7 ? @"CPU_SUBTYPE_ARM_V7" : 120 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V7F ? @"CPU_SUBTYPE_ARM_V7F" : 121 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V7S ? @"CPU_SUBTYPE_ARM_V7S" : 122 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V7K ? @"CPU_SUBTYPE_ARM_V7K" : 123 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V6M ? @"CPU_SUBTYPE_ARM_V6M" : 124 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V7M ? @"CPU_SUBTYPE_ARM_V7M" : 125 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V7EM ? @"CPU_SUBTYPE_ARM_V7EM" : 126 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM_V8 ? @"CPU_SUBTYPE_ARM_V8" : @"???") : 127 | fat_arch.cputype == CPU_TYPE_ARM64 ? 128 | ((fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64_ALL ? @"CPU_SUBTYPE_ARM64_ALL" : 129 | (fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64_V8 ? @"CPU_SUBTYPE_ARM64_V8" : @"???") : 130 | fat_arch.cputype == CPU_TYPE_I386 ? 131 | ((fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_I386_ALL ? @"CPU_SUBTYPE_I386_ALL" : @"???") : 132 | fat_arch.cputype == CPU_TYPE_X86_64 ? 133 | ((fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_X86_64_ALL ? @"CPU_SUBTYPE_X86_64_ALL" : @"???") : 134 | @"???"]; 135 | 136 | [dataController read_uint32:range lastReadHex:&lastReadHex]; 137 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 138 | :lastReadHex 139 | :@"Offset" 140 | :[NSString stringWithFormat:@"%u",fat_arch.offset]]; 141 | 142 | [dataController read_uint32:range lastReadHex:&lastReadHex]; 143 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 144 | :lastReadHex 145 | :@"Size" 146 | :[NSString stringWithFormat:@"%u",fat_arch.size]]; 147 | 148 | [dataController read_uint32:range lastReadHex:&lastReadHex]; 149 | [node.details appendRow:[NSString stringWithFormat:@"%.8lX", range.location] 150 | :lastReadHex 151 | :@"Align" 152 | :[NSString stringWithFormat:@"%u",(1 << fat_arch.align)]]; 153 | 154 | [node.details setAttributes:MVUnderlineAttributeName,@"YES",nil]; 155 | } 156 | 157 | return node; 158 | } 159 | 160 | //---------------------------------------------------------------------------- 161 | - (void)doMainTasks 162 | { 163 | struct fat_header fat_header; 164 | [dataController.fileData getBytes:&fat_header length:sizeof(struct fat_header)]; 165 | 166 | if (fat_header.magic == FAT_CIGAM) 167 | { 168 | swap_fat_header(&fat_header, NX_LittleEndian); 169 | } 170 | 171 | [self createHeaderNode:rootNode 172 | caption:@"Fat Header" 173 | location:imageOffset 174 | fat_header:&fat_header]; 175 | 176 | [super doMainTasks]; 177 | } 178 | 179 | @end 180 | 181 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBuildDate 6 | Thu Mar 21 20:13:01 CST 2019 7 | CFBuildNumber 8 | 9132 9 | CFBundleDevelopmentRegion 10 | English 11 | CFBundleDocumentTypes 12 | 13 | 14 | CFBundleTypeExtensions 15 | 16 | * 17 | 18 | CFBundleTypeName 19 | Mach-O Binaries 20 | CFBundleTypeRole 21 | Editor 22 | LSHandlerRank 23 | Alternate 24 | NSDocumentClass 25 | MVDocument 26 | NSPersistentStoreTypeKey 27 | Binary 28 | 29 | 30 | CFBundleExecutable 31 | ${EXECUTABLE_NAME} 32 | CFBundleIconFile 33 | redApple.icns 34 | CFBundleIdentifier 35 | ${PRODUCT_NAME:rfc1034identifier} 36 | CFBundleInfoDictionaryVersion 37 | 6.0 38 | CFBundleName 39 | ${PRODUCT_NAME} fG!'s branch 40 | CFBundlePackageType 41 | APPL 42 | CFBundleShortVersionString 43 | 2.4 44 | CFBundleSignature 45 | ???? 46 | CFBundleVersion 47 | 9132 48 | LSApplicationCategoryType 49 | public.app-category.developer-tools 50 | LSMinimumSystemVersion 51 | ${MACOSX_DEPLOYMENT_TARGET} 52 | NSMainNibFile 53 | MainMenu 54 | NSPrincipalClass 55 | NSApplication 56 | SecTaskAccess 57 | 58 | allowed 59 | debug 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Layout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Layout.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 18/03/2011. 6 | * 7 | */ 8 | 9 | 10 | #define MATCH_STRUCT(obj,location) \ 11 | struct obj const * obj = (struct obj *)[self imageAt:(location)]; \ 12 | if (!obj) [NSException raise:@"null exception" format:@#obj " is null"]; 13 | 14 | @class MVDataController; 15 | @class MVArchiver; 16 | @class MVNode; 17 | 18 | 19 | @interface MVLayout : NSObject 20 | { 21 | MVNode * __weak rootNode; 22 | MVDataController * __weak dataController; 23 | uint32_t imageOffset; // absolute physical offset of the image in binary 24 | uint32_t imageSize; // size of the image corresponds to this layout 25 | NSThread * backgroundThread; 26 | MVArchiver * archiver; 27 | } 28 | 29 | @property(nonatomic,weak,readonly) MVDataController * dataController; 30 | @property(nonatomic,readonly) NSThread * backgroundThread; 31 | @property(nonatomic,readonly) MVArchiver * archiver; 32 | 33 | - (id) initWithDataController:(MVDataController *)dc rootNode:(MVNode *)node; 34 | - (void const *) imageAt:(uint32_t)location; 35 | - (void) printException:(NSException *)exception caption:(NSString *)caption; 36 | - (BOOL) is64bit; 37 | - (void) doMainTasks; 38 | - (void) doBackgroundTasks; 39 | - (NSString *) convertToRVA: (NSString *)offsetStr; 40 | - (MVNode *) findNodeByUserInfo:(NSDictionary *)userInfo; 41 | 42 | - (MVNode *) createDataNode:(MVNode *)parent 43 | caption:(NSString *)caption 44 | location:(uint32_t)location 45 | length:(uint32_t)length; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Layout.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Layout.mm 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 18/03/2011. 6 | * 7 | */ 8 | 9 | #import "Common.h" 10 | #import "Document.h" 11 | #import "DataController.h" 12 | #import "Layout.h" 13 | 14 | //============================================================================ 15 | @implementation MVLayout 16 | 17 | @synthesize dataController, backgroundThread, archiver; 18 | 19 | /* 20 | - (void)dealloc 21 | { 22 | NSLog(@"********MVLayout deallocated: %@", self); 23 | } 24 | */ 25 | 26 | //----------------------------------------------------------------------------- 27 | - (id)init 28 | { 29 | NSAssert(NO, @"plain init is not allowed"); 30 | return nil; 31 | } 32 | 33 | //----------------------------------------------------------------------------- 34 | - (id)initWithDataController:(MVDataController *)dc rootNode:(MVNode *)node 35 | { 36 | if (self = [super init]) 37 | { 38 | dataController = dc; 39 | rootNode = node; 40 | imageOffset = node.dataRange.location; 41 | imageSize = node.dataRange.length; 42 | backgroundThread = [[NSThread alloc] initWithTarget:self selector:@selector(doBackgroundTasks) object:nil]; 43 | 44 | const char *tmp = [[MVDocument temporaryDirectory] UTF8String]; 45 | char *swapFilePath = strdup(tmp); 46 | if (mktemp(swapFilePath) == NULL) 47 | { 48 | NSLog(@"mktemp failed!"); 49 | free(swapFilePath); 50 | return NO; 51 | } 52 | 53 | NSString *swapPath = [NSString stringWithFormat:@"%s.%@", swapFilePath, [[dataController fileName] lastPathComponent]]; 54 | free(swapFilePath); 55 | archiver = [MVArchiver archiverWithPath:swapPath]; 56 | } 57 | return self; 58 | } 59 | 60 | //----------------------------------------------------------------------------- 61 | - (void const *)imageAt:(uint32_t)location 62 | { 63 | auto p = (uint8_t const *)[dataController.realData bytes]; 64 | return p ? p + location : NULL; 65 | } 66 | 67 | //----------------------------------------------------------------------------- 68 | - (NSString *)description 69 | { 70 | return [[super description] stringByAppendingFormat:@" [%@]",rootNode.caption]; 71 | } 72 | 73 | //----------------------------------------------------------------------------- 74 | -(void)printException:(NSException *)exception caption:(NSString *)caption 75 | { 76 | @synchronized([NSApp class]) 77 | { 78 | NSLog(@"%@: Exception (%@): %@", self, caption, [exception name]); 79 | NSLog(@" Reason: %@", [exception reason]); 80 | NSLog(@" User Info: %@", [exception userInfo]); 81 | NSLog(@" Backtrace:\n%@", [exception callStackSymbols]); 82 | } 83 | } 84 | 85 | //----------------------------------------------------------------------------- 86 | - (BOOL)is64bit 87 | { 88 | return NO; 89 | } 90 | 91 | //----------------------------------------------------------------------------- 92 | - (void)doMainTasks 93 | { 94 | } 95 | 96 | //----------------------------------------------------------------------------- 97 | - (void)doBackgroundTasks 98 | { 99 | [archiver halt]; 100 | } 101 | 102 | //----------------------------------------------------------------------------- 103 | - (NSString *)convertToRVA: (NSString *)offsetStr 104 | { 105 | return @""; 106 | } 107 | 108 | //----------------------------------------------------------------------------- 109 | // Depth-first Traversal of nodes 110 | //----------------------------------------------------------------------------- 111 | - (MVNode *)findNodeByUserInfo:(NSDictionary *)userInfo 112 | { 113 | [dataController.treeLock lock]; 114 | MVNode * node = [rootNode findNodeByUserInfo:userInfo]; 115 | [dataController.treeLock unlock]; 116 | 117 | return node; 118 | } 119 | 120 | //----------------------------------------------------------------------------- 121 | // Create data node without details table (only hex content) 122 | //----------------------------------------------------------------------------- 123 | - (MVNode *)createDataNode:(MVNode *)parent 124 | caption:(NSString *)caption 125 | location:(uint32_t)location 126 | length:(uint32_t)length 127 | { 128 | MVNode * node = [parent insertChild:caption location:location length:length]; 129 | return node; 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /LinkEdit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * LinkEdit.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 20/07/2010. 6 | * 7 | */ 8 | 9 | #import "MachOLayout.h" 10 | @interface MachOLayout (LinkEdit) 11 | 12 | - (MVNode *) createRelocNode:(MVNode *)parent 13 | caption:(NSString *)caption 14 | location:(uint32_t)location 15 | length:(uint32_t)length 16 | baseAddress:(uint32_t)baseAddress; 17 | 18 | - (MVNode *) createReloc64Node:(MVNode *)parent 19 | caption:(NSString *)caption 20 | location:(uint32_t)location 21 | length:(uint32_t)length 22 | baseAddress:(uint64_t)baseAddress; 23 | 24 | - (MVNode *) createSymbolsNode:parent 25 | caption:(NSString *)caption 26 | location:(uint32_t)location 27 | length:(uint32_t)length; 28 | 29 | - (MVNode *) createSymbols64Node:parent 30 | caption:(NSString *)caption 31 | location:(uint32_t)location 32 | length:(uint32_t)length; 33 | 34 | - (MVNode *) createReferencesNode:parent 35 | caption:(NSString *)caption 36 | location:(uint32_t)location 37 | length:(uint32_t)length; 38 | 39 | - (MVNode *) createISymbolsNode:parent 40 | caption:(NSString *)caption 41 | location:(uint32_t)location 42 | length:(uint32_t)length; 43 | 44 | - (MVNode *) createISymbols64Node:parent 45 | caption:(NSString *)caption 46 | location:(uint32_t)location 47 | length:(uint32_t)length; 48 | 49 | - (MVNode *) createTOCNode:parent 50 | caption:(NSString *)caption 51 | location:(uint32_t)location 52 | length:(uint32_t)length; 53 | 54 | - (MVNode *) createTOC64Node:parent 55 | caption:(NSString *)caption 56 | location:(uint32_t)location 57 | length:(uint32_t)length; 58 | 59 | - (MVNode *) createModulesNode:parent 60 | caption:(NSString *)caption 61 | location:(uint32_t)location 62 | length:(uint32_t)length; 63 | 64 | - (MVNode *) createModules64Node:parent 65 | caption:(NSString *)caption 66 | location:(uint32_t)location 67 | length:(uint32_t)length; 68 | 69 | - (MVNode *) createTwoLevelHintsNode:parent 70 | caption:(NSString *)caption 71 | location:(uint32_t)location 72 | length:(uint32_t)length 73 | index:(uint32_t)index; 74 | 75 | - (MVNode *) createSplitSegmentNode:parent 76 | caption:(NSString *)caption 77 | location:(uint32_t)location 78 | length:(uint32_t)length 79 | baseAddress:(uint64_t)baseAddress; 80 | 81 | - (MVNode *) createFunctionStartsNode:parent 82 | caption:(NSString *)caption 83 | location:(uint32_t)location 84 | length:(uint32_t)length 85 | baseAddress:(uint64_t)baseAddress; 86 | 87 | - (MVNode *) createDataInCodeEntriesNode:parent 88 | caption:(NSString *)caption 89 | location:(uint32_t)location 90 | length:(uint32_t)length; 91 | 92 | 93 | @end 94 | 95 | -------------------------------------------------------------------------------- /LoadCommands.h: -------------------------------------------------------------------------------- 1 | /* 2 | * LoadCommands.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 20/07/2010. 6 | * 7 | */ 8 | 9 | #import "MachOLayout.h" 10 | 11 | 12 | @interface MachOLayout (LoadCommands) 13 | 14 | - (NSString *)getNameForCommand:(uint32_t)cmd; 15 | 16 | -(MVNode *)createLoadCommandNode:(MVNode *)parent 17 | caption:(NSString *)caption 18 | location:(uint32_t)location 19 | length:(uint32_t)length 20 | command:(uint32_t)command; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /MachOLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MachOLayout.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 15/06/2010. 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #import "Layout.h" 16 | 17 | typedef std::vector CommandVector; 18 | typedef std::vector SegmentVector; 19 | typedef std::vector Segment64Vector; 20 | typedef std::vector SectionVector; 21 | typedef std::vector Section64Vector; 22 | typedef std::vector NListVector; 23 | typedef std::vector NList64Vector; 24 | typedef std::vector DylibVector; 25 | typedef std::vector ModuleVector; 26 | typedef std::vector Module64Vector; 27 | typedef std::vector DataInCodeEntryVector; 28 | typedef std::vector IndirectSymbolVector; 29 | 30 | typedef std::map > RelocMap; // fileOffset --> 31 | typedef std::map > SegmentInfoMap; // fileOffset --> 32 | typedef std::map > SectionInfoMap; // address --> 33 | typedef std::map ExceptionFrameMap; // LSDA_addr --> PCBegin_addr 34 | 35 | @interface MachOLayout : MVLayout 36 | { 37 | uint64_t entryPoint; // instruction pointer in thread command 38 | 39 | CommandVector commands; // load commands 40 | SegmentVector segments; // segment entries for 32-bit architectures 41 | Segment64Vector segments_64; // segment entries for 64-bit architectures 42 | SectionVector sections; // section entries for 32-bit architectures 43 | Section64Vector sections_64; // section entries for 64-bit architectures 44 | NListVector symbols; // symbol entries in the symbol table for 32-bit architectures 45 | NList64Vector symbols_64; // symbol entries in the symbol table for 64-bit architectures 46 | IndirectSymbolVector isymbols; // indirect symbols 47 | 48 | DylibVector dylibs; // imported dynamic libraries 49 | ModuleVector modules; // module table entries in a dynamic shared library for 32-bit architectures 50 | Module64Vector modules_64; // module table entries in a dynamic shared library for 64-bit architectures 51 | DataInCodeEntryVector dices; // data in code entries 52 | char const * strtab; // pointer to the string table 53 | 54 | //RelocMap relocMap; // section relocations 55 | SegmentInfoMap segmentInfo; // segment info lookup table by offset 56 | SectionInfoMap sectionInfo; // section info lookup table by address 57 | ExceptionFrameMap lsdaInfo; // LSDA info lookup table by address 58 | 59 | NSMutableDictionary * symbolNames; // symbol names by address 60 | } 61 | 62 | + (MachOLayout *)layoutWithDataController:(MVDataController *)dc rootNode:(MVNode *)node; 63 | 64 | - (struct section const *)getSectionByIndex:(uint32_t)index; 65 | - (struct section_64 const *)getSection64ByIndex:(uint32_t)index; 66 | 67 | - (struct nlist const *)getSymbolByIndex:(uint32_t)index; 68 | - (struct nlist_64 const *)getSymbol64ByIndex:(uint32_t)index; 69 | 70 | - (struct dylib const *)getDylibByIndex:(uint32_t)index; 71 | 72 | - (NSDictionary *)userInfoForSection:(struct section const *)section; 73 | - (NSDictionary *)userInfoForSection64:(struct section_64 const *)section_64; 74 | 75 | - (MVNode *)sectionNodeContainsRVA:(uint32_t)rva; 76 | - (MVNode *)sectionNodeContainsRVA64:(uint64_t)rva; 77 | 78 | - (NSString *)findSectionContainsRVA:(uint32_t)rva; 79 | - (NSString *)findSectionContainsRVA64:(uint64_t)rva64; 80 | 81 | - (NSString *)findSymbolAtRVA:(uint32_t)rva; 82 | - (NSString *)findSymbolAtRVA64:(uint64_t)rva64; 83 | 84 | - (uint32_t)fileOffsetToRVA:(uint32_t)offset; 85 | - (uint64_t)fileOffsetToRVA64:(uint32_t)offset; 86 | 87 | - (uint32_t)RVAToFileOffset:(uint32_t)rva; 88 | - (uint32_t)RVA64ToFileOffset:(uint64_t)rva64; 89 | 90 | - (void)addRelocAtFileOffset:(uint32_t)offset withLength:(uint32_t)length andValue:(uint64_t)value; 91 | 92 | - (BOOL)isDylibStub; 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /ObjC.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ObjC.h 3 | * MachOView 4 | * 5 | * Created by Peter Saghelyi on 17/10/2011. 6 | * 7 | */ 8 | 9 | #import "MachOLayout.h" 10 | 11 | typedef std::vector PointerVector; 12 | typedef std::vector Pointer64Vector; 13 | 14 | @interface MachOLayout (ObjC) 15 | 16 | 17 | - (MVNode *)createObjCCFStringsNode:(MVNode *)parent 18 | caption:(NSString *)caption 19 | location:(uint32_t)location 20 | length:(uint32_t)length; 21 | 22 | - (MVNode *)createObjCCFStrings64Node:(MVNode *)parent 23 | caption:(NSString *)caption 24 | location:(uint32_t)location 25 | length:(uint32_t)length; 26 | 27 | - (MVNode *)createObjCImageInfoNode:(MVNode *)parent 28 | caption:(NSString *)caption 29 | location:(uint32_t)location 30 | length:(uint32_t)length; 31 | 32 | - (MVNode *)createObjCModulesNode:(MVNode *)parent 33 | caption:(NSString *)caption 34 | location:(uint32_t)location 35 | length:(uint32_t)length; 36 | 37 | - (MVNode *)createObjCClassExtNode:(MVNode *)parent 38 | caption:(NSString *)caption 39 | location:(uint32_t)location 40 | length:(uint32_t)length; 41 | 42 | - (MVNode *)createObjCProtocolExtNode:(MVNode *)parent 43 | caption:(NSString *)caption 44 | location:(uint32_t)location 45 | length:(uint32_t)length; 46 | 47 | - (MVNode *)createObjC2PointerListNode:(MVNode *)parent 48 | caption:(NSString *)caption 49 | location:(uint32_t)location 50 | length:(uint32_t)length 51 | pointers:(PointerVector &)pointers; 52 | 53 | - (MVNode *)createObjC2Pointer64ListNode:(MVNode *)parent 54 | caption:(NSString *)caption 55 | location:(uint32_t)location 56 | length:(uint32_t)length 57 | pointers:(Pointer64Vector &)pointers; 58 | 59 | - (MVNode *)createObjC2MsgRefsNode:(MVNode *)parent 60 | caption:(NSString *)caption 61 | location:(uint32_t)location 62 | length:(uint32_t)length; 63 | 64 | - (MVNode *)createObjC2MsgRefs64Node:(MVNode *)parent 65 | caption:(NSString *)caption 66 | location:(uint32_t)location 67 | length:(uint32_t)length; 68 | 69 | -(void)parseObjC2ClassPointers:(PointerVector const *)classes 70 | CategoryPointers:(PointerVector const *)categories 71 | ProtocolPointers:(PointerVector const *)protocols; 72 | 73 | -(void)parseObjC2Class64Pointers:(Pointer64Vector const *)classes 74 | Category64Pointers:(Pointer64Vector const *)categories 75 | Protocol64Pointers:(Pointer64Vector const *)protocols; 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /PreferenceController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MVPreferenceController.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 12/24/12. 6 | * 7 | */ 8 | 9 | @interface MVPreferenceController: NSWindowController 10 | { 11 | IBOutlet NSButton * openAtLaunch; 12 | } 13 | 14 | - (IBAction)toggleOpenAtLaunch:(id)sender; 15 | 16 | @end -------------------------------------------------------------------------------- /PreferenceController.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * PreferencesWindowController.mm 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 12/24/12. 6 | * 7 | */ 8 | 9 | #import "PreferenceController.h" 10 | 11 | @implementation MVPreferenceController 12 | 13 | -(id)init 14 | { 15 | self = [super initWithWindowNibName:@"Preferences"]; 16 | return self; 17 | } 18 | 19 | - (IBAction)toggleOpenAtLaunch:(id)sender 20 | { 21 | // nothing to do here? 22 | } 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Mach-O Browser' target in the 'Mach-O Browser' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | _____ .__ ____________ ____.__ 2 | / \ _____ ____ | |__ \_____ \ \ / /|__| ______ _ __ 3 | / \ / \\__ \ _/ ___\| | \ / | \ Y / | |/ __ \ \/ \/ / 4 | / Y \/ __ \\ \___| Y \/ | \ / | \ ___/\ / 5 | \____|__ (____ /\___ >___| /\_______ /\___/ |__|\___ >\/\_/ 6 | \/ \/ \/ \/ \/ \/ 7 | 8 | A fork from MachOView to update and fix some bugs, mostly Mountain Lion & iOS 6 related. 9 | Also some small changes to the original behaviour. 10 | 11 | Original MachOView by psaghelyi at http://sourceforge.net/projects/machoview/. 12 | Thanks to psaghelyi for his great work :-) 13 | 14 | Latest versions are Lion+ only. 15 | The LLVM disassembler was replaced with Capstone. This eliminates Clang/LLVM packages requirements. 16 | The downside is that Capstone stops disassembling on bad instructions which means that for now data in code and jump tables data will create problems and __text section disassembly might be incomplete in binaries that contain such data. 17 | Capstone improved disassembly on error but data in code locations are available in header so this can and should be improved. 18 | 19 | A static Capstone library extracted from the official DMG is included in the repo. 20 | If you want to be safe you should download Capstone and compile it yourself. 21 | 22 | Now features the attach option to analyse headers of a running process. 23 | To use this feature you will need to codesign the binary. 24 | Follow this LLDB guide to create the certificate and then codesign MachOView binary. 25 | https://llvm.org/svn/llvm-project/lldb/trunk/docs/code-signing.txt 26 | The necessary entitlements are already added to Info.plist. 27 | 28 | Be warned that this allows MachOView to have task_for_pid() privs under current under and control 29 | every process from user running it. 30 | The whole Mach-O parsing code needs to be reviewed and made more robust. 31 | 32 | Enjoy, 33 | fG! -------------------------------------------------------------------------------- /README.orig: -------------------------------------------------------------------------------- 1 | 2 | Hungry Apple icons by Nicholas Boyd (http://loafninja.deviantart.com) 3 | 4 | todo: 5 | - code sections parsing on demand 6 | - string table 7 | 8 | ver 2.4.9200 9 | - Lots of leaks fixed 10 | - Updated disassembler from cctools-855 11 | - Updated llvm disassembler from libLTO OSX10.9 12 | - ARM64 relocations in detail (need to review) 13 | - Added new load commands 14 | 15 | ver 2.4.9000 16 | - ARM64 17 | - LC_ENCRYPTION_INFO_64,LC_LINKER_OPTION 18 | - data in code and entries (DICES) 19 | - updated disassembler (cctools-845 and LLVM with enhanced symbol table) 20 | - SDK 10.8 / deploy 10.8 21 | - fix for multithreaded usage of CoreAnimation 22 | 23 | ver 2.3.8505 24 | - updated disassembler (LLVM included for testing) 25 | - some GUI improvements (PreferencePanel) 26 | - transitions to __weak references instead of __unsafe_retain 27 | - SDK 10.8 / deploy 10.6 28 | - crash fix for disassembling encrypted ARM text sections 29 | 30 | ver 2.3.8370 31 | - merge changes from fG! 32 | -- do not reopen unclosed binaries 33 | -- some new Load Commands 34 | -- bugfixes 35 | 36 | ver 2.3.8345 37 | - Transition to ARC (but targeting OS X 10.6 for compatibility) 38 | - FAT binary layout in details 39 | - LC_ENCRYPTION_INFO,LC_PREBIND_CKSUM,LC_RPATH,LC_FUNCTION_STARTS 40 | - twolevel swapping for smaller memory usage and better GUI response 41 | - Better ObjectiveC 2 section parsing 42 | 43 | ver 2.2.6500 44 | - objC sections 45 | - crash fix for concurrent treeView update 46 | - crash fix for disassembler (could read beyond file data) 47 | - relocs/bindings stored in a shadow NSData for faster access 48 | - improved exception records parser 49 | 50 | ver 2.1.5290 51 | - mainly bugfixes (relocInfoInfo, static libraries) 52 | - stop button for cancelling background tasks 53 | - exception safe symbol/section namelookup 54 | - disassembler updated to cctools-806 55 | 56 | ver 2.0.5000 57 | - ARM support 58 | - symbolic disassembling of text sections (based on otool) 59 | - split segment info in details 60 | - fast symbol stubs in details 61 | - improved RAW/RVA switch 62 | - typelist is fixed in LSDAs 63 | 64 | ver 1.3.4090 65 | - some new file types, section types 66 | - minor fixes 67 | - indirect symbols showed between squared brackets 68 | 69 | ver 1.3.4045 70 | - static libraries (binary archives) 71 | - dyld info parsing in details 72 | - base SDK and deploy target detection 73 | - fix indirect symbol issues in compressed Mach-O files 74 | - fix treeLock stability (now belongs to dataController not to the layout) 75 | - display multiply symbols for the same address 76 | 77 | ver 1.3.3047 78 | - swapfile based processing to avoid memory overhead for extremely big binaries 79 | (note: Ctrl+click toggles swap file usage on the selected node for faster access) 80 | - two-level namespaces in details 81 | - export dylibs (e.g.: libSystem.B.dylib) 82 | - safer symbol/section table access 83 | 84 | ver 1.2.2632 85 | - some command binary representation (dyld info, routines, two-level namespace) 86 | - better grouping and ordering of parsed content 87 | - 64bit exception data and relocation fixes 88 | - more stable name unmangling in tooltips 89 | 90 | ver 1.2.2200 91 | - tooltip with unmangled name for all the mangled symbol 92 | - better section parsing 93 | - common symbol table for better search (types distinguished by coloured background) 94 | 95 | ver 1.2.1842: 96 | - coloured background for special items: 97 | local/absolute indirect symbol 98 | scattered relocation 99 | - edit and save function 100 | - RVA/RWA offset uses segments' properties for calculation 101 | -------------------------------------------------------------------------------- /ReadWrite.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ReadWrite.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 20/07/2010. 6 | * 7 | */ 8 | 9 | #import "DataController.h" 10 | @interface MVDataController (ReadWrite) 11 | 12 | 13 | - (uint8_t) read_uint8:(NSRange &)range; 14 | - (uint16_t) read_uint16:(NSRange &)range; 15 | - (uint32_t) read_uint32:(NSRange &)range; 16 | - (uint64_t) read_uint64:(NSRange &)range; 17 | - (int8_t) read_int8:(NSRange &)range; 18 | - (int16_t) read_int16:(NSRange &)range; 19 | - (int32_t) read_int32:(NSRange &)range; 20 | - (int64_t) read_int64:(NSRange &)range; 21 | 22 | - (uint8_t) read_uint8:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 23 | - (uint16_t) read_uint16:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 24 | - (uint32_t) read_uint32:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 25 | - (uint64_t) read_uint64:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 26 | - (int8_t) read_int8:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 27 | - (int16_t) read_int16:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 28 | - (int32_t) read_int32:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 29 | - (int64_t) read_int64:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 30 | 31 | - (NSString *) read_string:(NSRange &)range; 32 | - (NSString *) read_string:(NSRange &)range fixlen:(NSUInteger)len; 33 | - (NSData *) read_bytes:(NSRange &)range length:(NSUInteger)length; 34 | - (int64_t) read_sleb128:(NSRange &)range; 35 | - (uint64_t) read_uleb128:(NSRange &)range; 36 | 37 | - (NSString *) read_string:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 38 | - (NSString *) read_string:(NSRange &)range fixlen:(NSUInteger)len lastReadHex:(NSString * __autoreleasing *)lastReadHex; 39 | - (NSData *) read_bytes:(NSRange &)range length:(NSUInteger)length lastReadHex:(NSString * __autoreleasing *)lastReadHex; 40 | - (int64_t) read_sleb128:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 41 | - (uint64_t) read_uleb128:(NSRange &)range lastReadHex:(NSString * __autoreleasing *)lastReadHex; 42 | 43 | - (void) write_uint8:(NSUInteger)location data:(uint8_t)data; 44 | - (void) write_uint16:(NSUInteger)location data:(uint16_t)data; 45 | - (void) write_uint32:(NSUInteger)location data:(uint32_t)data; 46 | - (void) write_uint64:(NSUInteger)location data:(uint64_t)data; 47 | - (void) write_int8:(NSUInteger)location data:(int8_t)data; 48 | - (void) write_int16:(NSUInteger)location data:(int16_t)data; 49 | - (void) write_int32:(NSUInteger)location data:(int32_t)data; 50 | - (void) write_int64:(NSUInteger)location data:(int64_t)data; 51 | - (void) write_string:(NSUInteger)location data:(NSString *)data; 52 | - (void) write_bytes:(NSUInteger)location data:(NSData *)data; 53 | - (void) write_sleb128:(NSUInteger)location data:(int64_t)data; 54 | - (void) write_uleb128:(NSUInteger)location data:(uint64_t)data; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /SectionContents.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SectionContents.h 3 | * MachOView 4 | * 5 | * Created by psaghelyi on 15/09/2010. 6 | * 7 | */ 8 | 9 | #import "MachOLayout.h" 10 | 11 | @interface MachOLayout (SectionContents) 12 | 13 | - (MVNode *)createPointersNode:(MVNode *)parent 14 | caption:(NSString *)caption 15 | location:(uint32_t)location 16 | length:(uint32_t)length; 17 | 18 | 19 | - (MVNode *)createPointers64Node:(MVNode *)parent 20 | caption:(NSString *)caption 21 | location:(uint32_t)location 22 | length:(uint32_t)length; 23 | 24 | -(MVNode *)createCStringsNode:(MVNode *)parent 25 | caption:(NSString *)caption 26 | location:(uint32_t)location 27 | length:(uint32_t)length; 28 | 29 | -(MVNode *)createLiteralsNode:(MVNode *)parent 30 | caption:(NSString *)caption 31 | location:(uint32_t)location 32 | length:(uint32_t)length 33 | stride:(uint32_t)stride; 34 | 35 | - (MVNode *)createIndPointersNode:(MVNode *)parent 36 | caption:(NSString *)caption 37 | location:(uint32_t)location 38 | length:(uint32_t)length; 39 | 40 | - (MVNode *)createIndPointers64Node:(MVNode *)parent 41 | caption:(NSString *)caption 42 | location:(uint32_t)location 43 | length:(uint32_t)length; 44 | 45 | - (MVNode *)createIndStubsNode:(MVNode *)parent 46 | caption:(NSString *)caption 47 | location:(uint32_t)location 48 | length:(uint32_t)length 49 | stride:(uint32_t)stride; 50 | 51 | - (MVNode *)createIndStubs64Node:(MVNode *)parent 52 | caption:(NSString *)caption 53 | location:(uint32_t)location 54 | length:(uint32_t)length 55 | stride:(uint32_t)stride; 56 | 57 | - (MVNode *)createStubHelperNode:(MVNode *)parent 58 | caption:(NSString *)caption 59 | location:(uint32_t)location 60 | length:(uint32_t)length; 61 | 62 | - (MVNode *)createTextNode:(MVNode *)parent 63 | caption:(NSString *)caption 64 | location:(uint32_t)location 65 | length:(uint32_t)length 66 | reloff:(uint32_t)reloff 67 | nreloc:(uint32_t)nreloc 68 | extreloff:(uint32_t)extreloff 69 | nextrel:(uint32_t)nextrel 70 | locreloff:(uint32_t)locreloff 71 | nlocrel:(uint32_t)nlocrel; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /capstone/LEB128.h: -------------------------------------------------------------------------------- 1 | //===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file declares some utility functions for encoding SLEB128 and 11 | // ULEB128 values. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | /* Capstone Disassembly Engine */ 16 | /* By Nguyen Anh Quynh , 2013-2014 */ 17 | 18 | #ifndef CS_LLVM_SUPPORT_LEB128_H 19 | #define CS_LLVM_SUPPORT_LEB128_H 20 | 21 | #include 22 | 23 | /// Utility function to decode a ULEB128 value. 24 | static inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n) 25 | { 26 | const uint8_t *orig_p = p; 27 | uint64_t Value = 0; 28 | unsigned Shift = 0; 29 | do { 30 | Value += (*p & 0x7f) << Shift; 31 | Shift += 7; 32 | } while (*p++ >= 128); 33 | if (n) 34 | *n = (unsigned)(p - orig_p); 35 | return Value; 36 | } 37 | 38 | #endif // LLVM_SYSTEM_LEB128_H 39 | -------------------------------------------------------------------------------- /capstone/MCDisassembler.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_MCDISASSEMBLER_H 5 | #define CS_MCDISASSEMBLER_H 6 | 7 | typedef enum DecodeStatus { 8 | MCDisassembler_Fail = 0, 9 | MCDisassembler_SoftFail = 1, 10 | MCDisassembler_Success = 3, 11 | } DecodeStatus; 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /capstone/MCFixedLenDisassembler.h: -------------------------------------------------------------------------------- 1 | //===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // Fixed length disassembler decoder state machine driver. 10 | //===----------------------------------------------------------------------===// 11 | 12 | /* Capstone Disassembly Engine */ 13 | /* By Nguyen Anh Quynh , 2013-2014 */ 14 | 15 | #ifndef CS_LLVM_MC_MCFIXEDLENDISASSEMBLER_H 16 | #define CS_LLVM_MC_MCFIXEDLENDISASSEMBLER_H 17 | 18 | // Disassembler state machine opcodes. 19 | enum DecoderOps { 20 | MCD_OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len) 21 | MCD_OPC_FilterValue, // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip) 22 | MCD_OPC_CheckField, // OPC_CheckField(uint8_t Start, uint8_t Len, 23 | // uleb128 Val, uint16_t NumToSkip) 24 | MCD_OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip) 25 | MCD_OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx) 26 | MCD_OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask) 27 | MCD_OPC_Fail // OPC_Fail() 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /capstone/MCInst.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #if defined(CAPSTONE_HAS_OSXKERNEL) 5 | #include 6 | #else 7 | #include 8 | #include 9 | #endif 10 | #include 11 | 12 | #include "MCInst.h" 13 | #include "utils.h" 14 | 15 | #define MCINST_CACHE (ARR_SIZE(mcInst->Operands) - 1) 16 | 17 | void MCInst_Init(MCInst *inst) 18 | { 19 | inst->OpcodePub = 0; 20 | inst->size = 0; 21 | inst->has_imm = false; 22 | inst->op1_size = 0; 23 | inst->writeback = false; 24 | } 25 | 26 | void MCInst_clear(MCInst *inst) 27 | { 28 | inst->size = 0; 29 | } 30 | 31 | // do not free @Op 32 | void MCInst_insert0(MCInst *inst, int index, MCOperand *Op) 33 | { 34 | int i; 35 | 36 | for(i = inst->size; i > index; i--) 37 | //memcpy(&(inst->Operands[i]), &(inst->Operands[i-1]), sizeof(MCOperand)); 38 | inst->Operands[i] = inst->Operands[i-1]; 39 | 40 | inst->Operands[index] = *Op; 41 | inst->size++; 42 | } 43 | 44 | void MCInst_setOpcode(MCInst *inst, unsigned Op) 45 | { 46 | inst->Opcode = Op; 47 | } 48 | 49 | void MCInst_setOpcodePub(MCInst *inst, unsigned Op) 50 | { 51 | inst->OpcodePub = Op; 52 | } 53 | 54 | unsigned MCInst_getOpcode(const MCInst *inst) 55 | { 56 | return inst->Opcode; 57 | } 58 | 59 | unsigned MCInst_getOpcodePub(const MCInst *inst) 60 | { 61 | return inst->OpcodePub; 62 | } 63 | 64 | MCOperand *MCInst_getOperand(MCInst *inst, unsigned i) 65 | { 66 | return &inst->Operands[i]; 67 | } 68 | 69 | unsigned MCInst_getNumOperands(const MCInst *inst) 70 | { 71 | return inst->size; 72 | } 73 | 74 | // This addOperand2 function doesnt free Op 75 | void MCInst_addOperand2(MCInst *inst, MCOperand *Op) 76 | { 77 | inst->Operands[inst->size] = *Op; 78 | 79 | inst->size++; 80 | } 81 | 82 | void MCOperand_Init(MCOperand *op) 83 | { 84 | op->Kind = kInvalid; 85 | op->FPImmVal = 0.0; 86 | } 87 | 88 | bool MCOperand_isValid(const MCOperand *op) 89 | { 90 | return op->Kind != kInvalid; 91 | } 92 | 93 | bool MCOperand_isReg(const MCOperand *op) 94 | { 95 | return op->Kind == kRegister; 96 | } 97 | 98 | bool MCOperand_isImm(const MCOperand *op) 99 | { 100 | return op->Kind == kImmediate; 101 | } 102 | 103 | bool MCOperand_isFPImm(const MCOperand *op) 104 | { 105 | return op->Kind == kFPImmediate; 106 | } 107 | 108 | /// getReg - Returns the register number. 109 | unsigned MCOperand_getReg(const MCOperand *op) 110 | { 111 | return op->RegVal; 112 | } 113 | 114 | /// setReg - Set the register number. 115 | void MCOperand_setReg(MCOperand *op, unsigned Reg) 116 | { 117 | op->RegVal = Reg; 118 | } 119 | 120 | int64_t MCOperand_getImm(MCOperand *op) 121 | { 122 | return op->ImmVal; 123 | } 124 | 125 | void MCOperand_setImm(MCOperand *op, int64_t Val) 126 | { 127 | op->ImmVal = Val; 128 | } 129 | 130 | double MCOperand_getFPImm(const MCOperand *op) 131 | { 132 | return op->FPImmVal; 133 | } 134 | 135 | void MCOperand_setFPImm(MCOperand *op, double Val) 136 | { 137 | op->FPImmVal = Val; 138 | } 139 | 140 | MCOperand *MCOperand_CreateReg1(MCInst *mcInst, unsigned Reg) 141 | { 142 | MCOperand *op = &(mcInst->Operands[MCINST_CACHE]); 143 | 144 | op->Kind = kRegister; 145 | op->RegVal = Reg; 146 | 147 | return op; 148 | } 149 | 150 | void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg) 151 | { 152 | MCOperand *op = &(mcInst->Operands[mcInst->size]); 153 | mcInst->size++; 154 | 155 | op->Kind = kRegister; 156 | op->RegVal = Reg; 157 | } 158 | 159 | MCOperand *MCOperand_CreateImm1(MCInst *mcInst, int64_t Val) 160 | { 161 | MCOperand *op = &(mcInst->Operands[MCINST_CACHE]); 162 | 163 | op->Kind = kImmediate; 164 | op->ImmVal = Val; 165 | 166 | return op; 167 | } 168 | 169 | void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val) 170 | { 171 | MCOperand *op = &(mcInst->Operands[mcInst->size]); 172 | mcInst->size++; 173 | 174 | op->Kind = kImmediate; 175 | op->ImmVal = Val; 176 | } 177 | -------------------------------------------------------------------------------- /capstone/MCInst.h: -------------------------------------------------------------------------------- 1 | //===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file contains the declaration of the MCInst and MCOperand classes, which 11 | // is the basic representation used to represent low-level machine code 12 | // instructions. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | /* Capstone Disassembly Engine */ 17 | /* By Nguyen Anh Quynh , 2013-2014 */ 18 | 19 | #ifndef CS_MCINST_H 20 | #define CS_MCINST_H 21 | 22 | #include 23 | 24 | #include "include/capstone.h" 25 | 26 | typedef struct MCInst MCInst; 27 | typedef struct cs_struct cs_struct; 28 | typedef struct MCOperand MCOperand; 29 | 30 | /// MCOperand - Instances of this class represent operands of the MCInst class. 31 | /// This is a simple discriminated union. 32 | struct MCOperand { 33 | enum { 34 | kInvalid = 0, ///< Uninitialized. 35 | kRegister, ///< Register operand. 36 | kImmediate, ///< Immediate operand. 37 | kFPImmediate, ///< Floating-point immediate operand. 38 | } MachineOperandType; 39 | unsigned char Kind; 40 | 41 | union { 42 | unsigned RegVal; 43 | int64_t ImmVal; 44 | double FPImmVal; 45 | }; 46 | }; 47 | 48 | bool MCOperand_isValid(const MCOperand *op); 49 | 50 | bool MCOperand_isReg(const MCOperand *op); 51 | 52 | bool MCOperand_isImm(const MCOperand *op); 53 | 54 | bool MCOperand_isFPImm(const MCOperand *op); 55 | 56 | bool MCOperand_isInst(const MCOperand *op); 57 | 58 | void MCInst_clear(MCInst *m); 59 | 60 | /// getReg - Returns the register number. 61 | unsigned MCOperand_getReg(const MCOperand *op); 62 | 63 | /// setReg - Set the register number. 64 | void MCOperand_setReg(MCOperand *op, unsigned Reg); 65 | 66 | int64_t MCOperand_getImm(MCOperand *op); 67 | 68 | void MCOperand_setImm(MCOperand *op, int64_t Val); 69 | 70 | double MCOperand_getFPImm(const MCOperand *op); 71 | 72 | void MCOperand_setFPImm(MCOperand *op, double Val); 73 | 74 | const MCInst *MCOperand_getInst(const MCOperand *op); 75 | 76 | void MCOperand_setInst(MCOperand *op, const MCInst *Val); 77 | 78 | // create Reg operand in the next slot 79 | void MCOperand_CreateReg0(MCInst *inst, unsigned Reg); 80 | 81 | // create Reg operand use the last-unused slot 82 | MCOperand *MCOperand_CreateReg1(MCInst *inst, unsigned Reg); 83 | 84 | // create Imm operand in the next slot 85 | void MCOperand_CreateImm0(MCInst *inst, int64_t Val); 86 | 87 | // create Imm operand in the last-unused slot 88 | MCOperand *MCOperand_CreateImm1(MCInst *inst, int64_t Val); 89 | 90 | /// MCInst - Instances of this class represent a single low-level machine 91 | /// instruction. 92 | struct MCInst { 93 | unsigned OpcodePub; 94 | uint8_t size; // number of operands 95 | bool has_imm; // indicate this instruction has an X86_OP_IMM operand - used for ATT syntax 96 | uint8_t op1_size; // size of 1st operand - for X86 Intel syntax 97 | unsigned Opcode; 98 | MCOperand Operands[48]; 99 | cs_insn *flat_insn; // insn to be exposed to public 100 | uint64_t address; // address of this insn 101 | cs_struct *csh; // save the main csh 102 | uint8_t x86opsize; // opsize for [mem] operand 103 | 104 | // (Optional) instruction prefix, which can be up to 4 bytes. 105 | // A prefix byte gets value 0 when irrelevant. 106 | // This is copied from cs_x86 struct 107 | uint8_t x86_prefix[4]; 108 | uint8_t imm_size; // immediate size for X86_OP_IMM operand 109 | bool writeback; // writeback for ARM 110 | }; 111 | 112 | void MCInst_Init(MCInst *inst); 113 | 114 | void MCInst_clear(MCInst *inst); 115 | 116 | // do not free operand after inserting 117 | void MCInst_insert0(MCInst *inst, int index, MCOperand *Op); 118 | 119 | void MCInst_setOpcode(MCInst *inst, unsigned Op); 120 | 121 | unsigned MCInst_getOpcode(const MCInst*); 122 | 123 | void MCInst_setOpcodePub(MCInst *inst, unsigned Op); 124 | 125 | unsigned MCInst_getOpcodePub(const MCInst*); 126 | 127 | MCOperand *MCInst_getOperand(MCInst *inst, unsigned i); 128 | 129 | unsigned MCInst_getNumOperands(const MCInst *inst); 130 | 131 | // This addOperand2 function doesnt free Op 132 | void MCInst_addOperand2(MCInst *inst, MCOperand *Op); 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /capstone/MCInstrDesc.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #include "MCInstrDesc.h" 5 | 6 | /// isPredicate - Set if this is one of the operands that made up of 7 | /// the predicate operand that controls an isPredicable() instruction. 8 | bool MCOperandInfo_isPredicate(MCOperandInfo *m) 9 | { 10 | return m->Flags & (1 << MCOI_Predicate); 11 | } 12 | 13 | /// isOptionalDef - Set if this operand is a optional def. 14 | /// 15 | bool MCOperandInfo_isOptionalDef(MCOperandInfo *m) 16 | { 17 | return m->Flags & (1 << MCOI_OptionalDef); 18 | } 19 | -------------------------------------------------------------------------------- /capstone/MCInstrDesc.h: -------------------------------------------------------------------------------- 1 | //===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the MCOperandInfo and MCInstrDesc classes, which 11 | // are used to describe target instructions and their operands. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | /* Capstone Disassembly Engine */ 16 | /* By Nguyen Anh Quynh , 2013-2014 */ 17 | 18 | #ifndef CS_LLVM_MC_MCINSTRDESC_H 19 | #define CS_LLVM_MC_MCINSTRDESC_H 20 | 21 | #include 22 | #include "include/platform.h" 23 | 24 | //===----------------------------------------------------------------------===// 25 | // Machine Operand Flags and Description 26 | //===----------------------------------------------------------------------===// 27 | 28 | // Operand constraints 29 | enum MCOI_OperandConstraint { 30 | MCOI_TIED_TO = 0, // Must be allocated the same register as. 31 | MCOI_EARLY_CLOBBER // Operand is an early clobber register operand 32 | }; 33 | 34 | /// OperandFlags - These are flags set on operands, but should be considered 35 | /// private, all access should go through the MCOperandInfo accessors. 36 | /// See the accessors for a description of what these are. 37 | enum MCOI_OperandFlags { 38 | MCOI_LookupPtrRegClass = 0, 39 | MCOI_Predicate, 40 | MCOI_OptionalDef 41 | }; 42 | 43 | /// Operand Type - Operands are tagged with one of the values of this enum. 44 | enum MCOI_OperandType { 45 | MCOI_OPERAND_UNKNOWN, 46 | MCOI_OPERAND_IMMEDIATE, 47 | MCOI_OPERAND_REGISTER, 48 | MCOI_OPERAND_MEMORY, 49 | MCOI_OPERAND_PCREL 50 | }; 51 | 52 | 53 | /// MCOperandInfo - This holds information about one operand of a machine 54 | /// instruction, indicating the register class for register operands, etc. 55 | /// 56 | typedef struct MCOperandInfo { 57 | /// RegClass - This specifies the register class enumeration of the operand 58 | /// if the operand is a register. If isLookupPtrRegClass is set, then this is 59 | /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to 60 | /// get a dynamic register class. 61 | int16_t RegClass; 62 | 63 | /// Flags - These are flags from the MCOI::OperandFlags enum. 64 | uint8_t Flags; 65 | 66 | /// OperandType - Information about the type of the operand. 67 | uint8_t OperandType; 68 | 69 | /// Lower 16 bits are used to specify which constraints are set. The higher 16 70 | /// bits are used to specify the value of constraints (4 bits each). 71 | uint32_t Constraints; 72 | /// Currently no other information. 73 | } MCOperandInfo; 74 | 75 | 76 | //===----------------------------------------------------------------------===// 77 | // Machine Instruction Flags and Description 78 | //===----------------------------------------------------------------------===// 79 | 80 | /// MCInstrDesc flags - These should be considered private to the 81 | /// implementation of the MCInstrDesc class. Clients should use the predicate 82 | /// methods on MCInstrDesc, not use these directly. These all correspond to 83 | /// bitfields in the MCInstrDesc::Flags field. 84 | enum { 85 | MCID_Variadic = 0, 86 | MCID_HasOptionalDef, 87 | MCID_Pseudo, 88 | MCID_Return, 89 | MCID_Call, 90 | MCID_Barrier, 91 | MCID_Terminator, 92 | MCID_Branch, 93 | MCID_IndirectBranch, 94 | MCID_Compare, 95 | MCID_MoveImm, 96 | MCID_Bitcast, 97 | MCID_Select, 98 | MCID_DelaySlot, 99 | MCID_FoldableAsLoad, 100 | MCID_MayLoad, 101 | MCID_MayStore, 102 | MCID_Predicable, 103 | MCID_NotDuplicable, 104 | MCID_UnmodeledSideEffects, 105 | MCID_Commutable, 106 | MCID_ConvertibleTo3Addr, 107 | MCID_UsesCustomInserter, 108 | MCID_HasPostISelHook, 109 | MCID_Rematerializable, 110 | MCID_CheapAsAMove, 111 | MCID_ExtraSrcRegAllocReq, 112 | MCID_ExtraDefRegAllocReq, 113 | MCID_RegSequence, 114 | }; 115 | 116 | /// MCInstrDesc - Describe properties that are true of each instruction in the 117 | /// target description file. This captures information about side effects, 118 | /// register use and many other things. There is one instance of this struct 119 | /// for each target instruction class, and the MachineInstr class points to 120 | /// this struct directly to describe itself. 121 | typedef struct MCInstrDesc { 122 | unsigned short Opcode; // The opcode number 123 | unsigned char NumOperands; // Num of args (may be more if variable_ops) 124 | unsigned char NumDefs; // Num of args that are definitions 125 | unsigned short SchedClass; // enum identifying instr sched class 126 | unsigned char Size; // Number of bytes in encoding. 127 | unsigned Flags; // Flags identifying machine instr class 128 | uint64_t TSFlags; // Target Specific Flag values 129 | char ImplicitUses; // Registers implicitly read by this instr 130 | char ImplicitDefs; // Registers implicitly defined by this instr 131 | MCOperandInfo *OpInfo; // 'NumOperands' entries about operands 132 | uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any 133 | // A complex method to determine is a certain is deprecated or not, and return 134 | // the reason for deprecation. 135 | //bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &); 136 | unsigned char ComplexDeprecationInfo; // dummy field, just to satisfy initializer 137 | } MCInstrDesc; 138 | 139 | bool MCOperandInfo_isPredicate(MCOperandInfo *m); 140 | 141 | bool MCOperandInfo_isOptionalDef(MCOperandInfo *m); 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /capstone/MCRegisterInfo.c: -------------------------------------------------------------------------------- 1 | //=== MC/MCRegisterInfo.cpp - Target Register Description -------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file implements MCRegisterInfo functions. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | /* Capstone Disassembly Engine */ 15 | /* By Nguyen Anh Quynh , 2013-2014 */ 16 | 17 | #include "MCRegisterInfo.h" 18 | 19 | /// DiffListIterator - Base iterator class that can traverse the 20 | /// differentially encoded register and regunit lists in DiffLists. 21 | /// Don't use this class directly, use one of the specialized sub-classes 22 | /// defined below. 23 | typedef struct DiffListIterator { 24 | uint16_t Val; 25 | MCPhysReg *List; 26 | } DiffListIterator; 27 | 28 | void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI, 29 | MCRegisterDesc *D, unsigned NR, 30 | unsigned RA, unsigned PC, 31 | MCRegisterClass *C, unsigned NC, 32 | uint16_t (*RURoots)[2], unsigned NRU, 33 | MCPhysReg *DL, 34 | char *Strings, 35 | uint16_t *SubIndices, unsigned NumIndices, 36 | uint16_t *RET) 37 | { 38 | RI->Desc = D; 39 | RI->NumRegs = NR; 40 | RI->RAReg = RA; 41 | RI->PCReg = PC; 42 | RI->Classes = C; 43 | RI->DiffLists = DL; 44 | RI->RegStrings = Strings; 45 | RI->NumClasses = NC; 46 | RI->RegUnitRoots = RURoots; 47 | RI->NumRegUnits = NRU; 48 | RI->SubRegIndices = SubIndices; 49 | RI->NumSubRegIndices = NumIndices; 50 | RI->RegEncodingTable = RET; 51 | } 52 | 53 | static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, MCPhysReg *DiffList) 54 | { 55 | d->Val = InitVal; 56 | d->List = DiffList; 57 | } 58 | 59 | static uint16_t DiffListIterator_getVal(DiffListIterator *d) 60 | { 61 | return d->Val; 62 | } 63 | 64 | static bool DiffListIterator_next(DiffListIterator *d) 65 | { 66 | MCPhysReg D; 67 | 68 | if (d->List == 0) 69 | return false; 70 | 71 | D = *d->List; 72 | d->List++; 73 | d->Val += D; 74 | 75 | if (!D) 76 | d->List = 0; 77 | 78 | return (D != 0); 79 | } 80 | 81 | static bool DiffListIterator_isValid(DiffListIterator *d) 82 | { 83 | return (d->List != 0); 84 | } 85 | 86 | unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, MCRegisterClass *RC) 87 | { 88 | DiffListIterator iter; 89 | 90 | if (Reg >= RI->NumRegs) { 91 | return 0; 92 | } 93 | 94 | DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs); 95 | DiffListIterator_next(&iter); 96 | 97 | while(DiffListIterator_isValid(&iter)) { 98 | uint16_t val = DiffListIterator_getVal(&iter); 99 | if (MCRegisterClass_contains(RC, val) && Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx)) 100 | return val; 101 | 102 | DiffListIterator_next(&iter); 103 | } 104 | 105 | return 0; 106 | } 107 | 108 | unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx) 109 | { 110 | DiffListIterator iter; 111 | uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices; 112 | 113 | DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs); 114 | DiffListIterator_next(&iter); 115 | 116 | while(DiffListIterator_isValid(&iter)) { 117 | if (*SRI == Idx) 118 | return DiffListIterator_getVal(&iter); 119 | DiffListIterator_next(&iter); 120 | ++SRI; 121 | } 122 | 123 | return 0; 124 | } 125 | 126 | MCRegisterClass* MCRegisterInfo_getRegClass(MCRegisterInfo *RI, unsigned i) 127 | { 128 | //assert(i < getNumRegClasses() && "Register Class ID out of range"); 129 | if (i >= RI->NumClasses) 130 | return 0; 131 | return &(RI->Classes[i]); 132 | } 133 | 134 | bool MCRegisterClass_contains(MCRegisterClass *c, unsigned Reg) 135 | { 136 | unsigned InByte = Reg % 8; 137 | unsigned Byte = Reg / 8; 138 | 139 | if (Byte >= c->RegSetSize) 140 | return false; 141 | 142 | return (c->RegSet[Byte] & (1 << InByte)) != 0; 143 | } 144 | -------------------------------------------------------------------------------- /capstone/MCRegisterInfo.h: -------------------------------------------------------------------------------- 1 | //=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file describes an abstract interface used to get information about a 11 | // target machines register file. This information is used for a variety of 12 | // purposed, especially register allocation. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | /* Capstone Disassembly Engine */ 17 | /* By Nguyen Anh Quynh , 2013-2014 */ 18 | 19 | #ifndef CS_LLVM_MC_MCREGISTERINFO_H 20 | #define CS_LLVM_MC_MCREGISTERINFO_H 21 | 22 | #include 23 | #include "include/platform.h" 24 | 25 | /// An unsigned integer type large enough to represent all physical registers, 26 | /// but not necessarily virtual registers. 27 | typedef uint16_t MCPhysReg; 28 | typedef MCPhysReg* iterator; 29 | 30 | typedef struct MCRegisterClass { 31 | char *Name; 32 | iterator RegsBegin; 33 | uint8_t *RegSet; 34 | uint16_t RegsSize; 35 | uint16_t RegSetSize; 36 | uint16_t ID; 37 | uint16_t RegSize, Alignment; // Size & Alignment of register in bytes 38 | int8_t CopyCost; 39 | bool Allocatable; 40 | } MCRegisterClass; 41 | 42 | /// MCRegisterDesc - This record contains information about a particular 43 | /// register. The SubRegs field is a zero terminated array of registers that 44 | /// are sub-registers of the specific register, e.g. AL, AH are sub-registers 45 | /// of AX. The SuperRegs field is a zero terminated array of registers that are 46 | /// super-registers of the specific register, e.g. RAX, EAX, are 47 | /// super-registers of AX. 48 | /// 49 | typedef struct MCRegisterDesc { 50 | uint32_t Name; // Printable name for the reg (for debugging) 51 | uint32_t SubRegs; // Sub-register set, described above 52 | uint32_t SuperRegs; // Super-register set, described above 53 | 54 | // Offset into MCRI::SubRegIndices of a list of sub-register indices for each 55 | // sub-register in SubRegs. 56 | uint32_t SubRegIndices; 57 | 58 | // RegUnits - Points to the list of register units. The low 4 bits holds the 59 | // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator. 60 | uint32_t RegUnits; 61 | } MCRegisterDesc; 62 | 63 | /// MCRegisterInfo base class - We assume that the target defines a static 64 | /// array of MCRegisterDesc objects that represent all of the machine 65 | /// registers that the target has. As such, we simply have to track a pointer 66 | /// to this array so that we can turn register number into a register 67 | /// descriptor. 68 | /// 69 | /// Note this class is designed to be a base class of TargetRegisterInfo, which 70 | /// is the interface used by codegen. However, specific targets *should never* 71 | /// specialize this class. MCRegisterInfo should only contain getters to access 72 | /// TableGen generated physical register data. It must not be extended with 73 | /// virtual methods. 74 | /// 75 | typedef struct MCRegisterInfo { 76 | MCRegisterDesc *Desc; // Pointer to the descriptor array 77 | unsigned NumRegs; // Number of entries in the array 78 | unsigned RAReg; // Return address register 79 | unsigned PCReg; // Program counter register 80 | MCRegisterClass *Classes; // Pointer to the regclass array 81 | unsigned NumClasses; // Number of entries in the array 82 | unsigned NumRegUnits; // Number of regunits. 83 | uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table. 84 | MCPhysReg *DiffLists; // Pointer to the difflists array 85 | char *RegStrings; // Pointer to the string table. 86 | uint16_t *SubRegIndices; // Pointer to the subreg lookup 87 | // array. 88 | unsigned NumSubRegIndices; // Number of subreg indices. 89 | uint16_t *RegEncodingTable; // Pointer to array of register 90 | // encodings. 91 | } MCRegisterInfo; 92 | 93 | void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI, 94 | MCRegisterDesc *D, unsigned NR, unsigned RA, 95 | unsigned PC, 96 | MCRegisterClass *C, unsigned NC, 97 | uint16_t (*RURoots)[2], 98 | unsigned NRU, 99 | MCPhysReg *DL, 100 | char *Strings, 101 | uint16_t *SubIndices, 102 | unsigned NumIndices, 103 | uint16_t *RET); 104 | 105 | 106 | unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, MCRegisterClass *RC); 107 | 108 | unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx); 109 | 110 | MCRegisterClass* MCRegisterInfo_getRegClass(MCRegisterInfo *RI, unsigned i); 111 | 112 | bool MCRegisterClass_contains(MCRegisterClass *c, unsigned Reg); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /capstone/SStream.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #include 5 | #include 6 | #if defined(CAPSTONE_HAS_OSXKERNEL) 7 | #include 8 | #else 9 | #include 10 | #endif 11 | #include 12 | 13 | #include "SStream.h" 14 | #include "cs_priv.h" 15 | #include "myinttypes.h" 16 | #include "utils.h" 17 | 18 | #ifdef _MSC_VER 19 | #pragma warning(disable: 4996) // disable MSVC's warning on strcpy() 20 | #endif 21 | 22 | void SStream_Init(SStream *ss) 23 | { 24 | ss->index = 0; 25 | ss->buffer[0] = '\0'; 26 | } 27 | 28 | void SStream_concat0(SStream *ss, char *s) 29 | { 30 | #ifndef CAPSTONE_DIET 31 | unsigned int len = (unsigned int) strlen(s); 32 | 33 | memcpy(ss->buffer + ss->index, s, len); 34 | ss->index += len; 35 | ss->buffer[ss->index] = '\0'; 36 | #endif 37 | } 38 | 39 | void SStream_concat(SStream *ss, const char *fmt, ...) 40 | { 41 | #ifndef CAPSTONE_DIET 42 | va_list ap; 43 | int ret; 44 | 45 | va_start(ap, fmt); 46 | ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap); 47 | va_end(ap); 48 | ss->index += ret; 49 | #endif 50 | } 51 | 52 | // print number with prefix # 53 | void printInt64Bang(SStream *O, int64_t val) 54 | { 55 | if (val >= 0) { 56 | if (val > HEX_THRESHOLD) 57 | SStream_concat(O, "#0x%"PRIx64, val); 58 | else 59 | SStream_concat(O, "#%"PRIu64, val); 60 | } else { 61 | if (val <- HEX_THRESHOLD) 62 | SStream_concat(O, "#-0x%"PRIx64, -val); 63 | else 64 | SStream_concat(O, "#-%"PRIu64, -val); 65 | } 66 | } 67 | 68 | void printUInt64Bang(SStream *O, uint64_t val) 69 | { 70 | if (val > HEX_THRESHOLD) 71 | SStream_concat(O, "#0x%"PRIx64, val); 72 | else 73 | SStream_concat(O, "#%"PRIu64, val); 74 | } 75 | 76 | // print number 77 | void printInt64(SStream *O, int64_t val) 78 | { 79 | if (val >= 0) { 80 | if (val > HEX_THRESHOLD) 81 | SStream_concat(O, "0x%"PRIx64, val); 82 | else 83 | SStream_concat(O, "%"PRIu64, val); 84 | } else { 85 | if (val <- HEX_THRESHOLD) 86 | SStream_concat(O, "-0x%"PRIx64, -val); 87 | else 88 | SStream_concat(O, "-%"PRIu64, -val); 89 | } 90 | } 91 | 92 | // print number in decimal mode 93 | void printInt32BangDec(SStream *O, int32_t val) 94 | { 95 | if (val >= 0) 96 | SStream_concat(O, "#%u", val); 97 | else 98 | SStream_concat(O, "#-%u", -val); 99 | } 100 | 101 | void printInt32Bang(SStream *O, int32_t val) 102 | { 103 | if (val >= 0) { 104 | if (val > HEX_THRESHOLD) 105 | SStream_concat(O, "#0x%x", val); 106 | else 107 | SStream_concat(O, "#%u", val); 108 | } else { 109 | if (val <- HEX_THRESHOLD) 110 | SStream_concat(O, "#-0x%x", -val); 111 | else 112 | SStream_concat(O, "#-%u", -val); 113 | } 114 | } 115 | 116 | void printInt32(SStream *O, int32_t val) 117 | { 118 | if (val >= 0) { 119 | if (val > HEX_THRESHOLD) 120 | SStream_concat(O, "0x%x", val); 121 | else 122 | SStream_concat(O, "%u", val); 123 | } else { 124 | if (val <- HEX_THRESHOLD) 125 | SStream_concat(O, "-0x%x", -val); 126 | else 127 | SStream_concat(O, "-%u", -val); 128 | } 129 | } 130 | 131 | void printUInt32Bang(SStream *O, uint32_t val) 132 | { 133 | if (val > HEX_THRESHOLD) 134 | SStream_concat(O, "#0x%x", val); 135 | else 136 | SStream_concat(O, "#%u", val); 137 | } 138 | 139 | void printUInt32(SStream *O, uint32_t val) 140 | { 141 | if (val > HEX_THRESHOLD) 142 | SStream_concat(O, "0x%x", val); 143 | else 144 | SStream_concat(O, "%u", val); 145 | } 146 | 147 | /* 148 | int main() 149 | { 150 | SStream ss; 151 | int64_t i; 152 | 153 | SStream_Init(&ss); 154 | 155 | SStream_concat(&ss, "hello "); 156 | SStream_concat(&ss, "%d - 0x%x", 200, 16); 157 | 158 | i = 123; 159 | SStream_concat(&ss, " + %ld", i); 160 | SStream_concat(&ss, "%s", "haaaaa"); 161 | 162 | printf("%s\n", ss.buffer); 163 | 164 | return 0; 165 | } 166 | */ 167 | -------------------------------------------------------------------------------- /capstone/SStream.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_SSTREAM_H_ 5 | #define CS_SSTREAM_H_ 6 | 7 | typedef struct SStream { 8 | char buffer[512]; 9 | int index; 10 | } SStream; 11 | 12 | void SStream_Init(SStream *ss); 13 | 14 | void SStream_concat(SStream *ss, const char *fmt, ...); 15 | 16 | void SStream_concat0(SStream *ss, char *s); 17 | 18 | void printInt64Bang(SStream *O, int64_t val); 19 | 20 | void printUInt64Bang(SStream *O, uint64_t val); 21 | 22 | void printInt64(SStream *O, int64_t val); 23 | 24 | void printInt32Bang(SStream *O, int32_t val); 25 | 26 | void printInt32(SStream *O, int32_t val); 27 | 28 | void printUInt32Bang(SStream *O, uint32_t val); 29 | 30 | void printUInt32(SStream *O, uint32_t val); 31 | 32 | // print number in decimal mode 33 | void printInt32BangDec(SStream *O, int32_t val); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /capstone/arch/AArch64/AArch64AddressingModes.h: -------------------------------------------------------------------------------- 1 | //===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file contains the AArch64 addressing mode implementation stuff. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef CS_AARCH64_ADDRESSINGMODES_H 15 | #define CS_AARCH64_ADDRESSINGMODES_H 16 | 17 | /* Capstone Disassembly Engine */ 18 | /* By Nguyen Anh Quynh , 2014 */ 19 | 20 | #include "../../MathExtras.h" 21 | 22 | /// AArch64_AM - AArch64 Addressing Mode Stuff 23 | 24 | //===----------------------------------------------------------------------===// 25 | // Shifts 26 | // 27 | 28 | typedef enum AArch64_AM_ShiftExtendType { 29 | AArch64_AM_InvalidShiftExtend = -1, 30 | AArch64_AM_LSL = 0, 31 | AArch64_AM_LSR, 32 | AArch64_AM_ASR, 33 | AArch64_AM_ROR, 34 | AArch64_AM_MSL, 35 | 36 | AArch64_AM_UXTB, 37 | AArch64_AM_UXTH, 38 | AArch64_AM_UXTW, 39 | AArch64_AM_UXTX, 40 | 41 | AArch64_AM_SXTB, 42 | AArch64_AM_SXTH, 43 | AArch64_AM_SXTW, 44 | AArch64_AM_SXTX, 45 | } AArch64_AM_ShiftExtendType; 46 | 47 | /// getShiftName - Get the string encoding for the shift type. 48 | static inline const char *AArch64_AM_getShiftExtendName(AArch64_AM_ShiftExtendType ST) 49 | { 50 | switch (ST) { 51 | default: return NULL; // never reach 52 | case AArch64_AM_LSL: return "lsl"; 53 | case AArch64_AM_LSR: return "lsr"; 54 | case AArch64_AM_ASR: return "asr"; 55 | case AArch64_AM_ROR: return "ror"; 56 | case AArch64_AM_MSL: return "msl"; 57 | case AArch64_AM_UXTB: return "uxtb"; 58 | case AArch64_AM_UXTH: return "uxth"; 59 | case AArch64_AM_UXTW: return "uxtw"; 60 | case AArch64_AM_UXTX: return "uxtx"; 61 | case AArch64_AM_SXTB: return "sxtb"; 62 | case AArch64_AM_SXTH: return "sxth"; 63 | case AArch64_AM_SXTW: return "sxtw"; 64 | case AArch64_AM_SXTX: return "sxtx"; 65 | } 66 | } 67 | 68 | /// getShiftType - Extract the shift type. 69 | static inline AArch64_AM_ShiftExtendType AArch64_AM_getShiftType(unsigned Imm) 70 | { 71 | switch ((Imm >> 6) & 0x7) { 72 | default: return AArch64_AM_InvalidShiftExtend; 73 | case 0: return AArch64_AM_LSL; 74 | case 1: return AArch64_AM_LSR; 75 | case 2: return AArch64_AM_ASR; 76 | case 3: return AArch64_AM_ROR; 77 | case 4: return AArch64_AM_MSL; 78 | } 79 | } 80 | 81 | /// getShiftValue - Extract the shift value. 82 | static inline unsigned AArch64_AM_getShiftValue(unsigned Imm) 83 | { 84 | return Imm & 0x3f; 85 | } 86 | 87 | //===----------------------------------------------------------------------===// 88 | // Extends 89 | // 90 | 91 | /// getArithShiftValue - get the arithmetic shift value. 92 | static inline unsigned AArch64_AM_getArithShiftValue(unsigned Imm) 93 | { 94 | return Imm & 0x7; 95 | } 96 | 97 | /// getExtendType - Extract the extend type for operands of arithmetic ops. 98 | static inline AArch64_AM_ShiftExtendType AArch64_AM_getExtendType(unsigned Imm) 99 | { 100 | // assert((Imm & 0x7) == Imm && "invalid immediate!"); 101 | switch (Imm) { 102 | default: // llvm_unreachable("Compiler bug!"); 103 | case 0: return AArch64_AM_UXTB; 104 | case 1: return AArch64_AM_UXTH; 105 | case 2: return AArch64_AM_UXTW; 106 | case 3: return AArch64_AM_UXTX; 107 | case 4: return AArch64_AM_SXTB; 108 | case 5: return AArch64_AM_SXTH; 109 | case 6: return AArch64_AM_SXTW; 110 | case 7: return AArch64_AM_SXTX; 111 | } 112 | } 113 | 114 | static inline AArch64_AM_ShiftExtendType AArch64_AM_getArithExtendType(unsigned Imm) 115 | { 116 | return AArch64_AM_getExtendType((Imm >> 3) & 0x7); 117 | } 118 | 119 | static inline uint64_t ror(uint64_t elt, unsigned size) 120 | { 121 | return ((elt & 1) << (size-1)) | (elt >> 1); 122 | } 123 | 124 | /// decodeLogicalImmediate - Decode a logical immediate value in the form 125 | /// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the 126 | /// integer value it represents with regSize bits. 127 | static inline uint64_t AArch64_AM_decodeLogicalImmediate(uint64_t val, unsigned regSize) 128 | { 129 | // Extract the N, imms, and immr fields. 130 | unsigned N = (val >> 12) & 1; 131 | unsigned immr = (val >> 6) & 0x3f; 132 | unsigned imms = val & 0x3f; 133 | unsigned i; 134 | 135 | // assert((regSize == 64 || N == 0) && "undefined logical immediate encoding"); 136 | int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f)); 137 | // assert(len >= 0 && "undefined logical immediate encoding"); 138 | unsigned size = (1 << len); 139 | unsigned R = immr & (size - 1); 140 | unsigned S = imms & (size - 1); 141 | // assert(S != size - 1 && "undefined logical immediate encoding"); 142 | uint64_t pattern = (1ULL << (S + 1)) - 1; 143 | for (i = 0; i < R; ++i) 144 | pattern = ror(pattern, size); 145 | 146 | // Replicate the pattern to fill the regSize. 147 | while (size != regSize) { 148 | pattern |= (pattern << size); 149 | size *= 2; 150 | } 151 | 152 | return pattern; 153 | } 154 | 155 | /// isValidDecodeLogicalImmediate - Check to see if the logical immediate value 156 | /// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits) 157 | /// is a valid encoding for an integer value with regSize bits. 158 | static inline bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize) 159 | { 160 | unsigned size; 161 | unsigned S; 162 | int len; 163 | // Extract the N and imms fields needed for checking. 164 | unsigned N = (val >> 12) & 1; 165 | unsigned imms = val & 0x3f; 166 | 167 | if (regSize == 32 && N != 0) // undefined logical immediate encoding 168 | return false; 169 | len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f)); 170 | if (len < 0) // undefined logical immediate encoding 171 | return false; 172 | size = (1 << len); 173 | S = imms & (size - 1); 174 | if (S == size - 1) // undefined logical immediate encoding 175 | return false; 176 | 177 | return true; 178 | } 179 | 180 | //===----------------------------------------------------------------------===// 181 | // Floating-point Immediates 182 | // 183 | static inline float AArch64_AM_getFPImmFloat(unsigned Imm) 184 | { 185 | // We expect an 8-bit binary encoding of a floating-point number here. 186 | union { 187 | uint32_t I; 188 | float F; 189 | } FPUnion; 190 | 191 | uint8_t Sign = (Imm >> 7) & 0x1; 192 | uint8_t Exp = (Imm >> 4) & 0x7; 193 | uint8_t Mantissa = Imm & 0xf; 194 | 195 | // 8-bit FP iEEEE Float Encoding 196 | // abcd efgh aBbbbbbc defgh000 00000000 00000000 197 | // 198 | // where B = NOT(b); 199 | 200 | FPUnion.I = 0; 201 | FPUnion.I |= Sign << 31; 202 | FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; 203 | FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; 204 | FPUnion.I |= (Exp & 0x3) << 23; 205 | FPUnion.I |= Mantissa << 19; 206 | 207 | return FPUnion.F; 208 | } 209 | 210 | //===--------------------------------------------------------------------===// 211 | // AdvSIMD Modified Immediates 212 | //===--------------------------------------------------------------------===// 213 | 214 | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType10(uint8_t Imm) 215 | { 216 | uint64_t EncVal = 0; 217 | if (Imm & 0x80) EncVal |= 0xff00000000000000ULL; 218 | if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL; 219 | if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL; 220 | if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL; 221 | if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL; 222 | if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL; 223 | if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL; 224 | if (Imm & 0x01) EncVal |= 0x00000000000000ffULL; 225 | return EncVal; 226 | } 227 | 228 | #endif 229 | -------------------------------------------------------------------------------- /capstone/arch/AArch64/AArch64Disassembler.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_AARCH64_DISASSEMBLER_H 5 | #define CS_AARCH64_DISASSEMBLER_H 6 | 7 | #include 8 | 9 | #include "../../include/capstone.h" 10 | #include "../../MCRegisterInfo.h" 11 | #include "../../MCInst.h" 12 | 13 | void AArch64_init(MCRegisterInfo *MRI); 14 | 15 | bool AArch64_getInstruction(csh ud, const uint8_t *code, size_t code_len, 16 | MCInst *instr, uint16_t *size, uint64_t address, void *info); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /capstone/arch/AArch64/AArch64GenSubtargetInfo.inc: -------------------------------------------------------------------------------- 1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ 2 | |* *| 3 | |*Subtarget Enumeration Source Fragment *| 4 | |* *| 5 | |* Automatically generated file, do not edit! *| 6 | |* *| 7 | \*===----------------------------------------------------------------------===*/ 8 | 9 | /* Capstone Disassembly Engine, http://www.capstone-engine.org */ 10 | /* By Nguyen Anh Quynh , 2013-2014 */ 11 | 12 | 13 | #ifdef GET_SUBTARGETINFO_ENUM 14 | #undef GET_SUBTARGETINFO_ENUM 15 | 16 | enum { 17 | AArch64_FeatureCRC = 1ULL << 0, 18 | AArch64_FeatureCrypto = 1ULL << 1, 19 | AArch64_FeatureFPARMv8 = 1ULL << 2, 20 | AArch64_FeatureNEON = 1ULL << 3, 21 | AArch64_FeatureZCRegMove = 1ULL << 4, 22 | AArch64_FeatureZCZeroing = 1ULL << 5, 23 | AArch64_ProcA53 = 1ULL << 6, 24 | AArch64_ProcA57 = 1ULL << 7, 25 | AArch64_ProcCyclone = 1ULL << 8 26 | }; 27 | 28 | #endif // GET_SUBTARGETINFO_ENUM 29 | 30 | -------------------------------------------------------------------------------- /capstone/arch/AArch64/AArch64InstPrinter.h: -------------------------------------------------------------------------------- 1 | //===-- AArch64InstPrinter.h - Convert AArch64 MCInst to assembly syntax --===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This class prints an AArch64 MCInst to a .s file. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | /* Capstone Disassembly Engine */ 15 | /* By Nguyen Anh Quynh , 2013-2014 */ 16 | 17 | #ifndef CS_LLVM_AARCH64INSTPRINTER_H 18 | #define CS_LLVM_AARCH64INSTPRINTER_H 19 | 20 | #include "../../MCInst.h" 21 | #include "../../MCRegisterInfo.h" 22 | #include "../../SStream.h" 23 | 24 | void AArch64_printInst(MCInst *MI, SStream *O, void *); 25 | 26 | void AArch64_post_printer(csh handle, cs_insn *pub_insn, char *insn_asm, MCInst *mci); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /capstone/arch/AArch64/AArch64Mapping.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_ARM64_MAP_H 5 | #define CS_ARM64_MAP_H 6 | 7 | #include "../../include/capstone.h" 8 | 9 | // return name of regiser in friendly string 10 | const char *AArch64_reg_name(csh handle, unsigned int reg); 11 | 12 | // given internal insn id, return public instruction info 13 | void AArch64_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); 14 | 15 | const char *AArch64_insn_name(csh handle, unsigned int id); 16 | 17 | const char *AArch64_group_name(csh handle, unsigned int id); 18 | 19 | // map instruction name to public instruction ID 20 | arm64_reg AArch64_map_insn(const char *name); 21 | 22 | // map internal vregister to public register 23 | arm64_reg AArch64_map_vregister(unsigned int r); 24 | 25 | void arm64_op_addReg(MCInst *MI, int reg); 26 | 27 | void arm64_op_addVectorArrSpecifier(MCInst * MI, int sp); 28 | 29 | void arm64_op_addVectorElementSizeSpecifier(MCInst * MI, int sp); 30 | 31 | void arm64_op_addFP(MCInst *MI, float fp); 32 | 33 | void arm64_op_addImm(MCInst *MI, int64_t imm); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /capstone/arch/AArch64/AArch64Module.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Dang Hoang Vu 2013 */ 3 | 4 | #ifdef CAPSTONE_HAS_ARM64 5 | 6 | #include "../../utils.h" 7 | #include "../../MCRegisterInfo.h" 8 | #include "AArch64Disassembler.h" 9 | #include "AArch64InstPrinter.h" 10 | #include "AArch64Mapping.h" 11 | 12 | static cs_err init(cs_struct *ud) 13 | { 14 | MCRegisterInfo *mri; 15 | 16 | // verify if requested mode is valid 17 | if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_BIG_ENDIAN)) 18 | return CS_ERR_MODE; 19 | 20 | mri = cs_mem_malloc(sizeof(*mri)); 21 | 22 | AArch64_init(mri); 23 | ud->printer = AArch64_printInst; 24 | ud->printer_info = mri; 25 | ud->getinsn_info = mri; 26 | ud->disasm = AArch64_getInstruction; 27 | ud->reg_name = AArch64_reg_name; 28 | ud->insn_id = AArch64_get_insn_id; 29 | ud->insn_name = AArch64_insn_name; 30 | ud->group_name = AArch64_group_name; 31 | ud->post_printer = AArch64_post_printer; 32 | 33 | return CS_ERR_OK; 34 | } 35 | 36 | static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) 37 | { 38 | return CS_ERR_OK; 39 | } 40 | 41 | static void destroy(cs_struct *handle) 42 | { 43 | } 44 | 45 | void AArch64_enable(void) 46 | { 47 | arch_init[CS_ARCH_ARM64] = init; 48 | arch_option[CS_ARCH_ARM64] = option; 49 | arch_destroy[CS_ARCH_ARM64] = destroy; 50 | 51 | // support this arch 52 | all_arch |= (1 << CS_ARCH_ARM64); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /capstone/arch/ARM/ARMDisassembler.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_ARMDISASSEMBLER_H 5 | #define CS_ARMDISASSEMBLER_H 6 | 7 | #include "../../include/capstone.h" 8 | #include "../../MCRegisterInfo.h" 9 | 10 | void ARM_init(MCRegisterInfo *MRI); 11 | 12 | bool ARM_getInstruction(csh handle, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); 13 | 14 | bool Thumb_getInstruction(csh handle, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); 15 | 16 | uint64_t ARM_getFeatureBits(unsigned int mode); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /capstone/arch/ARM/ARMGenSubtargetInfo.inc: -------------------------------------------------------------------------------- 1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ 2 | |* *| 3 | |*Subtarget Enumeration Source Fragment *| 4 | |* *| 5 | |* Automatically generated file, do not edit! *| 6 | |* *| 7 | \*===----------------------------------------------------------------------===*/ 8 | 9 | /* Capstone Disassembly Engine, http://www.capstone-engine.org */ 10 | /* By Nguyen Anh Quynh , 2013-2014 */ 11 | 12 | 13 | #ifdef GET_SUBTARGETINFO_ENUM 14 | #undef GET_SUBTARGETINFO_ENUM 15 | 16 | #define ARM_FeatureAAPCS (1ULL << 0) 17 | #define ARM_FeatureAClass (1ULL << 1) 18 | #define ARM_FeatureAPCS (1ULL << 2) 19 | #define ARM_FeatureAvoidMOVsShOp (1ULL << 3) 20 | #define ARM_FeatureAvoidPartialCPSR (1ULL << 4) 21 | #define ARM_FeatureCRC (1ULL << 5) 22 | #define ARM_FeatureCrypto (1ULL << 6) 23 | #define ARM_FeatureD16 (1ULL << 7) 24 | #define ARM_FeatureDB (1ULL << 8) 25 | #define ARM_FeatureDSPThumb2 (1ULL << 9) 26 | #define ARM_FeatureFP16 (1ULL << 10) 27 | #define ARM_FeatureFPARMv8 (1ULL << 11) 28 | #define ARM_FeatureHWDiv (1ULL << 12) 29 | #define ARM_FeatureHWDivARM (1ULL << 13) 30 | #define ARM_FeatureHasRAS (1ULL << 14) 31 | #define ARM_FeatureHasSlowFPVMLx (1ULL << 15) 32 | #define ARM_FeatureMClass (1ULL << 16) 33 | #define ARM_FeatureMP (1ULL << 17) 34 | #define ARM_FeatureNEON (1ULL << 18) 35 | #define ARM_FeatureNEONForFP (1ULL << 19) 36 | #define ARM_FeatureNaClTrap (1ULL << 20) 37 | #define ARM_FeatureNoARM (1ULL << 21) 38 | #define ARM_FeaturePerfMon (1ULL << 22) 39 | #define ARM_FeaturePref32BitThumb (1ULL << 23) 40 | #define ARM_FeatureRClass (1ULL << 24) 41 | #define ARM_FeatureSlowFPBrcc (1ULL << 25) 42 | #define ARM_FeatureT2XtPk (1ULL << 26) 43 | #define ARM_FeatureThumb2 (1ULL << 27) 44 | #define ARM_FeatureTrustZone (1ULL << 28) 45 | #define ARM_FeatureVFP2 (1ULL << 29) 46 | #define ARM_FeatureVFP3 (1ULL << 30) 47 | #define ARM_FeatureVFP4 (1ULL << 31) 48 | #define ARM_FeatureVFPOnlySP (1ULL << 32) 49 | #define ARM_FeatureVMLxForwarding (1ULL << 33) 50 | #define ARM_FeatureVirtualization (1ULL << 34) 51 | #define ARM_FeatureZCZeroing (1ULL << 35) 52 | #define ARM_HasV4TOps (1ULL << 36) 53 | #define ARM_HasV5TEOps (1ULL << 37) 54 | #define ARM_HasV5TOps (1ULL << 38) 55 | #define ARM_HasV6MOps (1ULL << 39) 56 | #define ARM_HasV6Ops (1ULL << 40) 57 | #define ARM_HasV6T2Ops (1ULL << 41) 58 | #define ARM_HasV7Ops (1ULL << 42) 59 | #define ARM_HasV8Ops (1ULL << 43) 60 | #define ARM_ModeThumb (1ULL << 44) 61 | #define ARM_ProcA5 (1ULL << 45) 62 | #define ARM_ProcA7 (1ULL << 46) 63 | #define ARM_ProcA8 (1ULL << 47) 64 | #define ARM_ProcA9 (1ULL << 48) 65 | #define ARM_ProcA12 (1ULL << 49) 66 | #define ARM_ProcA15 (1ULL << 50) 67 | #define ARM_ProcA53 (1ULL << 51) 68 | #define ARM_ProcA57 (1ULL << 52) 69 | #define ARM_ProcKrait (1ULL << 53) 70 | #define ARM_ProcR5 (1ULL << 54) 71 | #define ARM_ProcSwift (1ULL << 55) 72 | 73 | #endif // GET_SUBTARGETINFO_ENUM 74 | 75 | -------------------------------------------------------------------------------- /capstone/arch/ARM/ARMInstPrinter.h: -------------------------------------------------------------------------------- 1 | //===- ARMInstPrinter.h - Convert ARM MCInst to assembly syntax -*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This class prints an ARM MCInst to a .s file. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | /* Capstone Disassembly Engine */ 15 | /* By Nguyen Anh Quynh , 2013-2014 */ 16 | 17 | #ifndef CS_ARMINSTPRINTER_H 18 | #define CS_ARMINSTPRINTER_H 19 | 20 | #include "../../MCInst.h" 21 | #include "../../MCRegisterInfo.h" 22 | #include "../../SStream.h" 23 | 24 | void ARM_printInst(MCInst *MI, SStream *O, void *Info); 25 | void ARM_post_printer(csh handle, cs_insn *pub_insn, char *mnem, MCInst *mci); 26 | 27 | // setup handle->get_regname 28 | void ARM_getRegName(cs_struct *handle, int value); 29 | 30 | // specify vector data type for vector instructions 31 | void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd); 32 | 33 | void ARM_addVectorDataSize(MCInst *MI, int size); 34 | 35 | void ARM_addReg(MCInst *MI, int reg); 36 | 37 | // load usermode registers (LDM, STM) 38 | void ARM_addUserMode(MCInst *MI); 39 | 40 | // sysreg for MRS/MSR 41 | void ARM_addSysReg(MCInst *MI, arm_sysreg reg); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /capstone/arch/ARM/ARMMapping.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_ARM_MAP_H 5 | #define CS_ARM_MAP_H 6 | 7 | #include "../../include/capstone.h" 8 | #include "../../utils.h" 9 | 10 | // return name of regiser in friendly string 11 | const char *ARM_reg_name(csh handle, unsigned int reg); 12 | const char *ARM_reg_name2(csh handle, unsigned int reg); 13 | 14 | // given internal insn id, return public instruction ID 15 | void ARM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); 16 | 17 | const char *ARM_insn_name(csh handle, unsigned int id); 18 | 19 | const char *ARM_group_name(csh handle, unsigned int id); 20 | 21 | // check if this insn is relative branch 22 | bool ARM_rel_branch(cs_struct *h, unsigned int insn_id); 23 | 24 | bool ARM_blx_to_arm_mode(cs_struct *h, unsigned int insn_id); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /capstone/arch/ARM/ARMModule.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Dang Hoang Vu 2013 */ 3 | 4 | #ifdef CAPSTONE_HAS_ARM 5 | 6 | #include "../../cs_priv.h" 7 | #include "../../MCRegisterInfo.h" 8 | #include "ARMDisassembler.h" 9 | #include "ARMInstPrinter.h" 10 | #include "ARMMapping.h" 11 | 12 | static cs_err init(cs_struct *ud) 13 | { 14 | MCRegisterInfo *mri; 15 | 16 | // verify if requested mode is valid 17 | if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_ARM | CS_MODE_V8 | 18 | CS_MODE_MCLASS | CS_MODE_THUMB | CS_MODE_BIG_ENDIAN)) 19 | return CS_ERR_MODE; 20 | 21 | mri = cs_mem_malloc(sizeof(*mri)); 22 | 23 | ARM_init(mri); 24 | ARM_getRegName(ud, 0); // use default get_regname 25 | 26 | ud->printer = ARM_printInst; 27 | ud->printer_info = mri; 28 | ud->reg_name = ARM_reg_name; 29 | ud->insn_id = ARM_get_insn_id; 30 | ud->insn_name = ARM_insn_name; 31 | ud->group_name = ARM_group_name; 32 | ud->post_printer = ARM_post_printer; 33 | 34 | if (ud->mode & CS_MODE_THUMB) 35 | ud->disasm = Thumb_getInstruction; 36 | else 37 | ud->disasm = ARM_getInstruction; 38 | 39 | return CS_ERR_OK; 40 | } 41 | 42 | static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) 43 | { 44 | switch(type) { 45 | case CS_OPT_MODE: 46 | if (value & CS_MODE_THUMB) 47 | handle->disasm = Thumb_getInstruction; 48 | else 49 | handle->disasm = ARM_getInstruction; 50 | 51 | handle->mode = (cs_mode)value; 52 | break; 53 | case CS_OPT_SYNTAX: 54 | ARM_getRegName(handle, (int)value); 55 | handle->syntax = (int)value; 56 | break; 57 | default: 58 | break; 59 | } 60 | 61 | return CS_ERR_OK; 62 | } 63 | 64 | static void destroy(cs_struct *handle) 65 | { 66 | } 67 | 68 | void ARM_enable(void) 69 | { 70 | arch_init[CS_ARCH_ARM] = init; 71 | arch_option[CS_ARCH_ARM] = option; 72 | arch_destroy[CS_ARCH_ARM] = destroy; 73 | 74 | // support this arch 75 | all_arch |= (1 << CS_ARCH_ARM); 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /capstone/arch/PowerPC/PPCDisassembler.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_PPCDISASSEMBLER_H 5 | #define CS_PPCDISASSEMBLER_H 6 | 7 | #include 8 | 9 | #include "../../include/capstone.h" 10 | #include "../../MCRegisterInfo.h" 11 | #include "../../MCInst.h" 12 | 13 | void PPC_init(MCRegisterInfo *MRI); 14 | 15 | bool PPC_getInstruction(csh ud, const uint8_t *code, size_t code_len, 16 | MCInst *instr, uint16_t *size, uint64_t address, void *info); 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /capstone/arch/PowerPC/PPCGenSubtargetInfo.inc: -------------------------------------------------------------------------------- 1 | /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ 2 | |* *| 3 | |*Subtarget Enumeration Source Fragment *| 4 | |* *| 5 | |* Automatically generated file, do not edit! *| 6 | |* *| 7 | \*===----------------------------------------------------------------------===*/ 8 | 9 | /* Capstone Disassembly Engine, http://www.capstone-engine.org */ 10 | /* By Nguyen Anh Quynh , 2013-2014 */ 11 | 12 | 13 | #ifdef GET_SUBTARGETINFO_ENUM 14 | #undef GET_SUBTARGETINFO_ENUM 15 | 16 | #define PPC_DeprecatedDST (1ULL << 0) 17 | #define PPC_DeprecatedMFTB (1ULL << 1) 18 | #define PPC_Directive32 (1ULL << 2) 19 | #define PPC_Directive64 (1ULL << 3) 20 | #define PPC_Directive440 (1ULL << 4) 21 | #define PPC_Directive601 (1ULL << 5) 22 | #define PPC_Directive602 (1ULL << 6) 23 | #define PPC_Directive603 (1ULL << 7) 24 | #define PPC_Directive604 (1ULL << 8) 25 | #define PPC_Directive620 (1ULL << 9) 26 | #define PPC_Directive750 (1ULL << 10) 27 | #define PPC_Directive970 (1ULL << 11) 28 | #define PPC_Directive7400 (1ULL << 12) 29 | #define PPC_DirectiveA2 (1ULL << 13) 30 | #define PPC_DirectiveE500mc (1ULL << 14) 31 | #define PPC_DirectiveE5500 (1ULL << 15) 32 | #define PPC_DirectivePwr3 (1ULL << 16) 33 | #define PPC_DirectivePwr4 (1ULL << 17) 34 | #define PPC_DirectivePwr5 (1ULL << 18) 35 | #define PPC_DirectivePwr5x (1ULL << 19) 36 | #define PPC_DirectivePwr6 (1ULL << 20) 37 | #define PPC_DirectivePwr6x (1ULL << 21) 38 | #define PPC_DirectivePwr7 (1ULL << 22) 39 | #define PPC_DirectivePwr8 (1ULL << 23) 40 | #define PPC_Feature64Bit (1ULL << 24) 41 | #define PPC_Feature64BitRegs (1ULL << 25) 42 | #define PPC_FeatureAltivec (1ULL << 26) 43 | #define PPC_FeatureBookE (1ULL << 27) 44 | #define PPC_FeatureCRBits (1ULL << 28) 45 | #define PPC_FeatureE500 (1ULL << 29) 46 | #define PPC_FeatureELFv1 (1ULL << 30) 47 | #define PPC_FeatureELFv2 (1ULL << 31) 48 | #define PPC_FeatureFCPSGN (1ULL << 32) 49 | #define PPC_FeatureFPCVT (1ULL << 33) 50 | #define PPC_FeatureFPRND (1ULL << 34) 51 | #define PPC_FeatureFRE (1ULL << 35) 52 | #define PPC_FeatureFRES (1ULL << 36) 53 | #define PPC_FeatureFRSQRTE (1ULL << 37) 54 | #define PPC_FeatureFRSQRTES (1ULL << 38) 55 | #define PPC_FeatureFSqrt (1ULL << 39) 56 | #define PPC_FeatureISEL (1ULL << 40) 57 | #define PPC_FeatureLDBRX (1ULL << 41) 58 | #define PPC_FeatureLFIWAX (1ULL << 42) 59 | #define PPC_FeatureMFOCRF (1ULL << 43) 60 | #define PPC_FeaturePOPCNTD (1ULL << 44) 61 | #define PPC_FeaturePPC4xx (1ULL << 45) 62 | #define PPC_FeaturePPC6xx (1ULL << 46) 63 | #define PPC_FeatureQPX (1ULL << 47) 64 | #define PPC_FeatureRecipPrec (1ULL << 48) 65 | #define PPC_FeatureSPE (1ULL << 49) 66 | #define PPC_FeatureSTFIWX (1ULL << 50) 67 | #define PPC_FeatureVSX (1ULL << 51) 68 | 69 | #endif // GET_SUBTARGETINFO_ENUM 70 | 71 | -------------------------------------------------------------------------------- /capstone/arch/PowerPC/PPCInstPrinter.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_PPCINSTPRINTER_H 5 | #define CS_PPCINSTPRINTER_H 6 | 7 | #include "../../MCInst.h" 8 | #include "../../MCRegisterInfo.h" 9 | #include "../../SStream.h" 10 | 11 | void PPC_printInst(MCInst *MI, SStream *O, void *Info); 12 | 13 | void PPC_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /capstone/arch/PowerPC/PPCMapping.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_PPC_MAP_H 5 | #define CS_PPC_MAP_H 6 | 7 | #include "../../include/capstone.h" 8 | 9 | // return name of regiser in friendly string 10 | const char *PPC_reg_name(csh handle, unsigned int reg); 11 | 12 | // given internal insn id, return public instruction info 13 | void PPC_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); 14 | 15 | const char *PPC_insn_name(csh handle, unsigned int id); 16 | const char *PPC_group_name(csh handle, unsigned int id); 17 | 18 | // map internal raw register to 'public' register 19 | ppc_reg PPC_map_register(unsigned int r); 20 | 21 | struct ppc_alias { 22 | unsigned int id; // instruction id 23 | int cc; // code condition 24 | const char *mnem; 25 | }; 26 | 27 | // given alias mnemonic, return instruction ID & CC 28 | bool PPC_alias_insn(const char *name, struct ppc_alias *alias); 29 | 30 | // check if this insn is relative branch 31 | bool PPC_abs_branch(cs_struct *h, unsigned int id); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /capstone/arch/PowerPC/PPCModule.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifdef CAPSTONE_HAS_POWERPC 5 | 6 | #include "../../utils.h" 7 | #include "../../MCRegisterInfo.h" 8 | #include "PPCDisassembler.h" 9 | #include "PPCInstPrinter.h" 10 | #include "PPCMapping.h" 11 | 12 | static cs_err init(cs_struct *ud) 13 | { 14 | MCRegisterInfo *mri; 15 | 16 | // verify if requested mode is valid 17 | if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | 18 | CS_MODE_BIG_ENDIAN)) 19 | return CS_ERR_MODE; 20 | 21 | mri = (MCRegisterInfo *) cs_mem_malloc(sizeof(*mri)); 22 | 23 | PPC_init(mri); 24 | ud->printer = PPC_printInst; 25 | ud->printer_info = mri; 26 | ud->getinsn_info = mri; 27 | ud->disasm = PPC_getInstruction; 28 | ud->post_printer = PPC_post_printer; 29 | 30 | ud->reg_name = PPC_reg_name; 31 | ud->insn_id = PPC_get_insn_id; 32 | ud->insn_name = PPC_insn_name; 33 | ud->group_name = PPC_group_name; 34 | 35 | return CS_ERR_OK; 36 | } 37 | 38 | static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) 39 | { 40 | if (type == CS_OPT_SYNTAX) 41 | handle->syntax = (int) value; 42 | 43 | return CS_ERR_OK; 44 | } 45 | 46 | static void destroy(cs_struct *handle) 47 | { 48 | } 49 | 50 | void PPC_enable(void) 51 | { 52 | arch_init[CS_ARCH_PPC] = init; 53 | arch_option[CS_ARCH_PPC] = option; 54 | arch_destroy[CS_ARCH_PPC] = destroy; 55 | 56 | // support this arch 57 | all_arch |= (1 << CS_ARCH_PPC); 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /capstone/arch/PowerPC/PPCPredicates.h: -------------------------------------------------------------------------------- 1 | //===-- PPCPredicates.h - PPC Branch Predicate Information ------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file describes the PowerPC branch predicates. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | /* Capstone Disassembly Engine */ 15 | /* By Nguyen Anh Quynh , 2013-2014 */ 16 | 17 | #ifndef CS_POWERPC_PPCPREDICATES_H 18 | #define CS_POWERPC_PPCPREDICATES_H 19 | 20 | #include "../../include/ppc.h" 21 | 22 | // NOTE: duplicate of ppc_bc in ppc.h to maitain code compatibility with LLVM 23 | typedef enum ppc_predicate { 24 | PPC_PRED_LT = (0 << 5) | 12, 25 | PPC_PRED_LE = (1 << 5) | 4, 26 | PPC_PRED_EQ = (2 << 5) | 12, 27 | PPC_PRED_GE = (0 << 5) | 4, 28 | PPC_PRED_GT = (1 << 5) | 12, 29 | PPC_PRED_NE = (2 << 5) | 4, 30 | PPC_PRED_UN = (3 << 5) | 12, 31 | PPC_PRED_NU = (3 << 5) | 4, 32 | PPC_PRED_LT_MINUS = (0 << 5) | 14, 33 | PPC_PRED_LE_MINUS = (1 << 5) | 6, 34 | PPC_PRED_EQ_MINUS = (2 << 5) | 14, 35 | PPC_PRED_GE_MINUS = (0 << 5) | 6, 36 | PPC_PRED_GT_MINUS = (1 << 5) | 14, 37 | PPC_PRED_NE_MINUS = (2 << 5) | 6, 38 | PPC_PRED_UN_MINUS = (3 << 5) | 14, 39 | PPC_PRED_NU_MINUS = (3 << 5) | 6, 40 | PPC_PRED_LT_PLUS = (0 << 5) | 15, 41 | PPC_PRED_LE_PLUS = (1 << 5) | 7, 42 | PPC_PRED_EQ_PLUS = (2 << 5) | 15, 43 | PPC_PRED_GE_PLUS = (0 << 5) | 7, 44 | PPC_PRED_GT_PLUS = (1 << 5) | 15, 45 | PPC_PRED_NE_PLUS = (2 << 5) | 7, 46 | PPC_PRED_UN_PLUS = (3 << 5) | 15, 47 | PPC_PRED_NU_PLUS = (3 << 5) | 7, 48 | 49 | // When dealing with individual condition-register bits, we have simple set 50 | // and unset predicates. 51 | PPC_PRED_BIT_SET = 1024, 52 | PPC_PRED_BIT_UNSET = 1025 53 | } ppc_predicate; 54 | 55 | /// Invert the specified predicate. != -> ==, < -> >=. 56 | ppc_predicate InvertPredicate(ppc_predicate Opcode); 57 | 58 | /// Assume the condition register is set by MI(a,b), return the predicate if 59 | /// we modify the instructions such that condition register is set by MI(b,a). 60 | ppc_predicate getSwappedPredicate(ppc_predicate Opcode); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /capstone/arch/X86/X86BaseInfo.h: -------------------------------------------------------------------------------- 1 | //===-- X86BaseInfo.h - Top level definitions for X86 -------- --*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file contains small standalone helper functions and enum definitions for 11 | // the X86 target useful for the compiler back-end and the MC libraries. 12 | // As such, it deliberately does not include references to LLVM core 13 | // code gen types, passes, etc.. 14 | // 15 | //===----------------------------------------------------------------------===// 16 | 17 | #ifndef CS_X86_BASEINFO_H 18 | #define CS_X86_BASEINFO_H 19 | 20 | /* Capstone Disassembly Engine */ 21 | /* By Nguyen Anh Quynh , 2013-2014 */ 22 | 23 | // Enums for memory operand decoding. Each memory operand is represented with 24 | // a 5 operand sequence in the form: 25 | // [BaseReg, ScaleAmt, IndexReg, Disp, Segment] 26 | // These enums help decode this. 27 | enum { 28 | X86_AddrBaseReg = 0, 29 | X86_AddrScaleAmt = 1, 30 | X86_AddrIndexReg = 2, 31 | X86_AddrDisp = 3, 32 | 33 | /// AddrSegmentReg - The operand # of the segment in the memory operand. 34 | X86_AddrSegmentReg = 4, 35 | 36 | /// AddrNumOperands - Total number of operands in a memory reference. 37 | X86_AddrNumOperands = 5 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /capstone/arch/X86/X86Disassembler.h: -------------------------------------------------------------------------------- 1 | //===-- X86Disassembler.h - Disassembler for x86 and x86_64 -----*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // The X86 disassembler is a table-driven disassembler for the 16-, 32-, and 11 | // 64-bit X86 instruction sets. The main decode sequence for an assembly 12 | // instruction in this disassembler is: 13 | // 14 | // 1. Read the prefix bytes and determine the attributes of the instruction. 15 | // These attributes, recorded in enum attributeBits 16 | // (X86DisassemblerDecoderCommon.h), form a bitmask. The table CONTEXTS_SYM 17 | // provides a mapping from bitmasks to contexts, which are represented by 18 | // enum InstructionContext (ibid.). 19 | // 20 | // 2. Read the opcode, and determine what kind of opcode it is. The 21 | // disassembler distinguishes four kinds of opcodes, which are enumerated in 22 | // OpcodeType (X86DisassemblerDecoderCommon.h): one-byte (0xnn), two-byte 23 | // (0x0f 0xnn), three-byte-38 (0x0f 0x38 0xnn), or three-byte-3a 24 | // (0x0f 0x3a 0xnn). Mandatory prefixes are treated as part of the context. 25 | // 26 | // 3. Depending on the opcode type, look in one of four ClassDecision structures 27 | // (X86DisassemblerDecoderCommon.h). Use the opcode class to determine which 28 | // OpcodeDecision (ibid.) to look the opcode in. Look up the opcode, to get 29 | // a ModRMDecision (ibid.). 30 | // 31 | // 4. Some instructions, such as escape opcodes or extended opcodes, or even 32 | // instructions that have ModRM*Reg / ModRM*Mem forms in LLVM, need the 33 | // ModR/M byte to complete decode. The ModRMDecision's type is an entry from 34 | // ModRMDecisionType (X86DisassemblerDecoderCommon.h) that indicates if the 35 | // ModR/M byte is required and how to interpret it. 36 | // 37 | // 5. After resolving the ModRMDecision, the disassembler has a unique ID 38 | // of type InstrUID (X86DisassemblerDecoderCommon.h). Looking this ID up in 39 | // INSTRUCTIONS_SYM yields the name of the instruction and the encodings and 40 | // meanings of its operands. 41 | // 42 | // 6. For each operand, its encoding is an entry from OperandEncoding 43 | // (X86DisassemblerDecoderCommon.h) and its type is an entry from 44 | // OperandType (ibid.). The encoding indicates how to read it from the 45 | // instruction; the type indicates how to interpret the value once it has 46 | // been read. For example, a register operand could be stored in the R/M 47 | // field of the ModR/M byte, the REG field of the ModR/M byte, or added to 48 | // the main opcode. This is orthogonal from its meaning (an GPR or an XMM 49 | // register, for instance). Given this information, the operands can be 50 | // extracted and interpreted. 51 | // 52 | // 7. As the last step, the disassembler translates the instruction information 53 | // and operands into a format understandable by the client - in this case, an 54 | // MCInst for use by the MC infrastructure. 55 | // 56 | // The disassembler is broken broadly into two parts: the table emitter that 57 | // emits the instruction decode tables discussed above during compilation, and 58 | // the disassembler itself. The table emitter is documented in more detail in 59 | // utils/TableGen/X86DisassemblerEmitter.h. 60 | // 61 | // X86Disassembler.h contains the public interface for the disassembler, 62 | // adhering to the MCDisassembler interface. 63 | // X86Disassembler.cpp contains the code responsible for step 7, and for 64 | // invoking the decoder to execute steps 1-6. 65 | // X86DisassemblerDecoderCommon.h contains the definitions needed by both the 66 | // table emitter and the disassembler. 67 | // X86DisassemblerDecoder.h contains the public interface of the decoder, 68 | // factored out into C for possible use by other projects. 69 | // X86DisassemblerDecoder.c contains the source code of the decoder, which is 70 | // responsible for steps 1-6. 71 | // 72 | //===----------------------------------------------------------------------===// 73 | 74 | /* Capstone Disassembly Engine */ 75 | /* By Nguyen Anh Quynh , 2013-2014 */ 76 | 77 | #ifndef CS_X86_DISASSEMBLER_H 78 | #define CS_X86_DISASSEMBLER_H 79 | 80 | #include 81 | 82 | #include "../../include/capstone.h" 83 | 84 | #include "../../MCInst.h" 85 | 86 | #include "../../MCRegisterInfo.h" 87 | #include "X86DisassemblerDecoderCommon.h" 88 | 89 | bool X86_getInstruction(csh handle, const uint8_t *code, size_t code_len, 90 | MCInst *instr, uint16_t *size, uint64_t address, void *info); 91 | 92 | void X86_init(MCRegisterInfo *MRI); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /capstone/arch/X86/X86InstPrinter.h: -------------------------------------------------------------------------------- 1 | //= X86IntelInstPrinter.h - Convert X86 MCInst to assembly syntax -*- C++ -*-=// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This class prints an X86 MCInst to Intel style .s file syntax. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | /* Capstone Disassembly Engine */ 15 | /* By Nguyen Anh Quynh , 2013-2014 */ 16 | 17 | #ifndef CS_X86_INSTPRINTER_H 18 | #define CS_X86_INSTPRINTER_H 19 | 20 | #include "../../MCInst.h" 21 | #include "../../SStream.h" 22 | 23 | void X86_Intel_printInst(MCInst *MI, SStream *OS, void *Info); 24 | void X86_ATT_printInst(MCInst *MI, SStream *OS, void *Info); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /capstone/arch/X86/X86Mapping.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_X86_MAP_H 5 | #define CS_X86_MAP_H 6 | 7 | #include "../../include/capstone.h" 8 | #include "../../cs_priv.h" 9 | 10 | // map sib_base to x86_reg 11 | x86_reg x86_map_sib_base(int r); 12 | 13 | // map sib_index to x86_reg 14 | x86_reg x86_map_sib_index(int r); 15 | 16 | // map seg_override to x86_reg 17 | x86_reg x86_map_segment(int r); 18 | 19 | // return name of regiser in friendly string 20 | const char *X86_reg_name(csh handle, unsigned int reg); 21 | 22 | // given internal insn id, return public instruction info 23 | void X86_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id); 24 | 25 | // return insn name, given insn id 26 | const char *X86_insn_name(csh handle, unsigned int id); 27 | 28 | // return group name, given group id 29 | const char *X86_group_name(csh handle, unsigned int id); 30 | 31 | // return register of given instruction id 32 | // return 0 if not found 33 | // this is to handle instructions embedding accumulate registers into AsmStrs[] 34 | x86_reg X86_insn_reg_intel(unsigned int id); 35 | x86_reg X86_insn_reg_att(unsigned int id); 36 | bool X86_insn_reg_intel2(unsigned int id, x86_reg *reg1, x86_reg *reg2); 37 | bool X86_insn_reg_att2(unsigned int id, x86_reg *reg1, x86_reg *reg2); 38 | 39 | extern uint64_t arch_masks[9]; 40 | 41 | // handle LOCK/REP/REPNE prefixes 42 | // return True if we patch mnemonic, like in MULPD case 43 | bool X86_lockrep(MCInst *MI, SStream *O); 44 | 45 | // map registers to sizes 46 | extern uint8_t regsize_map_32[]; 47 | extern uint8_t regsize_map_64[]; 48 | 49 | void op_addReg(MCInst *MI, int reg); 50 | void op_addImm(MCInst *MI, int v); 51 | 52 | void op_addAvxBroadcast(MCInst *MI, x86_avx_bcast v); 53 | 54 | void op_addSseCC(MCInst *MI, int v); 55 | void op_addAvxCC(MCInst *MI, int v); 56 | 57 | void op_addAvxZeroOpmask(MCInst *MI); 58 | 59 | void op_addAvxSae(MCInst *MI); 60 | 61 | void op_addAvxRoundingMode(MCInst *MI, int v); 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /capstone/arch/X86/X86Module.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Dang Hoang Vu 2013 */ 3 | 4 | #ifdef CAPSTONE_HAS_X86 5 | 6 | #include "../../cs_priv.h" 7 | #include "../../MCRegisterInfo.h" 8 | #include "X86Disassembler.h" 9 | #include "X86InstPrinter.h" 10 | #include "X86Mapping.h" 11 | 12 | static cs_err init(cs_struct *ud) 13 | { 14 | MCRegisterInfo *mri; 15 | 16 | // verify if requested mode is valid 17 | if (ud->mode & ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_32 | CS_MODE_64 | CS_MODE_16)) 18 | return CS_ERR_MODE; 19 | 20 | mri = cs_mem_malloc(sizeof(*mri)); 21 | 22 | X86_init(mri); 23 | 24 | // by default, we use Intel syntax 25 | ud->printer = X86_Intel_printInst; 26 | ud->syntax = CS_OPT_SYNTAX_INTEL; 27 | ud->printer_info = mri; 28 | ud->disasm = X86_getInstruction; 29 | ud->reg_name = X86_reg_name; 30 | ud->insn_id = X86_get_insn_id; 31 | ud->insn_name = X86_insn_name; 32 | ud->group_name = X86_group_name; 33 | ud->post_printer = NULL;; 34 | 35 | if (ud->mode == CS_MODE_64) 36 | ud->regsize_map = regsize_map_64; 37 | else 38 | ud->regsize_map = regsize_map_32; 39 | 40 | return CS_ERR_OK; 41 | } 42 | 43 | static cs_err option(cs_struct *handle, cs_opt_type type, size_t value) 44 | { 45 | switch(type) { 46 | default: 47 | break; 48 | case CS_OPT_MODE: 49 | if (value == CS_MODE_64) 50 | handle->regsize_map = regsize_map_64; 51 | else 52 | handle->regsize_map = regsize_map_32; 53 | 54 | handle->mode = (cs_mode)value; 55 | break; 56 | case CS_OPT_SYNTAX: 57 | switch(value) { 58 | default: 59 | // wrong syntax value 60 | handle->errnum = CS_ERR_OPTION; 61 | return CS_ERR_OPTION; 62 | 63 | case CS_OPT_SYNTAX_DEFAULT: 64 | case CS_OPT_SYNTAX_INTEL: 65 | handle->printer = X86_Intel_printInst; 66 | handle->syntax = CS_OPT_SYNTAX_INTEL; 67 | break; 68 | 69 | case CS_OPT_SYNTAX_ATT: 70 | #if !defined(CAPSTONE_DIET) && !defined(CAPSTONE_X86_ATT_DISABLE) 71 | handle->printer = X86_ATT_printInst; 72 | handle->syntax = CS_OPT_SYNTAX_ATT; 73 | break; 74 | #elif !defined(CAPSTONE_DIET) && defined(CAPSTONE_X86_ATT_DISABLE) 75 | // ATT syntax is unsupported 76 | handle->errnum = CS_ERR_X86_ATT; 77 | return CS_ERR_X86_ATT; 78 | #else // CAPSTONE_DIET 79 | // this is irrelevant in CAPSTONE_DIET mode 80 | handle->errnum = CS_ERR_DIET; 81 | return CS_ERR_DIET; 82 | #endif 83 | } 84 | break; 85 | } 86 | 87 | return CS_ERR_OK; 88 | } 89 | 90 | static void destroy(cs_struct *handle) 91 | { 92 | } 93 | 94 | void X86_enable(void) 95 | { 96 | arch_init[CS_ARCH_X86] = init; 97 | arch_option[CS_ARCH_X86] = option; 98 | arch_destroy[CS_ARCH_X86] = destroy; 99 | 100 | // support this arch 101 | all_arch |= (1 << CS_ARCH_X86); 102 | } 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /capstone/cs_priv.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_PRIV_H 5 | #define CS_PRIV_H 6 | 7 | #include 8 | 9 | #include "MCInst.h" 10 | #include "SStream.h" 11 | 12 | typedef void (*Printer_t)(MCInst *MI, SStream *OS, void *info); 13 | 14 | // function to be called after Printer_t 15 | // this is the best time to gather insn's characteristics 16 | typedef void (*PostPrinter_t)(csh handle, cs_insn *, char *mnem, MCInst *mci); 17 | 18 | typedef bool (*Disasm_t)(csh handle, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); 19 | 20 | typedef const char *(*GetName_t)(csh handle, unsigned int id); 21 | 22 | typedef void (*GetID_t)(cs_struct *h, cs_insn *insn, unsigned int id); 23 | 24 | // return register name, given register ID 25 | typedef char *(*GetRegisterName_t)(unsigned RegNo); 26 | 27 | // for ARM only 28 | typedef struct ARM_ITStatus { 29 | unsigned char ITStates[128]; // FIXME 30 | unsigned int size; 31 | } ARM_ITStatus; 32 | 33 | struct cs_struct { 34 | cs_arch arch; 35 | cs_mode mode; 36 | Printer_t printer; // asm printer 37 | void *printer_info; // aux info for printer 38 | Disasm_t disasm; // disassembler 39 | void *getinsn_info; // auxiliary info for printer 40 | bool big_endian; 41 | GetName_t reg_name; 42 | GetName_t insn_name; 43 | GetName_t group_name; 44 | GetID_t insn_id; 45 | PostPrinter_t post_printer; 46 | cs_err errnum; 47 | ARM_ITStatus ITBlock; // for Arm only 48 | cs_opt_value detail; 49 | int syntax; // asm syntax for simple printer such as ARM, Mips & PPC 50 | bool doing_mem; // handling memory operand in InstPrinter code 51 | unsigned short *insn_cache; // index caching for mapping.c 52 | GetRegisterName_t get_regname; 53 | bool skipdata; // set this to True if we skip data when disassembling 54 | uint8_t skipdata_size; // how many bytes to skip 55 | cs_opt_skipdata skipdata_setup; // user-defined skipdata setup 56 | uint8_t *regsize_map; // map to register size (x86-only for now) 57 | }; 58 | 59 | #define MAX_ARCH 8 60 | 61 | // constructor initialization for all archs 62 | extern cs_err (*arch_init[MAX_ARCH]) (cs_struct *); 63 | 64 | // support cs_option() for all archs 65 | extern cs_err (*arch_option[MAX_ARCH]) (cs_struct*, cs_opt_type, size_t value); 66 | 67 | // deinitialized functions: to be called when cs_close() is called 68 | extern void (*arch_destroy[MAX_ARCH]) (cs_struct*); 69 | 70 | extern unsigned int all_arch; 71 | 72 | extern cs_malloc_t cs_mem_malloc; 73 | extern cs_calloc_t cs_mem_calloc; 74 | extern cs_realloc_t cs_mem_realloc; 75 | extern cs_free_t cs_mem_free; 76 | extern cs_vsnprintf_t cs_vsnprintf; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /capstone/include/platform.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Axel Souchet & Nguyen Anh Quynh, 2014 */ 3 | 4 | // handle C99 issue (for pre-2013 VisualStudio) 5 | #ifndef CAPSTONE_PLATFORM_H 6 | #define CAPSTONE_PLATFORM_H 7 | 8 | #if !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) 9 | // MSVC 10 | 11 | // stdbool.h 12 | #if (_MSC_VER < 1800) 13 | #ifndef __cplusplus 14 | typedef unsigned char bool; 15 | #define false 0 16 | #define true 1 17 | #endif 18 | 19 | #else 20 | // VisualStudio 2013+ -> C99 is supported 21 | #include 22 | #endif 23 | 24 | #else // not MSVC -> C99 is supported 25 | #include 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /capstone/include/xcore.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPSTONE_XCORE_H 2 | #define CAPSTONE_XCORE_H 3 | 4 | /* Capstone Disassembly Engine */ 5 | /* By Nguyen Anh Quynh , 2014 */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include 12 | #include "platform.h" 13 | 14 | #ifdef _MSC_VER 15 | #pragma warning(disable:4201) 16 | #endif 17 | 18 | //> Operand type for instruction's operands 19 | typedef enum xcore_op_type { 20 | XCORE_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). 21 | XCORE_OP_REG, // = CS_OP_REG (Register operand). 22 | XCORE_OP_IMM, // = CS_OP_IMM (Immediate operand). 23 | XCORE_OP_MEM, // = CS_OP_MEM (Memory operand). 24 | } xcore_op_type; 25 | 26 | // Instruction's operand referring to memory 27 | // This is associated with XCORE_OP_MEM operand type above 28 | typedef struct xcore_op_mem { 29 | uint8_t base; // base register 30 | uint8_t index; // index register 31 | int32_t disp; // displacement/offset value 32 | int direct; // +1: forward, -1: backward 33 | } xcore_op_mem; 34 | 35 | // Instruction operand 36 | typedef struct cs_xcore_op { 37 | xcore_op_type type; // operand type 38 | union { 39 | unsigned int reg; // register value for REG operand 40 | int32_t imm; // immediate value for IMM operand 41 | xcore_op_mem mem; // base/disp value for MEM operand 42 | }; 43 | } cs_xcore_op; 44 | 45 | // Instruction structure 46 | typedef struct cs_xcore { 47 | // Number of operands of this instruction, 48 | // or 0 when instruction has no operand. 49 | uint8_t op_count; 50 | cs_xcore_op operands[8]; // operands for this instruction. 51 | } cs_xcore; 52 | 53 | //> XCore registers 54 | typedef enum xcore_reg { 55 | XCORE_REG_INVALID = 0, 56 | 57 | XCORE_REG_CP, 58 | XCORE_REG_DP, 59 | XCORE_REG_LR, 60 | XCORE_REG_SP, 61 | XCORE_REG_R0, 62 | XCORE_REG_R1, 63 | XCORE_REG_R2, 64 | XCORE_REG_R3, 65 | XCORE_REG_R4, 66 | XCORE_REG_R5, 67 | XCORE_REG_R6, 68 | XCORE_REG_R7, 69 | XCORE_REG_R8, 70 | XCORE_REG_R9, 71 | XCORE_REG_R10, 72 | XCORE_REG_R11, 73 | 74 | //> pseudo registers 75 | XCORE_REG_PC, // pc 76 | 77 | // internal thread registers 78 | // see The-XMOS-XS1-Architecture(X7879A).pdf 79 | XCORE_REG_SCP, // save pc 80 | XCORE_REG_SSR, // save status 81 | XCORE_REG_ET, // exception type 82 | XCORE_REG_ED, // exception data 83 | XCORE_REG_SED, // save exception data 84 | XCORE_REG_KEP, // kernel entry pointer 85 | XCORE_REG_KSP, // kernel stack pointer 86 | XCORE_REG_ID, // thread ID 87 | 88 | XCORE_REG_ENDING, // <-- mark the end of the list of registers 89 | } xcore_reg; 90 | 91 | //> XCore instruction 92 | typedef enum xcore_insn { 93 | XCORE_INS_INVALID = 0, 94 | 95 | XCORE_INS_ADD, 96 | XCORE_INS_ANDNOT, 97 | XCORE_INS_AND, 98 | XCORE_INS_ASHR, 99 | XCORE_INS_BAU, 100 | XCORE_INS_BITREV, 101 | XCORE_INS_BLA, 102 | XCORE_INS_BLAT, 103 | XCORE_INS_BL, 104 | XCORE_INS_BF, 105 | XCORE_INS_BT, 106 | XCORE_INS_BU, 107 | XCORE_INS_BRU, 108 | XCORE_INS_BYTEREV, 109 | XCORE_INS_CHKCT, 110 | XCORE_INS_CLRE, 111 | XCORE_INS_CLRPT, 112 | XCORE_INS_CLRSR, 113 | XCORE_INS_CLZ, 114 | XCORE_INS_CRC8, 115 | XCORE_INS_CRC32, 116 | XCORE_INS_DCALL, 117 | XCORE_INS_DENTSP, 118 | XCORE_INS_DGETREG, 119 | XCORE_INS_DIVS, 120 | XCORE_INS_DIVU, 121 | XCORE_INS_DRESTSP, 122 | XCORE_INS_DRET, 123 | XCORE_INS_ECALLF, 124 | XCORE_INS_ECALLT, 125 | XCORE_INS_EDU, 126 | XCORE_INS_EEF, 127 | XCORE_INS_EET, 128 | XCORE_INS_EEU, 129 | XCORE_INS_ENDIN, 130 | XCORE_INS_ENTSP, 131 | XCORE_INS_EQ, 132 | XCORE_INS_EXTDP, 133 | XCORE_INS_EXTSP, 134 | XCORE_INS_FREER, 135 | XCORE_INS_FREET, 136 | XCORE_INS_GETD, 137 | XCORE_INS_GET, 138 | XCORE_INS_GETN, 139 | XCORE_INS_GETR, 140 | XCORE_INS_GETSR, 141 | XCORE_INS_GETST, 142 | XCORE_INS_GETTS, 143 | XCORE_INS_INCT, 144 | XCORE_INS_INIT, 145 | XCORE_INS_INPW, 146 | XCORE_INS_INSHR, 147 | XCORE_INS_INT, 148 | XCORE_INS_IN, 149 | XCORE_INS_KCALL, 150 | XCORE_INS_KENTSP, 151 | XCORE_INS_KRESTSP, 152 | XCORE_INS_KRET, 153 | XCORE_INS_LADD, 154 | XCORE_INS_LD16S, 155 | XCORE_INS_LD8U, 156 | XCORE_INS_LDA16, 157 | XCORE_INS_LDAP, 158 | XCORE_INS_LDAW, 159 | XCORE_INS_LDC, 160 | XCORE_INS_LDW, 161 | XCORE_INS_LDIVU, 162 | XCORE_INS_LMUL, 163 | XCORE_INS_LSS, 164 | XCORE_INS_LSUB, 165 | XCORE_INS_LSU, 166 | XCORE_INS_MACCS, 167 | XCORE_INS_MACCU, 168 | XCORE_INS_MJOIN, 169 | XCORE_INS_MKMSK, 170 | XCORE_INS_MSYNC, 171 | XCORE_INS_MUL, 172 | XCORE_INS_NEG, 173 | XCORE_INS_NOT, 174 | XCORE_INS_OR, 175 | XCORE_INS_OUTCT, 176 | XCORE_INS_OUTPW, 177 | XCORE_INS_OUTSHR, 178 | XCORE_INS_OUTT, 179 | XCORE_INS_OUT, 180 | XCORE_INS_PEEK, 181 | XCORE_INS_REMS, 182 | XCORE_INS_REMU, 183 | XCORE_INS_RETSP, 184 | XCORE_INS_SETCLK, 185 | XCORE_INS_SET, 186 | XCORE_INS_SETC, 187 | XCORE_INS_SETD, 188 | XCORE_INS_SETEV, 189 | XCORE_INS_SETN, 190 | XCORE_INS_SETPSC, 191 | XCORE_INS_SETPT, 192 | XCORE_INS_SETRDY, 193 | XCORE_INS_SETSR, 194 | XCORE_INS_SETTW, 195 | XCORE_INS_SETV, 196 | XCORE_INS_SEXT, 197 | XCORE_INS_SHL, 198 | XCORE_INS_SHR, 199 | XCORE_INS_SSYNC, 200 | XCORE_INS_ST16, 201 | XCORE_INS_ST8, 202 | XCORE_INS_STW, 203 | XCORE_INS_SUB, 204 | XCORE_INS_SYNCR, 205 | XCORE_INS_TESTCT, 206 | XCORE_INS_TESTLCL, 207 | XCORE_INS_TESTWCT, 208 | XCORE_INS_TSETMR, 209 | XCORE_INS_START, 210 | XCORE_INS_WAITEF, 211 | XCORE_INS_WAITET, 212 | XCORE_INS_WAITEU, 213 | XCORE_INS_XOR, 214 | XCORE_INS_ZEXT, 215 | 216 | XCORE_INS_ENDING, // <-- mark the end of the list of instructions 217 | } xcore_insn; 218 | 219 | //> Group of XCore instructions 220 | typedef enum xcore_insn_group { 221 | XCORE_GRP_INVALID = 0, // = CS_GRP_INVALID 222 | 223 | //> Generic groups 224 | // all jump instructions (conditional+direct+indirect jumps) 225 | XCORE_GRP_JUMP, // = CS_GRP_JUMP 226 | 227 | XCORE_GRP_ENDING, // <-- mark the end of the list of groups 228 | } xcore_insn_group; 229 | 230 | #ifdef __cplusplus 231 | } 232 | #endif 233 | 234 | #endif 235 | -------------------------------------------------------------------------------- /capstone/inttypes.h: -------------------------------------------------------------------------------- 1 | #if defined(_MSC_VER) && _MSC_VER <= 1700 2 | #include "msvc/headers/inttypes.h" 3 | #else 4 | #include 5 | #endif 6 | -------------------------------------------------------------------------------- /capstone/myinttypes.h: -------------------------------------------------------------------------------- 1 | #if defined(_MSC_VER) && _MSC_VER <= 1700 2 | #include "msvc/headers/inttypes.h" 3 | #elif defined(CAPSTONE_HAS_OSXKERNEL) 4 | /* this is a trimmed copy of system inttypes.h that doesn't exist 5 | in OSX kernel framework headers */ 6 | #include "osxkernel_inttypes.h" 7 | #else 8 | #include 9 | #endif 10 | -------------------------------------------------------------------------------- /capstone/osxkernel_inttypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2004, 2013 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | /* 25 | * -- Standard C header, defined in ISO/IEC 9899:1999 26 | * (aka "C99"), section 7.8. This defines format string conversion 27 | * specifiers suitable for use within arguments to fprintf and fscanf 28 | * and their ilk. 29 | */ 30 | 31 | #if !defined(_INTTYPES_H_) 32 | #define _INTTYPES_H_ 33 | 34 | # define __PRI_8_LENGTH_MODIFIER__ "hh" 35 | # define __PRI_64_LENGTH_MODIFIER__ "ll" 36 | # define __SCN_64_LENGTH_MODIFIER__ "ll" 37 | # define __PRI_MAX_LENGTH_MODIFIER__ "j" 38 | # define __SCN_MAX_LENGTH_MODIFIER__ "j" 39 | 40 | # define PRId8 __PRI_8_LENGTH_MODIFIER__ "d" 41 | # define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i" 42 | # define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o" 43 | # define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u" 44 | # define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x" 45 | # define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X" 46 | 47 | # define PRId16 "hd" 48 | # define PRIi16 "hi" 49 | # define PRIo16 "ho" 50 | # define PRIu16 "hu" 51 | # define PRIx16 "hx" 52 | # define PRIX16 "hX" 53 | 54 | # define PRId32 "d" 55 | # define PRIi32 "i" 56 | # define PRIo32 "o" 57 | # define PRIu32 "u" 58 | # define PRIx32 "x" 59 | # define PRIX32 "X" 60 | 61 | # define PRId64 __PRI_64_LENGTH_MODIFIER__ "d" 62 | # define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i" 63 | # define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o" 64 | # define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u" 65 | # define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x" 66 | # define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X" 67 | 68 | # define PRIdLEAST8 PRId8 69 | # define PRIiLEAST8 PRIi8 70 | # define PRIoLEAST8 PRIo8 71 | # define PRIuLEAST8 PRIu8 72 | # define PRIxLEAST8 PRIx8 73 | # define PRIXLEAST8 PRIX8 74 | 75 | # define PRIdLEAST16 PRId16 76 | # define PRIiLEAST16 PRIi16 77 | # define PRIoLEAST16 PRIo16 78 | # define PRIuLEAST16 PRIu16 79 | # define PRIxLEAST16 PRIx16 80 | # define PRIXLEAST16 PRIX16 81 | 82 | # define PRIdLEAST32 PRId32 83 | # define PRIiLEAST32 PRIi32 84 | # define PRIoLEAST32 PRIo32 85 | # define PRIuLEAST32 PRIu32 86 | # define PRIxLEAST32 PRIx32 87 | # define PRIXLEAST32 PRIX32 88 | 89 | # define PRIdLEAST64 PRId64 90 | # define PRIiLEAST64 PRIi64 91 | # define PRIoLEAST64 PRIo64 92 | # define PRIuLEAST64 PRIu64 93 | # define PRIxLEAST64 PRIx64 94 | # define PRIXLEAST64 PRIX64 95 | 96 | # define PRIdFAST8 PRId8 97 | # define PRIiFAST8 PRIi8 98 | # define PRIoFAST8 PRIo8 99 | # define PRIuFAST8 PRIu8 100 | # define PRIxFAST8 PRIx8 101 | # define PRIXFAST8 PRIX8 102 | 103 | # define PRIdFAST16 PRId16 104 | # define PRIiFAST16 PRIi16 105 | # define PRIoFAST16 PRIo16 106 | # define PRIuFAST16 PRIu16 107 | # define PRIxFAST16 PRIx16 108 | # define PRIXFAST16 PRIX16 109 | 110 | # define PRIdFAST32 PRId32 111 | # define PRIiFAST32 PRIi32 112 | # define PRIoFAST32 PRIo32 113 | # define PRIuFAST32 PRIu32 114 | # define PRIxFAST32 PRIx32 115 | # define PRIXFAST32 PRIX32 116 | 117 | # define PRIdFAST64 PRId64 118 | # define PRIiFAST64 PRIi64 119 | # define PRIoFAST64 PRIo64 120 | # define PRIuFAST64 PRIu64 121 | # define PRIxFAST64 PRIx64 122 | # define PRIXFAST64 PRIX64 123 | 124 | /* int32_t is 'int', but intptr_t is 'long'. */ 125 | # define PRIdPTR "ld" 126 | # define PRIiPTR "li" 127 | # define PRIoPTR "lo" 128 | # define PRIuPTR "lu" 129 | # define PRIxPTR "lx" 130 | # define PRIXPTR "lX" 131 | 132 | # define PRIdMAX __PRI_MAX_LENGTH_MODIFIER__ "d" 133 | # define PRIiMAX __PRI_MAX_LENGTH_MODIFIER__ "i" 134 | # define PRIoMAX __PRI_MAX_LENGTH_MODIFIER__ "o" 135 | # define PRIuMAX __PRI_MAX_LENGTH_MODIFIER__ "u" 136 | # define PRIxMAX __PRI_MAX_LENGTH_MODIFIER__ "x" 137 | # define PRIXMAX __PRI_MAX_LENGTH_MODIFIER__ "X" 138 | 139 | # define SCNd8 __PRI_8_LENGTH_MODIFIER__ "d" 140 | # define SCNi8 __PRI_8_LENGTH_MODIFIER__ "i" 141 | # define SCNo8 __PRI_8_LENGTH_MODIFIER__ "o" 142 | # define SCNu8 __PRI_8_LENGTH_MODIFIER__ "u" 143 | # define SCNx8 __PRI_8_LENGTH_MODIFIER__ "x" 144 | 145 | # define SCNd16 "hd" 146 | # define SCNi16 "hi" 147 | # define SCNo16 "ho" 148 | # define SCNu16 "hu" 149 | # define SCNx16 "hx" 150 | 151 | # define SCNd32 "d" 152 | # define SCNi32 "i" 153 | # define SCNo32 "o" 154 | # define SCNu32 "u" 155 | # define SCNx32 "x" 156 | 157 | # define SCNd64 __SCN_64_LENGTH_MODIFIER__ "d" 158 | # define SCNi64 __SCN_64_LENGTH_MODIFIER__ "i" 159 | # define SCNo64 __SCN_64_LENGTH_MODIFIER__ "o" 160 | # define SCNu64 __SCN_64_LENGTH_MODIFIER__ "u" 161 | # define SCNx64 __SCN_64_LENGTH_MODIFIER__ "x" 162 | 163 | # define SCNdLEAST8 SCNd8 164 | # define SCNiLEAST8 SCNi8 165 | # define SCNoLEAST8 SCNo8 166 | # define SCNuLEAST8 SCNu8 167 | # define SCNxLEAST8 SCNx8 168 | 169 | # define SCNdLEAST16 SCNd16 170 | # define SCNiLEAST16 SCNi16 171 | # define SCNoLEAST16 SCNo16 172 | # define SCNuLEAST16 SCNu16 173 | # define SCNxLEAST16 SCNx16 174 | 175 | # define SCNdLEAST32 SCNd32 176 | # define SCNiLEAST32 SCNi32 177 | # define SCNoLEAST32 SCNo32 178 | # define SCNuLEAST32 SCNu32 179 | # define SCNxLEAST32 SCNx32 180 | 181 | # define SCNdLEAST64 SCNd64 182 | # define SCNiLEAST64 SCNi64 183 | # define SCNoLEAST64 SCNo64 184 | # define SCNuLEAST64 SCNu64 185 | # define SCNxLEAST64 SCNx64 186 | 187 | # define SCNdFAST8 SCNd8 188 | # define SCNiFAST8 SCNi8 189 | # define SCNoFAST8 SCNo8 190 | # define SCNuFAST8 SCNu8 191 | # define SCNxFAST8 SCNx8 192 | 193 | # define SCNdFAST16 SCNd16 194 | # define SCNiFAST16 SCNi16 195 | # define SCNoFAST16 SCNo16 196 | # define SCNuFAST16 SCNu16 197 | # define SCNxFAST16 SCNx16 198 | 199 | # define SCNdFAST32 SCNd32 200 | # define SCNiFAST32 SCNi32 201 | # define SCNoFAST32 SCNo32 202 | # define SCNuFAST32 SCNu32 203 | # define SCNxFAST32 SCNx32 204 | 205 | # define SCNdFAST64 SCNd64 206 | # define SCNiFAST64 SCNi64 207 | # define SCNoFAST64 SCNo64 208 | # define SCNuFAST64 SCNu64 209 | # define SCNxFAST64 SCNx64 210 | 211 | # define SCNdPTR "ld" 212 | # define SCNiPTR "li" 213 | # define SCNoPTR "lo" 214 | # define SCNuPTR "lu" 215 | # define SCNxPTR "lx" 216 | 217 | # define SCNdMAX __SCN_MAX_LENGTH_MODIFIER__ "d" 218 | # define SCNiMAX __SCN_MAX_LENGTH_MODIFIER__ "i" 219 | # define SCNoMAX __SCN_MAX_LENGTH_MODIFIER__ "o" 220 | # define SCNuMAX __SCN_MAX_LENGTH_MODIFIER__ "u" 221 | # define SCNxMAX __SCN_MAX_LENGTH_MODIFIER__ "x" 222 | 223 | #endif /* !_INTTYPES_H_ */ 224 | -------------------------------------------------------------------------------- /capstone/utils.c: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #if defined(CAPSTONE_HAS_OSXKERNEL) 5 | #include 6 | #else 7 | #include 8 | #endif 9 | #include 10 | 11 | #include "utils.h" 12 | 13 | // create a cache for fast id lookup 14 | static unsigned short *make_id2insn(insn_map *insns, unsigned int size) 15 | { 16 | // NOTE: assume that the max id is always put at the end of insns array 17 | unsigned short max_id = insns[size - 1].id; 18 | unsigned short i; 19 | 20 | unsigned short *cache = (unsigned short *)cs_mem_malloc(sizeof(*cache) * (max_id + 1)); 21 | 22 | for (i = 1; i < size; i++) 23 | cache[insns[i].id] = i; 24 | 25 | return cache; 26 | } 27 | 28 | // look for @id in @insns, given its size in @max. first time call will update @cache. 29 | // return 0 if not found 30 | unsigned short insn_find(insn_map *insns, unsigned int max, unsigned int id, unsigned short **cache) 31 | { 32 | if (id > insns[max - 1].id) 33 | return 0; 34 | 35 | if (*cache == NULL) 36 | *cache = make_id2insn(insns, max); 37 | 38 | return (*cache)[id]; 39 | } 40 | 41 | int name2id(name_map* map, int max, const char *name) 42 | { 43 | int i; 44 | 45 | for (i = 0; i < max; i++) { 46 | if (!strcmp(map[i].name, name)) { 47 | return map[i].id; 48 | } 49 | } 50 | 51 | // nothing match 52 | return -1; 53 | } 54 | 55 | // count number of positive members in a list. 56 | // NOTE: list must be guaranteed to end in 0 57 | unsigned int count_positive(unsigned char *list) 58 | { 59 | unsigned int c; 60 | 61 | for (c = 0; list[c] > 0; c++); 62 | 63 | return c; 64 | } 65 | 66 | char *cs_strdup(const char *str) 67 | { 68 | size_t len = strlen(str)+ 1; 69 | void *new = cs_mem_malloc(len); 70 | 71 | if (new == NULL) 72 | return NULL; 73 | 74 | return (char *)memmove(new, str, len); 75 | } 76 | 77 | // we need this since Windows doesnt have snprintf() 78 | int cs_snprintf(char *buffer, size_t size, const char *fmt, ...) 79 | { 80 | int ret; 81 | 82 | va_list ap; 83 | va_start(ap, fmt); 84 | ret = cs_vsnprintf(buffer, size, fmt, ap); 85 | va_end(ap); 86 | 87 | return ret; 88 | } 89 | -------------------------------------------------------------------------------- /capstone/utils.h: -------------------------------------------------------------------------------- 1 | /* Capstone Disassembly Engine */ 2 | /* By Nguyen Anh Quynh , 2013-2014 */ 3 | 4 | #ifndef CS_UTILS_H 5 | #define CS_UTILS_H 6 | 7 | #include 8 | #include "include/capstone.h" 9 | #include "cs_priv.h" 10 | 11 | // threshold number, so above this number will be printed in hexa mode 12 | #define HEX_THRESHOLD 9 13 | 14 | // map instruction to its characteristics 15 | typedef struct insn_map { 16 | unsigned short id; 17 | unsigned short mapid; 18 | #ifndef CAPSTONE_DIET 19 | unsigned char regs_use[12]; // list of implicit registers used by this instruction 20 | unsigned char regs_mod[20]; // list of implicit registers modified by this instruction 21 | unsigned char groups[8]; // list of group this instruction belong to 22 | bool branch; // branch instruction? 23 | bool indirect_branch; // indirect branch instruction? 24 | #endif 25 | } insn_map; 26 | 27 | // look for @id in @m, given its size in @max. first time call will update @cache. 28 | // return 0 if not found 29 | unsigned short insn_find(insn_map *m, unsigned int max, unsigned int id, unsigned short **cache); 30 | 31 | // map id to string 32 | typedef struct name_map { 33 | unsigned int id; 34 | char *name; 35 | } name_map; 36 | 37 | // map a name to its ID 38 | // return 0 if not found 39 | int name2id(name_map* map, int max, const char *name); 40 | 41 | // count number of positive members in a list. 42 | // NOTE: list must be guaranteed to end in 0 43 | unsigned int count_positive(unsigned char *list); 44 | 45 | #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0])) 46 | 47 | char *cs_strdup(const char *str); 48 | 49 | #define MIN(x, y) ((x) < (y) ? (x) : (y)) 50 | 51 | // we need this since Windows doesnt have snprintf() 52 | int cs_snprintf(char *buffer, size_t size, const char *fmt, ...); 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /createdmg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #TARGET=Debug 4 | TARGET=Release 5 | 6 | # Build disassembler 7 | cd otool_disasm 8 | /usr/bin/xcodebuild -configuration $TARGET 9 | cp -f build/$TARGET/libdisasm.a .. 10 | cd .. 11 | 12 | # Build MachOView 13 | /usr/bin/xcodebuild -configuration $TARGET 14 | 15 | # Create DMG Installer 16 | buildPlist="build/"$TARGET"/MachOView.app/Contents/Info.plist" 17 | CFBuildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBuildNumber" $buildPlist) 18 | CFBundleShortVersionString=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $buildPlist) 19 | cp -f README "build/"$TARGET 20 | 21 | hdiutil create -fs HFS+ -volname "MachOView" -srcfolder "build/"$TARGET "MachOView-"$CFBundleShortVersionString.$CFBuildNumber".dmg" 22 | -------------------------------------------------------------------------------- /greenApple.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intheway/MachOView/a3dbb7ef4c62fab34a656646b781a139010d28c2/greenApple.icns -------------------------------------------------------------------------------- /mach-o/arch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _MACH_O_ARCH_H_ 24 | #define _MACH_O_ARCH_H_ 25 | /* 26 | * Copyright (c) 1997 Apple Computer, Inc. 27 | * 28 | * Functions that deal with information about architectures. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | /* The NXArchInfo structs contain the architectures symbolic name 37 | * (such as "ppc"), its CPU type and CPU subtype as defined in 38 | * mach/machine.h, the byte order for the architecture, and a 39 | * describing string (such as "PowerPC"). 40 | * There will both be entries for specific CPUs (such as ppc604e) as 41 | * well as generic "family" entries (such as ppc). 42 | */ 43 | typedef struct { 44 | const char *name; 45 | cpu_type_t cputype; 46 | cpu_subtype_t cpusubtype; 47 | enum NXByteOrder byteorder; 48 | const char *description; 49 | } NXArchInfo; 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif /* __cplusplus */ 54 | 55 | /* NXGetAllArchInfos() returns a pointer to an array of all known 56 | * NXArchInfo structures. The last NXArchInfo is marked by a NULL name. 57 | */ 58 | extern const NXArchInfo *NXGetAllArchInfos(void); 59 | 60 | /* NXGetLocalArchInfo() returns the NXArchInfo for the local host, or NULL 61 | * if none is known. 62 | */ 63 | extern const NXArchInfo *NXGetLocalArchInfo(void); 64 | 65 | /* NXGetArchInfoFromName() and NXGetArchInfoFromCpuType() return the 66 | * NXArchInfo from the architecture's name or cputype/cpusubtype 67 | * combination. A cpusubtype of CPU_SUBTYPE_MULTIPLE can be used 68 | * to request the most general NXArchInfo known for the given cputype. 69 | * NULL is returned if no matching NXArchInfo can be found. 70 | */ 71 | extern const NXArchInfo *NXGetArchInfoFromName(const char *name); 72 | extern const NXArchInfo *NXGetArchInfoFromCpuType(cpu_type_t cputype, 73 | cpu_subtype_t cpusubtype); 74 | 75 | /* NXFindBestFatArch() is passed a cputype and cpusubtype and a set of 76 | * fat_arch structs and selects the best one that matches (if any) and returns 77 | * a pointer to that fat_arch struct (or NULL). The fat_arch structs must be 78 | * in the host byte order and correct such that the fat_archs really points to 79 | * enough memory for nfat_arch structs. It is possible that this routine could 80 | * fail if new cputypes or cpusubtypes are added and an old version of this 81 | * routine is used. But if there is an exact match between the cputype and 82 | * cpusubtype and one of the fat_arch structs this routine will always succeed. 83 | */ 84 | extern struct fat_arch *NXFindBestFatArch(cpu_type_t cputype, 85 | cpu_subtype_t cpusubtype, 86 | struct fat_arch *fat_archs, 87 | uint32_t nfat_archs); 88 | 89 | /* NXCombineCpuSubtypes() returns the resulting cpusubtype when combining two 90 | * different cpusubtypes for the specified cputype. If the two cpusubtypes 91 | * can't be combined (the specific subtypes are mutually exclusive) -1 is 92 | * returned indicating it is an error to combine them. This can also fail and 93 | * return -1 if new cputypes or cpusubtypes are added and an old version of 94 | * this routine is used. But if the cpusubtypes are the same they can always 95 | * be combined and this routine will return the cpusubtype pass in. 96 | */ 97 | extern cpu_subtype_t NXCombineCpuSubtypes(cpu_type_t cputype, 98 | cpu_subtype_t cpusubtype1, 99 | cpu_subtype_t cpusubtype2); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif /* __cplusplus */ 104 | 105 | #endif /* _MACH_O_ARCH_H_ */ 106 | -------------------------------------------------------------------------------- /mach-o/arm/reloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Relocation types used in the arm implementation. Relocation entries for 25 | * things other than instructions use the same generic relocation as discribed 26 | * in and their r_type is ARM_RELOC_VANILLA, one of the 27 | * *_SECTDIFF or the *_PB_LA_PTR types. The rest of the relocation types are 28 | * for instructions. Since they are for instructions the r_address field 29 | * indicates the 32 bit instruction that the relocation is to be preformed on. 30 | */ 31 | enum reloc_type_arm 32 | { 33 | ARM_RELOC_VANILLA, /* generic relocation as discribed above */ 34 | ARM_RELOC_PAIR, /* the second relocation entry of a pair */ 35 | ARM_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ 36 | ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol 37 | referenced was local. */ 38 | ARM_RELOC_PB_LA_PTR,/* prebound lazy pointer */ 39 | ARM_RELOC_BR24, /* 24 bit branch displacement (to a word address) */ 40 | ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word 41 | address) */ 42 | ARM_THUMB_32BIT_BRANCH, /* obsolete - a thumb 32-bit branch instruction 43 | possibly needing page-spanning branch workaround */ 44 | 45 | /* 46 | * For these two r_type relocations they always have a pair following them 47 | * and the r_length bits are used differently. The encoding of the 48 | * r_length is as follows: 49 | * low bit of r_length: 50 | * 0 - :lower16: for movw instructions 51 | * 1 - :upper16: for movt instructions 52 | * high bit of r_length: 53 | * 0 - arm instructions 54 | * 1 - thumb instructions 55 | * the other half of the relocated expression is in the following pair 56 | * relocation entry in the the low 16 bits of r_address field. 57 | */ 58 | ARM_RELOC_HALF, 59 | ARM_RELOC_HALF_SECTDIFF 60 | }; 61 | -------------------------------------------------------------------------------- /mach-o/arm64/reloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Relocation types used in the arm64 implementation. 25 | */ 26 | enum reloc_type_arm64 27 | { 28 | ARM64_RELOC_UNSIGNED, // for pointers 29 | ARM64_RELOC_SUBTRACTOR, // must be followed by a ARM64_RELOC_UNSIGNED 30 | ARM64_RELOC_BRANCH26, // a B/BL instruction with 26-bit displacement 31 | ARM64_RELOC_PAGE21, // pc-rel distance to page of target 32 | ARM64_RELOC_PAGEOFF12, // offset within page, scaled by r_length 33 | ARM64_RELOC_GOT_LOAD_PAGE21, // pc-rel distance to page of GOT slot 34 | ARM64_RELOC_GOT_LOAD_PAGEOFF12, // offset within page of GOT slot, 35 | // scaled by r_length 36 | ARM64_RELOC_POINTER_TO_GOT, // for pointers to GOT slots 37 | ARM64_RELOC_TLVP_LOAD_PAGE21, // pc-rel distance to page of TLVP slot 38 | ARM64_RELOC_TLVP_LOAD_PAGEOFF12, // offset within page of TLVP slot, 39 | // scaled by r_length 40 | ARM64_RELOC_ADDEND // must be followed by PAGE21 or PAGEOFF12 41 | }; 42 | -------------------------------------------------------------------------------- /mach-o/compact_unwind_encoding.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2008-2009 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | 26 | #ifndef __COMPACT_UNWIND_ENCODING__ 27 | #define __COMPACT_UNWIND_ENCODING__ 28 | 29 | #include 30 | 31 | 32 | // 33 | // Each final linked mach-o image has an optional __TEXT, __unwind_info section. 34 | // This section is much smaller and faster to use than the __eh_frame section. 35 | // 36 | 37 | 38 | 39 | // 40 | // Compilers usually emit standard Dwarf FDEs. The linker recognizes standard FDEs and 41 | // synthesizes a matching compact_unwind_encoding_t and adds it to the __unwind_info table. 42 | // It is also possible for the compiler to emit __unwind_info entries for functions that 43 | // have different unwind requirements at different ranges in the function. 44 | // 45 | typedef uint32_t compact_unwind_encoding_t; 46 | 47 | 48 | 49 | // 50 | // The __unwind_info section is laid out for an efficient two level lookup. 51 | // The header of the section contains a coarse index that maps function address 52 | // to the page (4096 byte block) containing the unwind info for that function. 53 | // 54 | 55 | #define UNWIND_SECTION_VERSION 1 56 | struct unwind_info_section_header 57 | { 58 | uint32_t version; // UNWIND_SECTION_VERSION 59 | uint32_t commonEncodingsArraySectionOffset; 60 | uint32_t commonEncodingsArrayCount; 61 | uint32_t personalityArraySectionOffset; 62 | uint32_t personalityArrayCount; 63 | uint32_t indexSectionOffset; 64 | uint32_t indexCount; 65 | // compact_unwind_encoding_t[] 66 | // uintptr_t personalities[] 67 | // unwind_info_section_header_index_entry[] 68 | // unwind_info_section_header_lsda_index_entry[] 69 | }; 70 | 71 | struct unwind_info_section_header_index_entry 72 | { 73 | uint32_t functionOffset; 74 | uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page 75 | uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range 76 | }; 77 | 78 | struct unwind_info_section_header_lsda_index_entry 79 | { 80 | uint32_t functionOffset; 81 | uint32_t lsdaOffset; 82 | }; 83 | 84 | // 85 | // There are two kinds of second level index pages: regular and compressed. 86 | // A compressed page can hold up to 1021 entries, but it cannot be used 87 | // if too many different encoding types are used. The regular page holds 88 | // 511 entries. 89 | // 90 | 91 | struct unwind_info_regular_second_level_entry 92 | { 93 | uint32_t functionOffset; 94 | compact_unwind_encoding_t encoding; 95 | }; 96 | 97 | #define UNWIND_SECOND_LEVEL_REGULAR 2 98 | struct unwind_info_regular_second_level_page_header 99 | { 100 | uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR 101 | uint16_t entryPageOffset; 102 | uint16_t entryCount; 103 | // entry array 104 | }; 105 | 106 | #define UNWIND_SECOND_LEVEL_COMPRESSED 3 107 | struct unwind_info_compressed_second_level_page_header 108 | { 109 | uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED 110 | uint16_t entryPageOffset; 111 | uint16_t entryCount; 112 | uint16_t encodingsPageOffset; 113 | uint16_t encodingsCount; 114 | // 32-bit entry array 115 | // encodings array 116 | }; 117 | 118 | #define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF) 119 | #define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF) 120 | 121 | 122 | 123 | // architecture independent bits 124 | enum { 125 | UNWIND_IS_NOT_FUNCTION_START = 0x80000000, 126 | UNWIND_HAS_LSDA = 0x40000000, 127 | UNWIND_PERSONALITY_MASK = 0x30000000, 128 | }; 129 | 130 | 131 | // x86_64 132 | // 133 | // 1-bit: start 134 | // 1-bit: has lsda 135 | // 2-bit: personality index 136 | // 137 | // 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=dwarf 138 | // rbp based: 139 | // 15-bits (5*3-bits per reg) register permutation 140 | // 8-bits for stack offset 141 | // frameless: 142 | // 8-bits stack size 143 | // 3-bits stack adjust 144 | // 3-bits register count 145 | // 10-bits register permutation 146 | // 147 | enum { 148 | UNWIND_X86_64_MODE_MASK = 0x0F000000, 149 | UNWIND_X86_64_MODE_COMPATIBILITY = 0x00000000, 150 | UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, 151 | UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, 152 | UNWIND_X86_64_MODE_STACK_IND = 0x03000000, 153 | UNWIND_X86_64_MODE_DWARF = 0x04000000, 154 | 155 | UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF, 156 | UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000, 157 | 158 | UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000, 159 | UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000, 160 | UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00, 161 | UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, 162 | 163 | UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x03FFFFFF, 164 | }; 165 | 166 | enum { 167 | UNWIND_X86_64_REG_NONE = 0, 168 | UNWIND_X86_64_REG_RBX = 1, 169 | UNWIND_X86_64_REG_R12 = 2, 170 | UNWIND_X86_64_REG_R13 = 3, 171 | UNWIND_X86_64_REG_R14 = 4, 172 | UNWIND_X86_64_REG_R15 = 5, 173 | UNWIND_X86_64_REG_RBP = 6, 174 | }; 175 | 176 | 177 | // x86 178 | // 179 | // 1-bit: start 180 | // 1-bit: has lsda 181 | // 2-bit: personality index 182 | // 183 | // 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=dwarf 184 | // ebp based: 185 | // 15-bits (5*3-bits per reg) register permutation 186 | // 8-bits for stack offset 187 | // frameless: 188 | // 8-bits stack size 189 | // 3-bits stack adjust 190 | // 3-bits register count 191 | // 10-bits register permutation 192 | // 193 | enum { 194 | UNWIND_X86_MODE_MASK = 0x0F000000, 195 | UNWIND_X86_MODE_COMPATIBILITY = 0x00000000, 196 | UNWIND_X86_MODE_EBP_FRAME = 0x01000000, 197 | UNWIND_X86_MODE_STACK_IMMD = 0x02000000, 198 | UNWIND_X86_MODE_STACK_IND = 0x03000000, 199 | UNWIND_X86_MODE_DWARF = 0x04000000, 200 | 201 | UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF, 202 | UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000, 203 | 204 | UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000, 205 | UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000, 206 | UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00, 207 | UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, 208 | 209 | UNWIND_X86_DWARF_SECTION_OFFSET = 0x03FFFFFF, 210 | }; 211 | 212 | enum { 213 | UNWIND_X86_REG_NONE = 0, 214 | UNWIND_X86_REG_EBX = 1, 215 | UNWIND_X86_REG_ECX = 2, 216 | UNWIND_X86_REG_EDX = 3, 217 | UNWIND_X86_REG_EDI = 4, 218 | UNWIND_X86_REG_ESI = 5, 219 | UNWIND_X86_REG_EBP = 6, 220 | }; 221 | 222 | 223 | #endif 224 | 225 | -------------------------------------------------------------------------------- /mach-o/fat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _MACH_O_FAT_H_ 24 | #define _MACH_O_FAT_H_ 25 | /* 26 | * This header file describes the structures of the file format for "fat" 27 | * architecture specific file (wrapper design). At the begining of the file 28 | * there is one fat_header structure followed by a number of fat_arch 29 | * structures. For each architecture in the file, specified by a pair of 30 | * cputype and cpusubtype, the fat_header describes the file offset, file 31 | * size and alignment in the file of the architecture specific member. 32 | * The padded bytes in the file to place each member on it's specific alignment 33 | * are defined to be read as zeros and can be left as "holes" if the file system 34 | * can support them as long as they read as zeros. 35 | * 36 | * All structures defined here are always written and read to/from disk 37 | * in big-endian order. 38 | */ 39 | 40 | /* 41 | * is needed here for the cpu_type_t and cpu_subtype_t types 42 | * and contains the constants for the possible values of these types. 43 | */ 44 | #include 45 | #include 46 | #include 47 | 48 | #define FAT_MAGIC 0xcafebabe 49 | #define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */ 50 | 51 | struct fat_header { 52 | uint32_t magic; /* FAT_MAGIC */ 53 | uint32_t nfat_arch; /* number of structs that follow */ 54 | }; 55 | 56 | struct fat_arch { 57 | cpu_type_t cputype; /* cpu specifier (int) */ 58 | cpu_subtype_t cpusubtype; /* machine specifier (int) */ 59 | uint32_t offset; /* file offset to this object file */ 60 | uint32_t size; /* size of this object file */ 61 | uint32_t align; /* alignment as a power of 2 */ 62 | }; 63 | 64 | #endif /* _MACH_O_FAT_H_ */ 65 | -------------------------------------------------------------------------------- /mach-o/ranlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* ranlib.h 4.1 83/05/03 */ 24 | #ifndef _MACH_O_RANLIB_H_ 25 | #define _MACH_O_RANLIB_H_ 26 | 27 | #include 28 | #include /* off_t */ 29 | 30 | /* 31 | * There are two known orders of table of contents for archives. The first is 32 | * the order ranlib(1) originally produced and still produces without any 33 | * options. This table of contents has the archive member name "__.SYMDEF" 34 | * This order has the ranlib structures in the order the objects appear in the 35 | * archive and the symbol names of those objects in the order of symbol table. 36 | * The second know order is sorted by symbol name and is produced with the -s 37 | * option to ranlib(1). This table of contents has the archive member name 38 | * "__.SYMDEF SORTED" and many programs (notably the 1.0 version of ld(1) can't 39 | * tell the difference between names because of the imbedded blank in the name 40 | * and works with either table of contents). This second order is used by the 41 | * post 1.0 link editor to produce faster linking. The original 1.0 version of 42 | * ranlib(1) gets confused when it is run on a archive with the second type of 43 | * table of contents because it and ar(1) which it uses use different ways to 44 | * determined the member name (ar(1) treats all blanks in the name as 45 | * significant and ranlib(1) only checks for the first one). 46 | */ 47 | #define SYMDEF "__.SYMDEF" 48 | #define SYMDEF_SORTED "__.SYMDEF SORTED" 49 | 50 | /* 51 | * Structure of the __.SYMDEF table of contents for an archive. 52 | * __.SYMDEF begins with a long giving the size in bytes of the ranlib 53 | * structures which immediately follow, and then continues with a string 54 | * table consisting of a long giving the number of bytes of strings which 55 | * follow and then the strings themselves. The ran_strx fields index the 56 | * string table whose first byte is numbered 0. 57 | */ 58 | struct ranlib { 59 | union { 60 | uint32_t ran_strx; /* string table index of */ 61 | #ifndef __LP64__ 62 | char *ran_name; /* symbol defined by */ 63 | #endif 64 | } ran_un; 65 | uint32_t ran_off; /* library member at this offset */ 66 | }; 67 | #endif /* _MACH_O_RANLIB_H_ */ 68 | -------------------------------------------------------------------------------- /mach-o/swap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _MACH_O_SWAP_H_ 24 | #define _MACH_O_SWAP_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif /* __cplusplus */ 37 | 38 | extern void swap_fat_header( 39 | struct fat_header *fat_header, 40 | enum NXByteOrder target_byte_order); 41 | 42 | extern void swap_fat_arch( 43 | struct fat_arch *fat_archs, 44 | uint32_t nfat_arch, 45 | enum NXByteOrder target_byte_order); 46 | 47 | extern void swap_mach_header( 48 | struct mach_header *mh, 49 | enum NXByteOrder target_byte_order); 50 | 51 | extern void swap_mach_header_64( 52 | struct mach_header_64 *mh, 53 | enum NXByteOrder target_byte_order); 54 | 55 | extern void swap_load_command( 56 | struct load_command *lc, 57 | enum NXByteOrder target_byte_order); 58 | 59 | extern void swap_segment_command( 60 | struct segment_command *sg, 61 | enum NXByteOrder target_byte_order); 62 | 63 | extern void swap_segment_command_64( 64 | struct segment_command_64 *sg, 65 | enum NXByteOrder target_byte_order); 66 | 67 | extern void swap_section( 68 | struct section *s, 69 | uint32_t nsects, 70 | enum NXByteOrder target_byte_order); 71 | 72 | extern void swap_section_64( 73 | struct section_64 *s, 74 | uint32_t nsects, 75 | enum NXByteOrder target_byte_order); 76 | 77 | extern void swap_symtab_command( 78 | struct symtab_command *st, 79 | enum NXByteOrder target_byte_order); 80 | 81 | extern void swap_dysymtab_command( 82 | struct dysymtab_command *dyst, 83 | enum NXByteOrder target_byte_sex); 84 | 85 | extern void swap_symseg_command( 86 | struct symseg_command *ss, 87 | enum NXByteOrder target_byte_order); 88 | 89 | extern void swap_fvmlib_command( 90 | struct fvmlib_command *fl, 91 | enum NXByteOrder target_byte_order); 92 | 93 | extern void swap_dylib_command( 94 | struct dylib_command *dl, 95 | enum NXByteOrder target_byte_sex); 96 | 97 | extern void swap_sub_framework_command( 98 | struct sub_framework_command *sub, 99 | enum NXByteOrder target_byte_sex); 100 | 101 | extern void swap_sub_umbrella_command( 102 | struct sub_umbrella_command *usub, 103 | enum NXByteOrder target_byte_sex); 104 | 105 | extern void swap_sub_library_command( 106 | struct sub_library_command *lsub, 107 | enum NXByteOrder target_byte_sex); 108 | 109 | extern void swap_sub_client_command( 110 | struct sub_client_command *csub, 111 | enum NXByteOrder target_byte_sex); 112 | 113 | extern void swap_prebound_dylib_command( 114 | struct prebound_dylib_command *pbdylib, 115 | enum NXByteOrder target_byte_sex); 116 | 117 | extern void swap_dylinker_command( 118 | struct dylinker_command *dyld, 119 | enum NXByteOrder target_byte_sex); 120 | 121 | extern void swap_fvmfile_command( 122 | struct fvmfile_command *ff, 123 | enum NXByteOrder target_byte_order); 124 | 125 | extern void swap_thread_command( 126 | struct thread_command *ut, 127 | enum NXByteOrder target_byte_order); 128 | 129 | extern void swap_ident_command( 130 | struct ident_command *ident, 131 | enum NXByteOrder target_byte_order); 132 | 133 | extern void swap_routines_command( 134 | struct routines_command *r_cmd, 135 | enum NXByteOrder target_byte_sex); 136 | 137 | extern void swap_routines_command_64( 138 | struct routines_command_64 *r_cmd, 139 | enum NXByteOrder target_byte_sex); 140 | 141 | extern void swap_twolevel_hints_command( 142 | struct twolevel_hints_command *hints_cmd, 143 | enum NXByteOrder target_byte_sex); 144 | 145 | extern void swap_prebind_cksum_command( 146 | struct prebind_cksum_command *cksum_cmd, 147 | enum NXByteOrder target_byte_sex); 148 | 149 | extern void swap_uuid_command( 150 | struct uuid_command *uuid_cmd, 151 | enum NXByteOrder target_byte_sex); 152 | 153 | extern void swap_linkedit_data_command( 154 | struct linkedit_data_command *ld, 155 | enum NXByteOrder target_byte_sex); 156 | 157 | extern void swap_version_min_command( 158 | struct version_min_command *ver_cmd, 159 | enum NXByteOrder target_byte_sex); 160 | 161 | extern void swap_rpath_command( 162 | struct rpath_command *rpath_cmd, 163 | enum NXByteOrder target_byte_sex); 164 | 165 | extern void swap_encryption_command( 166 | struct encryption_info_command *ec, 167 | enum NXByteOrder target_byte_sex); 168 | 169 | extern void swap_encryption_command_64( 170 | struct encryption_info_command_64 *ec, 171 | enum NXByteOrder target_byte_sex); 172 | 173 | extern void swap_linker_option_command( 174 | struct linker_option_command *lo, 175 | enum NXByteOrder target_byte_sex); 176 | 177 | extern void swap_dyld_info_command( 178 | struct dyld_info_command *ed, 179 | enum NXByteOrder target_byte_sex); 180 | 181 | extern void swap_entry_point_command( 182 | struct entry_point_command *ep, 183 | enum NXByteOrder target_byte_sex); 184 | 185 | extern void swap_source_version_command( 186 | struct source_version_command *sv, 187 | enum NXByteOrder target_byte_sex); 188 | 189 | extern void swap_prebind_cksum_command( 190 | struct prebind_cksum_command *cksum_cmd, 191 | enum NXByteOrder target_byte_sex); 192 | 193 | extern void swap_uuid_command( 194 | struct uuid_command *uuid_cmd, 195 | enum NXByteOrder target_byte_sex); 196 | 197 | extern void swap_twolevel_hint( 198 | struct twolevel_hint *hints, 199 | uint32_t nhints, 200 | enum NXByteOrder target_byte_sex); 201 | 202 | extern void swap_nlist( 203 | struct nlist *symbols, 204 | uint32_t nsymbols, 205 | enum NXByteOrder target_byte_order); 206 | 207 | extern void swap_nlist_64( 208 | struct nlist_64 *symbols, 209 | uint32_t nsymbols, 210 | enum NXByteOrder target_byte_order); 211 | 212 | extern void swap_ranlib( 213 | struct ranlib *ranlibs, 214 | uint32_t nranlibs, 215 | enum NXByteOrder target_byte_order); 216 | 217 | extern void swap_relocation_info( 218 | struct relocation_info *relocs, 219 | uint32_t nrelocs, 220 | enum NXByteOrder target_byte_order); 221 | 222 | extern void swap_indirect_symbols( 223 | uint32_t *indirect_symbols, 224 | uint32_t nindirect_symbols, 225 | enum NXByteOrder target_byte_sex); 226 | 227 | extern void swap_dylib_reference( 228 | struct dylib_reference *refs, 229 | uint32_t nrefs, 230 | enum NXByteOrder target_byte_sex); 231 | 232 | extern void swap_dylib_module( 233 | struct dylib_module *mods, 234 | uint32_t nmods, 235 | enum NXByteOrder target_byte_sex); 236 | 237 | extern void swap_dylib_module_64( 238 | struct dylib_module_64 *mods, 239 | uint32_t nmods, 240 | enum NXByteOrder target_byte_sex); 241 | 242 | extern void swap_dylib_table_of_contents( 243 | struct dylib_table_of_contents *tocs, 244 | uint32_t ntocs, 245 | enum NXByteOrder target_byte_sex); 246 | 247 | #ifdef __cplusplus 248 | } 249 | #endif /* __cplusplus */ 250 | 251 | #endif /* _MACH_O_SWAP_H_ */ 252 | -------------------------------------------------------------------------------- /mach-o/x86_64/reloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Relocations for x86_64 are a bit different than for other architectures in 25 | * Mach-O: Scattered relocations are not used. Almost all relocations produced 26 | * by the compiler are external relocations. An external relocation has the 27 | * r_extern bit set to 1 and the r_symbolnum field contains the symbol table 28 | * index of the target label. 29 | * 30 | * When the assembler is generating relocations, if the target label is a local 31 | * label (begins with 'L'), then the previous non-local label in the same 32 | * section is used as the target of the external relocation. An addend is used 33 | * with the distance from that non-local label to the target label. Only when 34 | * there is no previous non-local label in the section is an internal 35 | * relocation used. 36 | * 37 | * The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does 38 | * not have RELA relocations). For PC-relative relocations, the addend is 39 | * stored directly in the instruction. This is different from other Mach-O 40 | * architectures, which encode the addend minus the current section offset. 41 | * 42 | * The relocation types are: 43 | * 44 | * X86_64_RELOC_UNSIGNED // for absolute addresses 45 | * X86_64_RELOC_SIGNED // for signed 32-bit displacement 46 | * X86_64_RELOC_BRANCH // a CALL/JMP instruction with 32-bit displacement 47 | * X86_64_RELOC_GOT_LOAD // a MOVQ load of a GOT entry 48 | * X86_64_RELOC_GOT // other GOT references 49 | * X86_64_RELOC_SUBTRACTOR // must be followed by a X86_64_RELOC_UNSIGNED 50 | * 51 | * The following are sample assembly instructions, followed by the relocation 52 | * and section content they generate in an object file: 53 | * 54 | * call _foo 55 | * r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 56 | * E8 00 00 00 00 57 | * 58 | * call _foo+4 59 | * r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 60 | * E8 04 00 00 00 61 | * 62 | * movq _foo@GOTPCREL(%rip), %rax 63 | * r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 64 | * 48 8B 05 00 00 00 00 65 | * 66 | * pushq _foo@GOTPCREL(%rip) 67 | * r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 68 | * FF 35 00 00 00 00 69 | * 70 | * movl _foo(%rip), %eax 71 | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 72 | * 8B 05 00 00 00 00 73 | * 74 | * movl _foo+4(%rip), %eax 75 | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 76 | * 8B 05 04 00 00 00 77 | * 78 | * movb $0x12, _foo(%rip) 79 | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 80 | * C6 05 FF FF FF FF 12 81 | * 82 | * movl $0x12345678, _foo(%rip) 83 | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo 84 | * C7 05 FC FF FF FF 78 56 34 12 85 | * 86 | * .quad _foo 87 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo 88 | * 00 00 00 00 00 00 00 00 89 | * 90 | * .quad _foo+4 91 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo 92 | * 04 00 00 00 00 00 00 00 93 | * 94 | * .quad _foo - _bar 95 | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar 96 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo 97 | * 00 00 00 00 00 00 00 00 98 | * 99 | * .quad _foo - _bar + 4 100 | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar 101 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo 102 | * 04 00 00 00 00 00 00 00 103 | * 104 | * .long _foo - _bar 105 | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar 106 | * r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo 107 | * 00 00 00 00 108 | * 109 | * lea L1(%rip), %rax 110 | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev 111 | * 48 8d 05 12 00 00 00 112 | * // assumes _prev is the first non-local label 0x12 bytes before L1 113 | * 114 | * lea L0(%rip), %rax 115 | * r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3 116 | * 48 8d 05 56 00 00 00 117 | * // assumes L0 is in third section and there is no previous non-local label. 118 | * // The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction. 119 | * // address_of_next_instruction is the address of the relocation + 4. 120 | * 121 | * add $6,L0(%rip) 122 | * r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3 123 | * 83 05 18 00 00 00 06 124 | * // assumes L0 is in third section and there is no previous non-local label. 125 | * // The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction. 126 | * // address_of_next_instruction is the address of the relocation + 4 + 1. 127 | * // The +1 comes from SIGNED_1. This is used because the relocation is not 128 | * // at the end of the instruction. 129 | * 130 | * .quad L1 131 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev 132 | * 12 00 00 00 00 00 00 00 133 | * // assumes _prev is the first non-local label 0x12 bytes before L1 134 | * 135 | * .quad L0 136 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3 137 | * 56 00 00 00 00 00 00 00 138 | * // assumes L0 is in third section, has an address of 0x00000056 in .o 139 | * // file, and there is no previous non-local label 140 | * 141 | * .quad _foo - . 142 | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev 143 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo 144 | * EE FF FF FF FF FF FF FF 145 | * // assumes _prev is the first non-local label 0x12 bytes before this 146 | * // .quad 147 | * 148 | * .quad _foo - L1 149 | * r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev 150 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo 151 | * EE FF FF FF FF FF FF FF 152 | * // assumes _prev is the first non-local label 0x12 bytes before L1 153 | * 154 | * .quad L1 - _prev 155 | * // No relocations. This is an assembly time constant. 156 | * 12 00 00 00 00 00 00 00 157 | * // assumes _prev is the first non-local label 0x12 bytes before L1 158 | * 159 | * 160 | * 161 | * In final linked images, there are only two valid relocation kinds: 162 | * 163 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index 164 | * This tells dyld to add the address of a symbol to a pointer sized (8-byte) 165 | * piece of data (i.e on disk the 8-byte piece of data contains the addend). The 166 | * r_symbolnum contains the index into the symbol table of the target symbol. 167 | * 168 | * r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0 169 | * This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount 170 | * the containing image was loaded from its base address (e.g. slide). 171 | * 172 | */ 173 | enum reloc_type_x86_64 174 | { 175 | X86_64_RELOC_UNSIGNED, // for absolute addresses 176 | X86_64_RELOC_SIGNED, // for signed 32-bit displacement 177 | X86_64_RELOC_BRANCH, // a CALL/JMP instruction with 32-bit displacement 178 | X86_64_RELOC_GOT_LOAD, // a MOVQ load of a GOT entry 179 | X86_64_RELOC_GOT, // other GOT references 180 | X86_64_RELOC_SUBTRACTOR, // must be followed by a X86_64_RELOC_UNSIGNED 181 | X86_64_RELOC_SIGNED_1, // for signed 32-bit displacement with a -1 addend 182 | X86_64_RELOC_SIGNED_2, // for signed 32-bit displacement with a -2 addend 183 | X86_64_RELOC_SIGNED_4, // for signed 32-bit displacement with a -4 addend 184 | X86_64_RELOC_TLV, // for thread local variables 185 | }; 186 | -------------------------------------------------------------------------------- /machoview.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /machoview.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /machoview.xcodeproj/project.xcworkspace/xcuserdata/junzhan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intheway/MachOView/a3dbb7ef4c62fab34a656646b781a139010d28c2/machoview.xcodeproj/project.xcworkspace/xcuserdata/junzhan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /machoview.xcodeproj/xcuserdata/junzhan.xcuserdatad/xcschemes/MachOView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /machoview.xcodeproj/xcuserdata/junzhan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MachOView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8D1107260486CEB800E47090 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Mach-O Browser 4 | // 5 | // Created by psaghelyi on 10/06/2010. 6 | // 7 | 8 | 9 | // every std IO operation needs to be paused until pipes are in use 10 | NSCondition * pipeCondition; 11 | int32_t numIOThread; 12 | 13 | int 14 | main(int argc, const char *argv[]) 15 | { 16 | pipeCondition = [[NSCondition alloc]init]; 17 | numIOThread = 0; 18 | return NSApplicationMain(argc, argv); 19 | } 20 | -------------------------------------------------------------------------------- /redApple.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intheway/MachOView/a3dbb7ef4c62fab34a656646b781a139010d28c2/redApple.icns -------------------------------------------------------------------------------- /stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intheway/MachOView/a3dbb7ef4c62fab34a656646b781a139010d28c2/stop.png --------------------------------------------------------------------------------