首页
社区
课程
招聘
[原创]IDA分析器指南
发表于: 2022-4-15 23:55 10592

[原创]IDA分析器指南

2022-4-15 23:55
10592

IDA处理器模块主要分析为三大块,分析器、模拟器和输出器。其中分析器的功能是分析单条指令,模拟器的功能是对指令的模拟,输出器的功能是着色输出反汇编文本。

分析器的工作包括分析单条指令,用与指令有关的信息填充数据结构insn_t。分析器要充分解析指令的每个比特,填充操作数信息,方便模拟器和输出器的工作。
SDK无法考虑到所有处理器架构,故相关的结构体包含通用字段和额外字段。在开始编写分析器代码前,你需要充分了解目标处理器的指令形式,按需使用额外字段来存储相关的指令信息。
例如:tms320c6系列的指令形式如下所示,你应该使用insn_t中额外字段来存储parallel、cond、unit、cross path这些信息。
[parallel] [cond] ins [.unit][cross path] [op1], [op2], [op3], ...

与分析器相关的数据结构有insn_t和op_t,前者存储指令的信息,后者存储操作数信息。

指令的操作数个数很多时候不是唯一的,具体要看处理器指令集,以下列举一些例子,可以看到操作数的类型有寄存器、立即数、寻址偏移,常量地址。

IDA归纳总结这些操作类型,为我们提供了以下操作数类型。像R15[R0+4]这种寻址操作,它是一个操作数,还是是两个或者三个操作数,这取决于你,但只会影响模拟器和输出器的复杂程度。
一般我们会其整体看作一个操作数,并将R0存储到phrase中,4存储到value中,而R15存储到额外字段中,操作数类型选择o_displ,这样可以在输出器中把整个操作数一次性输出。

分析器用到的sdk函数不多,因为只是给insn_t结构体赋值。

//[*]表示必须设置的字段
struct insn_t
{
    ea_t cs;    //代码段寄存器地址,由IDA设置
    ea_t ip;    //当前程序计数器地址,由IDA设置
    ea_t ea;    //当前指令所在地址,由IDA设置,一般与ip相同
    uint16 itype;    //[*]指令类型,一般为指令枚举中的一个元素
    uint16 size;    //[*]指令所占的长度
    union            //额外字段,由开发者决定该字段的作用,可以随意使用
    {
        uint32 auxpref;
        uint16 auxpref_u16[2];
        uint8  auxpref_u8[4];
    };
    char segpref;    //额外字段,由开发者决定该字段的作用,可以随意使用
    char insnpref;    //额外字段,由开发者决定该字段的作用,可以随意使用
    int16 flags;    //以INSN_开头的flag组合,很少用到
    op_t ops[UA_MAXOP];        //[*]操作数信息,指令用了哪些操作数是由LPH中的instruc字段决定的
}
//[*]表示必须设置的字段
struct insn_t
{
    ea_t cs;    //代码段寄存器地址,由IDA设置
    ea_t ip;    //当前程序计数器地址,由IDA设置
    ea_t ea;    //当前指令所在地址,由IDA设置,一般与ip相同
    uint16 itype;    //[*]指令类型,一般为指令枚举中的一个元素
    uint16 size;    //[*]指令所占的长度
    union            //额外字段,由开发者决定该字段的作用,可以随意使用
    {
        uint32 auxpref;
        uint16 auxpref_u16[2];
        uint8  auxpref_u8[4];
    };
    char segpref;    //额外字段,由开发者决定该字段的作用,可以随意使用
    char insnpref;    //额外字段,由开发者决定该字段的作用,可以随意使用
    int16 flags;    //以INSN_开头的flag组合,很少用到
    op_t ops[UA_MAXOP];        //[*]操作数信息,指令用了哪些操作数是由LPH中的instruc字段决定的
}
//[*]表示必须设置的字段
struct op_t
{
    uchar n;    //操作数的序号,一般不需要修改
    optype_t type;    //[*]操作数类型,后面会讲解
    char offb;    //指令字节中偏移所在位置,很少用到
    char offo;    //offb的补充,很少用到
    uchar flags;    //以OF_开头的flag组合,
    op_dtype_t dtype;    //[*]操作数本身的类型
    union    //[*]当type=o_reg、o_phrase、o_displ时使用
    {
        uint16 reg;
        uint16 phrase;
    };
    union    //[*]当type=o_imm、o_displ时使用
    {
        uval_t value;
        struct
        {
            uint16 low;
            uint16 high;
        } value_shorts;
    };
    union    //[*]当type=o_mem、o_displ、o_far、o_near时使用
    {
        ea_t addr;
        struct
        {
            uint16 low;
            uint16 high;
        } addr_shorts;
    };
    union    //额外字段,由开发者决定该字段的作用,可以随意使用
    {
        ea_t specval;
        struct
        {
            uint16 low;
            uint16 high;
        } specval_shorts;
    };
    char specflag1; //额外字段,由开发者决定该字段的作用,可以随意使用
    char specflag2; //额外字段,由开发者决定该字段的作用,可以随意使用
    char specflag3; //额外字段,由开发者决定该字段的作用,可以随意使用
    char specflag4; //额外字段,由开发者决定该字段的作用,可以随意使用
}
//[*]表示必须设置的字段
struct op_t
{
    uchar n;    //操作数的序号,一般不需要修改
    optype_t type;    //[*]操作数类型,后面会讲解
    char offb;    //指令字节中偏移所在位置,很少用到
    char offo;    //offb的补充,很少用到
    uchar flags;    //以OF_开头的flag组合,
    op_dtype_t dtype;    //[*]操作数本身的类型
    union    //[*]当type=o_reg、o_phrase、o_displ时使用
    {
        uint16 reg;
        uint16 phrase;
    };
    union    //[*]当type=o_imm、o_displ时使用
    {
        uval_t value;
        struct
        {
            uint16 low;
            uint16 high;
        } value_shorts;
    };

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//