易语言程序的破解99%的时候都需要用到FF55FC5F5E这个特征码

新建一个MFC应用程序:

去编辑MFC的.rc资源文件来DIY窗体

静态编译的,把很多静态库的代码都添加进去了 ,所以速度很慢
消息机制针对的是GUI程序(比如窗口程序),你点击关闭按钮,会产生一个消息,首先OS捕获这个消息,然后通过user32.dll里面的函数来处理,给你挂到对应进程的消息队列当中(在内核区),然后用户程序的WinMain循环取出消息,
把程序在od当中暂停下来,查看他的调用堆栈,在最上面的函数是最先被调用的
模态对话框的本质就是UI线程阻塞,主线程卡住while(1)等待弹出的对话框返回消息,不然就一直执行弹出的对话框当中的逻辑,直到你点击确定或者关闭,才会break掉这个while(1),主线程才能根据这个返回的结果进行后续的相关处理,如果你觉得这样空跑CPU的话也可以使用PV原语把主线程阻塞:

编写GUI程序的时候,窗体创建出来之后,他里面是有一个死循环的,接收所有和他有关的消息,里面的空间当然也可以给外界发消息

从AFX开始的函数是MFC接收系统消息的函数:


在VS当中如何打开调用堆栈?
先把程序断在自己想要的位置 》调试》窗口》调用堆栈:

从OS的消息派发,一直传递到MFC消息队列,最后传到OnClickBtn
其中最重要的函数就是_AfxDispatchMsg了:
这里强调一下:和Win32程序不同,MFC的消息回调函数是由MFC的其他代码自己调用,而win32的是操作系统的user32模块帮我们调用的

MFC当中所有的按钮事件的函数都会先走到这里,即使在按钮事件当中什么代码都没写:

其中最重要的参数就是pfn!我的好兄弟,这里面直接把函数地址扔给你了!!还不感谢大自然的馈赠!!!😂😂😂:

我们在od当中,直接ctrl+g转到afxdispatchMsg函数

在函数的头部push ebp下断,断下来之后我们直接看他的堆栈,第一个就是返回地址,对于stdcall是从右往左压栈的,然后从堆栈的视角,是从下往上生长的,所以应该从返回地址正着往下数第四个参数就是pfn,实际上od已经帮你标注好了,但是为了防止别人做手脚,我们就用最基本的方法来找pfn

我们可以回到上级调用查看一下,在反汇编窗口中,距离call最近的是第一个参数:

在数据窗口中跟随:

然后我们ctrl+g转到011b8e这个地址,发现果然是按钮事件处理函数:

在C语言代码中,执行以下语句,代表进入按钮事件处理函数了:

特征码提取原则:
1、有call不行,如果有,一律用??替换掉call后面的绝对地址
2、常量不行,如果有,一律用??代替4位绝对地址
注意:
游戏辅助99%需要提取特征码,主要是为了防止游戏更新你可以快速定位到关键位置!这样就不用每次都重新找基址了!!!
特征码的本质就是从茫茫的4GB当中如何快速进入我想要的函数体里面!!!

教你个小技巧:白色划线的就是常量的地址


加上调试信息之后就有了,这从侧面向我们证实了调试符号的重要性!!!

快速查找小技巧:二进制复制》win+r》输入notepad》粘贴

常量:[0x12345678],不行

push 0x123 》立即数,可以
大多情况下别人发布的软件是肯定没有调试信息的,就需要我们把关键函数(按钮点击)/MFC走到按钮事件的afxdispatchmessage函数
在内存m窗口,从头开始搜索,一定能够搜到:
注:内存是程序的所有身家,进程所有的秘密都在这里,只是有可能被加密罢了



然后在反汇编窗口转到这个地址,下断点:

然后找到他的第四个参数,把里面的地址复制出来:


在反汇编窗口转到这个地址:

搜特征码一定从内存窗口里面搜!!!
注意!!!afxdispatchmsg函数只分发按钮事件!!!
重要博弈!!!
①当人们都知道要防按钮事件的时候,我们就需要提取afxdispatch的特征码了,如果人们又都知道afxdispatch了,我们就需要提取pumpmessage的特征码了,进一步推理,我们可以一直跟到afxwinmain甚至要在user32那里开始博弈!!!
②由于所有MFC程序的afxdispatch都一样,所有你提取出来的特征码可以适用于所有的MFC程序,当然release版本是经过优化了,所以还要再单独提取一份
思考:如果对方每次编译生成不同的编码应该怎么办?如果对方重写MFC的接口走自己的消息处理机制应该怎么办?
易语言的调试符号在tools/link.ini位置
取消掉注释+/DEBUG:FULL即可生成pdb文件了



如果有pdb文件的话:
直接秒了,函数名什么的都给你显示出来了
本来别人看不懂你这个call是干什么的,一旦有了函数名就直接秒了

注意:在Debug版本当中,编译的信息都是编译到PE文件当中的,pdb是辅助调试的,有了pdb文件就不用把所有调试信息都放到PE文件当中了,使得exe文件特别大,只要把一小部分调试信息放进去就彳亍了,这就是为什么没有pdb文件od仍然能解析出来一部分调试信息
逆向的本质:研究各种语言底层是怎么实现的,因为那是我们博弈的平台

jmp:增量链接
如何防止别人用ff55fc5f5e拿捏我们?
》加钟,添加时钟可以让ff55fc5f5e一直断下来
如何破解?
》条件断点:[ebp-4]!=0x12345678
一个小案例:
平时我们写寻路call的时候会碰到线程随机崩掉的现象,还找不到原因?
》因为游戏修改全局变量的代码只能在主线程实现
解决方法:
小白:写一堆时钟,不用线程了,把寻路call全部写到时钟里面,而时钟又是在主线程当中执行的,就解决了这个bug
正确解决方案:绑定主线程,使用线程之间通信,在主线程当中写一个循环,你需要用到全局变量就给主线程发消息,在主线程当中回调去执行修改全局变量的代码,不涉及到修改全局变量的代码就在自己的线程当中执行
手动实现窗体的push大法:
ff25这个位置是易语言体
可以使用od的EWND插件,我这边也有源码,如果有需要的同学可以联系我要一下
OKOK,今天就先到这里来,我们下期再见吧!!!💕💕🤞