You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析IDA生成的汇编文件,提取函数指令助记符映射串?

问题描述

我有一份IDA Pro生成的ARM汇编文件,函数格式示例如下:

; =============== S U B R O U T I N E =======================================


release                                 ; DATA XREF: attribute_manager_create+78↓o
                                        ; attribute_manager_create+7C↓o ...

var_30          = -0x30
var_24          = -0x24
arg_0           =  0
arg_4           =  4

                PUSH    {R4-R9,LR}
                MOV     R7, R0
                LDR     R0, [R0,#0x34]
                SUB     SP, SP, #0x14
                MOV     R9, R3
                LDR     R3, [R0]
                MOV     R5, R1
                MOV     R8, R2
                BLX     R3
                LDR     R0, [R7,#0x30]
                ADD     R6, SP, #0x30+var_24
                LDR     R3, [R0,#4]
                BLX     R3
                MOV     R4, R0
                B       loc_7A7C
; ---------------------------------------------------------------------------

loc_7A70                                ; CODE XREF: release+5C↓j
                LDR     R3, [SP,#0x30+var_24]
                CMP     R3, R5
                BEQ     loc_7AB4

loc_7A7C                                ; CODE XREF: release+38↑j
                LDR     R3, [R4]
                MOV     R1, R6
                MOV     R0, R4
                BLX     R3
                CMP     R0, #0
                BNE     loc_7A70

loc_7A94                                ; CODE XREF: release+A0↓j
                LDR     R3, [R4,#8]
                MOV     R0, R4
                BLX     R3
                LDR     R0, [R7,#0x34]
                LDR     R3, [R0,#0xC]
                BLX     R3
                ADD     SP, SP, #0x14
                POP     {R4-R9,PC}
; ---------------------------------------------------------------------------

loc_7AB4                                ; CODE XREF: release+44↑j
                LDR     R3, [SP,#0x30+arg_4]
                STR     R3, [SP,#0x30+var_30]
                MOV     R2, R9
                LDR     R3, [SP,#0x30+arg_0]
                LDR     R6, [R5,#4]
                MOV     R1, R8
                MOV     R0, R5
                BLX     R6
                B       loc_7A94
; End of function release

需要解析该文件生成一个字典:键为函数名,值是将函数内ARM指令按指定字典映射为对应字母后拼接的字符串,不在字典中的指令直接跳过。指定映射字典如下:

arm_dict = {"MOV": "a","MVN": "b","ADD": "c","SUB": "d","MUL": "e","LSL": "f","LSR": "g","ASR": "h","ROR": "i","CMP": "j","AND": "k","ORR": "l","EOR": "m","LDR": "n","STR": "o","LDM": "p","STM": "q","PUSH": "r","POP": "s","B": "t","BL": "u","BLX": "v","BEQ": "w","SWI": "x","SVC": "y","NOP": "z"}

例如上述release函数的期望输出为:

{'release': 'randanaavncnvatjwvnnvavnnsct...'}

我之前尝试通过匹配S U B R O U T I N E和End of function标记来线性解析,但无法有效剔除指令操作数,需要示例代码或可行思路。

解决方案

核心思路

  1. 定位函数范围:用; =============== S U B R O U T I N E =======================================标记函数开始,; End of function标记函数结束,只处理中间的函数内容。
  2. 提取函数名:在函数开始标记后的第一行非空、非注释、非变量定义的行中,取第一个单词作为函数名。
  3. 过滤有效指令:跳过变量定义行(如var_30 = -0x30)、标签行(如loc_7A70)、注释行和空行,只处理包含ARM指令的行。
  4. 映射拼接:提取每行的指令操作码(行首的大写单词),用指定字典转换为对应字母,拼接成最终字符串。

示例Python代码

arm_dict = {"MOV": "a","MVN": "b","ADD": "c","SUB": "d","MUL": "e","LSL": "f","LSR": "g","ASR": "h","ROR": "i","CMP": "j","AND": "k","ORR": "l","EOR": "m","LDR": "n","STR": "o","LDM": "p","STM": "q","PUSH": "r","POP": "s","B": "t","BL": "u","BLX": "v","BEQ": "w","SWI": "x","SVC": "y","NOP": "z"}

def parse_ida_assembly(file_path):
    result = {}
    current_func = None
    in_function = False
    current_str = []

    with open(file_path, 'r') as f:
        for line in f:
            stripped_line = line.strip()
            # 触发函数开始解析状态
            if stripped_line.startswith('; =============== S U B R O U T I N E'):
                in_function = True
                current_str = []
                continue
            # 结束当前函数解析,保存结果
            if in_function and stripped_line.startswith('; End of function'):
                if current_func:
                    result[current_func] = ''.join(current_str)
                in_function = False
                current_func = None
                continue
            # 不在函数范围内则跳过
            if not in_function:
                continue
            # 提取函数名:匹配函数开始后的第一个有效行
            if not current_func and stripped_line and not stripped_line.startswith(';') and '=' not in stripped_line:
                current_func = stripped_line.split()[0]
                continue
            # 跳过变量定义、标签、注释和空行
            if '=' in stripped_line or (stripped_line and stripped_line.endswith(':')) or stripped_line.startswith(';') or not stripped_line:
                continue
            # 提取指令操作码并映射
            opcode = stripped_line.split()[0]
            if opcode in arm_dict:
                current_str.append(arm_dict[opcode])
    
    return result

# 使用示例
if __name__ == '__main__':
    output = parse_ida_assembly('your_assembly_file.asm')
    print(output)

代码说明

  • 函数范围控制:通过两个特殊注释标记切换解析状态,确保只处理函数内部内容。
  • 函数名提取:精准定位函数名所在行,避免误取注释或其他内容。
  • 指令过滤:通过行特征(包含=、以:结尾、以;开头)过滤无效行,只保留真正的指令行。
  • 操作码提取:拆分指令行取第一个元素作为操作码,直接匹配映射字典完成转换。

内容的提问来源于stack exchange,提问作者Pigeoncatcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:05:47