private void BuildImportTable() { IMAGE_DATA_DIRECTORY *directory = &this.headers->OptionalHeader.ImportTable; if (directory->Size > 0) { IMAGE_IMPORT_DESCRIPTOR *importDesc = (IMAGE_IMPORT_DESCRIPTOR *)(this.codeBase + directory->VirtualAddress); for (; !NativeDeclarations.IsBadReadPtr(new IntPtr(importDesc), (uint)Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR))) && importDesc->Name > 0; importDesc++) { uint *thunkRef; int * funcRef; string funcName = Marshal.PtrToStringAnsi(new IntPtr(this.codeBase + importDesc->Name)); IntPtr handle = NativeDeclarations.LoadLibrary(funcName); if (handle == IntPtr.Zero) { throw new NativeDllLoadException("Can't load libary " + funcName); } this.modules.Add(handle); if (importDesc->OriginalFirstThunk > 0) { thunkRef = (uint *)(codeBase + importDesc->OriginalFirstThunk); funcRef = (int *)(codeBase + importDesc->FirstThunk); } else { // no hint table thunkRef = (uint *)(codeBase + importDesc->FirstThunk); funcRef = (int *)(codeBase + importDesc->FirstThunk); } for (; *thunkRef > 0; thunkRef++, funcRef++) { string procName; if (NativeDeclarations.IMAGE_SNAP_BY_ORDINAL32(*thunkRef)) { procName = Marshal.PtrToStringAnsi(new IntPtr(NativeDeclarations.IMAGE_ORDINAL32(*thunkRef))); *funcRef = (int)NativeDeclarations.GetProcAddress(handle, procName); } else { IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(codeBase + (*thunkRef)); procName = Marshal.PtrToStringAnsi(new IntPtr(thunkData->Name)); *funcRef = (int)NativeDeclarations.GetProcAddress(handle, procName); } if (*funcRef == 0) { throw new NativeDllLoadException("Can't get adress for " + procName); } } } } }
public computeImports(string path, DataTable table) { uint hLib = LoadLibraryEx(path, 0, 0); uint size = 0; IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)ImageDirectoryEntryToData((void *)hLib, true, 1, out size); if (hLib != 0 && pIID != null) { table.Columns.Add("import function", typeof(string)); table.Columns.Add("address", typeof(string)); table.Columns.Add("dll", typeof(string)); table.Columns.Add("ordinal", typeof(string)); while (pIID->OriginalFirstThunk != 0) { char * szName = (char *)(hLib + pIID->Name); string name = Marshal.PtrToStringAnsi((IntPtr)szName); THUNK_DATA *pThunkOrg = (THUNK_DATA *)(hLib + pIID->OriginalFirstThunk); while (pThunkOrg->AddressOfData != 0) { char *szImportName; uint Ord; if ((pThunkOrg->Ordinal & 0x80000000) > 0) { Ord = pThunkOrg->Ordinal & 0xffff; table.Rows.Add("", pThunkOrg->Function.ToString("X8"), name, Ord.ToString()); } else { IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(hLib + pThunkOrg->AddressOfData); if (!IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME))) { Ord = pIBN->Hint; szImportName = (char *)pIBN->Name; string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName); table.Rows.Add(sImportName, pThunkOrg->Function.ToString("X8"), name, Ord.ToString()); } else { break; } } pThunkOrg++; } pIID++; } table.DefaultView.Sort = "import function"; } }
private static bool BuildImportTable(MEMORYMODULE module) { byte* codeBase = module.codeBase; IMAGE_IMPORT_DESCRIPTOR* importDesc; bool result = true; IMAGE_DATA_DIRECTORY* directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT); if (directory->Size == 0) { return true; } importDesc = (IMAGE_IMPORT_DESCRIPTOR*)(codeBase + directory->VirtualAddress); for (; !IsBadReadPtr(importDesc, (void*)IMAGE_IMPORT_DESCRIPTOR.UnmanagedSize) && importDesc->Name != 0; importDesc++) { void** thunkRef; void** funcRef; void** tmp; void* handle = module.loadLibrary(codeBase + importDesc->Name, module.userdata); if (handle == null) { result = false; break; } tmp = (void**)realloc(module.modules, (void*)((module.numModules + 1) * sizeof(void*))); if (tmp == null) { module.freeLibrary(handle, module.userdata); result = false; break; } module.modules = tmp; module.modules[module.numModules++] = handle; if (importDesc->OriginalFirstThunk != 0) { thunkRef = (void**)(codeBase + importDesc->OriginalFirstThunk); funcRef = (void**)(codeBase + importDesc->FirstThunk); } else { // no hint table thunkRef = (void**)(codeBase + importDesc->FirstThunk); funcRef = (void**)(codeBase + importDesc->FirstThunk); } for (; *thunkRef != null; thunkRef++, funcRef++) { if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { *funcRef = module.getProcAddress(handle, (byte*)IMAGE_ORDINAL(*thunkRef), module.userdata); } else { IMAGE_IMPORT_BY_NAME* thunkData = (IMAGE_IMPORT_BY_NAME*)(codeBase + (ulong)(*thunkRef)); *funcRef = module.getProcAddress(handle, thunkData->Name, module.userdata); } if (*funcRef == null) { result = false; break; } } if (!result) { module.freeLibrary(handle, module.userdata); break; } } return result; }
// using mscoree.dll as an example as it doesnt export any thing // so nothing shows up when use the own module. // and the only none delayload in mscoree.dll is the Kernel32.dll private static void LoadImports(uint hLib, bool mappedAsImage) { unsafe { { void *hMod = (void *)hLib; uint size = 0; uint BaseAddress = (uint)hMod; if (hMod != null) { IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size); if (pIID != null) { Console.WriteLine("Got Image Import Descriptor"); //walk the array until find the end of the array while (pIID->OriginalFirstThunk != 0) { try { //Name contains the RVA to the name of the dll. //Thus convert it to a virtual address first char * szName = (char *)(BaseAddress + pIID->Name); string name = Marshal.PtrToStringAnsi((IntPtr)szName); Console.WriteLine("pIID->Name = {0} BaseAddress - {1}", name, (uint)BaseAddress); // value in OriginalFirstThunk is an RVA. // convert it to virtual address. THUNK_DATA *pThunkOrg = (THUNK_DATA *)(BaseAddress + pIID->OriginalFirstThunk); while (pThunkOrg->AddressOfData != 0) { char *szImportName; uint Ord; if ((pThunkOrg->Ordinal & 0x80000000) > 0) { Ord = pThunkOrg->Ordinal & 0xffff; Console.WriteLine("imports ({0}).Ordinal{1} - Address: {2}", name, Ord, pThunkOrg->Function); } else { IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(BaseAddress + pThunkOrg->AddressOfData); if (!Interop.IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME))) { Ord = pIBN->Hint; szImportName = (char *)pIBN->Name; string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName); // yes i know i am a lazy ass Console.WriteLine("imports ({0}).{1}@{2} - Address: {3}", name, sImportName, Ord, pThunkOrg->Function); } else { Console.WriteLine("Bad ReadPtr Detected or EOF on Imports"); break; } } pThunkOrg++; } } catch (AccessViolationException e) { Console.WriteLine("An Access violation occured\n" + "this seems to suggest the end of the imports section\n"); Console.WriteLine(e); } pIID++; } } } } } }
// using mscoree.dll as an example as it doesnt export any thing // so nothing shows up if you use your own module. // and the only none delayload in mscoree.dll is the Kernel32.dll private static void TestImports(uint hLib, bool mappedAsImage) { unsafe { //fixed (char* pszModule = "mscoree.dll") { //void* hMod = Interop.GetModuleHandleW(pszModule); void *hMod = (void *)hLib; uint size = 0; uint BaseAddress = (uint)hMod; if (hMod != null) { Console.WriteLine("Got handle"); IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size); if (pIID != null) { Console.WriteLine("Got Image Import Descriptor"); while (pIID->OriginalFirstThunk != 0) { try { char * szName = (char *)(BaseAddress + pIID->Name); string name = Marshal.PtrToStringAnsi((IntPtr)szName); Console.WriteLine("pIID->Name = {0} BaseAddress - {1}", name, (uint)BaseAddress); THUNK_DATA *pThunkOrg = (THUNK_DATA *)(BaseAddress + pIID->OriginalFirstThunk); while (pThunkOrg->AddressOfData != 0) { char *szImportName; uint Ord; if ((pThunkOrg->Ordinal & 0x80000000) > 0) { Ord = pThunkOrg->Ordinal & 0xffff; Console.WriteLine("imports ({0}).Ordinal{1} - Address: {2}", name, Ord, pThunkOrg->Function); } else { IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(BaseAddress + pThunkOrg->AddressOfData); if (!Interop.IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME))) { Ord = pIBN->Hint; szImportName = (char *)pIBN->Name; string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName); // yes i know i am a lazy ass Console.WriteLine("imports ({0}).{1}@{2} - Address: {3}", name, sImportName, Ord, pThunkOrg->Function); } else { Console.WriteLine("Bad ReadPtr Detected or EOF on Imports"); break; } } pThunkOrg++; } } catch (AccessViolationException e) { Console.WriteLine("An Access violation occured\n" + "this seems to suggest the end of the imports section\n"); Console.WriteLine(e); } pIID++; } } } } } Console.WriteLine("Press Any Key To Continue......"); Console.ReadKey(); }
private static HarmonyImportLibrary ApplyImportLibrary(byte *basePtr, uint size, IMAGE_IMPORT_DESCRIPTOR *importDescriptor, string moduleName, HarmonyImportLibraryKind importLibraryKind, Func <string, IntPtr> getImportByName, Func <ushort, IntPtr> getImportByOrdinal) { const uint ImageOrdinalFlag32 = 0x80000000U; const ulong ImageOrdinalFlag64 = 0x8000000000000000UL; List <HarmonyImport> importThunks = new List <HarmonyImport>(); UIntPtr thunkRef; UIntPtr funcRef; if (importDescriptor->OriginalFirstThunk != 0) { thunkRef = (UIntPtr)(basePtr + importDescriptor->OriginalFirstThunk); funcRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk); } else { // No hint table. thunkRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk); funcRef = (UIntPtr)(basePtr + importDescriptor->FirstThunk); } bool is64BitMode = Environment.Is64BitProcess; uint thunk; for (; (thunk = *(uint *)thunkRef) != 0; thunkRef += sizeof(UIntPtr), funcRef += sizeof(UIntPtr)) { IntPtr procAddress; if (!is64BitMode && (thunk & ImageOrdinalFlag32) != 0 || is64BitMode && (thunk & ImageOrdinalFlag64) != 0) { procAddress = getImportByOrdinal((ushort)(thunk & 0xFFFF)); if (procAddress == IntPtr.Zero) { throw new LoadFailedException(string.Format("Unable to dependent library \"{0}\" is missing required import ordinal {1}.", moduleName, thunk & 0xFFFF)); } *(IntPtr *)funcRef = procAddress; importThunks.Add(new HarmonyImport((int)(thunk & 0xFFFF), null, procAddress)); } else { IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(basePtr + thunk); string thunkName = StringOperations.NulTerminatedBytesToString((byte *)thunkData + 2, basePtr, size); procAddress = getImportByName(thunkName); if (procAddress == IntPtr.Zero) { throw new LoadFailedException(string.Format("Unable to dependent library \"{0}\" is missing required import \"{1}\".", moduleName, thunkName)); } *(IntPtr *)funcRef = procAddress; importThunks.Add(new HarmonyImport(null, thunkName, procAddress)); } } return(new HarmonyImportLibrary(importLibraryKind, moduleName, importThunks)); }
// using mscoree.dll as an example as it doesnt export any thing // so nothing shows up when use the own module. // and the only none delayload in mscoree.dll is the Kernel32.dll /// <summary> /// return the imported dlls and functions from them /// </summary> /// <param name="filePath"></param> /// <param name="mappedAsImage"></param> /// <returns></returns> private void LoadImports(string filePath, bool mappedAsImage, List <ImportFunctionObject> ImportFunctions, List <String> ImportNames) { var hLib = LoadLibrary(filePath); if (hLib == null) { var errorCode = GetLastError(); } //var hLib = LoadLibraryEx(filePath, 0, // DONT_RESOLVE_DLL_REFERENCES | LOAD_IGNORE_CODE_AUTHZ_LEVEL); unsafe { { void *hMod = (void *)hLib; uint size = 0; uint BaseAddress = (uint)hMod; if (hMod != null) { IMAGE_IMPORT_DESCRIPTOR *pIID = (IMAGE_IMPORT_DESCRIPTOR *)Interop.ImageDirectoryEntryToData((void *)hMod, mappedAsImage, Interop.IMAGE_DIRECTORY_ENTRY_IMPORT, out size); if (pIID != null) { //walk the array until find the end of the array while (pIID->OriginalFirstThunk != 0) { try { //Name contains the RVA to the name of the dll. //Thus convert it to a virtual address first. char * szName = (char *)(BaseAddress + pIID->Name); string name = Marshal.PtrToStringAnsi((IntPtr)szName); if (!name.Contains("api-ms-win")) { ImportNames.Add(name); // value in OriginalFirstThunk is an RVA. // convert it to virtual address. THUNK_DATA *pThunkOrg = (THUNK_DATA *)(BaseAddress + pIID->OriginalFirstThunk); while (pThunkOrg->AddressOfData != 0) { char *szImportName; uint Ord; if ((pThunkOrg->Ordinal & 0x80000000) > 0) { Ord = pThunkOrg->Ordinal & 0xffff; } else { IMAGE_IMPORT_BY_NAME *pIBN = (IMAGE_IMPORT_BY_NAME *)(BaseAddress + pThunkOrg->AddressOfData); if (!Interop.IsBadReadPtr((void *)pIBN, (uint)sizeof(IMAGE_IMPORT_BY_NAME))) { Ord = pIBN->Hint; szImportName = (char *)pIBN->Name; string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName); UInt32 Address = pThunkOrg->Function; ImportFunctions.Add(new ImportFunctionObject(sImportName, Address, name)); } else { break; } } pThunkOrg++; } } //else //{ // smartSuggestionEngine.readErrorCode(name, 7); //} } catch (Exception e) { System.Diagnostics.Debug.WriteLine("An Access violation occured\n" + "this seems to suggest the end of the imports section\n"); System.Diagnostics.Debug.WriteLine(e); } pIID++; } } } } } return; }
private void LoadImports(LOADED_IMAGE loadedImage) { var hMod = (void *)loadedImage.MappedAddress; if (hMod != null) { Console.WriteLine("Got handle"); uint size; var pImportDir = (IMAGE_IMPORT_DESCRIPTOR *) ImageDirectoryEntryToData(hMod, false, IMAGE_DIRECTORY_ENTRY_IMPORT, out size); if (pImportDir != null) { while (pImportDir->OriginalFirstThunk != 0) { try { var szName = (char *)RvaToVa(loadedImage, pImportDir->Name); string name = Marshal.PtrToStringAnsi((IntPtr)szName); Imports.Add(name, new SortedList <string, IntPtr>()); var pThunkOrg = (THUNK_DATA *)RvaToVa(loadedImage, pImportDir->OriginalFirstThunk); while (pThunkOrg->AddressOfData != IntPtr.Zero) { uint ord; if ((pThunkOrg->Ordinal & 0x80000000) > 0) { ord = pThunkOrg->Ordinal & 0xffff; } else { IMAGE_IMPORT_BY_NAME *pImageByName = (IMAGE_IMPORT_BY_NAME *)RvaToVa(loadedImage, pThunkOrg->AddressOfData); if (!IsBadReadPtr(pImageByName, (uint)sizeof(IMAGE_IMPORT_BY_NAME))) { ord = pImageByName->Hint; var szImportName = pImageByName->Name; string sImportName = Marshal.PtrToStringAnsi((IntPtr)szImportName); string logzor = String.Format("imports ({0}).{1}@{2} - Address: {3}", name, sImportName, ord, pThunkOrg->Function); IntPtr ModuleHandle = GetModuleHandle(name); UIntPtr addr = GetProcAddress(ModuleHandle, sImportName); Imports[name].Add(sImportName, new IntPtr(pThunkOrg->Function + 0x400000)); } else { break; } } pThunkOrg++; } } catch (AccessViolationException e) { } pImportDir++; } } } }
private void BuildImportTable() { IMAGE_DATA_DIRECTORY *directory = &_headers->OptionalHeader.ImportTable; if (directory->Size == 0) { throw new NativeDllLoadException("Invalid import table."); } IMAGE_IMPORT_DESCRIPTOR *importDesc = (IMAGE_IMPORT_DESCRIPTOR *)(_codeBase + directory->VirtualAddress); for (; !Win.IsBadReadPtr((importDesc), (UIntPtrT)Marshal.SizeOf(typeof(IMAGE_IMPORT_DESCRIPTOR))) && importDesc->Name > 0; importDesc++) { UIntPtrT *thunkRef; Farproc * funcRef; HCoustomMudule handle = Win.LoadLibrary(_codeBase + importDesc->Name); if (InvalidHandle(handle)) { if (_modules.Any()) { _modules.ForEach(m => Win.FreeLibrary(m)); } throw new NativeDllLoadException("Can't load libary " + Marshal.PtrToStringAnsi(new IntPtr(_codeBase + importDesc->Name))); } _modules.Add(handle); if (importDesc->OriginalFirstThunk > 0) { thunkRef = (UIntPtrT *)(_codeBase + importDesc->OriginalFirstThunk); funcRef = (Farproc *)(_codeBase + importDesc->FirstThunk); } else { // no hint table thunkRef = (UIntPtrT *)(_codeBase + importDesc->FirstThunk); funcRef = (Farproc *)(_codeBase + importDesc->FirstThunk); } for (; *thunkRef > 0; thunkRef++, funcRef++) { string procName; if (Win.IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { procName = Marshal.PtrToStringAnsi(new IntPtr()); *funcRef = (Farproc)Win.GetProcAddress(handle, (byte *)Win.IMAGE_ORDINAL(*thunkRef)); } else { IMAGE_IMPORT_BY_NAME *thunkData = (IMAGE_IMPORT_BY_NAME *)(_codeBase + (*thunkRef)); *funcRef = (Farproc)Win.GetProcAddress(handle, thunkData->Name); } if (*funcRef == 0) { throw new NativeDllLoadException("Can't get adress for imported function."); } } } }