From 11a43724cbf155f63a25b1d3818853c1bbbf6690 Mon Sep 17 00:00:00 2001 From: David Major Date: Wed, 22 Oct 2014 09:01:16 +1300 Subject: [PATCH] Bug 1082670: Copy breakpadinjector's image header into the remote process. r=bsmedberg --- toolkit/crashreporter/LoadLibraryRemote.cpp | 76 +++++++++++++-------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/toolkit/crashreporter/LoadLibraryRemote.cpp b/toolkit/crashreporter/LoadLibraryRemote.cpp index 02212529be4..f22a6220fae 100644 --- a/toolkit/crashreporter/LoadLibraryRemote.cpp +++ b/toolkit/crashreporter/LoadLibraryRemote.cpp @@ -95,6 +95,35 @@ CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMO } } +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] = { { @@ -117,11 +146,20 @@ FinalizeSections(PMEMORYMODULE module, HANDLE hRemoteProcess) #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; iheaders->FileHeader.NumberOfSections; i++, section++) { - DWORD protect, oldProtect, size; + for (i=0; iCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0; int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; @@ -132,39 +170,17 @@ FinalizeSections(PMEMORYMODULE module, HANDLE hRemoteProcess) 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; }