static void FinalizeSections(MEMORYMODULE *module) { IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(module->headers); for (int i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++) { uint protect, oldProtect, size; uint executable = Convert.ToUInt32((section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0); uint readable = Convert.ToUInt32((section->Characteristics & IMAGE_SCN_MEM_READ) != 0); uint writeable = Convert.ToUInt32((section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0); if ((section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0) { // section is not needed any more and can safely be freed // course bug not free it at now. IntPtr sectionPhysicalAddress = new IntPtr(section->Name); #if AMD64 IntPtr pToFree = new IntPtr(section->VirtualSize + module->codeBase.ToInt64()); #else IntPtr pToFree = new IntPtr(section->VirtualSize + module->codeBase.ToInt32()); #endif VirtualFree(pToFree, section->SizeOfRawData, MEM_DECOMMIT); continue; } protect = ProtectionFlags[executable, readable, writeable]; if ((section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) != 0) { protect |= PAGE_NOCACHE; } // determine size of region size = section->SizeOfRawData; if (size == 0) { if ((section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) != 0) { size = module->headers->OptionalHeader.SizeOfInitializedData; } else if ((section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0) { size = module->headers->OptionalHeader.SizeOfUninitializedData; } } if (size > 0) { // change memory access flags #if AMD64 IntPtr pToFree = new IntPtr(section->VirtualSize + module->codeBase.ToInt64()); #else IntPtr pToFree = new IntPtr(section->VirtualSize + module->codeBase.ToInt32()); #endif VirtualProtect(pToFree, section->SizeOfRawData, protect, &oldProtect); } } }
static void CopySections(byte *data, IMAGE_NT_HEADERS *old_headers, MEMORYMODULE *module) { uint i, size; IntPtr codeBase1 = module->codeBase; #if AMD64 long codeBaseAddr = (long)codeBase1.ToInt64(); #else uint codeBaseAddr = (uint)codeBase1.ToInt64(); #endif IntPtr dest; IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(module->headers); for (i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++) { if (section->SizeOfRawData == 0) { // section doesn't contain data in the dll itself, but may define // uninitialized data size = old_headers->OptionalHeader.SectionAlignment; if (size > 0) { dest = VirtualAlloc(new IntPtr(codeBaseAddr + section->VirtualAddress), size, AllocationType.COMMIT, MemoryProtection.READWRITE);// MEM_COMMIT, PAGE_READWRITE); //section->PhysicalAddress = dest; memset(dest, 0, new UIntPtr(size)); section->VirtualSize = (uint)(dest.ToInt64() - codeBase1.ToInt64()); } // section is empty continue; } // commit memory block and copy data from dll dest = VirtualAlloc(new IntPtr(codeBaseAddr + section->VirtualAddress), section->SizeOfRawData, AllocationType.COMMIT, MemoryProtection.READWRITE); memcpy((byte *)dest.ToPointer(), (byte *)(data + section->PointerToRawData), new UIntPtr(section->SizeOfRawData)); section->VirtualSize = (uint)(dest.ToInt64() - codeBase1.ToInt64()); } }
static void PerformBaseRelocation(MEMORYMODULE *module, #if AMD64 Int64 delta