QList<segment_command_64> MACHFile::getSegmentsList64() { QList<load_command_offset> list=getLoadCommands_offset(); unsigned int nOffset=0; QList<segment_command_64> listResult; segment_command_64 record; for(int i=0; i<list.count(); i++) { if(list.at(i).cmd==LC_SEGMENT_64) { nOffset=list.at(i).offset; record.cmd=readDword(nOffset+offsetof(segment_command_64,cmd),isReverse()); record.cmdsize=readDword(nOffset+offsetof(segment_command_64,cmdsize),isReverse()); readArray(nOffset+offsetof(segment_command_64,segname),record.segname,16); record.vmaddr=readQword(nOffset+offsetof(segment_command_64,vmaddr),isReverse()); record.vmsize=readQword(nOffset+offsetof(segment_command_64,vmsize),isReverse()); record.fileoff=readQword(nOffset+offsetof(segment_command_64,fileoff),isReverse()); record.filesize=readQword(nOffset+offsetof(segment_command_64,filesize),isReverse()); record.maxprot=readDword(nOffset+offsetof(segment_command_64,maxprot),isReverse()); record.initprot=readDword(nOffset+offsetof(segment_command_64,initprot),isReverse()); record.nsects=readDword(nOffset+offsetof(segment_command_64,nsects),isReverse()); record.flags=readDword(nOffset+offsetof(segment_command_64,flags),isReverse()); listResult.append(record); } } return listResult; }
static ut64 getRefPtr(RCoreObjc *objc, ut64 classMethodsVA, bool *res) { ut64 namePtr = readQword (objc, classMethodsVA); int i, cnt = 0; ut64 res_at = 0LL; const char *k = addr_key (namePtr); *res = false; for (i = 0; ; i++) { ut64 at = sdb_array_get_num (objc->db, k, i, NULL); if (!at) { break; } if (inBetween (objc->_selrefs, at)) { *res = false; res_at = at; } else if (inBetween (objc->_msgrefs, at)) { *res = true; res_at = at; } else if (inBetween (objc->_const, at)) { cnt++; } } if (cnt > 1) { return 0LL; } return res_at; }
unsigned long long MACHFile::getEntryPoint() { unsigned long long nResult=0; unsigned int nNumberOfCommands=getHeader_ncmds(); if(nNumberOfCommands>0xFF) { nNumberOfCommands=0xFF; } for(int i=0; i<nNumberOfCommands; i++) { if((getLoadCommand_type(i)==LC_THREAD)||(getLoadCommand_type(i)==LC_UNIXTHREAD)) { unsigned int nOffset=getLoadCommand_offset(i); unsigned int nFlavor=readDword(nOffset+8,isReverse()); if(nFlavor==x86_THREAD_STATE32) { nResult=readDword(nOffset+16+offsetof(F_STRUCT_X86_THREAD_STATE32,eip),isReverse()); } else if(nFlavor==x86_THREAD_STATE64) { nResult=readQword(nOffset+16+offsetof(F_STRUCT_X86_THREAD_STATE64,rip),isReverse()); } } } return nResult; }
QList<section_64> MACHFile::getSectionsList64() { QList<section_64> listResult; QList<load_command_offset> list=getLoadCommands_offset(); unsigned int nOffset=0; section_64 record; unsigned int nNumberOfSections=0; for(int i=0; i<list.count(); i++) { if(list.at(i).cmd==LC_SEGMENT_64) { nOffset=list.at(i).offset; nNumberOfSections=readDword(nOffset+offsetof(segment_command_64,nsects),isReverse()); nOffset+=sizeof(segment_command_64); for(int j=0; j<nNumberOfSections; j++) { readArray(nOffset+offsetof(section_64,sectname),record.sectname,16); readArray(nOffset+offsetof(section_64,segname),record.segname,16); record.addr=readQword(nOffset+offsetof(section_64,addr),isReverse()); record.size=readQword(nOffset+offsetof(section_64,size),isReverse()); record.offset=readDword(nOffset+offsetof(section_64,offset),isReverse()); record.align=readDword(nOffset+offsetof(section_64,align),isReverse()); record.reloff=readDword(nOffset+offsetof(section_64,reloff),isReverse()); record.nreloc=readDword(nOffset+offsetof(section_64,nreloc),isReverse()); record.flags=readDword(nOffset+offsetof(section_64,flags),isReverse()); record.reserved1=readDword(nOffset+offsetof(section_64,reserved1),isReverse()); record.reserved2=readDword(nOffset+offsetof(section_64,reserved2),isReverse()); listResult.append(record); nOffset+=sizeof(section_64); } } } return listResult; }
void interpretLoad(Instruction* ins) { switch(ins->argSize) { case 1: pushByte(readByte(popDword())); break; case 2: pushWord(readWord(popDword())); break; case 4: pushDword(readDword(popDword())); break; case 8: pushQword(readQword(popDword())); break; } }
static bool objc_find_refs(RCore *core) { static const char *oldstr = NULL; RCoreObjc objc = {0}; const int objc2ClassSize = 0x28; const int objc2ClassInfoOffs = 0x20; const int objc2ClassMethSize = 0x18; const int objc2ClassBaseMethsOffs = 0x20; const int objc2ClassMethImpOffs = 0x10; objc.core = core; objc.word_size = (core->assembler->bits == 64)? 8: 4; RList *sections = r_bin_get_sections (core->bin); if (!sections) { return false; } RBinSection *s; RListIter *iter; r_list_foreach (sections, iter, s) { const char *name = s->name; if (strstr (name, "__objc_data")) { objc._data = s; } else if (strstr (name, "__objc_selrefs")) { objc._selrefs = s; } else if (strstr (name, "__objc_msgrefs")) { objc._msgrefs = s; } else if (strstr (name, "__objc_const")) { objc._const = s; } } if (!objc._const) { if (core->anal->verbose) { eprintf ("Could not find necessary objc_const section\n"); } return false; } if ((objc._selrefs || objc._msgrefs) && !(objc._data && objc._const)) { if (core->anal->verbose) { eprintf ("Could not find necessary Objective-C sections...\n"); } return false; } objc.db = sdb_new0 (); if (!objc_build_refs (&objc)) { return false; } oldstr = r_print_rowlog (core->print, "Parsing metadata in ObjC to find hidden xrefs"); r_print_rowlog_done (core->print, oldstr); int total = 0; ut64 off; for (off = 0; off < objc._data->vsize ; off += objc2ClassSize) { ut64 va = objc._data->vaddr + off; ut64 classRoVA = readQword (&objc, va + objc2ClassInfoOffs); if (isInvalid (classRoVA)) { continue; } ut64 classMethodsVA = readQword (&objc, classRoVA + objc2ClassBaseMethsOffs); if (isInvalid (classMethodsVA)) { continue; } int count = readDword (&objc, classMethodsVA + 4); classMethodsVA += 8; // advance to start of class methods array ut64 from = classMethodsVA; ut64 to = from + (objc2ClassMethSize * count); ut64 va2; for (va2 = from; va2 < to; va2 += objc2ClassMethSize) { bool isMsgRef = false; ut64 selRefVA = getRefPtr (&objc, va2, &isMsgRef); if (!selRefVA) { continue; } // # adjust pointer to beginning of message_ref struct to get xrefs if (isMsgRef) { selRefVA -= 8; } ut64 funcVA = readQword (&objc, va2 + objc2ClassMethImpOffs); RList *list = r_anal_xrefs_get (core->anal, selRefVA); RListIter *iter; RAnalRef *ref; r_list_foreach (list, iter, ref) { r_anal_xrefs_set (core->anal, ref->addr, funcVA, R_META_TYPE_CODE); total++; } } }
unsigned long long MACHFile::getSection_size64(unsigned int nSection) { return readQword(getSectionHeaderOffset(nSection)+offsetof(section_64,size),isReverse()); }
unsigned long long MACHFile::getSegment_filesize64(unsigned int nSegment) { return readQword(getSegmentHeaderOffset(nSegment)+offsetof(segment_command_64,filesize),isReverse()); }