首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>网络基础>文章内容
IDASDK对指令操作数的识别
来源:xfocus.net 作者:san 发布时间:2005-04-07  

IDASDK对指令操作数的识别


--[ 1. 相关结构

IDASDK的ua_ana0函数会调用ph.u_ana并且填充一个类型为insn_t的cmd结构。类insn_t在ua.hpp头文件里定义,通过这个类的结构可以轻松得到指定地址的指令类型和操作数等数据。

IDAPro支持的指令类型都在allins.hpp里定义,每一种类型的处理器对应一个枚举。通过比较cmd.itype可以判断指定地址的指令类型是什么。

操作定义在该类里类型为op_t的Operands数组结构,IDASDK允许一条指令最多有6个操作数。类op_t同样在ua.hpp里定义,本文主要要讨论的就是这个结构。类op_t里的type成员非常重要,就在op_t的上面一点定义,下面仔细介绍各种类型:

o_void

说明该操作数不可识别。

o_reg

说明该操作数只是一个寄存器。寄存器号保存在cmd.Operands[i].reg里面,对于x86的处理器来说,寄存器号可以在intel.hpp头文件里RegNo枚举变量中获取。其它类型的处理器,有些参考module目录下的一些头文件。当然,有很多类型的处理器没有资料。

o_mem

说明该操作数是一个引用目标地址的直接内存数据,这个目标虚拟地址保存在cmd.Operands[i].addr里。比如对于指令"mov eax, dword ptr ds:[0x00401000]",第二个操作数的类型是o_mem,用cmd.Operands[1].addr可以取到0x00401000。

o_phrase

说明该操作数是一个引用寄存器内容的内存数据。这种操作数可能包含基址寄存器、索引寄存器和缩放系数。当操作数只有一个寄存器的时候,寄存器号保存在cmd.Operands[i].phrase里。当操作数比较复杂的时候就会用到specflag。比如对于指令"lea eax, [ebx+ecx*4]",第二个操作数的类型是o_phrase。以这个指令为例,这时cmd.Operands[1].specflag1=1,cmd.Operands[1].specflag2=0x8B。specflag2的信息按照下面表格拆分表示:

+-----------------------------------------------+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----------------------------------------------+
| 缩放系数 | 索引寄存器 | 基址寄存器 |
+-----------------------------------------------+

缩放系数的值是这样对应的:

0 eq 0
1 eq 2
2 eq 4
3 eq 8

cmd.Operands[1].specflag2=0x8B拆解为:

+-----------------------------------------------+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----------------------------------------------+
| 1 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
+-----------------------------------------------+
| 2 -> 4 | 1 -> ecx | 3 -> ebx |
+-----------------------------------------------+

用表达式可以这样取:

基址寄存器 - specflag2 & 7
索引寄存器 - (specflag2 >> 3) & 7
缩放系数 - (specflag2 & 0xC0) >> 6

对于x86类型处理器,specflag确实是这样操作,但是对于其它类型的处理器,并不是这样,在小节里会提到。

o_displ

说明操作数是一个引用寄存器内容并且加偏移的内存数据。偏移值保存在cmd.Operands[i].addr里,其它信息同o_phrase。

o_imm

说明操作数是一个立即数。立即数的值保存在cmd.Operands[i].value里。

o_near

说明操作数是一个目标地址,通常用于分支跳转和调用指令的地址。目标虚拟地址保存在cmd.Operands[i].addr里。

o_far

说明操作数是一个跨段地址的引用。

--[ 2. 演示代码

/* oprand.cpp
*
* Oprand demo plugin for IDAPro
* Written by san
*
* Compile with:
* cl oprand.cpp /I "..\IDAPro\idasdk47\include" /D __NT__ /D __IDP__ /GX /link /dll "..\IDAPro\idasdk47\libvc.w32\ida.lib" /OUT:oprand.plw /export:PLUGIN
*/

#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <ua.hpp>
#include <allins.hpp>
#include <lines.hpp>

void test()
{
int i;
char ins[256];

ua_ana0(get_screen_ea());
generate_disasm_line(cmd.ea, ins, sizeof(ins));
tag_remove(ins, ins, sizeof(ins));

msg("%08X \"%s\" <==\n itype: %d\n size : %d\n pref : 0x%x\n",
cmd.ea, ins, cmd.itype, cmd.size, cmd.auxpref);

for (i=0; i<UA_MAXOP; i++) {
if (!cmd.Operands[i].type) break;
msg(" Op%d : %d\n", i+1, cmd.Operands[i].type);

switch (cmd.Operands[i].type)
{
case o_reg:
msg(" reg:%d dtyp:%d\n", cmd.Operands[i].reg, cmd.Operands[i].dtyp);
break;
case o_mem:
msg(" mem:0x%x dtyp:%d\n", cmd.Operands[i].addr, cmd.Operands[i].dtyp);
break;
case o_phrase:
msg(" phrase:0x%x dtyp:%d specflag1:0x%x specflag2:0x%x",
cmd.Operands[i].phrase, cmd.Operands[i].dtyp, cmd.Operands[i].specflag1, cmd.Operands[i].specflag2);
if (cmd.Operands[i].specflag1) {
msg(" base_reg:%d index_reg:%d scale:%x",
(cmd.Operands[i].specflag2 & 7),
((cmd.Operands[i].specflag2 >> 3) & 7),
((cmd.Operands[i].specflag2 & 0xC0) >> 6)
);
}
msg("\n");
break;
case o_displ:
msg(" displ:0x%x dtyp:%d specflag1:0x%x specflag2:0x%x",
cmd.Operands[i].addr, cmd.Operands[i].dtyp, cmd.Operands[i].specflag1, cmd.Operands[i].specflag2);
if (cmd.Operands[i].specflag1) {
msg(" base_reg:%d index_reg:%d scale:%x",
(cmd.Operands[i].specflag2 & 7),
((cmd.Operands[i].specflag2 >> 3) & 7),
((cmd.Operands[i].specflag2 & 0xC0) >> 6)
);
}
else {
msg(" reg:%d", cmd.Operands[i].reg);
}
msg("\n");
break;
case o_imm:
msg(" imm:0x%x\n", cmd.Operands[i].value);
break;
case o_far:
msg(" far:0x%x\n", cmd.Operands[i].addr);
break;
case o_near:
msg(" near:0x%x\n", cmd.Operands[i].addr);
break;
default:
msg(" other\n");
break;
}
}
}

/////////////////////////////////////////////////
// Internel Functions
/////////////////////////////////////////////////

int idaapi init(void)
{
return PLUGIN_OK;
}

void idaapi term(void)
{
}

void idaapi run(int arg)
{
test();
}

char comment[] = "";

char help[] = "";

char wanted_name[] = "Get Oprand";

char wanted_hotkey[] = "Alt-7";

plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
init,
term,
run,
comment,
help,
wanted_name,
wanted_hotkey
};

--[ 3. 小结

对于"rep movsd"指令的输出结果是这样的:

00401033 "rep movsd" <==
itype: 124
size : 2
pref : 0x180a
Op1 : 3
phrase:0x7 dtyp:2 specflag1:0x0 specflag2:0x0
Op2 : 3
phrase:0x6 dtyp:2 specflag1:0x0 specflag2:0x0

它的指令类型是NN_movs,通过比较"cmd.auxpref && aux_rep"就能得出是否有rep前缀。比较cmd.Operands[i].dtyp值,得出操作数都是32位的。两个操作数都是o_phrase类型,cmd.Operands[i].specflag1的值为0,所以cmd.Operands[i].phrase保存了操作数寄存器号。

对于其它处理器,specflag的操作却和x86是不同的。比如一条ARM指令的输出结果:

00011194 "LDRNE R6, [R5,R6,LSL#2]" <==
itype: 30
size : 4
pref : 0x0
Op1 : 1
reg:6 dtyp:2
Op2 : 3
phrase:0x5 dtyp:2 specflag1:0x6 specflag2:0x0 base_reg:0 index_reg:0 scale:0

对于ARM处理器,IDAPro不再是用specflag2的值分解,而是用specflag1。不知道第二个操作数的"LSL#2"如何表现出来,specflag3和specflag4的值也都是0。

对于操作数类型是o_idpspec的资料更加少,比如下面的这个ARM指令:

000111A4 "LDMFD SP!, {R4-R6,PC}" <==
itype: 33
size : 4
pref : 0xc0
Op1 : 1
reg:13 dtyp:2
Op2 : 10
other

第二个操作数的type是o_idpspec2,这时它的所有specflag值也都是0。

funnywei正在写一个把各种平台的汇编转换成中间汇编的东西,如果也用IDA插件来实现的话,想必也是会用到这些东西。希望我这块小小的破砖能够砸出f博士大大的玉来。;-)

--[ 4. 参考资料

idasdk47
http://www.cracklab.ru/art/cdee.php
http://reng.ru/tools/005/art.html



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·北京地区设置ADSL猫(惟帆的 KM3
·关于ip地址分类
·浅谈watchdog timeout出现的原因
·利用snmp实现remote ping
·端口大全(1-100中文)
·从IRQ到IRQL(APIC版)
·使用kgdb调试linux内核及内核模
·基于PassThru的NDIS中间层驱动程
·支持 PS/2 与 USB 的键盘过滤驱
·一种网络劫持分析、调试与编程实
·利用iptables打破电信对路由方式
·绕过Copy-On-Write机制安装全局H
  相关文章
·The NT Insider:Stop Interrupti
·非API函数检测操作系统类型
·A Crash Course on the Depths o
·深入分析进程PID相同的奥秘
·浅析本机API
·再谈进程PID相同的深入探究
·BroNIDS的安装与配置
·RSA算法基础--实践
·利用snmp实现remote ping
·使用kgdb调试linux内核及内核模
·使用ASP下载SQL数据库
·用Perl POE实现端口重定向
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved