跳到主要內容

SiglusEngine地區檢查分析(一)

之前為了破解SiglusEngine的地區限制,我有做了一些分析:
SiglusEngine地區限制破解

這一次我的目的是還原第一個關鍵跳轉那個地方的檢查算法。
首先回顧一下第一個關鍵跳轉:
0045DC5A  |.  E8 81F9FFFF         CALL 0045D5E0          ;檢查
0045DC5F  |.  84C0                         TEST AL,AL
0045DC61      E9 AA000000         JMP 0045DD10 ;第一個關鍵跳轉
0045DC66      90                              NOP

在 CALL 0045D5E0 這裡按 F7 跟進:
0045D5E0  /$  6A FF                    PUSH -1         ;函式開頭
0045D5E2  |.  68 D1087600        PUSH 007608D1                            
0045D5E7  |.  64:A1 0000000    MOV EAX,DWORD PTR FS:[0]
0045D5ED  |.  50                           PUSH EAX
0045D5EE  |.  81EC 7C020000 SUB ESP,27C
0045D5F4  |.  A1 90348000        MOV EAX,DWORD PTR DS:[803490]
0045D5F9  |.  33C4                       XOR EAX,ESP
這個函式有點長,我就不全部列出來了。

觀察一下這個函式,可以發現它呼叫了幾個API:
GetFileVersionInfoSize
GetFileVersionInfo
VerQueryValue

查了一下MSDN,這些API可以用來取得某個exe或dll的版本訊息,而其中就包括了
那個exe或dll所支援的語言。
我們進一步跟蹤程式,可以發現SiglusEngine是把kernel32.dll的版本資訊拿來檢查,
若kernel32.dll支援不支援日文就判定為非日本地區。由於kernel32.dll有可能支援數種語言,
引此需要一個迴圈來檢查,以下為原始程式碼:
0045D7F4  |> /66:813A 1104  /CMP WORD PTR DS:[EDX], 411 ;迴圈開頭,0x411為日文的Language ID
0045D7F9  |. |74 10         |           JE SHORT 0045D80B                     ;跳到最下方的MOV
0045D7FB  |. |83C2 04       |       ADD EDX,4
0045D7FE  |. |83C0 01       |        ADD EAX,1
0045D801  |. |3BC1          |          CMP EAX,ECX
0045D803  |. |895424 18     |      MOV DWORD PTR SS:[ESP+18],EDX
0045D807  |.^\7C EB         \        JL SHORT 0045D7F4      ;返回迴圈開頭
0045D809  |.  EB 05                    JMP SHORT 0045D810  ;跳過下面的MOV
0045D80B  |>  C64424 16 01   MOV BYTE PTR SS:[ESP+16],1
0045D810  |> \3BFB                   CMP EDI, EBX

以下為C語言的地區檢查函式,使用了上面發現的方法:
struct LANGANDCODEPAGE {
  WORD wLanguage;
  WORD wCodePage;
} *lpTranslate;

BOOL isSystemSupportsJapanese() {
HMODULE hVersion = LoadLibrary("version.dll");
FARPROC GetFileVersionInfo = GetProcAddress(hVersion, "GetFileVersionInfoA");
FARPROC GetFileVersionInfoSize = GetProcAddress(hVersion, "GetFileVersionInfoSizeA");
FARPROC VerQueryValue = GetProcAddress(hVersion, "VerQueryValueA");

char* szFileName = "kernel32.dll";
DWORD dwLength = GetFileVersionInfoSize(szFileName, NULL);
PBYTE pBlock = HeapAlloc(GetProcessHeap(), 0, dwLength);
GetFileVersionInfo(szFileName, 0, dwLength, pBlock);

// Read the list of languages and code pages.
UINT cbTranslate;
VerQueryValue(pBlock,
 "\\VarFileInfo\\Translation",
 (LPVOID*)&lpTranslate,
 &cbTranslate);

int i;
BOOL isSupport = FALSE;
TCHAR SubBlock[100];
for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ ) {
if(lpTranslate[i].wLanguage ==
MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN)) {
isSupport = TRUE;
break;
}
}
HeapFree(GetProcessHeap(), 0, pBlock);
return isSupport;
}

其中 MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN)
巨集展開之後就是常數0x411。

下一篇就來實現第二種地區檢查吧。

留言

這個網誌中的熱門文章

muv漢化補丁修復

muv的漢化補丁對Win10會有相容性問題,這自從補丁發佈到現在,漢化組都沒有修正的意思,這問題也折騰我好一陣子了,最後決定還是自己debug比較實際。 其實解決方法意外的簡單,不過追蹤的過程挺有趣的,也讓我學到了一個hook的實作方法。 在win10下啟動漢化補丁會出現下面這個對話框:

OllyDbg教學(一) -- 基本操作

這篇簡單介紹一下OllyDbg的用法,還有一些使用上的技巧,這邊假設讀者對程式的執行已經有一定的了解。 OllyDbg 1 主頁 OllyDbg 2 主頁 要用OllyDbg來debug一個程式有兩種方法,第一種是直接以OllyDbg啟動程式,另一種則是先啟動程式,在用OllyDbg附加到執行中的程式。一般用第一種方法就可以成功,第二種方法通常用於一些需要特殊啟動環境的程式。

SiglusEngine地區限制破解

新版網誌: https://casidi.github.io/2016/07/29/siglusengine-cracking/ 採用這個引擎的比較有名的就是key跟SAGA PLANETS這兩家公司了。 這次以SAGA PLANET做的一個小遊戲為分析對象,遊戲可以免費下載: 【はつゆきパズル☆神経衰弱☆】 下載下來的是一個壓縮檔,檔名為 hatsukipuzzle01.zip,直接解壓縮會得到一個資料夾, 名字為: はつゆきパズル 其實遊戲必要的只有 はつゆきパズル\StartData\GameData 這個資料夾,直接把GameData資料夾搬到隨便一個地方,執行SiglusEngine.exe即可啟動遊戲。