關於防止同一程式多次執行的破解方法--答hkip的提問 (3千字)

看雪資料發表於2001-06-15

關於防止同一程式多次執行的破解方法
          by liangs


hkip朋友提了一個問題如下:
如下的這個軟體,是個遊戲。他為了防止作弊不允許開兩個視窗。
可我找了半天都不知道怎麼解決這個問題。
http://61.141.247.212/MyGames/DownLoad/Setup-Plaza.exe
程式不大,只有6百K這個程式用ASPROTECT11加密,可以使用CASPR11解開。

-------------------------------------------------------------------
問題的解決:

上面的Setup-Plaza.exe實際上是個遊戲大廳的安裝程式,是中國遊戲中心
線上遊戲的大廳安裝程式,就象聯眾遊戲的大廳安裝程式一樣。這個程式脫殼
後反彙編的程式碼中找不到任何有用的提示,全都是亂碼。程式執行後,如果發
現已有一個程式在執行就會退出,也不給出任何提示,下bpx ExitProcess也
沒法中斷,faint!

在試過多箇中斷沒有效果的情況下,我跟蹤了一下程式的API呼叫,結果如下。

******************程式首次執行的跟蹤結果*************************
.....
FindWindowA(LPSTR:00465908:"iGameMainWndClass",LPSTR:00000000)::00417DBF
FindWindowA'returns: 00000000

SetRectEmpty()::00447247
SetRectEmpty'returns: FFFFFFFF

GetClassInfoA(HANDLE:00400000,LPSTR:00465908:"iGameMainWndClass",LPDATA:006FFD28)::00417E11
GetClassInfoA'returns: 00000000

LoadCursorA(HANDLE:00400000,LPSTR:00007F00)::00417E3F
LoadCursorA'returns: 00000000

GetClassInfoA(HANDLE:00400000,LPSTR:00465908:"iGameMainWndClass",LPDATA:006FFC70)::00437BA8
GetClassInfoA'returns: 00000000

RegisterClassA(LPDATA:006FFD28)::00437BB3
RegisterClassA'returns: 0000C306

LoadStringA(HANDLE:00400000,DWORD:000003F7,LPSTR:006FFBA4,DWORD:00000100)::0043C7AB
LoadStringA'returns: 00000013

lstrlenA(LPSTR:006FFBA4:"遊戲大廳 Ver 0.7.63")::0043A9DC
lstrlenA'returns: 00000013
.....
部分略。。。

★★★ 特別注意 ★★★
CreateWindowExA(DWORD:00000200,LPSTR:00465908:"iGameMainWndClass",LPSTR:020E42A0:"遊戲大廳 Ver 0.7.63",DWORD:00CF0000,DWORD:00000000,DWORD:00000000,DWORD:00000402,DWORD:000002E2,HWND:00000000,HANDLE:00000000,HANDLE:00400000,LPDATA:00000000)::0043758F


******************程式二次執行的跟蹤結果*************************
注意下面的跟蹤結果是執行一個程式不關閉的情況下,再執行程式的監視結果

FindWindowA(LPSTR:00465908:"iGameMainWndClass",LPSTR:00000000)::00417DBF
FindWindowA'returns: 00000FC8

FreeLibrary(HANDLE:10000000)::0041803F
FreeLibrary'returns: 00000001

CloseHandle(HANDLE:10000000)::0041804B
CloseHandle'returns: 00000000

UnhookWindowsHookEx(HANDLE:4B48779C)::0044D6FC
UnhookWindowsHookEx'returns: 00000001

LocalFree(HANDLE:005D0CC4)::0044ACE2
LocalFree'returns: 00000000
.....
部分略。。。

SetUnhandledExceptionFilter(LPDATA:7FC69E61)::0042D21B
SetUnhandledExceptionFilter'returns: 0042D1B8

ExitProcess(DWORD:00000000)::00428472

*************************************************************************

  大家比較一下上面兩次跟蹤的結果,會發現00417DBF的FindWindowA()的
返回值不同!!! 如果程式首次執行返回00000000,如果程式已經執行則返回
00000FC8。如果0417DBF的FindWindowA()返回00000000的話,我們可以看到
不遠處的CreateWindowExA(),這個API大家再熟悉不過了,就是產生程式的
主視窗。

  下面我們在來看看00417DBF處的程式呼叫:

//呼叫FindWindowA()
:00417DB9 FF1598154500            call dword ptr [00451598]     
:00417DBF 85C0                    test eax, eax
//這裡大家可以注意一下兩種情況下EAX中的返回值
:00417DC1 7407                    je 00417DCA
//如果EAX=0,就一切OK!!!

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00417C1A(U)
|
:00417DC3 33C0                    xor eax, eax
//不用說了,這個跳轉一跳就Over了!!!
:00417DC5 E94D020000              jmp 00418017


現在你知道怎麼改了,就將00417DC1的7407簡單的改為EB07就OK了。

上面我是透過API的跟蹤來破解的,當然你也可以透過bpx FindWindowA
來跟蹤搞定它,同樣的沒問題。

相關文章