Last active
April 24, 2024 04:18
-
-
Save m4now4r/4540c26e5fbcb2f353155c1e3ecdcbf7 to your computer and use it in GitHub Desktop.
Qakbot 5.0 - Decrypt strings using idapython
This file contains 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
import idautils, idc, idaapi, ida_bytes | |
decrypt_routine1 = 0x18000DE90 | |
decrypt_routine2 = 0x18000DE50 | |
enc_strings_blob1 = 0x1800297A0 | |
xor_bytes_array = b'\xc3\x4c\x4a\xd8\x7e\x10\xf2\xe9\x05\xe6\xe2\x8e\xaf\xfb\x6b\x32\xc3\x55\xb7\xbe\x9c\x8b\xd9\xc7\xf3\xd3\xa1\x87\xf7\xa7\xb8\x76\xb4\xc8\x2c\x74\x56\xbd\x03\xbc\xa9\x71\xfb\x4b\x89\x52\x95\x2c\x76\xd4\x94\xbf\x64\x23\xfa\x0a\x26\x46\x5e\xa9\x74\xd8\x1c\x2e\x47\x40\x98\x05\x3e\xde\x71\x65\x60\x3b\x03\x0a\x37\x8a\x29\x0e\xaa\x93\xcf\xc7\x35\x3e\x08\x6a\x2c\xab\x22\x6c\xd0\xef\x19\x37\xf3\xe2\x38\xfc\x34\x1b\x84\x61\x84\x0f\xa0\x78\xd1\xdd\x19\x5b\xc0\xcd\xb1\xc0\xb5\x9f\x00\x65\x04\xfa\x89\x39\xa5\xa3\x33\x60\xbf\x75\x5f\x10\xa6' | |
decrypt_routine3 = 0x180002AB8 | |
decrypt_routine4 = 0x180002A78 | |
enc_strings_blob2 = 0x1800282A0 | |
xor_bytes_array2 = b'\xa8\x34\xed\x43\x82\x7d\x35\x98\x52\x5b\x04\x43\x01\x49\xc8\x9e\xbb\x30\xd5\x98\x2e\xf5\x9a\x03\x7b\x02\x46\x13\x1f\x9b\x32\x9e\x1b\x77\xc3\xf9\xe0\xc8\x83\x4b\x94\xa5\x64\xa0\xf3\x04\x45\xe3\xa0\x8f\xda\xc0\x3a\xac\xb7\xa1\x7d\x0c\x2f\x45\x0d\x05\x32\x5b\xd3\x19\xb3\x62\xef\x5d\xa1\x26\x2f\xb5\xfc\x4a\xb3\xc3\xa5\x41\x93\x18\xb4\x41\xa5\xd5\x83\xa5\x7d\x26\x34\x9f\xcd\x7f\x1b\x3e\xe8\x73\x22\xeb\x1b\x3c\x27\xa2\xb3\x00\x3c\x93\xdc\xd2\xae\xf1\x02\x2e\x3e\x8b\xbe\xd1\x11\xd1\x42\x01\x39\xc0\x32\x6c\x78\x98\x9b\xf8\x2c\x81\xeb\x56\x5c\x29\xc1\x1e\x8a\xd5\xea\x8a\xcf\xb3\x4d\x01\x7a\x4e\x7b\xa1\xc9\x19\x01\x61\xef\x05\x3c\x76\x13\xc6\x93\x4a\x7e\x4e\x66\x71\xb9\xb7\xfc\x42\xb2\x36\x33\xaf\xca\xa8\x74\xd1\xeb\xf3\x90\xa5\xf8\xd3\xce\x94\x55\x4c\xe1\x96\x35\xa8\x34\xed\x43\x82\x7d\x35\x98\x52\x5b\x04\x43\x01\x49\xc8\x9e\xbb\x30\xd5\x98\x2e\xf5\x9a\x03\x7b\x02\x46\x13\x1f\x9b\x32\x9e\x1b\x77\xc3\xf9\xe0\xc8\x83\x4b\x94\xa5\x64\xa0\xf3\x04\x45\xe3\xa0\x8f\xda\xc0\x3a\xac\xb7\xa1\x7d\x0c\x2f\x45\x0d\x05\x32\x5b\xd3\x19\xb3\x62\xef\x5d\xa1\x26\x2f\xb5\xfc\x4a\xb3\xc3\xa5\x41\x93\x18\xb4\x41\xa5\xd5\x83\xa5\x7d\x26\x34\x9f\xcd\x7f\x1b\x3e\xe8\x73\x22\xeb\x1b\x3c\x27\xa2\xb3\x00\x3c\x93\xdc\xd2\xae\xf1\x02\x2e\x3e\x8b\xbe\xd1\x11\xd1\x42\x01\x39\xc0\x32\x6c\x78\x98\x9b\xf8\x2c\x81\xeb\x56\x5c\x29\xc1\x1e\x8a\xd5\xea\x8a\xcf\xb3\x4d\x01\x7a\x4e\x7b\xa1\xc9\x19\x01\x61\xef\x05\x3c\x76\x13\xc6\x93\x4a\x7e\x4e\x66\x71\xb9\xb7\xfc\x42\xb2\x36\x33\xaf\xca\xa8\x74\xd1\xeb\xf3\x90\xa5\xf8\xd3\xce\x94\x55\x4c\xe1\x96\x35' | |
index_bound1 = 0x1836 | |
index_bound2 = 0x5AD | |
black_list_xref_addr = [0x180014173, 0x180014106] | |
def decrypt(idx): | |
""" string decoding method """ | |
if idx >= index_bound1: | |
return # oob | |
output = "" | |
while True: | |
c = idc.get_wide_byte(enc_strings_blob1 + idx) ^ xor_bytes_array[(idx % len(xor_bytes_array))] | |
if c == 0: break | |
output += chr(c) | |
idx += 1 | |
return output | |
def decrypt2(idx): | |
""" string decoding method """ | |
if idx >= index_bound2: | |
return # oob | |
output = "" | |
while True: | |
c = idc.get_wide_byte(enc_strings_blob2 + idx) ^ xor_bytes_array2[(idx % len(xor_bytes_array2))] | |
if c == 0: break | |
output += chr(c) | |
idx += 1 | |
return output | |
def create_str_comment(idx, ea): | |
""" method to create the comments at offset to string decoding method """ | |
decStr = decrypt(idx) | |
idc.set_cmt(ea, decStr, 0) | |
return True | |
def create_str_comment2(idx, ea): | |
""" method to create the comments at offset to string decoding method """ | |
#index_value = get_operand_value(ca, 1) | |
decStr = decrypt2(idx) | |
idc.set_cmt(ea, decStr, 0) | |
return True | |
def decrypt_strings(func_addr): | |
""" decode all of the strings """ | |
for x in idautils.XrefsTo(func_addr, 0): | |
xref_addr = x.frm | |
if xref_addr in black_list_xref_addr or not ida_bytes.is_code(ida_bytes.get_full_flags(xref_addr)): | |
continue | |
str_idx_arg_ea = idaapi.get_arg_addrs(xref_addr)[0] | |
if idc.print_insn_mnem(str_idx_arg_ea) == "pop": | |
str_idx_value = idc.get_operand_value(idc.prev_head(str_idx_arg_ea), 0) | |
elif idc.print_insn_mnem(str_idx_arg_ea) == "push": | |
str_idx_value = idc.get_operand_value(str_idx_arg_ea, 0) | |
else: | |
str_idx_value = idc.get_operand_value(str_idx_arg_ea, 1) | |
if str_idx_value < 0xFFFF: | |
create_str_comment(str_idx_value, xref_addr) | |
def decrypt_strings2(func_addr): | |
""" decode all of the strings """ | |
for x in idautils.XrefsTo(func_addr, 0): | |
xref_addr = x.frm | |
if xref_addr in black_list_xref_addr or not ida_bytes.is_code(ida_bytes.get_full_flags(xref_addr)): | |
continue | |
str_idx_arg_ea = idaapi.get_arg_addrs(xref_addr)[0] | |
if idc.print_insn_mnem(str_idx_arg_ea) == "pop": | |
str_idx_value = idc.get_operand_value(idc.prev_head(str_idx_arg_ea), 0) | |
elif idc.print_insn_mnem(str_idx_arg_ea) == "push": | |
str_idx_value = idc.get_operand_value(str_idx_arg_ea, 0) | |
else: | |
str_idx_value = idc.get_operand_value(str_idx_arg_ea, 1) | |
if str_idx_value < 0xFFFF: | |
create_str_comment2(str_idx_value, xref_addr) | |
def main(): | |
decrypt_strings(decrypt_routine1) | |
decrypt_strings(decrypt_routine2) | |
decrypt_strings2(decrypt_routine3) | |
decrypt_strings2(decrypt_routine4) | |
output = open("all_decrypted_strings_with_index.txt","w") | |
decrypted = "" | |
# for decrypt all strings | |
print('[+] Decrypt all strings with index boundary is {}'.format(hex(index_bound1))) | |
decrypted += '[+] Decrypt all strings with index boundary is {}\n'.format(hex(index_bound1)) | |
idx = 0 | |
while idx < index_bound1: | |
dec_str = decrypt(idx) | |
print("index: %s, decrypted string: %s" % (hex(idx), dec_str)) | |
decrypted += "index: %s, decrypted string: %s \n" % (hex(idx), dec_str) | |
idx += len(dec_str) + 1 | |
print('[+] Decrypt all strings with index boundary is {}'.format(hex(index_bound2))) | |
decrypted += '\n[+] Decrypt all strings with index boundary is {}\n'.format(hex(index_bound2)) | |
idx = 0 | |
while idx < index_bound2: | |
dec_str = decrypt2(idx) | |
print("index: %s, decrypted string: %s" % (hex(idx), dec_str)) | |
decrypted += "index: %s, decrypted string: %s\n" % (hex(idx), dec_str) | |
idx += len(dec_str) + 1 | |
output.write(decrypted) | |
output.close() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment