gpt4 book ai didi

c++ - 逆向工程得到函数原型(prototype)

转载 作者:行者123 更新时间:2023-12-01 14:30:12 26 4
gpt4 key购买 nike

我正在尝试获取 asm 函数的原型(prototype),以便从我注入(inject)的 c++ dll 中调用它。

函数如下:

PUSH EBP
MOV EBP,ESP
PUSH -1
PUSH Program.0151A5BB
MOV EAX,DWORD PTR FS:[0]
PUSH EAX
SUB ESP,0F8
MOV EAX,DWORD PTR DS:[167D380]
XOR EAX,EBP
MOV DWORD PTR SS:[EBP-14],EAX
PUSH EBX
PUSH ESI
PUSH EDI
PUSH EAX
LEA EAX,DWORD PTR SS:[EBP-C]
MOV DWORD PTR FS:[0],EAX
MOV DWORD PTR SS:[EBP-10],ESP
MOV EDI,EDX
MOV ESI,ECX
MOV DWORD PTR SS:[EBP-4],0
CMP ESI,0FFFF
JE SHORT Program.0117DFC9
CALL Program.01205130
MOV ECX,82
CALL Program.012F2AE0
MOV ECX,ESI
CALL Program.012F3050
MOV ECX,EDI
CALL Program.012F3050
MOV ECX,DWORD PTR SS:[EBP+8]
CALL Program.012F2EA0
MOV ECX,DWORD PTR SS:[EBP+C]
CALL Program.012F3050
MOV ECX,DWORD PTR SS:[EBP+10]
CALL Program.012F2EA0
MOV ECX,DWORD PTR SS:[EBP+14]
CALL Program.012F2EA0
MOV CL,1
CALL Program.012F39B0
MOV DWORD PTR SS:[EBP-4],-1
MOV ECX,DWORD PTR SS:[EBP-C]
MOV DWORD PTR FS:[0],ECX
POP ECX
POP EDI
POP ESI
POP EBX
MOV ECX,DWORD PTR SS:[EBP-14]
XOR ECX,EBP
CALL Program.014BB1AC
MOV ESP,EBP
POP EBP
RETN

这里是调用这个函数的例子

JMP Program.001CDD83
CALL Program.000930A0
MOV ECX,EAX
CALL Program.0024EC10
PUSH EAX ; /Arg4
PUSH DWORD PTR SS:[EBP-168] ; |Arg3
PUSH DWORD PTR DS:[EDI+8] ; |Arg2
PUSH DWORD PTR SS:[EBP-160] ; |Arg1
MOV EDX,DWORD PTR SS:[EBP-16C] ; |
MOV ECX,DWORD PTR SS:[EBP-164] ; |
CALL Program.0006DF80 ; \<---- TARGET FUNCTION
ADD ESP,10
JMP Program.001CDD83
TEST EAX,800
JE SHORT Program.001CDF6D
TEST ESI,ESI
JE Program.001CDD83
CMP ESI,DWORD PTR DS:[72202C]
JE Program.001CDD83
CMP ESI,DWORD PTR DS:[584684]

通过函数调用,我能够推断出这是一个__fastcall 函数,因为它使用EDXECX 寄存器并且它需要4通过堆栈的附加参数。

在调用时检查堆栈和寄存器,我可以确定所有 6 个参数都是数字。

这是函数调用中的状态图片。

Registry and stack at the moment of the call

考虑到所有这些,我做出了这个定义

typedef void(__fastcall *_programFunction)(DWORD ECX, DWORD EDX, DWORD param1, DWORD param2, DWORD param3, DWORD param4);

它调用函数,函数在我的目标程序中有效但我的 DLL 崩溃显示此错误:

调试错误!运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是用一个调用约定声明的函数调用一个以不同调用约定声明的函数指针的结果。"

我很确定这是一个 __fastcall 函数,因为它是唯一一个在堆栈上优先考虑 EDXECX 的函数。加上调用函数没有清理堆栈,这是 __fastcall

的另一个提示

有什么技巧可以从 asm 代码中推导出函数 protptype 吗?

我的想法有问题吗?

谢谢!!

编辑:

我检查了 ma​​inactual 说的

ADD ESP, 10 after your function call seems more __cdecl to me: the caller cleans the stack. If it were a __fastcall you should find RET 10 at the end. –

当我将前两个参数手动添加到 ECXEDX 寄存器时,它会起作用。

像这样

typedef void(__cdecl *_targetFunction)(DWORD param1, DWORD param2, DWORD param3, DWORD param4);


_targetFunction fcall= (_targetFunction)(ADD_TARGET_FUNCTION);
__asm
{
mov ECX, ECX_PARAM
mov EDX, EDX_PARAM
}
fcall(param1, pram2, param3, param4);

谢谢!但为什么我必须这样做?有什么办法可以自动设置寄存器?

谢谢!

最佳答案

由于优化,您偶尔会发现与正常调用约定不完全匹配的函数。

在这种情况下,解决方案是使用您已经在问题中完成的内联汇编:

typedef void(__cdecl *_targetFunction)(DWORD param1, DWORD param2, DWORD param3, DWORD param4);


_targetFunction fcall= (_targetFunction)(ADD_TARGET_FUNCTION);
__asm
{
mov ECX, ECX_PARAM
mov EDX, EDX_PARAM
}
fcall(param1, pram2, param3, param4);

有时候事情就是这样。

关于c++ - 逆向工程得到函数原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36430604/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com