反汇编奇怪代码,利用指令地址定位全局变量

原创 2015年11月20日 17:39:26

全局变量的地址是已知的,所以我们一般就直接用全局变量的地址对其访问,或许为了阻碍反汇编,今天就遇到了这样一个例子。

首先看一个函数:

.text:00077464 sub_77464       proc near              
.text:00077464                 nop
.text:00077465                 nop
.text:00077466                 nop
.text:00077467                 nop
.text:00077468                 nop
.text:00077469                 nop
.text:0007746A                 nop
.text:0007746B                 nop
.text:0007746C                 mov     ebx, [esp+0]
.text:0007746F                 retn
.text:0007746F sub_77464       endp

nop指令是空指令,不用管他。

当某一函数A调用(call)这个sub_77464时,栈顶保存的是函数A中call指令的下一条指令的地址。所以mov ebx, [esp+0](+0似乎也是为了妨碍反编译)就取得了指令地址。

函数A中就可以利用ebx来定位全局变量了,比如:

.text:002E5250                 push    ebp
.text:002E5251                 push    edi
.text:002E5252                 push    esi
.text:002E5253                 push    ebx
.text:002E5254                 call    sub_77464       ; [esp] -> ebx
.text:002E5254                                         ; 用EIP(下一指令地址)来定位全局变量
.text:002E5259                 add     ebx, 452D9Bh    ; E
.text:002E525F                 lea     esp, [esp-52Ch]
.text:002E5266                 mov     eax, [esp+53Ch+arg_18]
.text:002E526D                 mov     edx, [esp+53Ch+arg_0]
.text:002E5274                 mov     [esp+53Ch+var_510], eax
.text:002E5278                 mov     eax, [esp+53Ch+arg_30]
.text:002E527F                 mov     [ebx+0EA4h], eax ; A
.text:002E5285                 mov     eax, [ebx-898h] ; B
.text:002E528B                 mov     [ebx+99654h], edx ; C
.text:002E5291                 mov     eax, [eax]
.text:002E5293                 test    al, 2
.text:002E5295                 mov     [esp+53Ch+var_51C], eax
.text:002E5299                 jz      loc_2E540A
.text:002E529F                 lea     eax, [ebx-22E509h] ; D
.text:002E52A5                 mov     [esp+53Ch+name], eax ; name
.text:002E52A8                 call    _opendir
.text:002E52AD                 xor     esi, esi
.text:002E52AF                 test    eax, eax
.text:002E52B1                 mov     ebp, eax
.text:002E52B3                 jnz     loc_2E53BE
.text:002E52B9                 jmp     loc_2E53FE

A、B、C、D、E处就用ebx来得到全局变量的地址。特别是E处,似乎也能起到阻碍反编译的效果。后面的大数字会被误认为是地址,然后其所指的目标就会被认为是数据,若一不小心是代码,那么就无法正确生成函数了。


可惜道高一尺,魔高一丈,IDA已经看破了这一招,一下是IDA整理出的代码:

.text:002E5250                 push    ebp
.text:002E5251                 push    edi
.text:002E5252                 push    esi
.text:002E5253                 push    ebx
.text:002E5254                 call    sub_77464       ; [esp] -> ebx
.text:002E5254                                         ; 用EIP(下一指令地址)来定位全局变量
.text:002E5259                 add     ebx, (offset loc_452D9A+1)
.text:002E525F                 lea     esp, [esp-52Ch]
.text:002E5266                 mov     eax, [esp+53Ch+arg_18]
.text:002E526D                 mov     edx, [esp+53Ch+arg_0]
.text:002E5274                 mov     [esp+53Ch+var_510], eax
.text:002E5278                 mov     eax, [esp+53Ch+arg_30]
.text:002E527F                 mov     (dword_738E98 - 737FF4h)[ebx], eax
.text:002E5285                 mov     eax, ds:(off_73775C - 737FF4h)[ebx]
.text:002E528B                 mov     ds:(dword_7D1648 - 737FF4h)[ebx], edx
.text:002E5291                 mov     eax, [eax]
.text:002E5293                 test    al, 2
.text:002E5295                 mov     [esp+53Ch+var_51C], eax
.text:002E5299                 jz      loc_2E540A
.text:002E529F                 lea     eax, (aProc - 737FF4h)[ebx] ; "/proc"
.text:002E52A5                 mov     [esp+53Ch+name], eax ; name
.text:002E52A8                 call    _opendir
.text:002E52AD                 xor     esi, esi
.text:002E52AF                 test    eax, eax
.text:002E52B1                 mov     ebp, eax
.text:002E52B3                 jnz     loc_2E53BE
.text:002E52B9                 jmp     loc_2E53FE



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C++ 重写重载重定义区别

重载overload:是函数名相同,参数列表不同 重载只是在类的内部存在。但是不能靠返回类型来判断。 重写override:也叫做覆盖。子类重新定义父类中有相同名称和参数的虚函数。函数特征相同。但是...

计算机系统内的字长到底指的是什么?

字长:CPU一次操作可以处理的二进制位数, 1字长 = 1 bit 字长越大,CPU运算能力越牛逼 举例子 一个字长是8的cpu,一次能进行不大于1111,1111 (8位) 的运算...

五子棋AI算法第二篇-极大极小值搜索算法

AI实现的基本思路-极大极小值搜索算法五子棋看起来有各种各样的走法,而实际上把每一步的走法展开,就是一颗巨大的博弈树。在这个树中,从根节点为0开始,奇数层表示电脑可能的走法,偶数层表示玩家可能的走法。...

使用IDA远程调试APK中的so,学习笔记

一、准备设备     1.打开设备的USB调试模式     2.复制android_server文件到设备上。此文件在IDA目录下dbgsrv文件夹中     3.设备连接到电脑。 二...

C++拷贝构造函数和赋值运算符根本的不同

首先要说明的是,若用户没有定义,C++隐式声明一个拷贝构造函数和一个赋值运算符(完成按数据成员复制的动作)。二者很像,但是在下边这点上有很大的不同:拷贝构造函数是只在对象实例化时才会被调用,也就是说,...

C++ 浮点数(double、float)如何定义NaN、正无穷、负无穷,以及如何判断是否是NaN

浮点数的标准可以看百度百科:http://baike.baidu.com/view/1698149.htm   NaN :阶码的每个二进制位全为1  并且  尾数不为0; 无穷:阶码的每个二进制位全为...
  • PDD123
  • PDD123
  • 2014-12-01 10:45
  • 4918

深入理解C++浮点数(float、double)类型数据比较、相等判断

浮点数在内存中的存储机制和整型数不同,其有舍入误差,在计算机中用近似表示任意某个实数。具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基...

C++反汇编九(全局变量与局部变量)

00401020 push ebp 00401021 mov ebp,esp 00401023 sub esp,44h 00401026 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)