我试图找出一种方法来自动解密函数多次调用的二进制文件中的某些字符串。但是,它为要解密的每个唯一字符串使用了不同的密钥。据我所知)并读取要解密的当前字符串的二进制文件,并获取xor键和长度,然后修补二进制文件以显示纯文本字符串。像这样

char* decrypt(char* string_to_decrypt, uint string_len, char xor_byte)


其中EDX始终保存加密的字符串的地址,两次按下是密钥和长度(9个长度,0x83密钥) />
mov eax并不总是存在。有没有办法读取反汇编并获取此功能,然后仅动态解密数据库中的所有字符串?

为了完整性,这是我开始的地方。

.text:0040168A push    83h
.text:0040168F push    9
.text:00401691 mov     eax, esi
.text:00401693 mov     edx, offset unk_406D58
.text:00401698 call    decrypt_string


谢谢。

编辑:
我们的回应使我朝着正确的方向前进。这是我想出的。很粗糙,我知道:)

import idaapi
import idc

ea = here()
print hex(ea)

xrefs = CodeRefsTo(ea,0)
    for xref in xrefs:
    print "Ref Addr: {}".format(hex(xref))

# for all xrefs, get string offset, length and key,
# decrypt that string, and patch or rename it to display decrypted string)


#1 楼

当我做类似的事情时,我使用了idc.PrevHead(ea)从呼叫站点进行迭代,所以它类似于以下内容:应该很明显。
祝你好运。

评论


谢谢,您的回答使我知道了我需要去的地方。我将解决方案附加到我的问题中。

– Gandolf
15年11月17日在1:44

#2 楼

您可以使用Sark完成大部分工作。它应该类似于以下内容:

import sark

def get_edx_values_at_calls_to(function):
    for xref in function.xrefs_to:
        if not xref.type.is_call:
            continue

        # start at the function call (`xref.frm`) and go back to the beginning of
        # the basic-block (`sark.CodeBlock(xref.frm).startEA`).
        for line in sark.lines(start=sark.CodeBlock(xref.frm).startEA,
                               end=xref.frm, 
                               reverse=True):
            if line.insn.mnem == 'mov' and line.insn.operands[0].reg == 'edx':
                yield line.insn.operands[1].value

decrypt_function = sark.Function()
for value in get_edx_values_at_calls_to(decrypt_function):
    pass  # decryption code


评论


感谢您的回复。我为您的项目添加了书签,以便稍后进行检出,但是我觉得由于我对IDAPython API还是很陌生,因此我会使用本机解决方案。

– Gandolf
15年11月17日在1:45