指针可以和整数互相转换
函数指针可以指向一个函数,它本身不过是一个整数,所以也可以用整数存储函数地址,然后强转成函数指针去调用。
void func(void);//有一个函数
int address = (int)func;//用整数保存其地址
((void(*)())address)();//通过地址调用func
函数指针调用数组中的代码
函数指针还可以帮我们调用数据区中的代码,假设我有一个 int Add(int,int) 函数用于将两个整数相加,我编译后把它的字节码取出来,存到一个数组里,然后用函数指针指向这个数组,就可以调用这个函数做加法了。
#include <Windows.h>
#include <stdio.h>
// 加法函数的字节码
unsigned char code[] =
{
0x55,
0x8B,0xEC,
0x83,0xEC,0x40,
0x53,
0x56,
0x57,
0x8D,0x7D,0xC0,
0xB9,0x10,0x00,0x00,0x00,
0xB8,0xCC,0xCC,0xCC,0xCC,
0xF3,0xAB,
0x8B,0x45,0x08,
0x03,0x45,0x0C,
0x5F,
0x5E,
0x5B,
0x8B,0xE5,
0x5D,
0xC3
};
int main(int argc, char *argv[])
{
// 修改数组内存权限为可执行
DWORD dwOldProtect = NULL;
BOOL bRet = VirtualProtectEx(GetCurrentProcess(), (LPVOID)code, 0x1000,
PAGE_EXECUTE_READWRITE, &dwOldProtect);
if (!bRet)
{
printf("修改内存属性失败,错误码: %d\n", GetLastError());
return 1;
}
typedef int(__cdecl *PFNADD)(int, int);
printf("%d\n", ((PFNADD)&code)(4, 7));
return 0;
}