/* ================= Sys_GetProcessorFeatures ================= */ int Sys_GetProcessorFeatures( void ) { int features = 0; //cpuFeatures_t features = (cpuFeatures_t)0; CPUINFO cpuinfo; GetCPUInfo( &cpuinfo, CI_FALSE ); if( HasCPUID() ) features |= CF_RDTSC; if( HasMMX( &cpuinfo ) ) features |= CF_MMX; if( HasMMXExt( &cpuinfo ) ) features |= CF_MMX_EXT; if( Has3DNow( &cpuinfo ) ) features |= CF_3DNOW; if( Has3DNowExt( &cpuinfo ) ) features |= CF_3DNOW_EXT; if( HasSSE( &cpuinfo ) ) features |= CF_SSE; if( HasSSE2( &cpuinfo ) ) features |= CF_SSE2; if( HasSSE3( &cpuinfo ) ) features |= CF_SSE3; if( HasSSSE3( &cpuinfo ) ) features |= CF_SSSE3; if( HasSSE4_1( &cpuinfo ) ) features |= CF_SSE4_1; if( HasSSE4_2( &cpuinfo ) ) features |= CF_SSE4_2; if( HasHTT( &cpuinfo ) ) features |= CF_HasHTT; if( HasSerial( &cpuinfo ) ) features |= CF_HasSerial; if( Is64Bit( &cpuinfo ) ) features |= CF_Is64Bit; return features; }
void GenerateApk(std::wstring path ) { //if ( !JREInstalled() ) //{ // MessageBoxW(NULL, L"未安装 java 运行环境,无法生成 apk 安装包,请安装 java 运行环境后重试!", L"提示", MB_OK | MB_ICONINFORMATION); // return; //} SHELLEXECUTEINFOW sei; memset(&sei, 0, sizeof(SHELLEXECUTEINFO)); std::wstring installPath = GetExePath() + L"\\dependency\\Android\\Remote\\install.exe"; wchar_t cmd[1024] = {0}; wsprintfW(cmd, L"-i \"%s\" -o \"%s\"", GetExePath().c_str(), path.c_str()); sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; sei.lpVerb = L"open"; sei.lpFile = installPath.c_str(); sei.lpParameters = cmd; sei.nShow = SW_HIDE; PVOID oldValue = NULL; if ( Is64Bit() && !oldValue ) { HMODULE kernel32 = GetModuleHandleA("kernel32.dll"); pWow64DisableWow64FsRedirection foo = (pWow64DisableWow64FsRedirection)GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection"); foo(&oldValue); } ShellExecuteExW(&sei); WaitForSingleObject(sei.hProcess, INFINITE); CloseHandle(sei.hProcess); if ( Is64Bit() && oldValue ) { HMODULE kernel32 = GetModuleHandleA("kernel32.dll"); pWow64RevertWow64FsRedirection foo = (pWow64RevertWow64FsRedirection)GetProcAddress(kernel32, "Wow64RevertWow64FsRedirection"); foo(oldValue); } }
BOOL CR_ModuleEx::DisAsm64() { if (!IsModuleLoaded() || !Is64Bit()) return FALSE; _CreateInfo64(); if (Info64()->Entrances().empty()) { _PrepareForDisAsm64(); } // disasm entrances bool needs_retry; do { // NOTE: Info64()->Entrances() may grow in _DisAsmAddr64 needs_retry = false; CR_Addr64Set addrs = Info64()->Entrances(); for (auto addr : addrs) { // check func stage auto stage = Info64()->GetFuncStage(addr); if (stage > 0) { continue; } needs_retry = true; _DisAsmAddr64(addr, addr); // get code func auto cf = Info64()->CodeFuncFromAddr(addr); assert(cf); // recurse all jumpees // NOTE: cf->Jumpees() may grow in _DisAsmAddr64 CR_Addr64Set jumpees; do { jumpees = cf->Jumpees(); for (auto jumpee : jumpees) { _DisAsmAddr64(addr, jumpee); } } while (jumpees.size() < cf->Jumpees().size()); } } while (needs_retry); return TRUE; } // CR_ModuleEx::DisAsm64
BOOL CR_ModuleEx::_PrepareForDisAsm64() { if (!IsModuleLoaded() || !Is64Bit()) return FALSE; _CreateInfo64(); if (Info64()->Entrances().size()) { return TRUE; } // register entrances auto RVA = RVAOfEntryPoint(); CR_Addr64 va = VA64FromRVA(RVA); Info64()->Entrances().emplace(va); { auto codefunc = make_shared<CR_CodeFunc64>(); codefunc->Addr() = va; codefunc->Name() = "EntryPoint"; codefunc->StackArgSizeRange().Set(0); Info64()->MapAddrToCodeFunc().emplace(va, codefunc); MapRVAToFuncName().emplace(RVA, codefunc->Name()); MapFuncNameToRVA().emplace(codefunc->Name(), RVA); } // exporting functions are entrances for (auto& e_symbol : ExportSymbols()) { va = VA64FromRVA(e_symbol.dwRVA); if (!AddressInCode64(va)) { continue; } Info64()->Entrances().emplace(va); MapRVAToFuncName().emplace(e_symbol.dwRVA, e_symbol.pszName); MapFuncNameToRVA().emplace(e_symbol.pszName, e_symbol.dwRVA); } return TRUE; } // CR_ModuleEx::_PrepareForDisAsm64
status_t ElfFile::CreateSymbolLookup(uint64 textDelta, ElfSymbolLookup*& _lookup) const { // Get the symbol table + corresponding string section. There may be two // symbol tables: the dynamic and the non-dynamic one. The former contains // only the symbols needed at run-time. The latter, if existing, is likely // more complete. So try to find and use the latter one, falling back to the // former. ElfSection* symbolSection; ElfSection* stringSection; if (!_FindSymbolSections(symbolSection, stringSection, SHT_SYMTAB) && !_FindSymbolSections(symbolSection, stringSection, SHT_DYNSYM)) { return B_ENTRY_NOT_FOUND; } // create a source with a segment for each section SymbolLookupSource* source = new(std::nothrow) SymbolLookupSource(fFD); if (source == NULL) return B_NO_MEMORY; BReference<SymbolLookupSource> sourceReference(source, true); if (!source->AddSegment(symbolSection->Offset(), symbolSection->Size(), symbolSection->Offset()) || !source->AddSegment(stringSection->Offset(), stringSection->Size(), stringSection->Offset())) { return B_NO_MEMORY; } // create the lookup size_t symbolTableEntrySize = Is64Bit() ? sizeof(ElfClass64::Sym) : sizeof(ElfClass32::Sym); uint32 symbolCount = uint32(symbolSection->Size() / symbolTableEntrySize); return ElfSymbolLookup::Create(source, symbolSection->Offset(), 0, stringSection->Offset(), symbolCount, symbolTableEntrySize, textDelta, f64Bit, fSwappedByteOrder, true, _lookup); }
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
BOOL OSInfo::Is32Bit() { return !Is64Bit (); }
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"); }