是否有 IDA 脚本/插件可以将指令翻译/注释为/使用伪代码?

逆向工程 艾达 拆卸 反编译器
2021-06-23 16:08:57

我不是要反编译器,因为我知道它不会一直产生准确的结果。我试过谷歌搜索,但我发现的只是反编译器。

问题

我发现不断参考指令集手册来找出各种不常见的指令是非常低效的。此外,我很少处理汇编,而且我发现我必须不断有意识地努力解释助记符语法,这极大地减慢了速度。

要求

汇编指令的每行翻译。作为一个非常简单的例子,在反汇编视图中替换add eax, ebxeax += ebx,或者只是用伪代码注释指令。无论是替换还是注释,将伪代码内联将有助于保留 IDA 提供的图形视图和其他方便的功能。

2个回答

您可以auto-comment在 IDA 中启用该选项,以获得如下内容:

在此处输入图片说明

或者也试一试snowman,一个 IDA Pro 的免费反编译器,它能够转换这个编译后的程序:

#include <stdio.h>

int main() {
        printf("Hello, World!\n");
        return 0;
}

进入

int64_t main() {
    puts("Hello, World!");
    return 0;
}

这是一个不完整的脚本,用于 x86:

#include <idc.idc>
/*
    Project name: Pseudo instruction adder 1.0

    Author: fastman92
*/

#define true 1
#define false 0


#define ARCHITECTURE_TYPE_X86 1
#define ARCHITECTURE_TYPE_X64 2

extern architectureType;
extern pointerSize;

static MakeInstructionComment_x86(ea)
{
    auto mnem = GetMnem(ea);

    auto op0 = GetOpnd(ea, 0);
    auto op1 = GetOpnd(ea, 1);

    auto comment = "";

    if(mnem == "push")
        comment = sprintf("ESP -= 4; *(int32_t*)ESP = %s;", op0);
    else if(mnem == "mov")
        comment = sprintf("%s = %s;", op0, op1);
    else if(mnem == "lea")
        comment = sprintf("%s = address(%s);", op0, op1);
    else if(mnem == "jmp")
        comment = sprintf("goto %s;", op0);
    else if(mnem == "pop")
        comment = sprintf("%s = *(int32_t*)ESP; ESP += 4;", op0);
    else if(mnem == "leave")
        comment = "EBP = *(int32_t*)ESP; ESP += 4;";
    else if(mnem == "retn")
        comment = "return;";
    else if(mnem == "sub")
        comment = sprintf("%s -= %s;", op0, op1);
    else if(mnem == "shr")
        comment = sprintf("%s = %s >> %s;", op0, op0, op1);
    else if(mnem == "shl")
        comment = sprintf("%s = %s << %s;", op0, op0, op1); 
    else if(mnem == "and")
        comment = sprintf("%s &= %s;", op0, op1);
    else if(mnem == "or")
        comment = sprintf("%s |= %s;", op0, op1);
    else if(mnem == "xor")
        comment = sprintf("%s ^= %s;", op0, op1);
    else if(mnem == "not")
        comment = sprintf("%s = ~%s;", op0, op0);
    else if(mnem == "cmp")
        comment = sprintf("EFL = cmp(%s, %s);", op0, op1);
    else if(mnem == "test")
        comment = sprintf("EFL = test(%s, %s);", op0, op1);

    else if(mnem == "jnb")
        comment = "goto, if A >= B;";
    else if(mnem == "jz")
        comment = "goto, if A == B;";
    else if(mnem == "jnz")
        comment = "goto, if A != B;";
    else if(mnem == "jb")
        comment = "goto, if A < B;";
    else if(mnem == "jbe")
        comment = "goto, if A <= B;";
    else if(mnem == "jl")
        comment = "goto, if A < B;";
    else if(mnem == "ja")
        comment = "goto, if A > B;";
    else if(mnem == "js")
        comment = "goto, if A < 0;";


    else if(mnem == "pusha")
        comment = "saveAllGeneralRegisterValues()";
    else if(mnem == "popa")
        comment = "restoreAllGeneralRegisterValues()";

    else if(mnem == "stc")
        comment = "setCarryFlag();";
    else if(mnem == "clc")
        comment = "clearCarryFlag();";
    else if(mnem == "cmps")
        comment = "memcmp;";
    else if(mnem == "movs")
        comment = "memset;";

    else if(mnem == "nop")
        comment = ";";

    else if(mnem == "call")
        comment = sprintf("call %s", op0);  
    else if(mnem == "inc")
        comment = sprintf("%s++;", op0);
    else if(mnem == "dec")
        comment = sprintf("%s--;", op0);
    else if(mnem == "add")
        comment = sprintf("%s += %s;", op0, op1);
    else
    {
        // Message("unknown: 0x%X mnem: %s\n", ea, mnem);
        return true;
    }

    MakeComm(ea, comment);

    // Message("0x%X: %s\n", ea, comment);
    return true;
}

static MakeInstructionComment(ea)
{
    if(architectureType == ARCHITECTURE_TYPE_X86)
        return MakeInstructionComment_x86(ea);      
}

static main()
{
    architectureType = ARCHITECTURE_TYPE_X86;

    if(architectureType == ARCHITECTURE_TYPE_X86)
    {
        pointerSize = 4;
    }


    Message("Start of pseudo instruction adder by fastman92\n");

    auto seg, loc;

    Message("========================================\n");

    seg = FirstSeg();   // Get address pointed by a first segment

    auto shouldBreak = false;

    while(seg != BADADDR )
    {   
        Message("----------------------------------------\n");

        loc = SegStart(seg);        

        Message("Adding pseudo code comments in segment %s\n", SegName(seg));


        while(loc != BADADDR && loc < SegEnd(seg))
        {                           
            if(isCode(GetFlags(loc)))
            {
                shouldBreak = !MakeInstructionComment(loc);

                if(shouldBreak)
                    break;
            }

            loc = NextHead(loc, BADADDR);           
        }


        if(shouldBreak)
            break;

        seg = NextSeg(seg);     // get address of the next segment
    }

    Message("End of pseudo instruction adder by fastman92\n");
}