不使用 IDA non-free 将 IDA 列表转换为程序集

逆向工程 艾达 拆卸 部件
2021-06-18 12:45:29

我目前正在处理大量 IDA Pro 列表 ( ~1TiB)。

对于一个项目,我需要在子程序级别mnemonicsoperands子程序级别执行分析因此,我想将 IDA 格式转换为普通汇编格式,因为现有的解析器仅适用于“PLAIN ASM”文件。

此外,这应该在不使用非免费版本的 IDA 的情况下完成。

国际开发协会

.text:00401000                             ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000                             ; Attributes: bp-based frame
.text:00401000
.text:00401000                             sub_401000      proc near           ; CODE XREF: sub_43BD35+Ap
.text:00401000
.text:00401000                             var_C           = dword ptr -0Ch
.text:00401000                             var_8           = dword ptr -8
.text:00401000                             var_4           = dword ptr -4
.text:00401000
.text:00401000 55                                  push    ebp
.text:00401001 8B EC                                   mov     ebp, esp
.text:00401003 83 EC 0C                                sub     esp, 0Ch
.text:00401006 89 4D F4                                mov     [ebp+var_C], ecx
.text:00401009 8B 45 F4                                mov     eax, [ebp+var_C]
.text:00401021 59                                  pop     ecx
.text:00401022
.text:00401022                             loc_401022:                 ; CODE XREF: sub_401000+Fj
.text:00401022 8B 45 F4                                mov     eax, [ebp+var_C]
.text:00401025 83 78 04 00                             cmp     dword ptr [eax+4], 0
.text:00401029 74 12                                   jz      short locret_40103D
.text:0040102B 8B 45 F4                                mov     eax, [ebp+var_C]
.text:0040102E 8B 40 04                                mov     eax, [eax+4]
.text:00401031 89 45 F8                                mov     [ebp+var_8], eax
.text:00401034 FF 75 F8                                push    [ebp+var_8]     ; void *
.text:00401037 E8 B8 0D 00 00                              call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:0040103C 59                                  pop     ecx
.text:0040103D
.text:0040103D                             locret_40103D:                  ; CODE XREF: sub_401000+29j
.text:0040103D C9                                  leave
.text:0040103E C3                                  retn
.text:0040103E                             sub_401000      endp

转换成:

普通 ASM

=============== S U B R O U T I N E =======================================
push    ebp
mov     ebp, esp
sub     esp, 0Ch
mov     [ebp+var_C], ecx
mov     eax, [ebp+var_C]
pop     ecx
mov     eax, [ebp+var_C]
cmp     dword ptr [eax+4], 0
jz      short locret_40103D
mov     eax, [ebp+var_C]
mov     eax, [eax+4]
mov     [ebp+var_8], eax
push    [ebp+var_8]     ; void *
call    ??3@YAXPAX@Z    ; operator delete(void *)
pop     ecx
leave
retn

问题: 是否已经存在用于这种(自动或批处理模式)转换的解决方案或脚本(最好不需要 IDA 非免费版本)?

2个回答

我假设您已经拥有 ida 生成的程序集输出,并且只有在您可以即兴创作的情况下才想解析测试。

假设我将IDA.ASM您帖子中的复制粘贴到文本文件中。

如果您在 Windows 上需要路径中使用的 unix 实用程序的 gnuwin32 端口,我可以仅使用下面的 XXX 打印所有反汇编行。


建议1:

文本文件的详细信息:

wc -l ida.asm & echo. & head -n 2 IDA.ASM & echo. & tail -n 2 IDA.ASM & echo. & head -n 11 IDA.ASM | tail -1

输出:

31 ida.asm

.text:00401000                             ; =============== S U B R O U T I N E =======================================
.text:00401000

.text:0040103E C3                                  retn
.text:0040103E                             sub_401000      endp
.text:00401000 55                                  push    ebp

文本解析以仅从所述文本文件中分离反汇编:

tac ida.asm | awk "{if(a[$1]++==0){print $0} }" | sort

结果如下:

:\>tac ida.asm | awk "{if(a[$1]++==0){print $0} }" | sort
.text:00401000 55                                  push    ebp
.text:00401001 8B EC                                   mov     ebp, esp
.text:00401003 83 EC 0C                                sub     esp, 0Ch
.text:00401006 89 4D F4                                mov     [ebp+var_C], ecx
.text:00401009 8B 45 F4                                mov     eax, [ebp+var_C]
.text:00401021 59                                  pop     ecx
.text:00401022 8B 45 F4                                mov     eax, [ebp+var_C]
.text:00401025 83 78 04 00                             cmp     dword ptr [eax+4], 0
.text:00401029 74 12                                   jz      short locret_40103D
.text:0040102B 8B 45 F4                                mov     eax, [ebp+var_C]
.text:0040102E 8B 40 04                                mov     eax, [eax+4]
.text:00401031 89 45 F8                                mov     [ebp+var_8], eax
.text:00401034 FF 75 F8                                push    [ebp+var_8]     ; void *
.text:00401037 E8 B8 0D 00 00                              call    ??3@YAXPAX@Z    ; operator delete(void *)
.text:0040103C 59                                  pop     ecx
.text:0040103D C9                                  leave
.text:0040103E                             sub_401000      endp.text:0040103E C3                                  retn

建议2:

正如我所评论的,如果您可以根据第一列比较打印组的最后一行,您可以消除 tac。我在 SO 周围搜索,仅根据第一列的比较结果,在每组结果中找到了打印的最后一行

我根据这个问题的需要对其进行了调整:

awk "{a[$1]=$0} END {for (i in a ) print a[i]}" IDA.lst  | sort | awk "{ print substr($0,42) }" | tr -s [:blank:]

输出:

 push ebp
 mov ebp, esp
 sub esp, 0Ch
 mov [ebp+var_C], ecx
 mov eax, [ebp+var_C]
 pop ecx
 mov eax, [ebp+var_C]
 cmp dword ptr [eax+4], 0
 jz short locret_40103D
 mov eax, [ebp+var_C]
 mov eax, [eax+4]
 mov [ebp+var_8], eax
 push [ebp+var_8] ; void *
 call ??3@YAXPAX@Z ; operator delete(void *)
 pop ecx
 leave
 sub_401000 endp

建议3:

基于上述建议的类似解决方案。这种方法还会尊重最后一条retn语句并过滤掉;行尾的注释 ( ):

grep -E "^.{10,15} [0-9A-F]{2} *" IDA.ASM | sort | cut -c40-200 | tr -s [:blank:] | cut -d ";" -f1

输出:

 push ebp
 mov ebp, esp
 sub esp, 0Ch
 mov [ebp+var_C], ecx
 mov eax, [ebp+var_C]
 pop ecx
 mov eax, [ebp+var_C]
 cmp dword ptr [eax+4], 0
 jz short locret_40103D
 mov eax, [ebp+var_C]
 mov eax, [eax+4]
 mov [ebp+var_8], eax
 push [ebp+var_8]
 call ??3@YAXPAX@Z
 pop ecx
 leave
 retn

纯基于 AWK 的建议

我不喜欢使用 n 个实用程序来完成一项工作
,我需要重新整理我的awkyquotient所以这里是一个 awk 唯一代码,
您可能需要测试冲洗并重复
它似乎适用于 plain.asm 的复制粘贴

{ 
    a[$1] = $0 ;                      # array a will contain last  entry in each group 
    if(b[$1]++==0) c[$1] = $0;        # array c will contain first entry of each group
} END { 
    n = asort(a); m = asort(c);       # sort both arrays
    if (n == m) {                     # some caution    
        for( k=1; k<=n; k++ ){     
            if(a[k]!= c[k]) {         # lets split input into 3 seperate arrays  
                d[k] = a[k]           # one where all entries except last is valid
                e[k] = c[k]           # one where only last entry is valid
            } else {
                f[k] = a[k]           # one where both arrays have same entries
            }
        }
    }
    o = asort(d); p = asort(e) ; q= asort(f) # sort all 3 arrays
    z = 1;
    while(z != o)    {
        g[z] = d[z]                  #insert final array with first n entries 
        z++;                         #(except last entry)
    }
    y = 1;
    while(y != q+1) {
        g[z] = f[y]                  #insert final array with all equal entries 
        z++;y++
    }
    x = p;
    while(x != p-1) {
        g[z] = e[x]                  # insert final array with last entry
        z++;x--
    }
    r = asort(g)                     # sort the final array and print substring
    startofdis = 44;                 # lets set a start    
    for (i = 1; i <= r; i++ ) {
    match(g[i] ,/;.*/);              # match everything after a ; (semicolon)
    if(RLENGTH == -1){               # awk should set the RSTART and RLENGTH
    print substr( g[i] ,startofdis)  # if RLENGHT == -1 no semicolon 
    }                                # lets print from startofdis to end
    else
    print substr(g[i] , startofdis , RSTART-startofdis ) # print only the middle portion
    }
}

结果如下

:\>awk -f awky.txt ida.lst
        push    ebp
            mov     ebp, esp
            sub     esp, 0Ch
            mov     [ebp+var_C], ecx
            mov     eax, [ebp+var_C]
        pop     ecx
            mov     eax, [ebp+var_C]
            cmp     dword ptr [eax+4], 0
            jz      short locret_40103D
            mov     eax, [ebp+var_C]
            mov     eax, [eax+4]
            mov     [ebp+var_8], eax
            push    [ebp+var_8]
                call    ??3@YAXPAX@Z
        pop     ecx
        leave
        retn

:\>

IDA 数据库对二进制代码的表示,有时为了分析程序逻辑需要一些自由。这些简化之一是自动创建您看到的参数和局部变量表示(arg_ 、var_)。

如果您想更接近更清晰的装配表示,请尝试Capstone如果您确定了需要使用 IDA(或其他一些反汇编程序)分析的函数的文件偏移量,您可以将它们提供给 Capstone 以生成反汇编。此外,您可以轻松编写一个 IDC 脚本(IIRC,IDA 的免费版本不附带 IDAPython 支持)来为您要分析的每个函数以二进制形式转储您需要的指令,并将其传递给 Capstone 以生成拆卸。