Index: bin/tools/mergebin.exe ================================================================== --- bin/tools/mergebin.exe +++ bin/tools/mergebin.exe cannot compute difference between binary files Index: tools/mergebin/mergebin.cpp ================================================================== --- tools/mergebin/mergebin.cpp +++ tools/mergebin/mergebin.cpp @@ -12,10 +12,15 @@ void DumpCLRInfo(LPCTSTR pszFile); void MergeModules(LPCTSTR pszAssembly, LPCTSTR pszNative, LPCTSTR pszSection); void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection); +typedef struct EXTRA_STUFF +{ + DWORD dwNativeEntryPoint; +} EXTRA_STUFF, *LPEXTRA_STUFF; + int _tmain(int argc, _TCHAR* argv[]) { if (argc == 1) { _tprintf(_T( @@ -173,11 +178,11 @@ { _tprintf(_T("Unable to retrieve .NET assembly information for file %s\n"), pszFile); return; } - _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb, pszFile); + _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb + sizeof(EXTRA_STUFF), pszFile); } void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection) { CPEFile peFile; @@ -202,23 +207,32 @@ #pragma data_seg(\"%s\")\n\ #pragma comment(linker, \"/SECTION:%s,ER\")\n\ char __ph[%d] = {0}; // The number of bytes to reserve\n\ #pragma data_seg()\n\n\ typedef BOOL (WINAPI *DLLMAIN)(HANDLE, DWORD, LPVOID);\n\ -extern BOOL WINAPI _DllMainCRTStartup(HANDLE, DWORD, LPVOID);\n\n\ +typedef struct EXTRA_STUFF\n\ +{\n\ + DWORD dwNativeEntryPoint;\n\ +} EXTRA_STUFF, *LPEXTRA_STUFF;\n\n\ __declspec(dllexport) BOOL WINAPI _CorDllMainStub(HANDLE hModule, DWORD dwReason, LPVOID pvReserved)\n\ {\n\ HANDLE hMod;\n\ - DLLMAIN proc;\n\n\ + DLLMAIN proc;\n\ + LPEXTRA_STUFF pExtra;\n\n\ hMod = GetModuleHandle(_T(\"mscoree\"));\n\ if (hMod)\n\ proc = (DLLMAIN)GetProcAddress(hMod, _T(\"_CorDllMain\"));\n\ else\n\ - proc = _DllMainCRTStartup;\n\n\ + {\n\ + MEMORY_BASIC_INFORMATION mbi;\n\n\ + VirtualQuery(_CorDllMainStub, &mbi, sizeof(mbi));\n\ + pExtra = (LPEXTRA_STUFF)__ph;\n\ + proc = (DLLMAIN)(pExtra->dwNativeEntryPoint + (DWORD)mbi.AllocationBase);\n\ + }\n\ return proc(hModule, dwReason, pvReserved);\n\ }\n\ -"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb); +"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb + sizeof(EXTRA_STUFF)); } /* When merged, the native DLL's entrypoint must go to _CorDllMain in MSCOREE.DLL. ** In order to do this, we need to change the DLL's entrypoint to "something" that will ** call CorDllMain. Since its too much hassle to add imports to the DLL and make drastic @@ -303,10 +317,11 @@ PIMAGE_NT_HEADERS64 pNT64; int diffRVA; CTableData *p; DWORD *pdwRVA; DWORD dwRows; + LPEXTRA_STUFF pExtra; // Open the .NET assembly hr = peFile.Open(pszAssembly); if (FAILED(hr)) return; @@ -330,13 +345,13 @@ _tprintf(_T("Unable to find section %s in file\n"), pszSection); return; } // If the section isn't large enough, tell the user how large it needs to be - if (pSection->Misc.VirtualSize < dwSize) + if (pSection->Misc.VirtualSize < (dwSize + sizeof(EXTRA_STUFF))) { - _tprintf(_T("Not enough room in section for data. Need %d bytes\n"), dwSize); + _tprintf(_T("Not enough room in section for data. Need %d bytes\n"), dwSize + sizeof(EXTRA_STUFF)); return; } /* ** Find a new entrypoint to use for the DLL. The old entrypoint is written into the .NET header @@ -349,10 +364,13 @@ } // Change this section's flags pSection->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ; dwDestRVA = pSection->VirtualAddress; + + pExtra = (LPEXTRA_STUFF)peDest.GetPtrFromRVA(dwDestRVA); + dwDestRVA += sizeof(EXTRA_STUFF); // If the native DLL has been merged with an assembly beforehand, we need to strip the .NET stuff and restore the entrypoint pCor = peDest; if (pCor) { @@ -378,16 +396,18 @@ pNT64 = peDest; // Fixup the NT header on the native DLL to include the new .NET header if (pNT) { - pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress; + pExtra->dwNativeEntryPoint = pNT->OptionalHeader.AddressOfEntryPoint; + pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = dwDestRVA; pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize; } else { - pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress; + pExtra->dwNativeEntryPoint = pNT64->OptionalHeader.AddressOfEntryPoint; + pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = dwDestRVA; pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize; } dwDestRVA += dwSize; if (dwDestRVA % 4) dwDestRVA += (4 - (dwDestRVA % 4)); Index: tools/mergebin/mergebin.vcproj ================================================================== --- tools/mergebin/mergebin.vcproj +++ tools/mergebin/mergebin.vcproj @@ -136,11 +136,11 @@