Skip to content

Instantly share code, notes, and snippets.

@a1ext
Last active September 21, 2018 15:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a1ext/f27748f172a36428994b06538efe27a1 to your computer and use it in GitHub Desktop.
Save a1ext/f27748f172a36428994b06538efe27a1 to your computer and use it in GitHub Desktop.
import struct
# get image base of malware module
image_base = ll.api.Findmodulebyname(u'12345678_db').base
# set this value to point to any 'decrypt_string' call
orig_eip = image_base + __extern__['decr_fn_rva']
DECR_PTR_SIZE = 0x4
MAX_ENCR_BUF_SIZE = 0x200
# here is where all the decrypted strings will be written
__result__ = dict()
# allocating memory in malware address space to hold current encrypted string
# as well as output buffer for holding string pointer
encr_str_addr = ll.memory.RemoteAllocRWE(None, MAX_ENCR_BUF_SIZE)
out_ptr = ll.memory.RemoteAllocRWE(None, DECR_PTR_SIZE)
if not encr_addr or not decr_addr:
raise Exception('[!] Cannot allocate memory in debugger')
for addr, cur_str in __extern__['refs'].iteritems():
encoded = cur_str.encode('utf-16le')
str_len = len(cur_str)
# build encrypted Delphi string
encr_str = struct.pack('<I', str_len) + encoded # TODO: check this
# decrypted address does not hold decrypted string but merely an address
# of decrypted string - which is allocated in malware during decryption
# init output pointer
decr_buff = ll.memory.WriteMemory('\0' * 4, out_ptr)
# write encrypted string to appropriate space in malware address space
ll.memory.WriteMemory(encr_str, encr_str_addr)
# setting registers to work with preset memory
ll.threads.SetEip(orig_eip)
ll.threads.SetRegisters({'eax': encr_str_addr + 4, 'edx': out_ptr})
# executing decrypt function
ll.utils.StepOver()
# at this point string should be decrypted in memory
ptr_to_decr_str = ll.memory.ReadDwordMemory(out_ptr)
if ptr_to_decr_str == 0:
print '[!] String @ 0x%x not decrypted' % int(addr)
continue
# reading Delphi string in bytes...
decr_len = ll.memory.ReadDwordMemory(ptr_to_decr_str - 4) # ... its length
# string length should be multiplied by 2 to read all of its bytes
decrypted = ll.memory.ReadMemory(decr_len * 2, ptr_to_decr_str) # ... its contents
# we have to apply code page for decrypted strings for them to look correct
__result__[addr] = decrypted.decode('utf-16le')
# freeing allocated memory
ll.memory.RemoteFree(out_ptr, 0)
ll.memory.RemoteFree(encr_str_addr, 0)
print '[*] Decrypting on Olly side finished'
print 'Check decrypted strings in __result__ variable on IDA side'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment