遊戲防止多開的方法一般是CreateMutex,那麼我們直接對Mutex做手腳就好了,
本菜比也是這幾個月才會的,大神請輕噴
我們實驗的對象是
可能用到的工具:IDA,CE(我的是6.2),一隻能用的IDE(我的是VS2005)
用PEID看一下cg_se_3000.exe是加了殼的,那麼就動态分析好了
首先啟動遊戲
用CE打開cg_se_3000.exe
找到kernel32.dll點進去,Ctrl F搜索CreateMutex(這個函數在kernel32裡)
我們會發現一個CreateMutexW和一個CreateMutexA,一個unicode版的一個ANSI版的,根據這個遊戲的尿性我認為肯定用CreateMutexA
這個函數的形式如下:
HANDLE WINAPI CreateMutex(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCTSTR lpName
);
WINAPI其實就是_stdcall調用方式,參數應該是從右向左入棧,而且不用手動清棧
那麼這裡調用CreateMutexA的方式目測就是
push szMutexName//互斥體名稱
push ?
push 0
call CreateMutexA//call 76E3D7D4
那麼我們開始搜調用CreateMutex函數的地方吧
搜了一下發現搜不到,怎麼回事呢?
其實一開始我也糾結了很久,後來才想到CreateMutexA的地址有沒可能是放在指針裡
那麼就是call dword ptr[xxx]
那麼,直接掃描内存好了。記得勾上16進制哦
不知道為什麼,CE的彙編掃描器貌似有問題,直接搜這個也搜不出來。
那麼直接搜彙編的機器碼好了,随便找一個call dword ptr,可以看到前2個字節都是FF 15
後面的是小端地址,那麼005BF290就是90F25B00(關于大小端這裡不多贅述,反正就是在intel x86的CPU上,地址是反過來的),于是call dword ptr[5BF290] 就是FF 15 90 F2 5B 00
直接搜内存吧
直接就找到了48019B這個位置
到反彙編裡Ctrl G填48019B,就能看到
應該是我們要的東西了沒錯
CreateMutex這個函數是有返回值的,返回的是互斥體句柄,
那麼後面這條mov 地址, eax就是mov hMutex, eax,也就是
hMutex = CreateMutexA(0, 1, szName);
szName的值看一下就好了,這裡用處不大
既然我們知道了hMutex句柄的地址(cg_se_3000.exe 5C6B7C)
直接對這個句柄releaseMutex不就好了嘛
寫了小程序試了下,發現遠程釋放Mutex根本無效,搜了一下文章發現也是,那麼我們隻有采用遠程注入的方法了~
上文提到,用遠程注入的方法,把代碼/dll注入。
後來試過代碼注入,因為ReleaseMutex和CloseHandle都是隻對本線程裡的句柄有效,而CreateRemoteThread出來的線程必然不是CreateMutex的線程,所以釋放是無效的,其實CreateMutex在WinMain裡,也就是整個進程的主線程。
能進入主線程的方法我隻想到注入dll,那麼這裡就講注入dll好了。
首先你要有一個exe,控制台還是win32還是MFC無所謂了:
然後你要有一個dll,創建工程的時候選擇Win32項目,dll 空項目:
我們先把簡單的dll寫好,隻有當第一次LoadLibrary的時候才執行釋放Mutex的動作
通過指針取得hMutex的值,然後釋放它
現在編寫注入用的exe
我們先按照遠程線程注入dll的步驟,把基礎都搭好。
提權
枚舉進程:
看看是否已經釋放過Mutex了,如果未釋放,就注入dll:
最後完善一下main:
現在release編譯一下,把exe跟dll放到同一目錄,運行一下:
最終效果:
,