游戏中脚本方式值修改-Godot Engine

游戏为 Tower.Tactics.Liberation
游戏使用引擎 Godot Engine, 版本3.5.2
游戏中的数值全是脚本中修改, 内部名称为GDScript

游戏运行中脚本的主函数为GDScriptFunction__call, 脚本运行时的ip值只有在栈上储存, 需要在函数中间Hook, 获取到脚本的ip, 顺便一起获取codeptr

AsmHook::HOOK_INFO	Info_GDScript_CodeIp;
BOOL WINAPIV Hook_GDScript_CodeIp(VOID *pUserParam, AsmHook::PUSHAD_DAT *pReg)
{
	COtherHook	*pThis = (COtherHook *)pUserParam;

#ifdef _WIN64
	gpCodePtrRun = (int *)pReg->rdx;
	codeip = (int)pReg->rax;

	return TRUE;
#endif

	return TRUE;
}

/*
.text:000000014025DE9A 4C 8B 65 38                                mov     r12, [rbp+5D0h+script]
.text:000000014025DE9E 4C 8B 75 18                                mov     r14, [rbp+5D0h+p_stack]
.text:000000014025DEA2 E9 49 93 FF FF                             jmp     loc_1402571F0
.text:000000014025DEA7                            ; ---------------------------------------------------------------------------
.text:000000014025DEA7
.text:000000014025DEA7                            loc_14025DEA7:                          ; CODE XREF: GDScriptFunction__call+A45↑j
.text:000000014025DEA7 48 8D 42 FC                                lea     rax, [rdx-4]
*/
BOOL	COtherHook::HookGDScript_CodeIp()
{
	BOOL	bRetVal;

	bRetVal = m_pMgr->HookItem(Hook_GDScript_CodeIp, this, &Info_GDScript_CodeIp, 0, "4C8B65384C8B7518E94993FFFF488D42FC");
	return TRUE;
}

实际修改值在 Variant__SetVal, 如游戏中gold修改
判断条件:

  1. 修改的值类型 double
  2. 当前的ip
  3. 当前ip的代码片段hash
AsmHook::HOOK_INFO	Info_Variant__SetVal;
BOOL WINAPIV Hook_Variant__SetVal(VOID *pUserParam, AsmHook::PUSHAD_DAT *pReg)
{
	COtherHook	*pThis = (COtherHook *)pUserParam;
	static	void *	DbgPtr = (void *)0x16059768;
#ifdef _WIN64
	void		*param64[8];
	void		*backaddr;
	void		*Self, *Value;
	Variant		*pValue, *pSelf;
	DWORD		dwHash;
	double		dAddVal;

	Self = (void *)pReg->rcx;
	Value = (void *)pReg->rdx;

	pSelf = (Variant *)Self;
	pValue = (Variant *)Value;
	if(pSelf->type == Variant::REAL)
	{
		if(DbgPtr == &pSelf->_data._real)
			int ccc = 0;
		if(codeip == 0x0b)
		{
			dwHash = NData::HashData(gpCodePtrRun+codeip, sizeof(int)*16);
			if(dwHash == 0x120ec788)
			{
				dAddVal = pValue->_data._real - pSelf->_data._real;
				if(dAddVal > 0.0)
				{
					dAddVal *= 8;
					pValue->_data._real = pSelf->_data._real + dAddVal;
					NSys::TraceL("Gold add mul 8");;
				}
			}
		}
	}

	return TRUE;
#endif

	return TRUE;
}


/*
.text:0000000141A93090 48 3B CA                                   cmp     rcx, rdx
.text:0000000141A93093 0F 84 73 03 00 00                          jz      locret_141A9340C		//	包含jmp  无法Hook
.text:0000000141A93099 48 89 5C 24 10                             mov     [rsp+arg_8], rbx		//	从这开始Hook
.text:0000000141A9309E 48 89 6C 24 18                             mov     [rsp+arg_10], rbp
.text:0000000141A930A3 56                                         push    rsi
.text:0000000141A930A4 57                                         push    rdi
.text:0000000141A930A5 41 54                                      push    r12
.text:0000000141A930A7 41 56                                      push    r14
.text:0000000141A930A9 41 57                                      push    r15
.text:0000000141A930AB 48 83 EC 40                                sub     rsp, 40h
*/
BOOL	COtherHook::HookVariant__SetVal()
{
	BOOL	bRetVal;

	bRetVal = m_pMgr->HookItem(Hook_Variant__SetVal, this, &Info_Variant__SetVal, 0, 
							   "483BCA0F847303000048895C241048896C241856574154415641574883EC40", NULL, 9);
	return TRUE;
}
posted @ 2024-10-10 10:31  Yofoo  阅读(504)  评论(0)    收藏  举报