[汇编]汇编练习(1):写个拳皇13修改器

        学了汇编有一段时间了,不练练手不太好,刚好把之前留下来的坑填完--拳皇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  

        最终版,可以解锁所有角色的试炼挑战,这个改好,就全成就了,不错不错:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值