IDA反编译器的使用 您所在的位置:网站首页 ida如何将汇编语言翻译成c语言 IDA反编译器的使用

IDA反编译器的使用

2023-07-30 17:44| 来源: 网络整理| 查看: 265

   IDA反编译器,正如IDA官网所说,虽然还原出来的代码不能直接使用,但是其参考作用不容否认。这里记录一些反编译时会用到的功能。

1.生成伪代码:

view-Open subviews-Generate pesudocode (快捷键F5)

->

(F5前后对比图)

2.伪代码切换到对应的反汇编代码:

前面说了,IDA生成的伪代码不可全信。当怀疑伪代码的正确性时,需要返回到反汇编代码对比。但是有别于IDA view和Hex view窗口,两者是同步定位的关系,Pseudocode和IDA view窗口之间不存在这样的关系。可以通过Jump-Jump to pseudocode (快捷键)跳回到对应的源码

3.修改变量(函数)名:

除非有pdb文件,否则反编译器生成的变量名/函数名简直惨不忍睹,这时候需要修改变量名。在变量上右键-Rename lvar-在Please enter a string对话框中输入变量名 (快捷键N),修改函数名同理。修改后,伪代码中所有使用该变量的地方都跟着被修正了。

->

(修改函数名/变量名前后)

4.修改变量类型:

如下面源码中,main函数中定义了字符串数组,并进行了初始化。

int main(int /*argc*/, char * /*argv*/[]) { int ret = 0; unsigned char result[32] = { 0 }; ... }

根据反汇编经验数组的初始化在反汇编代码中会以为数组元素赋值的形式实现。但是反编译器不能区分是普通变量初始化还是数组元素赋值,所以经常出错。下面是反编译器提供的伪代码:

int __cdecl main(int argc, const char **argv, const char **envp) { unsigned int j; // [esp+D0h] [ebp-4Ch] unsigned int i; // [esp+DCh] [ebp-40h] char Buf1; // [esp+E8h] [ebp-34h] int v7; // [esp+E9h] [ebp-33h] int v8; // [esp+EDh] [ebp-2Fh] int v9; // [esp+F1h] [ebp-2Bh] int v10; // [esp+F5h] [ebp-27h] int v11; // [esp+F9h] [ebp-23h] int v12; // [esp+FDh] [ebp-1Fh] int v13; // [esp+101h] [ebp-1Bh] __int16 v14; // [esp+105h] [ebp-17h] char v15; // [esp+107h] [ebp-15h] int ret; // [esp+110h] [ebp-Ch] ret = 0; Buf1 = 0; v7 = 0; v8 = 0; v9 = 0; v10 = 0; v11 = 0; v12 = 0; v13 = 0; v14 = 0; v15 = 0;

这样的伪代码与真实代码相去甚远,因此,需要将字符型变量v15修改成数组。在变量上右键-set lvar type-please enter a string中输入变量的新类型,下面是修正后的代码:

int __cdecl main(int argc, const char **argv, const char **envp) { unsigned int j; // [esp+D0h] [ebp-4Ch] unsigned int i; // [esp+DCh] [ebp-40h] char result[32]; // [esp+E8h] [ebp-34h] int ret; // [esp+110h] [ebp-Ch] ret = 0; result[0] = 0; *(_DWORD *)&result[1] = 0; *(_DWORD *)&result[5] = 0; *(_DWORD *)&result[9] = 0; *(_DWORD *)&result[13] = 0; *(_DWORD *)&result[17] = 0; *(_DWORD *)&result[21] = 0; *(_DWORD *)&result[25] = 0; *(_WORD *)&result[29] = 0; result[31] = 0; 5.转换为指针/结构体指针:

在x86机器上,整形变量和(结构体)指针变量占用的地址空间相同,所以,反编译器经常会混淆两者。如下面源码中,函数原型为:

void md5_final(md5_ctx *ctx, const unsigned char *buf, size_t size, unsigned char *result);

而反编译器生成如此不伦不类的函数原型:

void *__cdecl md5_final(int a1, char* a2, size_t a3, char* *a4) { unsigned int v4; // STFC_4 int v5; // STF0_4 signed __int64 v6; // rax unsigned int v8; // [esp+F0h] [ebp-54h] int Dst[14]; // [esp+FCh] [ebp-48h] int v10; // [esp+134h] [ebp-10h] int v11; // [esp+138h] [ebp-Ch]

对于基本类型指针,做法同4.修改变量类型,不再赘述;

对于非基本类型指针,为了将int变量修正为结构体指针变量,可以在变量定义处右键-convert to struct*-Select a structure,(如果是自定义的结构体,需要在IDA Structures窗口中创建该结构体,否则该结构体不会出现在"Select a structure"列表中)

最终生成如下伪代码:

void *__cdecl md5_final(md5_ctx *a1, char *a2, size_t a3, char *a4) { unsigned int v4; // STFC_4 int v5; // STF0_4 __int64 v6; // rax unsigned int v8; // [esp+F0h] [ebp-54h] int Dst[14]; // [esp+FCh] [ebp-48h] int v10; // [esp+134h] [ebp-10h] int v11; // [esp+138h] [ebp-Ch]

如果想撤回修改,将结构体指针变回整形变量,只要在变量上右键-Reset pointer type即可。

6.变量映射:

IDA生成的伪代码中变量满天飞,特别是参与大量计算的代码片。很多变量是中间变量,由反编译器生成的,并不存在于真正的源码中。这些中间变量的存在,多少会影响我们分析源码,所以我们要把这些中间变量映射到其他变量上。

如下面的源码:

static void md5_final(md5_ctx *ctx, const unsigned char *buf, size_t size, unsigned char *result) { ... uint32_t index = ((uint32_t)ctx->length_ & 63) >> 2; uint32_t shift = ((uint32_t)ctx->length_ & 3) * 8; //添加0x80进去,并且把余下的空间补充0 message[index] &= ~(0xFFFFFFFF hash_, message); index = 0; }

然而,经过IDA的反编译,生成若干中间变量:

void *__cdecl md5_final(md5_ctx *a1, char *a2, size_t a3, char *a4) { ... v4 = (unsigned __int64)(ctx->length & 0x3F) >> 2; v5 = 8 * (ctx->length & 3); message[v4] &= ~(-1


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有