本文所提到的所有观点均来自个人理解体会,技术指导:易道云tiger
使用C++语言调用游戏函数,关键点就两个,一个是要把他函数仿照出来,一个是找一个位置调用。
其实到这里我也知道之前在疑问笔记里提出的“为什么分析一个函数要‘参数’,‘返回值’,‘调用约定’三大件”问题的答案了,因为我们想要把这个函数模仿出来,就必然的需要这些内容。
以下面地址6DA8B3这个函数为例:他的三大件就是参数:“void*”,返回值:“某结构体或类指针”返回值,调用约定:“thiscall”。
当然返回值是怎么得到“某结构体或类指针”这个结论的,还需要到eax所指向的内存分析,这里略过。
下面是对函数的仿照:
typedef class Res
{
// 定义函数指针
typedef psro_string(Res::*PROC_WCHAR1)(wchar_t*);
public:
// 函数指针实例
static PROC_WCHAR1 _ReadTitle;
}*PRes;
ps:参数是怎么分析出是wchar_t*类型的需要到函数内部去看,略过
有了上面的代码之后,我们还需要给_ReadTitle初始化。因为我们是要调用别人写好的函数,所以使用typedef定义函数指针,而不是函数类型。把_ReadTitle赋值成函数对应的地址,即9A46C0(地址见图一)。完成这样的操作之后,一旦我们在自己的代码里(已经完成注入的)调用_ReadTitle,线程就会跑到_ReadTitle所指向的VA去执行。
关于仿照函数这个步骤,以前用汇编调用函数换成用C++代码调用函数的时候,老师怎么教我就怎么写,你如果问我为什么要仿照人家函数,我自己思考也应该能想出来,但是始终没有理解深刻。就好比小时候读“举头望明月,低头思故乡”,我张口就来的“表达了作者的思乡之情”,但是真正有一天我开始外出求学,某一天夜里站在阳台,恰好月光皎洁,恰好凉风吹过脖颈我打个寒战,一瞬间才体会到,哦,原来这才是举头望明月,低头思故乡。
所以对于新知识的理解,向来都是纸上得来终觉浅,绝知此事要躬行。从书本上学来的原理永远不及自己冥思苦想最后的明悟更加深刻。
以上是笔者个人的心得体会,如有纰漏还请不吝指教。