-
Notifications
You must be signed in to change notification settings - Fork 1
/
snatch_decrypt_strings.py
48 lines (40 loc) · 1.71 KB
/
snatch_decrypt_strings.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Author: Ladislav Baco, LIFARS
# Date: July 22, 2020
#
# (c) 2020 LIFARS
# This code is licensed under MIT license (see LICENSE for details)
import idaapi
import idautils
import ida_name
import ida_bytes
from base64 import b64decode
from itertools import cycle, izip
def get_params(ea):
data_addr = None
length = None
inst = idautils.DecodePreviousInstruction(ea)
if (inst != None) and (inst.get_canon_mnem() == "mov"):
length = inst.Op2.value
inst2 = idautils.DecodePreviousInstruction(inst.ea)
if (inst2 != None) and (inst2.get_canon_mnem() == "mov"):
inst3 = idautils.DecodePreviousInstruction(inst2.ea)
if (inst3 != None) and (inst3.get_canon_mnem() == "lea"):
length = inst.Op2.value
data_addr = inst3.Op2.addr
return data_addr, length
def decrypt_string(data, key):
crypt = b64decode(data)
plain = "".join(chr(ord(c)^ord(k)) for c,k in izip(crypt, cycle(key)))
return b64decode(plain)
arch = 64 if idaapi.get_inf_structure().is_64bit() else 32
ea = ida_name.get_name_ea(idaapi.BADADDR, "main.decodeString")
key_addr = ida_name.get_name_ea(idaapi.BADADDR, "main.encoderKey")
key = ida_bytes.get_bytes(ida_bytes.get_dword(key_addr), ida_bytes.get_dword(key_addr + arch/8))
for xref in idautils.CodeRefsTo(ea, True):
inst = idautils.DecodeInstruction(xref)
if (inst != None) and (inst.get_canon_mnem() == "call"):
data_addr, length = get_params(xref)
data = ida_bytes.get_bytes(data_addr, length)
decrypted_str = decrypt_string(data, key)
print "0x{:08x} -> 0x{:x}[0x{:x}] = \"{}\"".format(xref, data_addr, length, decrypted_str)
ida_bytes.set_cmt(xref, decrypted_str, False)