searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

反编译技术简介2

2023-07-26 07:36:07
7
0

为了解决局部变量和参数误识别问题,本文引入轻量级虚拟机技术。架构图如下:

        轻量级虚拟机由3部分组成,分别为X86解析器(X86 Parser)、存储单元(storage)和堆栈(stack)。X86解析器解析输入的机器指令,更新堆栈的状态信息。存储单元存储所有会被虚拟机所用到的数据。这些数据包括esp_func和VirtualESP.。esp_func表示的时栈顶指针ESP在进入子程序的值;而virtualESP表示的是esp_func与栈顶指针ESP之间的偏移。由于子程序在执行过程中,ESP的值会发生相应的变化,VirtualESP就是用来表示这种变化。

        X86解析器依次解析输入的各个及其指令,根据指令的不同,更新VirtualESP的值。算法代码如下:

    另外根据__stdcall调用约定(calling covention),被调用的函数在返回前负责恢复堆栈。因此,当调用__stdcall约定的函数时,根据该函数的参数所占堆栈空间大小,对VirtualESP进行恢复操作。如:被调用函数有两个整数型参数,占8字节的堆栈空间,则恢复时,VirtualESP += 8.

    接着,保留每次push的内容到数组中,以VirtualESP的值为索引,每次pop时,同样以VirtualESP为索引,在数组中找出对应push的内容。将其赋值给pop的操作数,这样就可以正确解决通过堆栈空间进行数据传递问题。

    轻量级虚拟机技术识别参数和局部变量算法演示如下:

初始化时,VirtualESP=0;

1.指令1执行后,VirtualESP=-0x30

2.指令2操作dword ptr[esp+0x34],实际上是操作dword ptr[esp_func + virtualESP + 0x34],即dwrod ptr[esp_func + 0x4],参数1。

3.指令3将参数1存放在数组中,索引号为-0x30。push执行后,virtualESP=-0x34.

4.指令4将0x4f00存放在数组中,索引号为-0x34。push执行后,virtualESP=-0x38.

5.指令5将eax存放在数组中,索引号为-0x38。push执行后,virtualESP=-0x3c.

6.指令6与指令2类似,dword ptr[esp+0x24],实际上是dword ptr[esp_func + VirtualESP + 0x24],即dword ptr[esp_func - 0x18],局部变量1.

7.指令8loadIcon函数是stdcall调用约定,根据库函数原型,知道它有2个参数。参数堆栈空间为8个字节。会u发堆栈时,virtualESP加上8,为VirtualESP =-0x34。

8.指令9pop执行后,virtualESP值为-0x30,以此为索引,在数组中查找,得到对应的push内容是参数1。将参数1复制给ecx。

9.指令11执行后,VirtualESP=0。

10.指令12与指令2类似。与指令6是同一个局部变量。

11.函数返回。

至次,分析完毕。

0条评论
作者已关闭评论
陈****标
6文章数
1粉丝数
陈****标
6 文章 | 1 粉丝
陈****标
6文章数
1粉丝数
陈****标
6 文章 | 1 粉丝
原创

反编译技术简介2

2023-07-26 07:36:07
7
0

为了解决局部变量和参数误识别问题,本文引入轻量级虚拟机技术。架构图如下:

        轻量级虚拟机由3部分组成,分别为X86解析器(X86 Parser)、存储单元(storage)和堆栈(stack)。X86解析器解析输入的机器指令,更新堆栈的状态信息。存储单元存储所有会被虚拟机所用到的数据。这些数据包括esp_func和VirtualESP.。esp_func表示的时栈顶指针ESP在进入子程序的值;而virtualESP表示的是esp_func与栈顶指针ESP之间的偏移。由于子程序在执行过程中,ESP的值会发生相应的变化,VirtualESP就是用来表示这种变化。

        X86解析器依次解析输入的各个及其指令,根据指令的不同,更新VirtualESP的值。算法代码如下:

    另外根据__stdcall调用约定(calling covention),被调用的函数在返回前负责恢复堆栈。因此,当调用__stdcall约定的函数时,根据该函数的参数所占堆栈空间大小,对VirtualESP进行恢复操作。如:被调用函数有两个整数型参数,占8字节的堆栈空间,则恢复时,VirtualESP += 8.

    接着,保留每次push的内容到数组中,以VirtualESP的值为索引,每次pop时,同样以VirtualESP为索引,在数组中找出对应push的内容。将其赋值给pop的操作数,这样就可以正确解决通过堆栈空间进行数据传递问题。

    轻量级虚拟机技术识别参数和局部变量算法演示如下:

初始化时,VirtualESP=0;

1.指令1执行后,VirtualESP=-0x30

2.指令2操作dword ptr[esp+0x34],实际上是操作dword ptr[esp_func + virtualESP + 0x34],即dwrod ptr[esp_func + 0x4],参数1。

3.指令3将参数1存放在数组中,索引号为-0x30。push执行后,virtualESP=-0x34.

4.指令4将0x4f00存放在数组中,索引号为-0x34。push执行后,virtualESP=-0x38.

5.指令5将eax存放在数组中,索引号为-0x38。push执行后,virtualESP=-0x3c.

6.指令6与指令2类似,dword ptr[esp+0x24],实际上是dword ptr[esp_func + VirtualESP + 0x24],即dword ptr[esp_func - 0x18],局部变量1.

7.指令8loadIcon函数是stdcall调用约定,根据库函数原型,知道它有2个参数。参数堆栈空间为8个字节。会u发堆栈时,virtualESP加上8,为VirtualESP =-0x34。

8.指令9pop执行后,virtualESP值为-0x30,以此为索引,在数组中查找,得到对应的push内容是参数1。将参数1复制给ecx。

9.指令11执行后,VirtualESP=0。

10.指令12与指令2类似。与指令6是同一个局部变量。

11.函数返回。

至次,分析完毕。

文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0