Solution0.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "def.hpp"
  2. // The following APIs are in version.lib
  3. // GetFileVersionInfoSize
  4. // GetFileVersionInfo
  5. // VerQueryValue
  6. // #pragma comment(lib, "version.lib")
  7. namespace Patcher {
  8. const char Solution0::Keyword[461] =
  9. "-----BEGIN PUBLIC KEY-----\r\n"
  10. "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I\r\n"
  11. "qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv\r\n"
  12. "a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF\r\n"
  13. "R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2\r\n"
  14. "WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt\r\n"
  15. "YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ\r\n"
  16. "awIDAQAB\r\n"
  17. "-----END PUBLIC KEY-----\r\n";
  18. bool Solution0::FindPatchOffset() noexcept {
  19. bool bFound = false;
  20. PIMAGE_SECTION_HEADER pResourceSection =
  21. Helper::ImageSectionHeader(pTargetFile->GetView<uint8_t>(), ".rsrc");
  22. if (pResourceSection == nullptr)
  23. return false;
  24. uint8_t* pResourceSectionData =
  25. pTargetFile->GetView<uint8_t>() + pResourceSection->PointerToRawData;
  26. for (DWORD i = 0; i < pResourceSection->SizeOfRawData; ++i) {
  27. if (memcmp(pResourceSectionData + i, Keyword, KeywordLength) == 0) {
  28. PatchOffset = pResourceSection->PointerToRawData + i;
  29. bFound = true;
  30. break;
  31. }
  32. }
  33. if (bFound)
  34. _tprintf_s(TEXT("MESSAGE: [Solution0] Keyword has been found: offset = +0x%08lx.\n"), PatchOffset);
  35. return bFound;
  36. }
  37. bool Solution0::MakePatch(RSACipher* cipher) const {
  38. uint8_t* lpTargetFileView = pTargetFile->GetView<uint8_t>();
  39. std::string RSAPublicKeyPEM;
  40. RSAPublicKeyPEM =
  41. cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
  42. if (RSAPublicKeyPEM.empty()) {
  43. REPORT_ERROR("ERROR: cipher->ExportKeyString failed.");
  44. return false;
  45. }
  46. // lambda function, replace '\n' to '\r\n'
  47. [](std::string& str, const std::string& OldSub, const std::string& NewSub) {
  48. std::string::size_type pos = 0;
  49. std::string::size_type srclen = OldSub.size();
  50. std::string::size_type dstlen = NewSub.size();
  51. while ((pos = str.find(OldSub, pos)) != std::string::npos) {
  52. str.replace(pos, srclen, NewSub);
  53. pos += dstlen;
  54. }
  55. } (RSAPublicKeyPEM, "\n", "\r\n");
  56. if (RSAPublicKeyPEM.length() != KeywordLength) {
  57. REPORT_ERROR("ERROR: Public key length does not match.");
  58. return false;
  59. }
  60. PRINT_MESSAGE("//");
  61. PRINT_MESSAGE("// Begin Solution0");
  62. PRINT_MESSAGE("//");
  63. _tprintf_s(TEXT("@+0x%08X\nPrevious:\n"), PatchOffset);
  64. Helper::PrintMemory(lpTargetFileView + PatchOffset,
  65. lpTargetFileView + PatchOffset + KeywordLength,
  66. lpTargetFileView);
  67. memcpy(lpTargetFileView + PatchOffset, RSAPublicKeyPEM.c_str(), KeywordLength);
  68. PRINT_MESSAGE("After:");
  69. Helper::PrintMemory(lpTargetFileView + PatchOffset,
  70. lpTargetFileView + PatchOffset + KeywordLength,
  71. lpTargetFileView);
  72. PRINT_MESSAGE("");
  73. return true;
  74. }
  75. // DWORD Solution0::GetMainAppVersion(LPDWORD lpMajorVer, LPDWORD lpMinorVer) {
  76. // BOOL bSuccess = FALSE;
  77. // DWORD dwLastError = ERROR_SUCCESS;
  78. // std::Tstring TargetFileFullName = InstallationPath + MainAppName;
  79. //
  80. // DWORD dwSize = 0;
  81. // PVOID lpData = NULL;
  82. // VS_FIXEDFILEINFO* lpVersionInfo = NULL;
  83. // UINT VersionInfoSize = 0;
  84. //
  85. // dwSize = GetFileVersionInfoSize(TargetFileFullName.c_str(),
  86. // &dwSize); // MSDN doesn't say it can be NULL.
  87. // // so I use dwSize to receive this deprecated value
  88. // if (dwSize == 0) {
  89. // dwLastError = GetLastError();
  90. // REPORT_ERROR_WITH_CODE("ERROR: GetFileVersionInfoSize failed.", dwLastError);
  91. // goto ON_Solution0_GetMainAppVersion_ERROR;
  92. // }
  93. //
  94. // lpData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
  95. // if (lpData == nullptr) {
  96. // dwLastError = GetLastError();
  97. // REPORT_ERROR_WITH_CODE("ERROR: HeapAlloc failed.", dwLastError);
  98. // goto ON_Solution0_GetMainAppVersion_ERROR;
  99. // }
  100. //
  101. // if (!GetFileVersionInfo(TargetFileFullName.c_str(), NULL, dwSize, lpData)) {
  102. // dwLastError = GetLastError();
  103. // REPORT_ERROR_WITH_CODE("ERROR: GetFileVersionInfo failed.", dwLastError);
  104. // goto ON_Solution0_GetMainAppVersion_ERROR;
  105. // }
  106. //
  107. // if (!VerQueryValue(lpData, TEXT("\\"), reinterpret_cast<LPVOID*>(&lpVersionInfo), &VersionInfoSize)) {
  108. // dwLastError = GetLastError();
  109. // REPORT_ERROR_WITH_CODE("ERROR: VerQueryValue failed.", dwLastError);
  110. // goto ON_Solution0_GetMainAppVersion_ERROR;
  111. // }
  112. //
  113. // *lpMajorVer = lpVersionInfo->dwProductVersionMS;
  114. // *lpMinorVer = lpVersionInfo->dwProductVersionLS;
  115. //
  116. // bSuccess = TRUE;
  117. // ON_Solution0_GetMainAppVersion_ERROR:
  118. // if (lpData)
  119. // HeapFree(GetProcessHeap(), NULL, lpData);
  120. // return bSuccess;
  121. // }
  122. }