Skip to content

Instantly share code, notes, and snippets.

@knez
Created June 14, 2023 15:36
Show Gist options
  • Select an option

  • Save knez/d3daee6aa3ecf5aa49fe7025ad8470be to your computer and use it in GitHub Desktop.

Select an option

Save knez/d3daee6aa3ecf5aa49fe7025ad8470be to your computer and use it in GitHub Desktop.
Zutto Dekiru Deobfuscator
"""
Deobfuscate Zutto Dekiru shellcode encoder
Example:
48 31 ED xor rbp, rbp
DA CB fcmove st, st(3)
54 push rsp
66 BD 17 01 mov bp, 117h
41 5C pop r12
66 41 81 E4 90 F1 and r12w, 0F190h
48 BA 06 E0 BB DD CA C2 8A 0C mov rdx, 0C8AC2CADDBBE006h ; xor constant
49 0F AE 04 24 fxsave64 qword ptr [r12] ; save registers
49 83 C4 08 add r12, 8
4D 8B 2C 24 mov r13, [r12] ; get fp instruction location
decryption:
48 FF CD dec rbp
49 31 54 ED 33 xor [r13+rbp*8+33h], rdx
48 85 ED test rbp, rbp
75 F3 jnz short decryption
<decrypted code>
"""
import idaapi
import ida_allins
import ida_auto
def decode_block(ea, size, key):
for _ in range(size):
patch_qword(ea, get_qword(ea) ^ key)
ea += 8
def is_last_layer(ea):
# is last if floating point instruction is not found
for _ in range(50):
insn = idaapi.insn_t()
length = idaapi.decode_insn(insn, ea)
if get_db_byte(ea) in range(0xD8, 0xDF + 1):
return 0
ea += length
return 1
def unpack_dekiru(ea):
i = 0
while True:
insn = idaapi.insn_t()
length = idaapi.decode_insn(insn, ea)
if insn.itype == ida_allins.NN_mov:
if insn.ops[0].type == ida_ua.o_reg and insn.ops[1].type == ida_ua.o_imm:
if insn.ops[1].value <= 0xFFFF:
size = insn.ops[1].value
else:
xor_key = insn.ops[1].value
if insn.itype == ida_allins.NN_jnz:
decode_block(ea + length, size, xor_key)
ida_bytes.del_items(ea + length, 0, 20)
ida_auto.auto_make_code(ea + length)
i += 1
if is_last_layer(ea + length):
print('Decoded', i, 'layers')
break
ea += length
unpack_dekiru(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment