idapython在样本分析中的使用-字符解密

最近接手的一个样本,样本中使用了大量的xor加密,由于本身样本不全,无法运行(好吧我最稀饭的动态调试没了,样本很有意思,以后有时间做票大的分析),这个时候就只好拜托idapython大法了(当然用idc也一样),期间遇到几个问题,遂记录一番。

样本加密的字符如下,很简单,push压栈之后,反复调用sub_1000204D解密。

此时,要写脚本的话,我们希望这个脚本能够足够通用,通常样本中的加密都是由一个函数实现,函数本身实现解密,传入的参数通常是解密字符,和key两个参数(当然肯定也有其他的模式),那么在写一个较为通用脚本前需要解决已下几个问题:

  1. 如何获取所有调用解密函数的地址
  2. 如何获取需要解密的字符
  3. 解密算法如何
  4. 解密之后的处理(最简单的比如注释)

首先针对第一个问题,如何获取调用解密函数的地址。

在ida中针对这一需求其实提供了一个函数XrefsTo,该函数会返回一个地址的所有引用,在ida中通过一下两句脚本可以测试一下。

for x in XrefsTo(0x1000204D,flags = 0):

print hex(x.frm)

测试结果如下:

 

第二个问题,如何获取加密的的字符串。

在本例中函数的调用如下。

 

此时我们需要用到几个函数

第一个函数为PrevHead,该函数用于获取一段代码段中的指令,ea为开始,mines为结尾,注意这个函数的搜索为降序搜索,说白了就是往前找。通过这个函数我们就可以获取解密函数之前的指令,即push offset xxxxx指令所在的代码区域了

long    PrevHead        (long ea, long minea); 

第二个函数为GetMnem,用于获取ea指定地址附近的指令

string  GetMnem         (long ea); 

第三个函数为GetOpnd,用于获取操作指定地址ea附近指令的操作码,注意此处的n为操作码的编号,由0开始,比如指令push offset xxxxx,0号操作码为push           

string  GetOpnd         (long ea,long n);

第四个函数为GetOperandValue,用于获取指定地址ea附近指令的操作数,通用n为操作数的编号,由0开始,比如指令push offset xxxxx,0号操作码为xxxxx

long  GetOperandValue   (long ea,long n);

通过这几个函数就可以获取压栈指令push压如的加密字符了,以下为参数获取函数

测试效果如下:

 

但是此处我们只是获取了加密字符的地址,此处还需要计算出加密字符串的截止地址。

 

第三个问题,解密字符。

由于此处只是简单的xor解密,含简单,当然以后有其他的加密方式,直接增加函数即可。

 

第四个问题,注释

可以通过函数MakeComm()实现。ea为注释地址,comment为注释类容。

Success MakeComm        (long ea,string comment);       // give a comment

至此把所有的内容整合起来即可

 

运行脚本之后的结果。

 

posted @ 2015-12-31 18:50  goabout2  阅读(2738)  评论(0编辑  收藏  举报