QString Interface::CallerUuid(int caller) { if ((caller >= 0) && (caller < NumCallers())) { return Callers()[caller].uuid; } return QString(); }
const QStringList Interface::GetProfile(ProfileType type) { QStringList list; if (type & ProfileType_Emitters) { int numEmitters = NumEmitters(); for (int i=0; i < numEmitters; i++) { QString uuid = Emitters()[i].uuid; InsertString(list, uuid); } } if (type & ProfileType_Receivers) { int numReceivers = NumReceivers(); for (int i=0; i < numReceivers; i++) { QString uuid = Receivers()[i].uuid; InsertString(list, uuid); } } if (type & ProfileType_Callers) { int numCallers = NumCallers(); for (int i=0; i < numCallers; i++) { QString uuid = Callers()[i].uuid; InsertString(list, uuid); } } if (type & ProfileType_FuncSets) { int numFuncSets = NumFuncSets(); for (int i=0; i < numFuncSets; i++) { QString uuid = FuncSets()[i].uuid; InsertString(list, uuid); } } return list; }
int Interface::GetCaller(const QString& uuid) { int numCallers = NumCallers(); for (int i=0; i < numCallers; i++) { if (uuid == Callers()[i].uuid) { return i; } } return -1; }
BOOL CR_ModuleEx::_DisAsmAddr64(CR_Addr64 func, CR_Addr64 va) { if (!IsModuleLoaded() || !Is64Bit()) return FALSE; // calculate int len; char outbuf[256]; CR_Addr64 addr; // add or retrieve the code function auto cf = Info64()->CodeFuncFromAddr(func); if (cf == NULL) { Info64()->MapAddrToCodeFunc().emplace(func, make_shared<CR_CodeFunc64>()); cf = Info64()->CodeFuncFromAddr(func); } assert(cf); if (func == va) { cf->Addr() = func; } auto pCode = CodeSectionHeader(); assert(pCode); DWORD rva = RVAFromVA64(va); LPBYTE input = m_pLoadedImage + rva; LPBYTE iend = m_pLoadedImage + pCode->RVA + pCode->SizeOfRawData; while (input < iend) { // add or retrieve op.code auto oc = Info64()->OpCodeFromAddr(va); if (oc == NULL) { Info64()->MapAddrToOpCode().emplace(va, make_shared<CR_OpCode64>()); oc = Info64()->OpCodeFromAddr(va); // set op.code address oc->Addr() = va; } assert(oc); if (oc->FuncAddrs().count(func) > 0) break; // add function address for this op.code oc->FuncAddrs().emplace(func); if (oc->FuncAddrs().size() > 1) { cf->FuncFlags() |= cr_FF_FUNCINFUNC; // function in function } if (oc->Codes().empty()) { // disassemble len = disasm(input, outbuf, sizeof(outbuf), 64, va, false, 0); // parse insn if (!len || input + len > iend) { len = 1; oc->Name() = "???"; oc->OpCodeType() = cr_OCT_UNKNOWN; // don't decompile if any unknown instruction. cf->FuncFlags() |= cr_FF_INVALID; } else { oc->Parse(outbuf); } // complement operand size oc->DeductOperandSizes(); // add asm codes to op.code oc->Codes().insert(oc->Codes().end(), input, &input[len]); } else { len = int(oc->Codes().size()); } BOOL bBreak = FALSE; switch (oc->OpCodeType()) { case cr_OCT_JCC: // conditional jump switch (oc->Operand(0)->GetOperandType()) { case cr_DF_IMM: addr = oc->Operand(0)->Value64(); cf->Jumpers().emplace(va); cf->Jumpees().emplace(addr); break; default: break; } break; case cr_OCT_JMP: // jump switch (oc->Operand(0)->GetOperandType()) { case cr_DF_IMM: if (func == va) { // func is jumper cf->FuncFlags() |= cr_FF_JUMPERFUNC; addr = oc->Operand(0)->Value64(); Info64()->Entrances().emplace(addr); cf->Callers().emplace(addr); auto newcf = Info64()->CodeFuncFromAddr(addr); if (newcf == NULL) { Info64()->MapAddrToCodeFunc().emplace( addr, make_shared<CR_CodeFunc64>()); newcf = Info64()->CodeFuncFromAddr(addr); } newcf->Addr() = addr; newcf->Callees().emplace(func); } else { addr = oc->Operand(0)->Value64(); cf->Jumpers().emplace(va); cf->Jumpees().emplace(addr); } break; case cr_DF_MEMIMM: if (func == va) { // func is jumper cf->FuncFlags() |= cr_FF_JUMPERFUNC; bBreak = TRUE; } break; default: break; } bBreak = TRUE; break; case cr_OCT_CALL: // call switch (oc->Operand(0)->GetOperandType()) { case cr_DF_IMM: // function call addr = oc->Operand(0)->Value64(); Info64()->Entrances().emplace(addr); cf->Callees().emplace(addr); { auto newcf = Info64()->CodeFuncFromAddr(addr); if (newcf == NULL) { Info64()->MapAddrToCodeFunc().emplace( addr, make_shared<CR_CodeFunc64>()); newcf = Info64()->CodeFuncFromAddr(addr); } newcf->Addr() = addr; newcf->Callers().emplace(func); } break; default: break; } break; case cr_OCT_RETURN: // return if (oc->Operands().size() && oc->Operand(0)->GetOperandType() == cr_DF_IMM) { cf->StackArgSizeRange().Set(oc->Operand(0)->Value64()); } else { if (func == va) { cf->FuncFlags() |= cr_FF_RETURNONLY; } } cf->Exits().insert(va); bBreak = TRUE; break; default: break; } if (bBreak) break; // move to next position input += len; va += len; } return TRUE; } // CR_ModuleEx::_DisAsmAddr64