學了彙編有一段時間了,不練練手不太好,剛好把之前留下來的坑填完--拳皇13的成就。PS:拳皇13在硬盤裏躺了有一兩年了(100對戰勝利的成就拿到後就沒玩了,剩下的都太煩了,需要100超必殺,100真超必殺,哪有這麼多氣,網絡又不好,還有打一半退出的沒素質貨),最近硬盤快爆了,清下空間。
先舉個簡單一點的,修改戰鬥時間:利用Cheat Engine(我的版本是6.8.3,最近翻不出去,下不到最新的)先找到戰鬥時間的地址。因爲時間是60秒,猜測大小是byte,通過幾次scan找到該地址,修改該地址數據,觀察遊戲,戰鬥時間跟剛纔修改的數據一致,確認找打了地址。
再利用Cheat Engine找出是那段代碼修改了該數據,得到以下數據:
0041F6F7 - 49 - dec ecx
0041F6F8 - 23 C1 - and eax,ecx
0041F6FA - 89 83 24020000 - mov [ebx+00000224],eax <<
0041F700 - E8 9BF5FFFF - call kofxiii.exe+1ECA0
0041F705 - 3B F8 - cmp edi,eax
EAX=0038F510
EBX=00831DD0
ECX=FFFFFFFF
EDX=FFFFFFFF
ESI=00831DD0
EDI=00000038
ESP=0DCDFE7C
EBP=0DCDFEA0
EIP=0041F700
通過OD調試,找出[ebx+00000224]=0x00831FF4,地址的值:0x0038F510,因爲是byte值,因此還得加0x2,所以時間地址:0x00831FF6,時間:56秒的16位是0x38。
經過2天的OD和IDA調試(果然自己很菜,看大佬找基址都是10幾分鐘),終於找出一個公式,但因爲Steam遊戲不能用OD和IDA啓動,只能附加調試,所以最終的基址不能確定,只好認爲現在最終找到的是基址,關機測試,換電腦測試,都沒問題,大致就認爲OK了。PS:某個詞典好屌,佔用了F8快捷鍵調試,害我花了2到3個小時找那個破程序佔用了。
追蹤到的順序:
00494DA4 |> \8BCF mov ecx,edi ; kofxiii.0082FB30
004956F8 |. 8BF1 mov esi,ecx ; kofxiii.0082FB30
00495768 |> \8B46 6C mov eax,dword ptr ds:[esi+0x6C] esi:0082FB30
00495778 |. 8D48 F8 lea ecx,dword ptr ds:[eax-0x8] eax:06150094
004942A3 mov ecx, [ecx+10h] ecx:0615008C
eax=461a30跳轉
00461A65 |. 83C1 08 add ecx,0x8 ecx:00831D08
004619C1 . 8BF9 mov edi,ecx, ecx:00831D10
先賦值ESI的值和EBX的值
00461A06 . 8B77 0C mov esi,dword ptr ds:[edi+0xC] edi:00831D10
00461A09 . 8D5F 08 lea ebx,dword ptr ds:[edi+0x8]
while(esi != ebx) ebx:00831D18
{
00461A13 > /8B4E 08 mov ecx,dword ptr ds:[esi+0x8]
調用前:第一次ESI:039CBA30 第二次ESI:039CBA48 第三次ESI:03AB1BF0
00461A1B . 8B76 04 mov esi,dword ptr ds:[esi+0x4]
調用後:第一次ESI:039CBA48 第二次ESI:03AB1BF0 第三次ESI:00831D18
}
0041F5F8 |. 8BD9 mov ebx,ecx ecx:00831DD0
0041F6FA |. 8983 24020000 mov dword ptr ds:[ebx+0x224],eax ; 戰鬥時間賦值 ebx:00831DD0
剩下的就簡單了,Copy之前寫過工具的代碼,快速搭建窗口,MFC沒有用過,不太熟悉,Winform倒是最近剛玩過,下面的截圖是大部分完成後的結果:時間控制,1P和2P的生命,能量及曝氣的控制。
關鍵代碼:
// 獲取戰鬥時間
short Kof13::GetBattleTime()
{
short result = -1;
DWORD dwAddr = GetBattleTimeAddr();
if (dwAddr != NULL && m_handleGame != NULL)
{
unsigned char dwResult = 0;
DWORD dwRead = 0;
ReadProcessMemory(m_handleGame, (LPCVOID)(dwAddr + 2), &dwResult, sizeof(dwResult), &dwRead);
if (dwRead != sizeof(dwResult))
return 0;
unsigned short battleTime = (unsigned short)dwResult;
result = (short)battleTime;
}
return result;
}
// 鎖定戰鬥時間
void Kof13::LockTime()
{
if (m_lockTime <= 0) return;
if (NULL == m_handleGame) return;
DWORD dwAddr = GetBattleTimeAddr();
if (NULL == dwAddr) return;
unsigned char value = (unsigned char)m_lockTime;
DWORD dwWrite = 0;
WriteProcessMemory(m_handleGame, (LPVOID)(dwAddr + 0x2), &value, sizeof(value), &dwWrite);
}
// 獲取戰鬥時間地址
DWORD Kof13::GetBattleTimeAddr()
{
if (!m_handleGame) return 0;
DWORD dwAddr = 0x0082FB30;
DWORD dwResult = 0;
DWORD dwRead = 0;
// [0082FB30 + 0x6C]
dwAddr += 0x6C;
ReadProcessMemory(m_handleGame, (LPCVOID)dwAddr, &dwResult, 4, &dwRead);
if (dwRead != 4)
return 0;
dwAddr = dwResult;
// [[0082FB30+0x6C]-0x8]
dwAddr -= 0x8;
// [[[0082FB30+0x6C]-0x8]+0x10]
dwAddr += 0x10;
ReadProcessMemory(m_handleGame, (LPCVOID)dwAddr, &dwResult, 4, &dwRead);
if (dwRead != 4)
return 0;
dwAddr = dwResult;
dwAddr += 0x8;
DWORD esiValue = 0;
DWORD ebxValue = 0;
ReadProcessMemory(m_handleGame, (LPCVOID)(dwAddr + 0xC), &dwResult, 4, &dwRead);
if (dwRead != 4)
return 0;
esiValue = dwResult;
ebxValue = dwAddr + 0x8;
DWORD ecxValue = 0;
while (esiValue != ebxValue)
{
DWORD dwTempValue = 0;
ReadProcessMemory(m_handleGame, (LPCVOID)(esiValue + 0x8), &dwResult, 4, &dwRead);
if (dwRead != 4)
return 0;
dwTempValue = dwResult;
ReadProcessMemory(m_handleGame, (LPCVOID)(esiValue + 0x4), &dwResult, 4, &dwRead);
if (dwRead != 4)
return 0;
esiValue = dwResult;
if (esiValue != ebxValue)
ecxValue = dwTempValue;
}
return ecxValue + 0x224;
}
Github上私有庫竟然免費了,現在才知道,恩,上傳上傳A_A,上傳代碼到私有庫上,防止外泄。不然怎麼會有外掛入門到入獄的說法呢?╮(-_-)╭,修改器寫好,刷成就就很快了。PS:想了很久,時間好像不確定是否找到了基址,因爲沒有找到最開始賦值的地方,而且好像時間的地址一直都是不變的,所以有2天的時間浪費了,像1P和2P的生命,能量及曝氣就很確定找到了基址,但代碼是不會公佈的,๑乛◡乛๑。
再附贈一個能量槽的追蹤順序:
ChearEngine查找調用地址
00486ED8 - 8B C1 - mov eax,ecx
00486EDA - 8B F7 - mov esi,edi
00486EDC - 89 87 DC000000 - mov [edi+000000DC],eax <<
00486EE2 - E8 690A0000 - call kofxiii.exe+87950
00486EE7 - E8 44000000 - call kofxiii.exe+86F30
EAX=00000000
EBX=00000000
ECX=00000000
EDX=024DA4B0
ESI=024DB578
EDI=024DB578
ESP=0D80F748
EBP=0D80F760
EIP=00486EE2
IDA調試找基址
0041E65A mov ecx, dword_8320A0[esi*4]
0041E661 mov [ebp+var_18], ecx
0041E6C6 mov esi, [ebp+var_18] ; var_18= dword ptr -18h ebp:0D80F950 0D80F91C [ebp+var_18]:0D80F938
0041E6F6 mov edi, esi
00486EDC mov [edi+0DCh], eax edi:03872770 024DB578
最終版,可以解鎖所有角色的試煉挑戰,這個改好,就全成就了,不錯不錯: