python count函数用法 comm_使用idapython脚本解码样本中的字符串

0x00 背景

在一次样本分析过程中,碰到了如下函数,此函数功能为解码字符串。

3591456879.png

按照平常的思路一般都是动态调试出字符串,然后在ida上打上注释。

如果此时同类型的样本量非常大,显然一个个的调试是不现实的。

这时便可以使用idapython辅助我们来对字符串进行解码。

此篇记下学习idapython脚本的过程。

0x01 确定解码过程

根据ida F5的结果来看,是将每个字节数据减去13

2602472667.png

我们很容易能编写出GenerateStr函数,如下:def GenerateStr(data):

str_len = len(data)

decode_str = ""

if str_len != 0:

index = 0

while index < str_len:

decode_str += chr(ord(data[index]) - 13)

index += 1

return decode_str

0x02 确定调用GenerateStr的地址

在ida中,可以查找GenerateStr的引用来确定哪些地方调用了此函数

3336062062.png

同样,在idapython中也提供了接口XrefsTo(func_addr, flags = 0)

0x03 获取GenerateStr的参数

通过观察,我们发现每次调用GenerateStr函数时,传入参数都是esi,则我们可以定位call GenerateStr,然后向上找mov esi, xxx,直到找到此指令时,xxx就是我们需要的参数地址

idapython脚本如下:def find_function_arg(addr):

while True:

# 获取上一条指令地址

addr = idc.PrevHead(addr)

# 判断当前指令的操作码为mov,且第一个操作数为esi

if GetMnem(addr) == "mov" and "esi" in GetOpnd(addr, 0):

# print "[+]Found it at 0x%x" % GetOperandValue(addr, 1)

break

# 返回第二个操作数

return GetOperandValue(addr, 1)

得到参数地址之后,我们要获取参数的内容,可以循环读直到空字符def get_string(addr):

output = ""

while Byte(addr) != 0:

output += chr(Byte(addr))

addr += 1

return output

0x04 完整代码def find_function_arg(addr):

while True:

addr = idc.PrevHead(addr)

if GetMnem(addr) == "mov" and "esi" in GetOpnd(addr, 0):

# print "[+]Found it at 0x%x" % GetOperandValue(addr, 1)

break

return GetOperandValue(addr, 1)

def get_string(addr):

output = ""

while Byte(addr) != 0:

output += chr(Byte(addr))

addr += 1

return output

def GenerateStr(data):

str_len = len(data)

decode_str = ""

if str_len != 0:

index = 0

while index < str_len:

decode_str += chr(ord(data[index]) - 13)

index += 1

return decode_str

if __name__ == '__main__':

func_addr = 0x00402F30

result = {}

for addr in XrefsTo(func_addr, flags = 0):

arg_addr = find_function_arg(addr.frm)

result[addr.frm] = (arg_addr, GenerateStr(get_string(arg_addr)))

# print result

for addr, (arg_addr, comm) in result.items():

# print "[+]CallFunc: ", hex(addr), "\tArgAddr: ", hex(arg_addr), "\tComm: ", comm

MakeComm(int(addr), comm) # 添加注释

MakeComm(int(arg_addr), comm) # 添加注释

print "done..."

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值