平常是否在测试某个游戏中想把一些状态打印出来呢,而用c写hook是否很不高效,每次更改代码又需要重新编译重新注入
下面将介绍一种使用ce lua对函数进行hook,并进行一些复杂的逻辑处理
应用场景:
分支执行
通过参数信息来筛选是否需要hook
通过调用lua后的返回值判断是否需要hook
参数打印
对函数的某个地方进行hook,并打印各种信息
ps:ce lua的接口在CE目录下的main.lua可查看
- 对目标函数(此处以SendMessageA为例子)进行AutoAssemble Code injection
- 编辑{$lua}部分
这里我将函数的各个参数以及函数返回地址打印出来
{$lua}
openLuaServer(“CELUASERVER”)
function myfunction(param) --create a global function called myfunction
print(“this function got called”)
print(“retAddr “…string.format(”%x”, readInteger(param+0x4)))
print(“param1 “…string.format(”%x”, readInteger(param+0x8)))
print(“param2 “…string.format(”%x”, readInteger(param+0xc)))
print(“param3 “…string.format(”%x”, readInteger(param+0x10)))
end
- 编辑{$asm}部分
大部分代码都是CE CodeInjection和Call CE lua function自动生成的
只需手工处理一下传入的参数(在newmem可见)
{$asm}
//…
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
push ebp //ebp保存
mov ebp,esp //ebp初始化
push eax //eax环境保存
push ebp //此处将ebp作为参数传入
push myluascript //函数名称
call LuaFunctionCall //lua调用
pop eax //eax恢复
mov esp,ebp //esp还原
pop ebp //ebp恢复
需注意的是AutoAssemble代码只是一个大致的框架,根据不同的场景需要进行一些调整
- Execute
在Lua Engine处查看控制台输出结果
AutoAssemble的全部代码:
{$lua}
openLuaServer(“CELUASERVER”)
function myfunction(param) --create a global function called myfunction
print(“this function got called”)
print(“retAddr “…string.format(”%x”, readInteger(param+0x4)))
print(“param1 “…string.format(”%x”, readInteger(param+0x8)))
print(“param2 “…string.format(”%x”, readInteger(param+0xc)))
print(“param3 “…string.format(”%x”, readInteger(param+0x10)))
end
{$asm}
//--------Ctrl+L Call CE lua function 自动生成的----------
loadlibrary(luaclient-i386.dll)
luacall(openLuaServer(‘CELUASERVER’))
globalalloc(luainit, 128)
globalalloc(LuaFunctionCall, 128)
label(luainit_exit)
globalalloc(luaserverinitialized, 4)
globalalloc(luaservername, 12)
luaservername:
db ‘CELUASERVER’,0
luainit:
cmp [luaserverinitialized],0
jne luainit_exit
push luaservername //初次调用则会加载lua的dll
call CELUA_Initialize //this function is defined in the luaclient dll
mov [luaserverinitialized],eax
luainit_exit:
ret
LuaFunctionCall:
push ebp
mov ebp,esp
call luainit
push [ebp+c]
push [ebp+8]
call CELUA_ExecuteFunction
pop ebp
ret 8
//luacall call example:
//push integervariableyouwishtopasstolua
//push addresstostringwithfunction //(The lua function will have access to the variable passed by name “parameter”)
//call LuaFunctionCall
//When done EAX will contain the result of the lua function EAX为函数返回值
//--------Ctrl+L Call CE lua function 自动生成的----------
//--------Ctrl+I CodeInjection 自动生成的----------
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)
myluascript:
db ‘myfunction(parameter)’,0
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
push ebp //ebp保存
mov ebp,esp //ebp初始化
push eax //eax环境保存
push ebp //此处将ebp作为参数传入
push myluascript //函数名称
call LuaFunctionCall //lua调用
pop eax //eax恢复
mov esp,ebp //esp还原
pop ebp //ebp恢复
originalcode:
mov edi,edi
push ebp
mov ebp,esp
exit:
jmp returnhere
“USER32.dll”+1B870:
jmp newmem
returnhere:
//--------Ctrl+I CodeInjection 自动生成的----------