Created
June 14, 2023 15:36
-
-
Save knez/d3daee6aa3ecf5aa49fe7025ad8470be to your computer and use it in GitHub Desktop.
Zutto Dekiru Deobfuscator
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
| """ | |
| 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