Преглед изворни кода

Add support for Navicat Premium 12.1.11 x86

Double Sine пре 7 година
родитељ
комит
b588e7f608
1 измењених фајлова са 108 додато и 1 уклоњено
  1. 108 1
      navicat-patcher/Solution2.cpp

+ 108 - 1
navicat-patcher/Solution2.cpp

@@ -13,6 +13,8 @@ namespace Patcher {
 
     uint8_t Solution2::Keywords[KeywordsCount][5];
 
+#if defined(_M_X64)
+
     void Solution2::BuildKeywords() noexcept {
         for (size_t i = 0; i < KeywordsCount; ++i) {
             Keywords[i][0] = 0x83;      // Keywords[i] = asm('xor eax, KeywordsMeta[i]') + 
@@ -44,7 +46,7 @@ namespace Patcher {
             DWORD PossibleRangeStart = 0xffffffff;
             DWORD PossibleRangeEnd;
             for (DWORD i = 0; i < textSection->SizeOfRawData; ++i) {
-                if (memcmp(ptextSectionData + i, Keywords[0], 5) == 0) {
+                if (memcmp(ptextSectionData + i, Keywords[0], sizeof(Keywords[0])) == 0) {
                     Hints[FirstKeywordCounter++] =
                         *reinterpret_cast<uint32_t*>(ptextSectionData + i + sizeof(Keywords[0])) +
                         i + sizeof(Keywords[0]) + sizeof(uint32_t);
@@ -100,6 +102,111 @@ namespace Patcher {
         return true;
     }
 
+#else
+
+    void Solution2::BuildKeywords() noexcept {
+        for (size_t i = 0; i < KeywordsCount; ++i) {
+            switch (i % 3) {
+                case 0:
+                    Keywords[i][0] = 0x83;      // Keywords[i] = asm('xor edx, KeywordsMeta[i]') + 
+                    Keywords[i][1] = 0xf2;
+                    Keywords[i][2] = KeywordsMeta[i];
+                    Keywords[i][3] = 0x88;      //               asm_prefix('mov byte ptr ds:xxxxxxxx, dl')
+                    Keywords[i][4] = 0x15;
+                    break;
+                case 1:
+                    Keywords[i][0] = 0x83;      // Keywords[i] = asm('xor eax, KeywordsMeta[i]') + 
+                    Keywords[i][1] = 0xf0;
+                    Keywords[i][2] = KeywordsMeta[i];
+                    Keywords[i][3] = 0xa2;      //               asm_prefix('mov byte ptr ds:xxxxxxxx, al')
+                    break;
+                default:
+                    Keywords[i][0] = 0x83;      // Keywords[i] = asm('xor ecx, KeywordsMeta[i]') + 
+                    Keywords[i][1] = 0xf1;
+                    Keywords[i][2] = KeywordsMeta[i];
+                    Keywords[i][3] = 0x88;      //               asm_prefix('mov byte ptr ds:xxxxxxxx, cl')
+                    Keywords[i][4] = 0x0D;
+                    break;
+            }
+            
+        }
+    }
+
+    bool Solution2::FindPatchOffset() noexcept {
+        PIMAGE_SECTION_HEADER textSection = nullptr;
+        uint8_t* pTargetFileView = pTargetFile->GetView<uint8_t>();
+        uint8_t* ptextSectionData = nullptr;
+        off_t Offsets[KeywordsCount];
+        memset(Offsets, -1, sizeof(Offsets));
+
+        textSection = Helper::ImageSectionHeader(pTargetFileView, ".text");
+        if (textSection == nullptr)
+            return false;
+        ptextSectionData = pTargetFileView + textSection->PointerToRawData;
+
+        BuildKeywords();
+
+        // Find offsets
+        {
+            size_t FirstKeywordCounter = 0;
+            uint32_t Hints[3];
+            DWORD PossibleRangeStart = 0xffffffff;
+            DWORD PossibleRangeEnd;
+            for (DWORD i = 0; i < textSection->SizeOfRawData; ++i) {
+                if (memcmp(ptextSectionData + i, Keywords[0], sizeof(Keywords[0])) == 0) {
+                    Hints[FirstKeywordCounter++] =
+                        *reinterpret_cast<uint32_t*>(ptextSectionData + i + sizeof(Keywords[0]));
+                    if (i < PossibleRangeStart)
+                        PossibleRangeStart = i;
+                }
+            }
+
+            PossibleRangeStart -= 0x1000;
+            PossibleRangeEnd = PossibleRangeStart + 0x100000;
+
+            // Keywords[0] should occur 3 times. 
+            if (FirstKeywordCounter != 3)
+                return false;
+
+            Helper::QuickSort(Hints, 0, _countof(Hints));
+
+            // assert
+            // if not satisfied, refuse to patch
+            if (Hints[2] - Hints[0] != 0x127382BE - 0x12738210)
+                return false;
+
+            for (size_t i = 0; i < KeywordsCount; ++i) {
+                uint8_t CurrentKeyword[9];
+                size_t CurrentKeywordSize = i % 3 == 1 ? 4 : 5;
+                memcpy(CurrentKeyword, Keywords[i], CurrentKeywordSize);
+                *reinterpret_cast<uint32_t*>(CurrentKeyword + CurrentKeywordSize) = Hints[0] + i;
+                CurrentKeywordSize += sizeof(uint32_t);
+
+                for (DWORD j = PossibleRangeStart; j < PossibleRangeEnd; ++j) {
+                    if (memcmp(ptextSectionData + j, CurrentKeyword, CurrentKeywordSize) == 0) {
+                        Offsets[i] = textSection->PointerToRawData + j;
+                        break;
+                    }
+                }
+
+                // if not found, refuse to patch
+                if (Offsets[i] == -1)
+                    return false;
+            }
+        }
+
+        static_assert(sizeof(PatchOffsets) == sizeof(Offsets), "static_assert failure!");
+        memcpy(PatchOffsets, Offsets, sizeof(PatchOffsets));
+
+        for (size_t i = 0; i < KeywordsCount; ++i)
+            _tprintf_s(TEXT("MESSAGE: [Solution2] Keywords[%zu] has been found: offset = +0x%08lx.\n"),
+                       i, PatchOffsets[i]);
+
+        return true;
+    }
+
+#endif
+
     bool Solution2::MakePatch(RSACipher* cipher) const {
         std::string RSAPublicKeyPEM;
         uint8_t* pTargetFileView = pTargetFile->GetView<uint8_t>();