Last active
July 27, 2023 19:55
-
-
Save a1ext/1524608512e57c9a82ba7cd166d62e48 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# if string reference is not found within 5 instructions - report unresolved | |
# returns an operand value or None if nothing is found | |
def find_function_arg(addr, max_insns=5): | |
for _ in xrange(max_insns): | |
addr = idc.PrevHead(addr) | |
if addr == idaapi.BADADDR: | |
break | |
if GetMnem(addr) == "mov" and GetOpnd(addr, 0) == 'eax': | |
return GetOperandValue(addr, 1) | |
return None | |
# gen an unicode string from given address | |
# returns None if failed | |
def get_string(addr): | |
out = "" | |
while True: | |
# if we are on the border of the section - return what has been already read | |
if not idaapi.get_flags(addr) or not idaapi.get_flags(addr + 1): | |
return out.decode('utf-16le') | |
c0 = Byte(addr) | |
c1 = Byte(addr + 1) | |
if c0 == 0 and c1 == 0: # is Null-terminator of wchar_t size | |
break | |
out += chr(c0) | |
out += chr(c1) | |
addr += 2 | |
return out.decode('utf-16le') | |
decrypt_func_addr = LocByName("decrypt_string") | |
print "[*] Attempting to grab decrypted strings from malware" | |
not_resolved = [] | |
# decr_fn_rva - holds RVA to decrypt fn, to calculate its address after relocation | |
# refs - dictionary with {addr: len} pairs | |
__extern__ = { | |
'decr_fn_rva': None, | |
'refs': dict() | |
} | |
for x in XrefsTo(decrypt_func_addr, 0): | |
ref = find_function_arg(x.frm) # see function definition below | |
# sometimes we cannot get string references, | |
# that's why these checks are important | |
if not ref or ref > 0x7FFFFFFF: | |
not_resolved.append(x.frm) | |
continue | |
if __extern__['decr_fn_rva'] is None: | |
__extern__['decr_fn_rva'] = int(x.frm) - idaapi.get_imagebase() | |
print hex(ref) | |
got_string = get_string(ref) # see function definition below | |
__extern__['refs'][ref] = got_string | |
for inst in not_resolved: | |
print 'Not resolved for 0x%x' % (inst,) | |
for addr, cur_str in __extern__['refs'].iteritems(): | |
print '0x%x: %s' % (addr, cur_str) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment