internal static void MemoryFreeLibrary(MEMORYMODULE mod) { MEMORYMODULE module = mod; if (module == null) return; if (module.initialized) { // notify library about detaching from process DllEntryProc DllEntry = (DllEntryProc)Marshal.GetDelegateForFunctionPointer((IntPtr)(module.codeBase + (WIN64 ? ((IMAGE_NT_HEADERS64*)module.headers)->OptionalHeader.AddressOfEntryPoint : ((IMAGE_NT_HEADERS32*)module.headers)->OptionalHeader.AddressOfEntryPoint)), typeof(DllEntryProc)); DllEntry(module.codeBase, DLL_PROCESS_DETACH, null); } if (module.modules != null) { // free previously opened libraries int i; for (i = 0; i < module.numModules; i++) if ((void*)((IntPtr*)module.modules)[i] != null) module.freeLibrary((void*)((IntPtr*)module.modules)[i], module.userdata); free(module.modules); } if (module.codeBase != null) { // release memory of library module.free(module.codeBase, null, MEM_RELEASE, module.userdata); } if (WIN64) FreePointerList(module.blockedMemory, module.free, module.userdata); }
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; }