int (*MakePacketBuffer)(const char * buf, int len, const char * splitstr, ...);
#define MakePacketBufferProto int (*)(const char *, int, const char *, ...)
我想像的是参数,在Ida Pro中实际上是这样显示的:int sub_66EEF0(int a1, int a2, const char *a3, ...)
如何在Ida中调用该函数:
sub_66EEF0(buf, 2048, "%c%c%c%c%s%c%c", v15, 250, v20, v21, v22, v23, v25);
#1 楼
您需要了解编译器如何生成函数。对于使用MSVC编译的32位Windows应用程序,由于所有参数都在堆栈上传递,因此您的工作会变得轻松一些。 Windows:----------------
Return Address
----------------
Argument #0
----------------
Argument #1
----------------
Argument #2
----------------
....
vararg例程仍然如此。这是一个简单的示例,向您展示如何获取附加值。如果您拦截诸如
printf
之类的东西,就会遇到的问题是,您必须解析格式字符串才能知道已向您传递了多少个参数。#include <stdio.h>
#include <windows.h>
#include <intrin.h>
#define print(x) printf("%10s: %x\n", #x, x)
void fn(int a, int b, ...) {
void ** Stack = (void**) _AddressOfReturnAddress();
print(Stack); // Address of SP upon function entry
print(Stack[0]); // Return address
print(Stack[1]); // a
print(Stack[2]); // b
print(Stack[3]); // vararg 1
};
void main() {
fn(1,2,3,4,5,6);
}
打印出:
Stack: 101feac
Stack[0]: ce10a4
Stack[1]: 1
Stack[2]: 2
Stack[3]: 3
#2 楼
不必知道参数的数量。实际上,参数的数量受常数限制(否则程序将需要无限的内存:)。
因此,您可以使用16个实参声明一个钩子函数,打印这些实参,并使用相同的16个实参调用原始函数。如果代码中断,则将args的数量加倍。
typedef unsigned long DW;
#define DW_MANYARGS DW arg1,DW arg2,DW arg3,DW arg4,DW arg5,DW arg6,DW arg7,DW arg8
#define MANYARGS arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8
DW hookFunc(DW_MANYARGS) {
// we do not expect a quadruple-word result here
DW res = originalFunc(MANYARGS);
return res;
}
注意事项:
不要忘记返回原始函数返回的内容。
请记住,有两个隐藏的参数:
0)如果返回值不适合int的大小,则返回值的地址;
1)
this
指针
评论
您必须使用MS Detours吗?知道函数的序言也将有很大帮助(因编译器而异)你为什么不能钩住这个?如果您知道函数的地址,则可以绕过它并获得控制权。但是,如果没有诸如“撤消”该功能和绕开返回地址之类的技巧,您可能无法随后恢复执行,因为该功能的序言可能不合适(如@Ditmar所暗示)。
您做了什么尝试来钩住它?
您是在尝试将功能钩入,移出还是同时钩挂?