文档章节

new 的反汇编解释

村长大神
 村长大神
发布于 2014/06/24 16:59
字数 1192
阅读 346
收藏 7
点赞 0
评论 0
int *p=new int [10];
00408170   push        ebp
00408171   mov         ebp,esp
00408173   push        ecx
00408174   push        1
00408176   mov         eax,dword ptr [cb]
00408179   push        eax
0040817A   call        _nh_malloc (004084e0)
0040817F   add         esp,8
00408182   mov         dword ptr [res],eax
00408185   mov         eax,dword ptr [res]
00408188   mov         esp,ebp
0040818A   pop         ebp
0040818B   ret
//谁能给具体解释下这段反汇编
00401122 89 45 FC             mov         dword ptr [res],eax//把_nh_malloc的返回值给[res]
00401125 8B 45 FC             mov         eax,dword ptr [res]//返回申请内存的指针

不太了解[res]是什么?
还有eax经过这两句不是没有变化么。。
就像r=ax;
ax=r;//这句还需要吗
 
 
3:        int *p=new int [10];
004010E8 6A 28                push        28h//内存的大小10*4
004010EA E8 21 00 00 00       call        operator new (00401110)
004010EF 83 C4 04             搜索add         esp,4

00401110 55                   push        ebp
00401111 8B EC                mov         ebp,esp
00401113 51                   push        ecx
00401114 6A 01                push        1//_nh_malloc参数2
00401116 8B 45 08             mov         eax,dword ptr [cb]
00401119 50                   push        eax//_nh_malloc参数1
0040111A E8 E1 3B 00 00       call        _nh_malloc (00404d00)//调用_nh_malloc申请内存
0040111F 83 C4 08             add         esp,8
00401122 89 45 FC             mov         dword ptr [res],eax//把_nh_malloc的返回值给[res]
00401125 8B 45 FC             mov         eax,dword ptr [res]//返回申请内存的指针
00401128 8B E5                mov         esp,ebp
0040112A 5D                   pop         ebp
0040112B C3                   ret//返回

调用过程可以看成这样:
new[4*10]->_nh_malloc(40, 1)->返回申请的指针

res这个是VC6.0反汇编后给出的变量名,其实它是一个局部变量
push        ecx  //这句就是申请res的内存的 相当sub esp, 4

00401122 89 45 FC             mov         dword ptr [res],eax//把_nh_malloc的返回值给[res]
00401125 8B 45 FC             mov         eax,dword ptr [res]//返回申请内存的指针
为什么会产生产生上面的2句代码?
因为这个是调试模式的编译,代码没有优化,所以才会产生这样的问题
<mov         dword ptr [res],eax> 等于 <res = _nh_malloc(...)>
<mov         eax,dword ptr [res] 等于 <return res;> >void TestClass( void )
99: {
004011C0 push ebp
004011C1 mov ebp,esp
004011C3 sub esp,5Ch
004011C6 push ebx
004011C7 push esi
004011C8 push edi
004011C9 lea edi,[ebp-5Ch]
004011CC mov ecx,17h
004011D1 mov eax,0CCCCCCCCh
004011D6 rep stos dword ptr [edi]
100: Assembly as( 0 ); // Assembly为12字节
004011D8 push 0
004011DA lea ecx,[ebp-0Ch]
004011DD call @ILT+30(Assembly::Assembly) (00401023)
101: char *p = new char[5];004011E2 push 5
004011E4 call operator new (00403840)
004011E9 add esp,4
004011EC mov dword ptr [ebp-18h],eax
004011EF mov eax,dword ptr [ebp-18h]
004011F2 mov dword ptr [ebp-10h],eax
102: const char *pTitle = "notificaiton";
004011F5 mov dword ptr [ebp-14h],offset string "notificaiton" (00429120)
上面红色的为源代码,源代码下面的就是vc6汇编的结果。有几处搞不清,请高手指点迷津:
1) add esp,4 :为什么要将栈指针加4,就算是吧new之后返回的指针值压入栈中,也不是将esp加4,而应该减4.
2) add esp,4 之后的那三句到底在干什么?
3) 为什么在这里看到汇编这样调用new操作符,当我在代码中嵌入这样的汇编时,
__asm
{
push 5
call operator new
}
它就告诉我
D:\Study\C++\TestAssembly\main.cpp(107) : error C2414: illegal number of operands
D:\Study\C++\TestAssembly\main.cpp(107) : error C2400: inline assembler syntax error in 'first operand'; found 'bad token'
D:\Study\C++\TestAssembly\main.cpp(108) : error C2400: inline assembler syntax error in 'opcode'; found 'bad token'
D:\Study\C++\TestAssembly\main.cpp(108) : warning C4405: 'mov' : identifier is reserved word
3)同样的语句mov dword ptr [ebp-14h],offset string "notificaiton"在上面的代码里,我把这句写在自己的内嵌汇编代码中就编译不过呢?
各位路过的大虾们,我的这些CC的问题让大家见笑了,不过还是恳请赐教!函数调用之前与调用之后堆栈指针的值(esp)必须不变。在call operator new之前不是push 5了吗?5是一个int,大小为4字节,因此esp减了4(注意堆栈是倒增长的)。call完了operator new,必须把esp加上4以保持堆栈平衡。
函数的返回值一般放在eax中,因此,add esp 4之后的3句是把new来的指针放到p变量中去。
嵌入汇编有自己的语法,跟纯汇编略有区别,具体请看msdn。call operator new (00403840)
这里 operator new实际上给的是debug信息,并不是真正的函数名004011EC mov dword ptr [ebp-18h],eax
004011EF mov eax,dword ptr [ebp-18h]
004011F2 mov dword ptr [ebp-10h],eax
这三句相当于
1。函数返回的结果生成一个临时变量
2。将临时变量拷贝到目标变量中
比较符合C++的语义,当然C++是允许对这样的语义进行优化的。

