VOID D3DXMeshIndexEnumer::SetIndex( UINT uWhichIndex, DWORD dwIndex ) { _ASSERTE(uWhichIndex < GetIndexCount()); BYTE* pCurIndex = m_pBuffer + m_dwNumBytePerIndex * uWhichIndex; if(Is32Bit()) *reinterpret_cast<DWORD*>(pCurIndex) = dwIndex; else *reinterpret_cast<WORD*>(pCurIndex) = (WORD)dwIndex; }
void CR_Module::DumpImportSymbols() { PIMAGE_IMPORT_DESCRIPTOR descs; CR_StringSet dll_names; CR_DeqSet<CR_ImportSymbol> symbols; descs = ImportDescriptors(); if (descs == NULL) return; printf("\n### IMPORTS ###\n"); printf(" Characteristics: 0x%08lX\n", descs->Characteristics); printf(" TimeDateStamp: 0x%08lX (%s)\n", descs->TimeDateStamp, CrGetTimeStampString(descs->TimeDateStamp)); printf(" ForwarderChain: 0x%08lX\n", descs->ForwarderChain); printf(" Name: 0x%08lX (%s)\n", descs->Name, reinterpret_cast<char *>(GetData(descs->Name))); printf(" \n"); if (!_GetImportDllNames(dll_names)) return; for (DWORD i = 0; i < dll_names.size(); ++i) { printf(" %s\n", dll_names[i].c_str()); if (Is64Bit()) printf(" RVA VA HINT FUNCTION NAME\n"); else printf(" RVA VA HINT FUNCTION NAME\n"); if (_GetImportSymbols(i, symbols)) { for (DWORD j = 0; j < symbols.size(); j++) { if (Is64Bit()) { CR_Addr64 addr = VA64FromRVA(symbols[j].dwRVA); printf(" %08lX %08lX%08lX ", symbols[j].dwRVA, HILONG(addr), LOLONG(addr)); } else if (Is32Bit()) { CR_Addr32 addr = VA32FromRVA(symbols[j].dwRVA); printf(" %08lX %08lX ", symbols[j].dwRVA, addr); } if (symbols[j].Name.wImportByName) printf("%4X %s\n", symbols[j].wHint, symbols[j].pszName); else printf("Ordinal %d\n", symbols[j].Name.wOrdinal); } printf(" \n"); } } }
BOOL CR_ModuleEx::DisAsm32() { if (!IsModuleLoaded() || !Is32Bit()) return FALSE; _CreateInfo32(); if (Info32()->Entrances().empty()) { _PrepareForDisAsm32(); } // disasm entrances bool needs_retry; do { // NOTE: Info32()->Entrances() may grow in _DisAsmAddr32 needs_retry = false; CR_Addr32Set addrs = Info32()->Entrances(); for (auto addr : addrs) { // check func stage auto stage = Info32()->GetFuncStage(addr); if (stage > 0) { continue; } needs_retry = true; _DisAsmAddr32(addr, addr); // get code func auto cf = Info32()->CodeFuncFromAddr(addr); assert(cf); // recurse all jumpees // NOTE: cf->Jumpees() may grow in _DisAsmAddr32 CR_Addr32Set jumpees; do { jumpees = cf->Jumpees(); for (auto jumpee : jumpees) { _DisAsmAddr32(addr, jumpee); } } while (jumpees.size() < cf->Jumpees().size()); } } while (needs_retry); return TRUE; } // CR_ModuleEx::DisAsm32
BOOL CR_ModuleEx::_PrepareForDisAsm32() { if (!IsModuleLoaded() || !Is32Bit()) return FALSE; _CreateInfo32(); if (Info32()->Entrances().size()) { return TRUE; } // register entrances auto RVA = RVAOfEntryPoint(); CR_Addr32 va = VA32FromRVA(RVA); Info32()->Entrances().emplace(va); { auto codefunc = make_shared<CR_CodeFunc32>(); codefunc->Addr() = va; codefunc->Name() = "EntryPoint"; codefunc->StackArgSizeRange().Set(0); codefunc->FuncFlags() |= cr_FF_CDECL; Info32()->MapAddrToCodeFunc().emplace(va, codefunc); MapRVAToFuncName().emplace(RVA, codefunc->Name()); MapFuncNameToRVA().emplace(codefunc->Name(), RVA); } // exporting functions are entrances for (auto& e_symbol : ExportSymbols()) { va = VA32FromRVA(e_symbol.dwRVA); if (!AddressInCode32(va)) { continue; } Info32()->Entrances().emplace(va); MapRVAToFuncName().emplace(e_symbol.dwRVA, e_symbol.pszName); MapFuncNameToRVA().emplace(e_symbol.pszName, e_symbol.dwRVA); } return TRUE; } // CR_ModuleEx::_PrepareForDisAsm32
BOOL CR_ModuleEx::_DisAsmAddr32(CR_Addr32 func, CR_Addr32 va) { if (!IsModuleLoaded() || !Is32Bit()) return FALSE; int len; char outbuf[256]; CR_Addr32 addr; // add or retrieve the code function auto cf = Info32()->CodeFuncFromAddr(func); if (cf == NULL) { Info32()->MapAddrToCodeFunc().emplace(func, make_shared<CR_CodeFunc32>()); cf = Info32()->CodeFuncFromAddr(func); } assert(cf); if (func == va) { cf->Addr() = func; } const REAL_IMAGE_SECTION_HEADER *pCode = CodeSectionHeader(); assert(pCode); DWORD rva = RVAFromVA32(va); LPBYTE input = m_pLoadedImage + rva; LPBYTE iend = m_pLoadedImage + pCode->RVA + pCode->SizeOfRawData; while (input < iend) { // add or retrieve op.code auto oc = Info32()->OpCodeFromAddr(va); if (oc == NULL) { Info32()->MapAddrToOpCode().emplace(va, make_shared<CR_OpCode32>()); oc = Info32()->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), 32, 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)->Value32(); 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)->Value32(); Info32()->Entrances().emplace(addr); cf->Callers().emplace(addr); auto newcf = Info32()->CodeFuncFromAddr(addr); if (newcf == NULL) { Info32()->MapAddrToCodeFunc().emplace( addr, make_shared<CR_CodeFunc32>()); newcf = Info32()->CodeFuncFromAddr(addr); } newcf->Addr() = addr; newcf->Callees().emplace(func); } else { addr = oc->Operand(0)->Value32(); 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)->Value32(); Info32()->Entrances().emplace(addr); cf->Callees().emplace(addr); { auto newcf = Info32()->CodeFuncFromAddr(addr); if (newcf == NULL) { Info32()->MapAddrToCodeFunc().emplace( addr, make_shared<CR_CodeFunc32>()); newcf = Info32()->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) { // func is __stdcall cf->FuncFlags() |= cr_FF_STDCALL; cf->StackArgSizeRange().Set(oc->Operand(0)->Value32()); } else { // func is not __stdcall cf->FuncFlags() |= cr_FF_NOTSTDCALL; if (func == va) { cf->FuncFlags() |= cr_FF_RETURNONLY | cr_FF_CDECL; } } cf->Exits().insert(va); bBreak = TRUE; break; default: break; } if (bBreak) break; // move to next position input += len; va += len; } return TRUE; } // CR_ModuleEx::_DisAsmAddr32
void CR_Module::DumpDelayLoad() { if (DelayLoadDescriptors().empty()) { LoadDelayLoad(); if (DelayLoadDescriptors().empty()) return; } printf("\n### DELAY LOAD ###\n"); const std::size_t size = DelayLoadDescriptors().size(); DWORD rva; if (Is64Bit()) { CR_Addr64 addr; for (std::size_t i = 0; i < size; ++i) { printf(" ### Descr #%u ###\n", static_cast<int>(i)); printf(" NAME %-8s %-8s\n", "RVA", "VA"); rva = DelayLoadDescriptors()[i].grAttrs; addr = VA64FromRVA(rva); printf(" Attrs: %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); rva = DelayLoadDescriptors()[i].rvaDLLName; addr = VA64FromRVA(rva); printf(" DLL Name: %s\n", (LPCSTR)(LoadedImage() + rva)); printf(" : %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); rva = DelayLoadDescriptors()[i].rvaHmod; addr = VA64FromRVA(rva); printf(" Module: %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); rva = DelayLoadDescriptors()[i].rvaIAT; addr = VA64FromRVA(rva); printf(" IAT: %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); rva = DelayLoadDescriptors()[i].rvaINT; addr = VA64FromRVA(rva); printf(" INT: %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); rva = DelayLoadDescriptors()[i].rvaBoundIAT; addr = VA64FromRVA(rva); printf(" BoundIAT: %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); rva = DelayLoadDescriptors()[i].rvaUnloadIAT; addr = VA64FromRVA(rva); printf(" UnloadIAT: %08lX %08lX%08lX\n", rva, HILONG(addr), LOLONG(addr)); const char *pszTime = CrGetTimeStampString(DelayLoadDescriptors()[i].dwTimeStamp); printf(" dwTimeStamp: 0x%08lX (%s)", DelayLoadDescriptors()[i].dwTimeStamp, pszTime); } } else if (Is32Bit()) { CR_Addr32 addr; for (std::size_t i = 0; i < size; ++i) { printf(" ### Descr #%u ###\n", static_cast<int>(i)); printf(" NAME %-8s %-8s\n", "RVA", "VA"); rva = DelayLoadDescriptors()[i].grAttrs; addr = VA32FromRVA(rva); printf(" Attrs: %08lX %08lX\n", rva, addr); rva = DelayLoadDescriptors()[i].rvaDLLName; addr = VA32FromRVA(rva); printf(" DLL Name: %s\n", (LPCSTR)(LoadedImage() + rva)); printf(" : %08lX %08lX\n", rva, addr); rva = DelayLoadDescriptors()[i].rvaHmod; addr = VA32FromRVA(rva); printf(" Module: %08lX %08lX\n", rva, addr); rva = DelayLoadDescriptors()[i].rvaIAT; addr = VA32FromRVA(rva); printf(" IAT: %08lX %08lX\n", rva, addr); rva = DelayLoadDescriptors()[i].rvaINT; addr = VA32FromRVA(rva); printf(" INT: %08lX %08lX\n", rva, addr); rva = DelayLoadDescriptors()[i].rvaBoundIAT; addr = VA32FromRVA(rva); printf(" BoundIAT: %08lX %08lX\n", rva, addr); rva = DelayLoadDescriptors()[i].rvaUnloadIAT; addr = VA32FromRVA(rva); printf(" UnloadIAT: %08lX %08lX\n", rva, addr); const char *pszTime = CrGetTimeStampString(DelayLoadDescriptors()[i].dwTimeStamp); printf(" dwTimeStamp: 0x%08lX (%s)", DelayLoadDescriptors()[i].dwTimeStamp, pszTime); } } printf("\n\n"); }
void CR_Module::DumpExportSymbols() { PIMAGE_EXPORT_DIRECTORY pDir = ExportDirectory(); if (pDir == NULL) return; //DWORD dwNumberOfNames = pDir->NumberOfNames; //DWORD dwAddressOfFunctions = pDir->AddressOfFunctions; //DWORD dwAddressOfNames = pDir->AddressOfNames; //DWORD dwAddressOfOrdinals = pDir->AddressOfNameOrdinals; //LPDWORD pEAT = (LPDWORD)GetData(dwAddressOfFunctions); //LPDWORD pENPT = (LPDWORD)GetData(dwAddressOfNames); //LPWORD pOT = (LPWORD)GetData(dwAddressOfOrdinals); printf("\n### EXPORTS ###\n"); printf(" Characteristics: 0x%08lX\n", pDir->Characteristics); printf(" TimeDateStamp: 0x%08lX (%s)\n", pDir->TimeDateStamp, CrGetTimeStampString(pDir->TimeDateStamp)); printf(" Version: %u.%u\n", pDir->MajorVersion, pDir->MinorVersion); printf(" Name: 0x%08lX (%s)\n", pDir->Name, reinterpret_cast<char *>(GetData(pDir->Name))); printf(" Base: 0x%08lX (%lu)\n", pDir->Base, pDir->Base); printf(" NumberOfFunctions: 0x%08lX (%lu)\n", pDir->NumberOfFunctions, pDir->NumberOfFunctions); printf(" NumberOfNames: 0x%08lX (%lu)\n", pDir->NumberOfNames, pDir->NumberOfNames); printf(" AddressOfFunctions: 0x%08lX\n", pDir->AddressOfFunctions); printf(" AddressOfNames: 0x%08lX\n", pDir->AddressOfNames); printf(" AddressOfNameOrdinals: 0x%08lX\n", pDir->AddressOfNameOrdinals); printf(" \n"); printf(" %-50s %-5s ; %-8s %-8s\n", "FUNCTION NAME", "ORDI.", "RVA", "VA"); for (DWORD i = 0; i < ExportSymbols().size(); ++i) { CR_ExportSymbol& symbol = ExportSymbols()[i]; if (symbol.dwRVA) { if (Is64Bit()) { CR_Addr64 va = VA64FromRVA(symbol.dwRVA); if (symbol.pszName) printf(" %-50s @%-4lu ; %08lX %08lX%08lX\n", symbol.pszName, symbol.dwOrdinal, symbol.dwRVA, HILONG(va), LOLONG(va)); else printf(" %-50s @%-4lu ; %08lX %08lX%08lX\n", "(No Name)", symbol.dwOrdinal, symbol.dwRVA, HILONG(va), LOLONG(va)); } else if (Is32Bit()) { CR_Addr32 va = VA32FromRVA(symbol.dwRVA); if (symbol.pszName) printf(" %-50s @%-4lu ; %08lX %08lX\n", symbol.pszName, symbol.dwOrdinal, symbol.dwRVA, va); else printf(" %-50s @%-4lu ; %08lX %08lX\n", "(No Name)", symbol.dwOrdinal, symbol.dwRVA, va); } } else { if (symbol.pszName) printf(" %-50s @%-4lu ; (forwarded to %s)\n", "(No Name)", symbol.dwOrdinal, symbol.pszForwarded); else printf(" %-50s @%-4lu ; (forwarded to %s)\n", "(No Name)", symbol.dwOrdinal, symbol.pszForwarded); } } printf("\n\n"); }
PERawOptionalHeader64 * PEFileT<T>::GetRawOptionalHeader64() { return (PERawOptionalHeader64 *)(Is32Bit() ? GetRawOptionalHeader() : NULL); }
PERawNtHeaders64 * PEFileT<T>::GetRawNtHeaders64() { LIBPE_ASSERT_RET(NULL != m_pNtHeaders, NULL); return (PERawNtHeaders64 *)(Is32Bit() ? NULL : GetRawNtHeaders()); }
PERawNtHeaders32 * PEFileT<T>::GetRawNtHeaders32() { return (PERawNtHeaders32 *)(Is32Bit() ? GetRawNtHeaders() : NULL); }