首页
社区
课程
招聘
[原创]一次美丽的误会引发对函数调用保护的思考
发表于: 2019-8-9 17:52 6415

[原创]一次美丽的误会引发对函数调用保护的思考

2019-8-9 17:52
6415

各位大佬请指正,一时思考,并未做更多详细研究。

很久没碰wx了,最近想写个东西,就重新拿了起来,最新版本2.6.8.65(此时已经2.6.8.68)。

找到以前分析过的发送文本消息接口,发现函数大变样,很明显的vm痕迹。

当时也没在意,仔细看接口参数并没有变化,就直接拿来用了。

结果发现接口不能用了,并没有成功发送文本信息。

擦,难道vm里面藏了什么玄机,做了防止函数调用的保护??

...

正整备大干一场的时候,重新测试给别人发送消息是ok的。

这是一次美丽的误会,测试时是给自己的微信发送消息,结果证明该接口是不能给自己发的,所以没成功。

...

然后就继续说说先前自以为的wx在函数中可能做的防止调用的保护吧。

按照自己思考的防止别人调用函数的思路,其实就是检查调用源,那么肯定是从调用栈入手:

大概实现代码就是:

所以能够想到的对抗方式就是在调用TestAntiCall的时候,修改调用栈返回地址,让TestAntiCall误以为确实是正常调用。

这里分析只考虑检查一层返回地址。

比如如下正常调用代码,00003就是返回地址,在合法模块内,即可正常调用。

而我的调用TestAntiCall函数(在我的模块内)如下,add esp, 4;为TestAntiCall拿到的返回地址,这个地址肯定在我的模块内,调用失败。

然后尝试欺骗TestAntiCall,我们修改一下调用栈的返回地址(本来应该是MyRetAddr)。

通过push+jmp来替换通常的call,这样返回地址由我们自己压入,这里压入正常调用的返回地址g_SendTextMsgRetAddr

当然,就这么简单的调用,肯定会出问题的,因为jmp pfnWxSendTextMsg之后,就会返回到Right_TestAntiCall00003,如此显然导致栈破坏,会出现崩溃。

所以为了让程序正常执行,还需要多两个处理步骤。

为了拿到MyRetAddr的地址,通过call+pop的方法完成,如下:

上面拿到retaddr和MyRetAddr明显不是同一个,所以在fakeAntiTestCall中减去一个偏移24拿到MyRetAddr

偏移值通过下面的字节码可以计算出来10024E1E - 10024E06 = 24。

如此可以正常完成一次调用,但是还有问题,因为会反复修改Right_TestAntiCall的指令,可能在多线程中执行时出现问题。

所以更好的方法时在Right_TestAntiCall的模块中找一个不用(零值)的内存,用来保护临时指令,不细讲了,大家自行探索吧。

(完)

欢迎关注:汉客儿

 
 
 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (2)
雪    币: 2223
活跃值: (85)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
  
2019-8-10 15:52
0
雪    币: 4749
活跃值: (4296)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
呦西好东西非常感谢
2019-8-17 04:41
0
游客
登录 | 注册 方可回帖
返回
//