首页
社区
课程
招聘
VC++调用win32汇编DLL由于ESI寄存器使用不当导致的问题
2021-3-30 10:30 3316

VC++调用win32汇编DLL由于ESI寄存器使用不当导致的问题

2021-3-30 10:30
3316

老夫N久前用win32汇编写的一个与读卡器硬件交互的DLL供上层应用(C#)调用,上线运行一来一直相安无事。
直到昨日,该功能需要提供微型HTTP服务,老夫用C++进行调用win32汇编DLL中的一个导出函数,很简单很简单,但是·一运行,砰,嗝屁,debug下报错如图:

releas下虽不报错但得到的返回数据也会出现莫名问题,不完整,偶尔还直接驾崩,
出现这个问题无外乎想到2个原因:
1、被调用函数本身问题,函数体内出现某些异常导致堆栈平衡被破坏。
2、函数调用约定问题。
先是检查了下调用约定,也确实存在问题,我申明的是:
typedef int(FUN_xxxxxxx)(char);
这样一来VS默认的是cdecl方式,看了下当时汇编的源码是:
.model flat,stdcall
stdcall和cdecl区别这里就不多废话了╮(╯▽╰)╭;就是个由谁来扫尾的区别
随后改成typedef int(
stdcall FUN_xxxxxxx)(char);
在编译运行,卧槽·问题依旧,╮(╯▽╰)╭,当时老夫坐在办公椅上背靠着思索勒许久。
随后打开VS反汇编模式进行调试,一通调试后,最后偶然发现一个细节处
DEBUG模式下注意到有这么一句:
图片描述
比较之前保存在ESI中的原始ESP进行比较,要是不同进行CheckEsp检查就完蛋。
至此明白了,由于老夫在汇编代码中使用结构体时用了ESI寄存器
图片描述

 

随后修正如下:
图片描述
就是在使用ESI之前和之后分别加入PUSH ESI POP ESI来保存恢复ESI
至此,问题解决重新提交版本,通知更新,╮(╯▽╰)╭。
也是提醒,在汇编下使用某些特殊寄存器使用前最好还是push,pop下,以免跨语言使用出现莫名其妙的问题,╮(╯▽╰)╭


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 2418
活跃值: (2282)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dearfuture 2021-3-31 10:28
2
0

win的x86 abi下,esi属于非易失寄存器,编译器如果在函数用到了esi,就会在开头push结尾pop的,包括普通函数中的内联汇编都会自动添加push和pop。但如果是裸函数中的内联汇编或者masm就需要手动添加push和pop

最后于 2021-3-31 10:30 被dearfuture编辑 ,原因:
雪    币: 106
活跃值: (549)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xtayaitak 2021-3-31 13:07
3
0
用汇编写应用,有什么好处吗,为什么不用C或C++
雪    币: 405
活跃值: (1885)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
wowocock 1 2021-3-31 14:16
4
0

几十年前大家都养成了32位下除了EAX,ECX,EDX,都保存得习惯。pushfd pushad ... popad popfd

最后于 2021-3-31 14:17 被wowocock编辑 ,原因:
雪    币: 6124
活跃值: (4051)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
黑洛 1 2021-3-31 16:43
5
0
xtayaitak 用汇编写应用,有什么好处吗,为什么不用C或C++
没那么大容量,只能用汇编
游客
登录 | 注册 方可回帖
返回