Pdb dumpickery
This commit is contained in:
parent
0187b3943c
commit
af2c8c1384
BIN
game/Rayman3.exe
BIN
game/Rayman3.exe
Binary file not shown.
|
@ -13,7 +13,6 @@ function(setup_target TARGET DBG_MODE)
|
|||
)
|
||||
|
||||
if(WIN32 AND R3_32BIT)
|
||||
target_link_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../third_party/bink)
|
||||
target_link_libraries(${TARGET} PRIVATE
|
||||
binkw32
|
||||
d3d8
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,6 +19,8 @@ public class RemanConfig {
|
|||
public final String rootDir;
|
||||
// The output directory for the recompiled game
|
||||
public final String outputDir;
|
||||
// The output directory for the original game
|
||||
public final String originalDir;
|
||||
public final String typeBlacklistPath;
|
||||
public final String categoryPathBlacklistPath;
|
||||
public final String functionBlacklistPath;
|
||||
|
@ -67,6 +69,8 @@ public class RemanConfig {
|
|||
rootDir = new File(script.getSourceFile().getAbsolutePath()).getParentFile().getParentFile().getParentFile().toString();
|
||||
outputDir = new File(rootDir, RECOMPILE_PREFIX).toString();
|
||||
script.println("Output path: " + outputDir);
|
||||
|
||||
originalDir = new File(rootDir, "game").toString();
|
||||
|
||||
typeBlacklistPath = new File(outputDir, "type_blacklist.txt").toString();
|
||||
categoryPathBlacklistPath = new File(outputDir, "type_path_blacklist.txt").toString();
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
add_subdirectory(spdlog)
|
||||
|
||||
if(WIN32)
|
||||
add_library(binkw32 SHARED IMPORTED)
|
||||
set_target_properties(binkw32 PROPERTIES
|
||||
IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/bink/binkw32.lib
|
||||
add_library(binkw32_imp SHARED IMPORTED)
|
||||
set_target_properties(binkw32_imp PROPERTIES
|
||||
IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/bink/binkw32.lib
|
||||
)
|
||||
|
||||
# Copy to output dir
|
||||
set(BINK_DST ${CMAKE_CURRENT_BINARY_DIR}/bin/binkw32.dll)
|
||||
set(BINK_DST ${CMAKE_BINARY_DIR}/bin/binkw32.dll)
|
||||
add_custom_command(
|
||||
OUTPUT ${BINK_DST}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/third_party/bink/binkw32.dll ${BINK_DST}
|
||||
)
|
||||
add_custom_target(copy_binkw32 ALL DEPENDS ${BINK_DST})
|
||||
add_dependencies(binkw32 copy_binkw32)
|
||||
add_dependencies(binkw32_imp copy_binkw32)
|
||||
|
||||
add_library(binkw32 INTERFACE)
|
||||
target_link_libraries(binkw32 INTERFACE binkw32_imp)
|
||||
|
||||
set(SDK_LIB ${CMAKE_CURRENT_LIST_DIR}/mssdk/lib)
|
||||
|
||||
|
|
|
@ -15,11 +15,44 @@ typedef struct {
|
|||
// Followed by null-terminated PDB path
|
||||
} RSDS_DEBUG_FORMAT;
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER6433 {
|
||||
WORD Magic;
|
||||
BYTE MajorLinkerVersion;
|
||||
BYTE MinorLinkerVersion;
|
||||
DWORD SizeOfCode;
|
||||
DWORD SizeOfInitializedData;
|
||||
DWORD SizeOfUninitializedData;
|
||||
DWORD AddressOfEntryPoint;
|
||||
DWORD BaseOfCode;
|
||||
ULONGLONG ImageBase;
|
||||
DWORD SectionAlignment;
|
||||
DWORD FileAlignment;
|
||||
WORD MajorOperatingSystemVersion;
|
||||
WORD MinorOperatingSystemVersion;
|
||||
WORD MajorImageVersion;
|
||||
WORD MinorImageVersion;
|
||||
WORD MajorSubsystemVersion;
|
||||
WORD MinorSubsystemVersion;
|
||||
DWORD Win32VersionValue;
|
||||
DWORD SizeOfImage;
|
||||
DWORD SizeOfHeaders;
|
||||
DWORD CheckSum;
|
||||
WORD Subsystem;
|
||||
WORD DllCharacteristics;
|
||||
ULONGLONG SizeOfStackReserve;
|
||||
ULONGLONG SizeOfStackCommit;
|
||||
ULONGLONG SizeOfHeapReserve;
|
||||
ULONGLONG SizeOfHeapCommit;
|
||||
DWORD LoaderFlags;
|
||||
DWORD NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
};
|
||||
|
||||
class PEModifier {
|
||||
private:
|
||||
std::vector<BYTE> fileData;
|
||||
IMAGE_DOS_HEADER *dosHeader;
|
||||
IMAGE_NT_HEADERS *ntHeaders;
|
||||
IMAGE_NT_HEADERS32 *ntHeaders;
|
||||
IMAGE_SECTION_HEADER *sectionHeaders;
|
||||
|
||||
public:
|
||||
|
@ -41,10 +74,16 @@ public:
|
|||
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return false;
|
||||
|
||||
ntHeaders = (IMAGE_NT_HEADERS *)(fileData.data() + dosHeader->e_lfanew);
|
||||
ntHeaders = (IMAGE_NT_HEADERS32 *)(fileData.data() + dosHeader->e_lfanew);
|
||||
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return false;
|
||||
|
||||
// Verify it's actually a 32-bit PE
|
||||
if (ntHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
printf("Error: This is not a 32-bit PE file!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
sectionHeaders =
|
||||
(IMAGE_SECTION_HEADER *)((BYTE *)&ntHeaders->OptionalHeader +
|
||||
ntHeaders->FileHeader.SizeOfOptionalHeader);
|
||||
|
@ -62,7 +101,7 @@ public:
|
|||
}
|
||||
|
||||
bool addDebugDirectory(const std::string &pdbPath) {
|
||||
IMAGE_SECTION_HEADER *rsrcSection = findSection(".rsrc");
|
||||
IMAGE_SECTION_HEADER *rsrcSection = findSection(".rdata");
|
||||
if (!rsrcSection) {
|
||||
printf("Error: .rsrc section not found!\n");
|
||||
return false;
|
||||
|
@ -71,28 +110,21 @@ public:
|
|||
// Calculate debug data size
|
||||
size_t pdb_path_len = pdbPath.size() + 1;
|
||||
size_t debug_data_size = sizeof(RSDS_DEBUG_FORMAT) + pdb_path_len;
|
||||
size_t total_needed = sizeof(IMAGE_DEBUG_DIRECTORY) + debug_data_size + 32; // + padding
|
||||
|
||||
// Find end of rsrc section (aligned)
|
||||
DWORD sectionAlignment = ntHeaders->OptionalHeader.SectionAlignment;
|
||||
DWORD fileAlignment = ntHeaders->OptionalHeader.FileAlignment;
|
||||
|
||||
// Calculate where to place debug data in the rsrc section
|
||||
DWORD currentSectionEnd =
|
||||
rsrcSection->PointerToRawData + rsrcSection->SizeOfRawData;
|
||||
DWORD availableSpace =
|
||||
rsrcSection->Misc.VirtualSize - rsrcSection->SizeOfRawData;
|
||||
|
||||
if (debug_data_size > availableSpace) {
|
||||
printf("Error: Not enough space in .rsrc section! Need %zu bytes, have "
|
||||
"%lu\n",
|
||||
debug_data_size, availableSpace);
|
||||
// Check if we have enough space at the end of rsrc section
|
||||
if (total_needed > rsrcSection->SizeOfRawData) {
|
||||
printf("Error: Not enough space in .rsrc section! Need %zu bytes, section is %lu bytes\n",
|
||||
total_needed, rsrcSection->SizeOfRawData);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate RVA for debug data
|
||||
DWORD debugDataRVA =
|
||||
rsrcSection->VirtualAddress + rsrcSection->SizeOfRawData;
|
||||
DWORD debugDataFileOffset = currentSectionEnd;
|
||||
// Calculate where to place debug directory and data (at the very end of rsrc section)
|
||||
DWORD debugDirFileOffset = rsrcSection->PointerToRawData + rsrcSection->SizeOfRawData - total_needed;
|
||||
DWORD debugDataFileOffset = debugDirFileOffset + sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
DWORD debugDirRVA = rsrcSection->VirtualAddress + rsrcSection->SizeOfRawData - total_needed;
|
||||
DWORD debugDataRVA = debugDirRVA + sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
// Prepare debug data
|
||||
std::vector<BYTE> debugData(debug_data_size);
|
||||
|
@ -113,19 +145,7 @@ public:
|
|||
memcpy(debugData.data() + sizeof(RSDS_DEBUG_FORMAT), pdbPath.c_str(),
|
||||
pdb_path_len);
|
||||
|
||||
// Extend file data if needed
|
||||
if (debugDataFileOffset + debug_data_size > fileData.size()) {
|
||||
fileData.resize(debugDataFileOffset + debug_data_size);
|
||||
}
|
||||
|
||||
// Write debug data to rsrc section
|
||||
memcpy(fileData.data() + debugDataFileOffset, debugData.data(),
|
||||
debug_data_size);
|
||||
|
||||
// Update rsrc section size
|
||||
rsrcSection->SizeOfRawData += debug_data_size;
|
||||
|
||||
// Create/update debug directory entry
|
||||
// Create debug directory entry
|
||||
IMAGE_DEBUG_DIRECTORY debugDir = {0};
|
||||
debugDir.Characteristics = 0x00000000;
|
||||
debugDir.TimeDateStamp = ntHeaders->FileHeader.TimeDateStamp;
|
||||
|
@ -136,32 +156,26 @@ public:
|
|||
debugDir.AddressOfRawData = debugDataRVA;
|
||||
debugDir.PointerToRawData = debugDataFileOffset;
|
||||
|
||||
// Update debug directory in optional header
|
||||
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]
|
||||
.VirtualAddress = debugDataRVA;
|
||||
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size =
|
||||
sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
// Actually, we need to place the debug directory entry somewhere too
|
||||
// Let's put it right before the debug data
|
||||
DWORD debugDirRVA = debugDataRVA - sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
DWORD debugDirFileOffset =
|
||||
debugDataFileOffset - sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
// Adjust our calculations
|
||||
rsrcSection->SizeOfRawData += sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
// Write debug directory entry
|
||||
// Overwrite the end of rsrc section with debug directory entry
|
||||
memcpy(fileData.data() + debugDirFileOffset, &debugDir,
|
||||
sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
|
||||
// Overwrite with debug data
|
||||
memcpy(fileData.data() + debugDataFileOffset, debugData.data(),
|
||||
debug_data_size);
|
||||
|
||||
// Update optional header to point to debug directory
|
||||
printf("IMAGE_DIRECTORY_ENTRY_DEBUG constant value: %d\n", IMAGE_DIRECTORY_ENTRY_DEBUG);
|
||||
printf("Setting debug directory at index %d\n", IMAGE_DIRECTORY_ENTRY_DEBUG);
|
||||
printf("Debug directory RVA: 0x%08X\n", debugDirRVA);
|
||||
printf("Debug directory size: %d\n", sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
|
||||
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]
|
||||
.VirtualAddress = debugDirRVA;
|
||||
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size =
|
||||
sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
printf("Debug directory added at RVA: 0x%08X\n", debugDirRVA);
|
||||
printf("Debug directory added at RVA: 0x%08X (overwriting rsrc end)\n", debugDirRVA);
|
||||
printf("Debug data added at RVA: 0x%08X\n", debugDataRVA);
|
||||
|
||||
return true;
|
||||
|
@ -206,7 +220,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Save modified PE
|
||||
std::string outputPath = std::string(exePath) + ".debug";
|
||||
std::string outputPath = std::string(exePath);
|
||||
if (!pe.savePE(outputPath.c_str())) {
|
||||
printf("Error: Failed to save modified PE file\n");
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue