[筆記] 多開破解
因為論壇有人在問...就去查了一下...
rf: 多開限制突破
1. Findwindow突破
bp FindWindowW,運行程序斷下來,執行到返回,來到下面
首先FindWindowW判斷窗口是否存在(是否為NULL),下面有個je short FindWind.004F0EAD,存在就繼續向下執行,可以看到繼續向下的話,有個kernel32.ExitProcess了,所以我們直接將je改為jmp就可以。測試下可以多開了。也可以寫程序直接SetWindowText將窗口標題改掉。
2. EnumWindows突破
bp EnumWindows,運行程序斷下來,執行到返回
我們知道EnumWindows有個回調函數,call上面壓棧的參數地址應該就是回調函數地址,我們ctrl+g轉到看下,是個jmp,那就繼續轉,下面來到的地方就是回調函數了
向下拉看到GetWindowTextW了吧,回調函數中傳進來的窗口句柄,通過GetWindowTextW獲取窗口標題,然後比較,來判斷是否結束實例 所以將004F09BC 75 32 jnz short EnumWind.004F09F0這一行的jnz改為jmp就可以了,保存修改,運行試下,可以多開了。 牽扯到通過窗口標題來防止多開的都可以SetWindowText將窗口標題改掉來突破多開。
3. 互斥對象突破
同樣bp CreateMutexW,運行程序斷下來,執行到返回
調用GetLastError返回值與0xB7比較,0xB7是ERROR_ALREADY_EXISTS錯誤代碼,然後不相等就調走,所以將跳轉改為JMP,保存測試,成功多開。
4. 共享節法突破
思路是,共享節中的某個數據用來判斷是否運行過實例,我們可以捕捉訪問該段的代碼。 OD載入ALT+M顯示內存,這裡可以看到許多段,選中Shared段右鍵在訪問上設置中斷,對整個內存塊設置該類型斷點,這個斷點是一次性斷點,當所在段被讀取或執行時就中斷,中斷髮生後,斷點將被刪除。F9運行程序來到下面
轉到004F0E73這個地址我們看到有ExitProcess,可以斷定這兩句代碼就是拿出共享段中得某個數據與0比較來判斷是否有實例運行,我們將其JNZ NOP掉,讓其永遠不會跳轉,保存修改,成功多開。
rf: war3多開的實現
好孩子不怎麼玩遊戲,就拿這個練下手了,看郁的教程裝了個熱血,那個直接SetWindowText然後將遊戲換個目錄就可以多開。
先運行一個Frozen Throne.exe,然後再運行一個提示「魔獸爭霸資料片:冰封王座已經運行」,OD載入bp MessageBoxA下斷,執行後ait+f9返回用戶代碼
看到CloseHandle沒,應該是使用的創建互斥對象來防多開的,向上找,看到了GetLastError了
果斷JNZ改為JMP,上面看到使用的是CreateEvent。保存修改,運行下,不行,又出來錯誤提示「請核實您的冰封王座光盤已在光盤驅動器中,然後點擊重試」,OD載入修改好後的Frozen Throne.exe,發現是創建了個進程,Frozen Throne.exe就相當於個loader,那我們直接分析war3.exe吧
先運行一個war3.exe,然後再運行一個提示「warcraft III was unable to initialize」,od載入bp MessageBoxA,F9運行,斷下,ALT+F9返回用戶代碼,彈出那個窗口了,所在的是GAME.DLL這個模塊,在附近沒有發現可以跳過這個CALL的地方,按CTRL+F9執行到返回,往上拉可以看到「warcraft III was unable to initialize「這個字符串了,CTRL+F9繼續執行到返回
在這個CALL的上面看到了個跳轉,改為強制跳轉試下,保存修改,成功多開
rf: 多開限制突破
1. Findwindow突破
bp FindWindowW,運行程序斷下來,執行到返回,來到下面
004F0E5C 8BF4 mov esi,esp 004F0E5E 68 B8466A00 push FindWind.006A46B8 ; UNICODE "FindWindow" 004F0E63 6A 00 push 0 004F0E65 FF15 28EE6F00 call dword ptr ds:[<&USER32.FindWindow>; USER32.FindWindowW 004F0E6B 3BF4 cmp esi,esp 004F0E6D E8 280FFFFF call FindWind.004E1D9A 004F0E72 8945 C8 mov dword ptr ss:[ebp-38],eax 004F0E75 837D C8 00 cmp dword ptr ss:[ebp-38],0 004F0E79 74 32 je short FindWind.004F0EAD 004F0E7B 6A 00 push 0 004F0E7D 6A 00 push 0 004F0E7F 68 9C466A00 push FindWind.006A469C 004F0E84 E8 86DBFEFF call FindWind.004DEA0F 004F0E89 8BF4 mov esi,esp 004F0E8B 8B45 C8 mov eax,dword ptr ss:[ebp-38] 004F0E8E 50 push eax 004F0E8F FF15 E8EC6F00 call dword ptr ds:[<&USER32.SetForegro>; USER32.SetForegroundWindow 004F0E95 3BF4 cmp esi,esp 004F0E97 E8 FE0EFFFF call FindWind.004E1D9A 004F0E9C 8BF4 mov esi,esp 004F0E9E 6A 00 push 0 004F0EA0 FF15 74E96F00 call dword ptr ds:[<&KERNEL32.ExitProc>; kernel32.ExitProcess 004F0EA6 3BF4 cmp esi,esp 004F0EA8 E8 ED0EFFFF call FindWind.004E1D9A 004F0EAD 68 B8466A00 push FindWind.006A46B8 ; UNICODE "FindWindow" 004F0EB2 8B4D EC mov ecx,dword ptr ss:[ebp-14] 004F0EB5 E8 F3DDFEFF call FindWind.004DECAD
首先FindWindowW判斷窗口是否存在(是否為NULL),下面有個je short FindWind.004F0EAD,存在就繼續向下執行,可以看到繼續向下的話,有個kernel32.ExitProcess了,所以我們直接將je改為jmp就可以。測試下可以多開了。也可以寫程序直接SetWindowText將窗口標題改掉。
2. EnumWindows突破
bp EnumWindows,運行程序斷下來,執行到返回
004F0F9C 8BF4 mov esi,esp 004F0F9E 6A 00 push 0 004F0FA0 68 679C4D00 push EnumWind.004D9C67 004F0FA5 FF15 34EE6F00 call dword ptr ds:[<&USER32.EnumWindow>; USER32.EnumWindows
我們知道EnumWindows有個回調函數,call上面壓棧的參數地址應該就是回調函數地址,我們ctrl+g轉到看下,是個jmp,那就繼續轉,下面來到的地方就是回調函數了
004F0940 55 push ebp 004F0941 8BEC mov ebp,esp 004F0943 81EC CC020000 sub esp,2CC 004F0949 53 push ebx 004F094A 56 push esi 004F094B 57 push edi 004F094C 8DBD 34FDFFFF lea edi,dword ptr ss:[ebp-2CC] 004F0952 B9 B3000000 mov ecx,0B3 004F0957 B8 CCCCCCCC mov eax,CCCCCCCC 004F095C F3:AB rep stos dword ptr es:[edi] 004F095E A1 48526F00 mov eax,dword ptr ds:[6F5248] 004F0963 33C5 xor eax,ebp 004F0965 8945 FC mov dword ptr ss:[ebp-4],eax 004F0968 33C0 xor eax,eax 004F096A 66:8985 F8FDFFF>mov word ptr ss:[ebp-208],ax 004F0971 68 FE010000 push 1FE 004F0976 6A 00 push 0 004F0978 8D85 FAFDFFFF lea eax,dword ptr ss:[ebp-206] 004F097E 50 push eax 004F097F E8 2B40FFFF call EnumWind.004E49AF 004F0984 83C4 0C add esp,0C 004F0987 8BF4 mov esi,esp 004F0989 68 00010000 push 100 004F098E 8D85 F8FDFFFF lea eax,dword ptr ss:[ebp-208] 004F0994 50 push eax 004F0995 8B4D 08 mov ecx,dword ptr ss:[ebp+8] 004F0998 51 push ecx 004F0999 FF15 30EE6F00 call dword ptr ds:[<&USER32.GetWindowT>; USER32.GetWindowTextW 004F099F 3BF4 cmp esi,esp 004F09A1 E8 F413FFFF call EnumWind.004E1D9A 004F09A6 8D85 F8FDFFFF lea eax,dword ptr ss:[ebp-208] 004F09AC 50 push eax 004F09AD 68 38436A00 push EnumWind.006A4338 ; UNICODE "EnumWindows" 004F09B2 E8 00A7FEFF call EnumWind.004DB0B7 004F09B7 83C4 08 add esp,8 004F09BA 85C0 test eax,eax 004F09BC 75 32 jnz short EnumWind.004F09F0 004F09BE 6A 00 push 0 004F09C0 6A 00 push 0 004F09C2 68 1C436A00 push EnumWind.006A431C 004F09C7 E8 4DE0FEFF call EnumWind.004DEA19 004F09CC 8BF4 mov esi,esp 004F09CE 8B45 08 mov eax,dword ptr ss:[ebp+8] 004F09D1 50 push eax 004F09D2 FF15 ECEC6F00 call dword ptr ds:[<&USER32.SetForegro>; USER32.SetForegroundWindow 004F09D8 3BF4 cmp esi,esp 004F09DA E8 BB13FFFF call EnumWind.004E1D9A 004F09DF 8BF4 mov esi,esp 004F09E1 6A 00 push 0 004F09E3 FF15 78E96F00 call dword ptr ds:[<&KERNEL32.ExitProc>; kernel32.ExitProcess 004F09E9 3BF4 cmp esi,esp 004F09EB E8 AA13FFFF call EnumWind.004E1D9A 004F09F0 B8 01000000 mov eax,1 004F09F5 52 push edx 004F09F6 8BCD mov ecx,ebp 004F09F8 50 push eax 004F09F9 8D15 280A4F00 lea edx,dword ptr ds:[4F0A28] 004F09FF E8 E1D2FEFF call EnumWind.004DDCE5 004F0A04 58 pop eax 004F0A05 5A pop edx 004F0A06 5F pop edi 004F0A07 5E pop esi 004F0A08 5B pop ebx 004F0A09 8B4D FC mov ecx,dword ptr ss:[ebp-4] 004F0A0C 33CD xor ecx,ebp 004F0A0E E8 3BF6FEFF call EnumWind.004E004E 004F0A13 81C4 CC020000 add esp,2CC 004F0A19 3BEC cmp ebp,esp 004F0A1B E8 7A13FFFF call EnumWind.004E1D9A 004F0A20 8BE5 mov esp,ebp 004F0A22 5D pop ebp 004F0A23 C2 0800 retn 8
向下拉看到GetWindowTextW了吧,回調函數中傳進來的窗口句柄,通過GetWindowTextW獲取窗口標題,然後比較,來判斷是否結束實例 所以將004F09BC 75 32 jnz short EnumWind.004F09F0這一行的jnz改為jmp就可以了,保存修改,運行試下,可以多開了。 牽扯到通過窗口標題來防止多開的都可以SetWindowText將窗口標題改掉來突破多開。
3. 互斥對象突破
同樣bp CreateMutexW,運行程序斷下來,執行到返回
004F0E5E 68 B8466A00 push 互斥體單.006A46B8 004F0E63 6A 00 push 0 004F0E65 6A 00 push 0 004F0E67 FF15 74E96F00 call dword ptr ds:[<&KERNEL32.CreateMu>; kernel32.CreateMutexW 004F0E6D 3BF4 cmp esi,esp 004F0E6F E8 300FFFFF call 互斥體單.004E1DA4 004F0E74 A3 C46E6F00 mov dword ptr ds:[6F6EC4],eax 004F0E79 8BF4 mov esi,esp 004F0E7B FF15 78E96F00 call dword ptr ds:[<&KERNEL32.GetLastE>; ntdll.RtlGetLastWin32Error 004F0E81 3BF4 cmp esi,esp 004F0E83 E8 1C0FFFFF call 互斥體單.004E1DA4 004F0E88 3D B7000000 cmp eax,0B7 004F0E8D 75 1F jnz short 互斥體單.004F0EAE
調用GetLastError返回值與0xB7比較,0xB7是ERROR_ALREADY_EXISTS錯誤代碼,然後不相等就調走,所以將跳轉改為JMP,保存測試,成功多開。
4. 共享節法突破
思路是,共享節中的某個數據用來判斷是否運行過實例,我們可以捕捉訪問該段的代碼。 OD載入ALT+M顯示內存,這裡可以看到許多段,選中Shared段右鍵在訪問上設置中斷,對整個內存塊設置該類型斷點,這個斷點是一次性斷點,當所在段被讀取或執行時就中斷,中斷髮生後,斷點將被刪除。F9運行程序來到下面
004F0E5C 833D 00407000 0>CMP DWORD PTR DS:[704000],0 004F0E63 75 0E JNZ SHORT 共享節單.004F0E73
轉到004F0E73這個地址我們看到有ExitProcess,可以斷定這兩句代碼就是拿出共享段中得某個數據與0比較來判斷是否有實例運行,我們將其JNZ NOP掉,讓其永遠不會跳轉,保存修改,成功多開。
rf: war3多開的實現
好孩子不怎麼玩遊戲,就拿這個練下手了,看郁的教程裝了個熱血,那個直接SetWindowText然後將遊戲換個目錄就可以多開。
先運行一個Frozen Throne.exe,然後再運行一個提示「魔獸爭霸資料片:冰封王座已經運行」,OD載入bp MessageBoxA下斷,執行後ait+f9返回用戶代碼
004010AE |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 004010B0 |. 8D4C24 40 LEA ECX,DWORD PTR SS:[ESP+40] ; | 004010B4 |. 50 PUSH EAX ; |Title 004010B5 |. 51 PUSH ECX ; |Text 004010B6 |. 6A 00 PUSH 0 ; |hOwner = NULL 004010B8 |. FF15 34714000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA 004010BE |. 8B5424 10 MOV EDX,DWORD PTR SS:[ESP+10] 004010C2 |. 52 PUSH EDX ; /hObject 004010C3 |. FF15 58704000 CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle
看到CloseHandle沒,應該是使用的創建互斥對象來防多開的,向上找,看到了GetLastError了
0040103C |. FFD5 CALL EBP ; [GetLastError 0040103E |. 3D B7000000 CMP EAX,0B7 00401043 |. 75 1A JNZ SHORT Frozen_T.0040105F
果斷JNZ改為JMP,上面看到使用的是CreateEvent。保存修改,運行下,不行,又出來錯誤提示「請核實您的冰封王座光盤已在光盤驅動器中,然後點擊重試」,OD載入修改好後的Frozen Throne.exe,發現是創建了個進程,Frozen Throne.exe就相當於個loader,那我們直接分析war3.exe吧
先運行一個war3.exe,然後再運行一個提示「warcraft III was unable to initialize」,od載入bp MessageBoxA,F9運行,斷下,ALT+F9返回用戶代碼,彈出那個窗口了,所在的是GAME.DLL這個模塊,在附近沒有發現可以跳過這個CALL的地方,按CTRL+F9執行到返回,往上拉可以看到「warcraft III was unable to initialize「這個字符串了,CTRL+F9繼續執行到返回
6F00974A 85C0 TEST EAX,EAX 6F00974C 74 0F JE SHORT Game.6F00975D 6F00974E E8 ED270000 CALL Game.6F00BF40 6F009753 33C9 XOR ECX,ECX 6F009755 E8 66D1FFFF CALL Game.6F0068C0 ;返回到這個CALL 6F00975A 33C0 XOR EAX,EAX 6F00975C C3 RETN 6F00975D B9 9881886F MOV ECX,Game.6F888198 ; ASCII "Warcraft III Game Application"
在這個CALL的上面看到了個跳轉,改為強制跳轉試下,保存修改,成功多開
留言
張貼留言