--- a/toolkit/crashreporter/LoadLibraryRemote.cpp
+++ b/toolkit/crashreporter/LoadLibraryRemote.cpp
@@ -90,16 +90,45 @@ CopySections(const unsigned char *data,
memset(dest, 0, section->Misc.VirtualSize);
if (section->SizeOfRawData) {
memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData);
}
// section->Misc.PhysicalAddress = (POINTER_TYPE) module->remoteCodeBase + section->VirtualAddress;
}
}
+static bool
+CopyRegion(HANDLE hRemoteProcess, void* remoteAddress, void* localAddress, DWORD size, DWORD protect)
+{
+ if (size > 0) {
+ // Copy the data from local->remote and set the memory protection
+ if (!VirtualAllocEx(hRemoteProcess, remoteAddress, size, MEM_COMMIT, PAGE_READWRITE))
+ return false;
+
+ if (!WriteProcessMemory(hRemoteProcess,
+ remoteAddress,
+ localAddress,
+ size,
+ nullptr)) {
+#ifdef DEBUG_OUTPUT
+ OutputLastError("Error writing remote memory.\n");
+#endif
+ return false;
+ }
+
+ DWORD oldProtect;
+ if (VirtualProtectEx(hRemoteProcess, remoteAddress, size, protect, &oldProtect) == 0) {
+#ifdef DEBUG_OUTPUT
+ OutputLastError("Error protecting memory page");
+#endif
+ return false;
+ }
+ }
+ return true;
+}
// Protection flags for memory pages (Executable, Readable, Writeable)
static int ProtectionFlags[2][2][2] = {
{
// not executable
{PAGE_NOACCESS, PAGE_WRITECOPY},
{PAGE_READONLY, PAGE_READWRITE},
}, {
// executable
@@ -112,64 +141,51 @@ static bool
FinalizeSections(PMEMORYMODULE module, HANDLE hRemoteProcess)
{
#ifdef DEBUG_OUTPUT
fprintf(stderr, "Finalizing sections: local base %p, remote base %p\n",
module->localCodeBase, module->remoteCodeBase);
#endif
int i;
+ int numSections = module->headers->FileHeader.NumberOfSections;
+
+ if (numSections < 1)
+ return false;
+
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
-
+
+ // Copy any data before the first section (i.e. the image header)
+ if (!CopyRegion(hRemoteProcess, module->remoteCodeBase, module->localCodeBase, section->VirtualAddress, PAGE_READONLY))
+ return false;
+
// loop through all sections and change access flags
- for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
- DWORD protect, oldProtect, size;
+ for (i=0; i<numSections; i++, section++) {
+ DWORD protect, size;
int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
// determine protection flags based on characteristics
protect = ProtectionFlags[executable][readable][writeable];
if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) {
protect |= PAGE_NOCACHE;
}
+ void* remoteAddress = module->remoteCodeBase + section->VirtualAddress;
+ void* localAddress = module->localCodeBase + section->VirtualAddress;
+
// determine size of region
size = section->Misc.VirtualSize;
- if (size > 0) {
- void* remoteAddress = module->remoteCodeBase + section->VirtualAddress;
- void* localAddress = module->localCodeBase + section->VirtualAddress;
-
#ifdef DEBUG_OUTPUT
fprintf(stderr, "Copying section %s to %p, size %x, executable %i readable %i writeable %i\n",
section->Name, remoteAddress, size, executable, readable, writeable);
#endif
-
- // Copy the data from local->remote and set the memory protection
- if (!VirtualAllocEx(hRemoteProcess, remoteAddress, size, MEM_COMMIT, PAGE_READWRITE))
- return false;
-
- if (!WriteProcessMemory(hRemoteProcess,
- remoteAddress,
- localAddress,
- size,
- nullptr)) {
-#ifdef DEBUG_OUTPUT
- OutputLastError("Error writing remote memory.\n");
-#endif
- return false;
- }
-
- if (VirtualProtectEx(hRemoteProcess, remoteAddress, size, protect, &oldProtect) == 0) {
-#ifdef DEBUG_OUTPUT
- OutputLastError("Error protecting memory page");
-#endif
- return false;
- }
- }
+ if (!CopyRegion(hRemoteProcess, remoteAddress, localAddress, size, protect))
+ return false;
}
return true;
}
static void
PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta)
{
DWORD i;