From caf602b9286e93ba0538ed72f1cb49526d5bbfe4 Mon Sep 17 00:00:00 2001 From: Jason White Date: Mon, 14 Aug 2017 15:46:25 -0700 Subject: [PATCH] Add `--force` option to ignore PDB mismatch error --- src/ducible/main.cpp | 13 ++++++++++++- src/ducible/patch_image.cpp | 27 ++++++++++++++------------- src/ducible/patch_image.h | 16 +++++++++++++--- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/ducible/main.cpp b/src/ducible/main.cpp index d0c64d7..3e3ba25 100644 --- a/src/ducible/main.cpp +++ b/src/ducible/main.cpp @@ -96,6 +96,8 @@ struct OptionNames { const char* dryrunLong = "--dryrun"; const char* dryrunShort = "-n"; const char* dashDash = "--"; + const char* forceLong = "--force"; + const char* forceShort = "-f"; }; template<> @@ -106,6 +108,8 @@ struct OptionNames { const wchar_t* dryrunLong = L"--dryrun"; const wchar_t* dryrunShort = L"-n"; const wchar_t* dashDash = L"--"; + const wchar_t* forceLong = L"--force"; + const wchar_t* forceShort = L"-f"; }; /** @@ -123,6 +127,7 @@ class CommandOptions const CharT* image; const CharT* pdb; bool dryrun; + bool force; CommandOptions() : image(NULL), pdb(NULL), dryrun(false) {} @@ -171,6 +176,9 @@ class CommandOptions else if (arg == opt.dryrunLong || arg == opt.dryrunShort) { dryrun = true; } + else if (arg == opt.forceLong || arg == opt.forceShort) { + force = true; + } else if (arg.length() > 0 && arg.front() == '-') { throw UnknownOption(argv[i]); } @@ -221,6 +229,9 @@ Optional arguments: --help, -h Prints this help. --dryrun, -n No files are modified, only what would have been patched are printed. + --force, -f Proceed even if the PDB signatures don't match. Useful if you + already know an image is compatible with a PDB even though the + signatures don't match. )"; template @@ -254,7 +265,7 @@ int ducible(int argc, CharT** argv) } try { - patchImage(opts.image, opts.pdb, opts.dryrun); + patchImage(opts.image, opts.pdb, opts.dryrun, opts.force); } catch (const InvalidImage& error) { std::cerr << "Error: Invalid image (" << error.why() << ")\n"; diff --git a/src/ducible/patch_image.cpp b/src/ducible/patch_image.cpp index bde754b..6324f83 100644 --- a/src/ducible/patch_image.cpp +++ b/src/ducible/patch_image.cpp @@ -359,7 +359,7 @@ void patchNamesStream(MsfMemoryStream* stream) { * Patches the PDB header stream. */ void patchHeaderStream(MsfFile& msf, MsfMemoryStream* stream, const CV_INFO_PDB70* pdbInfo, - uint32_t timestamp, const uint8_t signature[16]) { + uint32_t timestamp, const uint8_t signature[16], bool force) { uint8_t* data = stream->data(); const uint8_t* dataEnd = stream->data() + stream->length(); @@ -374,8 +374,9 @@ void patchHeaderStream(MsfFile& msf, MsfMemoryStream* stream, const CV_INFO_PDB7 if (header->version < PdbVersion::vc70) throw InvalidPdb("unsupported PDB implementation version"); - // Check that this PDB matches what the PE file expects - if (!pdbInfo || !matchingSignatures(*pdbInfo, *header)) + // Check that this PDB matches what the PE file expects. Don't do the check + // if `force` was specified. + if (!force && (!pdbInfo || !matchingSignatures(*pdbInfo, *header))) throw InvalidPdb("PE and PDB signatures do not match"); // Patch the PDB header stream @@ -726,7 +727,7 @@ void patchPublicSymbolStream(MsfMemoryStream* stream) { * Rewrites a PDB, eliminating non-determinism. */ void patchPDB(MsfFile& msf, const CV_INFO_PDB70* pdbInfo, - uint32_t timestamp, const uint8_t signature[16]) { + uint32_t timestamp, const uint8_t signature[16], bool force) { msf.replaceStream((size_t)PdbStreamType::streamTable, nullptr); @@ -738,7 +739,7 @@ void patchPDB(MsfFile& msf, const CV_INFO_PDB70* pdbInfo, auto pdbHeaderStream = std::shared_ptr( new MsfMemoryStream(origPdbHeaderStream.get())); - patchHeaderStream(msf, pdbHeaderStream.get(), pdbInfo, timestamp, signature); + patchHeaderStream(msf, pdbHeaderStream.get(), pdbInfo, timestamp, signature, force); msf.replaceStream((size_t)PdbStreamType::header, pdbHeaderStream); @@ -784,7 +785,7 @@ void patchPDB(MsfFile& msf, const CV_INFO_PDB70* pdbInfo, */ template void patchPDB(const CharT* pdbPath, const CV_INFO_PDB70* pdbInfo, - uint32_t timestamp, const uint8_t signature[16], bool dryrun) { + uint32_t timestamp, const uint8_t signature[16], bool dryrun, bool force) { auto tmpPdbPath = getTempPdbPath(pdbPath); @@ -794,7 +795,7 @@ void patchPDB(const CharT* pdbPath, const CV_INFO_PDB70* pdbInfo, MsfFile msf(pdb); - patchPDB(msf, pdbInfo, timestamp, signature); + patchPDB(msf, pdbInfo, timestamp, signature, force); // Write out the rewritten PDB to disk. msf.write(tmpPdb); @@ -810,7 +811,7 @@ void patchPDB(const CharT* pdbPath, const CV_INFO_PDB70* pdbInfo, } template -void patchImageImpl(const CharT* imagePath, const CharT* pdbPath, bool dryrun) { +void patchImageImpl(const CharT* imagePath, const CharT* pdbPath, bool dryrun, bool force) { MemMap image(imagePath); uint8_t* buf = (uint8_t*)image.buf(); @@ -855,7 +856,7 @@ void patchImageImpl(const CharT* imagePath, const CharT* pdbPath, bool dryrun) { // Patch the PDB file. if (pdbPath) { - patchPDB(pdbPath, pdbInfo, pe.timestamp, pe.pdbSignature, dryrun); + patchPDB(pdbPath, pdbInfo, pe.timestamp, pe.pdbSignature, dryrun, force); } // Patch the ilk file with the new PDB signature. If we don't do this, @@ -871,14 +872,14 @@ void patchImageImpl(const CharT* imagePath, const CharT* pdbPath, bool dryrun) { #if defined(_WIN32) && defined(UNICODE) -void patchImage(const wchar_t* imagePath, const wchar_t* pdbPath, bool dryrun) { - patchImageImpl(imagePath, pdbPath, dryrun); +void patchImage(const wchar_t* imagePath, const wchar_t* pdbPath, bool dryrun, bool force) { + patchImageImpl(imagePath, pdbPath, dryrun, force); } #else -void patchImage(const char* imagePath, const char* pdbPath, bool dryrun) { - patchImageImpl(imagePath, pdbPath, dryrun); +void patchImage(const char* imagePath, const char* pdbPath, bool dryrun, bool force) { + patchImageImpl(imagePath, pdbPath, dryrun, force); } #endif diff --git a/src/ducible/patch_image.h b/src/ducible/patch_image.h index 33b6b69..97e92bc 100644 --- a/src/ducible/patch_image.h +++ b/src/ducible/patch_image.h @@ -27,10 +27,20 @@ */ #if defined(_WIN32) && defined(UNICODE) -void patchImage(const wchar_t* imagePath, const wchar_t* pdbPath, bool dryrun = true); +void patchImage( + const wchar_t* imagePath, + const wchar_t* pdbPath, + bool dryrun = true, + bool force = false + ); #else -void patchImage(const char* imagePath, const char* pdbPath, bool dryrun = true); +void patchImage( + const char* imagePath, + const char* pdbPath, + bool dryrun = true, + bool force = false + ); -#endif \ No newline at end of file +#endif