bool MMap::ResolveImport(ImageContext* pImage, bool useDelayed /*= false */) { auto imports = pImage->peImage.GetImports(useDelayed); if(imports.empty()) return true; // Traverse entries for(auto& importMod : imports) { std::wstring wstrDll = importMod.first; // Load dependency if needed auto hMod = FindOrMapDependency(pImage, wstrDll); if(!hMod) { // TODO: Add error code BLACBONE_TRACE(L"ManualMap: Failed to load dependency '%ls'. Status = 0x%x", wstrDll.c_str(), LastNtStatus()); return false; } for(auto& importFn : importMod.second) { exportData expData; if(importFn.importByOrd) expData = _process.Modules().GetExport(hMod, reinterpret_cast<const char*>(importFn.importOrdinal)); else expData = _process.Modules().GetExport(hMod, importFn.importName.c_str()); // Still forwarded, load missing modules while(expData.procAddress && expData.isForwarded) { std::wstring wdllpath = expData.forwardModule; // Ensure module is loaded auto hFwdMod = FindOrMapDependency(pImage, wdllpath); if(!hFwdMod) { // TODO: Add error code BLACBONE_TRACE(L"ManualMap: Failed to load forwarded dependency '%ls'. Status = 0x%x", wstrDll.c_str(), LastNtStatus()); return false; } if(expData.forwardByOrd) expData = _process.Modules().GetExport(hFwdMod, reinterpret_cast<const char*>(expData.forwardOrdinal), wdllpath.c_str()); else expData = _process.Modules().GetExport(hFwdMod, expData.forwardName.c_str(), wdllpath.c_str()); } // Failed to resolve import if(expData.procAddress == 0) { LastNtStatus(STATUS_ORDINAL_NOT_FOUND); if(importFn.importByOrd) BLACBONE_TRACE(L"ManualMap: Failed to get import #%d from image '%ls'", importFn.importOrdinal, wstrDll.c_str()); else BLACBONE_TRACE(L"ManualMap: Failed to get import '%ls' from image '%ls'", Utils::AnsiToWstring(importFn.importName).c_str(), wstrDll.c_str()); return false; } auto status = STATUS_SUCCESS; if(pImage->flags & HideVAD) { size_t address = static_cast<size_t>(expData.procAddress); status = Driver().WriteMem(_process.Id(), pImage->imgMem.Ptr() + importFn.ptrRVA, sizeof(address), &address); } else status = pImage->imgMem.Write(importFn.ptrRVA, static_cast<size_t>(expData.procAddress)); // Write function address if(!NT_SUCCESS(status)) { BLACBONE_TRACE(L"ManualMap: Failed to write import function address at offset 0x%x. Status = 0x%x", importFn.ptrRVA, status); return false; } } } return true; }
/// <summary> /// Resolves image import or delayed image import /// </summary> /// <param name="pImage">Image data</param> /// <param name="useDelayed">Resolve delayed import instead</param> /// <returns>true on success</returns> bool MMap::ResolveImport( ImageContext* pImage, bool useDelayed /*= false */ ) { auto imports = pImage->PEImage.ProcessImports( useDelayed ); if (imports.empty()) return true; // Traverse entries for (auto& importMod : imports) { std::wstring wstrDll = importMod.first; // Load dependency if needed auto hMod = FindOrMapDependency( pImage, wstrDll ); if (!hMod) { // TODO: Add error code return false; } for (auto& importFn : importMod.second) { exportData expData; if (importFn.importByOrd) expData = _process.modules().GetExport( hMod, reinterpret_cast<const char*>(importFn.importOrdinal) ); else expData = _process.modules().GetExport( hMod, importFn.importName.c_str() ); // Still forwarded, load missing modules while (expData.procAddress && expData.isForwarded) { std::wstring wdllpath = expData.forwardModule; // Ensure module is loaded auto hFwdMod = FindOrMapDependency( pImage, wdllpath ); if (!hFwdMod) { // TODO: Add error code return false; } if (expData.forwardByOrd) expData = _process.modules().GetExport( hFwdMod, reinterpret_cast<const char*>(expData.forwardOrdinal), wdllpath.c_str() ); else expData = _process.modules().GetExport( hFwdMod, expData.forwardName.c_str(), wdllpath.c_str() ); } // Failed to resolve import if (expData.procAddress == 0) { // TODO: Add error code return false; } // Write function address if (pImage->imgMem.Write( importFn.ptrRVA, static_cast<size_t>(expData.procAddress) ) != STATUS_SUCCESS) return false; } } return true; }