在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
分析下C#中的函数 先写一个小例子,一个静态函数,无返回值,无形参 在第17行与20行分别下断点 F5调试运行,此时中断在第17行MyFunction(), 在第17行右键反汇编,看下反汇编代码 这里的Call 002D0C30 对应用就是MyFunction() 此时F11直接进入MyFunction函数内部查看我们函数 002D2CA0就是MyFunction的入口,这里就有疑问了,明明上面Call 002D0C30,这里为什么是002D2CA0呢? 在地址栏上转到002D0C30,结果VS提示无法指定地址,当前地址处没有代码……Fuck VS 难道我们就这么放弃了吗?NO…换一种方式,用第三方调试器附加我们的控制台程序 一下就明了了,原来执先完call 002D0C30这条语句, 进入的不是我们的函数MyFunction, 而是先是入到002D0C30里,执行jmp 002D2CA0语句,再跳转到真正的MyFunction函数入口. 总结下: call 002D0C30-> 002D0C30 jmp 002D2CA0->002D2CA0(MyFunction真正的函数入口) 接着分析下堆栈,这里能看到的是调用堆栈,而我关心的是当前堆栈的情况 实际上当前堆栈.里压入的是执行完MyFunction()后的返回地址, 也就是第18行代码的地址002D2B00 为了验证,转到寄存器窗口,学过汇编的都知道ESP指针指向的是当前栈顶 Ok,ESP = 06D6EC18, 转到内存处去查看下06D6EC18处是否保存着002D2B00 总结下:当前堆栈栈顶存储的是执行完当前函数后的返回地址. 现在开始进行最后一步,分析下函数里反汇编代码的功能 002D2CA0 push ebp //前面这二句用来保存esp, //sub esp,2Ch 分配堆栈空间, 我们代码是个空函数,没有临时变量, //这里的2Ch空间是供下面VS添加的代码使用的 //这下面是一堆是VS生成的debug代码, release代码就不一样了 002D2CA6 sub esp,2Ch //这后面的代码是当前函数返回时必须要做的堆栈平衡处理 002D2CC0 nop //下面就是依次把入口处后保存的三个寄存器依次从栈中弹出 //ret 把栈顶的返回地址弹出,改变eip,让当前CPU跳转到Main函数中语句MyFunction()下一句代码的地址 002D2CC8 ret 未完待续,后面还有第二篇有返回值有参数的函数分析
|
请发表评论