operator new并不是最终可以导出的符号,而且C++对名字作适当的调整,而汇编代码并不接受C++的语法,所以很难通过call调用C++的函数,
lz你看到的call operator new 只是编译器根据机器指令计算出call的目标位置,锁定该函数的原始名字,便于调试罢了
 

© 著作权归作者所有

共有 人打赏支持
村长大神
粉丝 162
博文 247
码字总数 638701
作品 0
杭州
程序员
objdump选项解释

PS: 查看汇编的两种常用方式 1 (gdb)dissamble main 2 objdump objdump -x obj 以某种分类信息的形式把目标文件的数据组织(被分为几大块)输出 <可查到该文件的所有动态库> objdump -t obj ...

AlphaJay ⋅ 2010/09/10 ⋅ 0

基于虚拟机的软件保护技术

本文并不打算对vmprotect或其它某款软件安全套件进行深入讨论,而着眼于研究基于虚拟机的软件保护技术的起源、思想和实现。 现有软件保护技术概述 传统的软件保护技术,根据针对对象不同,可...

linuxprobe ⋅ 2016/07/18 ⋅ 0

clang 编译器

由于自己对 clang 的了解也不是很深,这里只对自己平常用的一些命令进行一些适当的解释。 编译生成可执行文件 -o 指定了输出文件的名称 得到 LLVM 字节码文件(不可读字节码文件) -O3: 表示...

衣介书生 ⋅ 01/08 ⋅ 0

nasm示例一:调用syscall打印Hello World

NASM是基于英特尔 x86 架构的汇编与反汇编工具。 syscall是x8664架构中专门做系统调用的指令,可参考syscall 1、示例 foo.nasm内容 编译 运行结果 2、代码解释 2.1、syscall x86平台syscall...

张依帅 ⋅ 06/09 ⋅ 0

第四篇 从goto 说起

MVC的设计任务显然没有完成,不过为了更好的把后续工作做好,此处不得不插播一些其他内容。以拓宽我们对C的学习。 以下说两句鬼话,绝非属于正常教育学习路线: 1、本篇将介绍ARM的工具,利用...

中山野鬼 ⋅ 2012/10/27 ⋅ 11

180302 逆向-抵御静态分析(1)

1625-5 王子昂 总结《2018年3月2日》 【连续第517天总结】 A. 抵御静态分析(1) B. 静态分析是逆向工程中常用的手段。 因此抵御静态分析也是一个很值得深入的话题。 花指令 在反汇编的过程中...

whklhhhh ⋅ 03/22 ⋅ 0

写给 iOS 开发者的 Hopper + lldb 简介

最近,关于 @Steipete 在Radar发布的帖子,笔者看到很多人在问「你是怎么理解那个伪代码的」。笔者想写博客已经有一段时间了,现在正好就此发表第一篇博文。笔者在一个叫 Hopper 的工具上花了...

OneAPM蓝海讯通 ⋅ 2016/03/18 ⋅ 0

SylixOS内存错误排查方法

1.应用程序测试代码 测试代码如程序清单 1.1所示: 程序清单 1.1 #include int main (int argc, char **argv) { sleep(2); volatile int a = (int )0x40; //设置物理地址 printf("value = %x...

深山野老 ⋅ 2017/11/22 ⋅ 0

【原创】objdump 的使用

objdump 是用来查看目标文件或者可执行的目标文件的构成的 GCC 工具。 objdump - display information from object files. objdump -x obj 以某种分类信息的形式把目标文件的数据组织(被分为...

摩云飞 ⋅ 2013/08/05 ⋅ 2

radare2 0.10.2 发布

radare2 0.10.2 发布了,radare2是一款开放源代码的逆向工程平台,它可以反汇编、调试、分析和操作二进制文件。 一些提升: Add and shortcuts to simplify loading rarun2 profiles and us...

oschina ⋅ 2016/04/12 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Boot整合模板引擎thymeleaf

项目结构 引入依赖pom.xml <!-- 引入 thymeleaf 模板依赖 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId......

yysue ⋅ 10分钟前 ⋅ 0

ConstraintLayout使用解析

AndroidStudio3.0创建Project默认的布局就是ConstraintLayout。 AndroidStudio3.0前的可以自己修改,使用ConstraintLayout。 为了要使用ConstraintLayout,我们需要在app/build.gradle文件中...

_OUTMAN_ ⋅ 22分钟前 ⋅ 0

OSChina 周三乱弹 —— 这样的女人私生活太混乱了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 胖达panda :你经历过体验到人生的大起大落吗?我一朋友在10秒内体验了,哈哈。@小小编辑 请点一首《almost lover》送给他。 《almost love...

小小编辑 ⋅ 55分钟前 ⋅ 9

自己动手写一个单链表

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源。 一、概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对...

公众号_好好学java ⋅ 今天 ⋅ 0

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部