5.8 指令

下面这些函数用来分析反汇编文件中的指令。它们定义在 ua.hpp,但除了定义在 lines.hpp 中的 generate_disasm_line()。

5.8.1 generate_disasm_line

定义

idaman bool ida_export

generate_disasm_line(ea_t ea, char *buf, size_t bufsize,

int flags=0)

含义

把地址 ea 的反汇编代码填充到*buf,长度限定为 bufsize。这些反汇编代码是着过色的,所以您需要使用 tag_remove() 来得到可以正常打印的文本(参看 5.20.1 章节)。

示例

#include <kernwin.hpp>

#include <lines.hpp>

ea_t ea = get_screen_ea();

// 将保存反汇编文本的缓冲区

char buf[MAXSTR];

// 保存反汇编文本

generate_disasm_line(ea, buf, sizeof(buf)-1);

// 显示着色文本的反汇编代码(在 IDA 的日志

// 窗口可能不太好读)

msg(“Current line: %s\n”, buf);

5.8.2 ua_ana0

定义

idaman int

ida_export ua_ana0(ea_t ea)

含义

反汇编地址 ea。返回指令的字节数长度,并且把该指令的信息填充到全局 cmd 结构。如果地址 ea 处没有指令,返回 0。这是只读函数,也不能修改 IDA 数据库。

示例

#include <kernwin.hpp>

#include <ua.hpp>

ea_t ea = get_screen_ea();

if (ua_ana0(ea) > 0)

msg(“Instruction size: %d bytes\n”, cmd.size);

else

msg(“Not at an instruction.\n”);

5.8.3 ua_code

定义

idaman int

ida export ua_code(ea_t ea)

含义

反汇编地址 ea。返回指令的字节数长度,并用指令的信息填充全局 cmd 结构,而且将最后的结果更新 IDA 的数据库。如果 ea 地址处没有指令,返回 0。

示例

#include <kernwin.hpp>

#include <ua.hpp>

ea_t saddr, eaddr;

ea_t addr;

// 获取用户的选择范围

int selected = read_selection(&saddr, %eaddr);

if (selected) {

// 重新分析选择的地址区域

for (addr = saddr; addr <= eaddr; addr++) {

ua_code(addr);

}

} else {

msg(“No selection.\n”);

}

5.8.4 ua_outop

定义

idaman bool ida_export

ua_outop(ea_t ea, char *buf, size_t bufsize, int n)

含义

用 ea 处指令的操作数序号 n 位置的文本,来填充*buf,长度限定为 bufsize,而且如果指令没有被定义,则更新 IDA 数据库。如果操作数 n 不存在,则返回 false。

返回到*buf 中的文本是着过色的,所以您需要使用 tag_remove() 来获得可正常打印的文本(参看 5.20.1 章节)

示例

#include <ua.hpp>

// 获取入口点地址

ea_t addr = inf.startIP;

// 把入口点的指令信息填充到 cmd。

ua_ana0(addr);

// 循环遍历每个操作数(直到碰到一个 o_void 类型),

// 并显示操作数文本

for (int i = 0; cmd.Operands[i].type != o_void; i++) {

char op[MAXSTR];

ua_outop(addr, op, sizeof(op)-1, i);

msg(“Operand %d: %s\n”, i, op);

}

5.8.5 ua_mnem

定义

idaman const char *ida_export

ua_mnem(ea_t ea, char *buf, size_t bufsize)

含义

把 ea 处指令的助记符填充到*buf,长度限定为 bufsize,如果指令没有被定义好,就更新 IDA 数据库。返回*buf 指针,或者 ea 处没有指令则返回 NULL。

示例

#include <segment.hpp>

#include <ua.hpp>

// 循环遍历每个可执行区段,并显示

// 每条指令的助记符

for (int s = 0; s < get_segm_qty(); s++) {

segment_t *seg = getnseg(s);

is (seg->type == SEG_CODE) {

int bytes = 0;

// a should always be the address of an

// instruction, which is why bytes is dynamic

// depending on the result of ua_mnem()

for (ea_t a = seg->startEA;

a < seg->endEA; a += bytes) {

char mnem[MAXSTR];

const char *res;

// 获取地址 a 的指令助记符,并保存到 mnem

res = ua_mnem(a, mnem, sizeof(mnem)-1);

// 如果是一条指令,则显示助记符,

// 并设置字节数到 cmd.size,

// 因此由 ua_mnem() 处理的下一地址,

// 即为下一条指令。

if (res != NULL) {

msg (“Mnemonic at %a: %s\n:”, a, mnem);

bytes = cmd.size;

} else {

msg (“No code\n”);

// 如果该地址处没有指令代码,

// 就把字节数加一,所有 ua_mnem()

// 不会继续处理下一个地址。

bytes = 1;

}

}

}

}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:0 次

字数:4410

最后编辑:1 个月前

最近更新:JSmiles

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。