import
flare_emu
from
idc
import
*
from
idaapi
import
*
import
idaapi
import
ida_allins
from
ida_ida
import
*
from
idautils
import
*
import
unicorn
from
keystone
import
*
from
unicorn
import
arm64_const
my_EH
=
flare_emu.EmuHelper()
def
emu_last_x_insn(ea, insn_cnt
=
10
, skip_ea
=
True
, stop_in_brach
=
True
, reg_info
=
{}):
count
=
0
curr_addr
=
ea
while
count < insn_cnt:
curr_addr
=
prev_head(curr_addr,
0
)
insn
=
idaapi.insn_t()
length
=
idaapi.decode_insn(insn, curr_addr)
if
stop_in_brach:
if
(insn.get_canon_feature() & CF_JUMP) !
=
0
or
(insn.get_canon_feature() & CF_CALL) !
=
0
or
insn.itype
in
[
ARM_b, ARM_bl, ARM_br, ARM_bx, ARM_blx1, ARM_blx2, ARM_cbz, ARM_cbnz, ARM_blr,
ARM_tbz, ARM_tbnz, ARM_ldrpc, ARM_ret] :
curr_addr
=
next_head(curr_addr, BADADDR)
break
count
+
=
1
start_addr
=
curr_addr
end_addr
=
ea
my_EH.emulateRange(start_addr, end_addr, registers
=
reg_info, count
=
insn_cnt)
return
my_EH.uc
def
is_valid_address(addr, segment_name
=
".data"
):
seg
=
get_segm_by_name(segment_name)
return
addr >
=
seg.start_ea
and
addr <
=
seg.end_ea
def
is_valid_string(string):
for
c
in
string:
if
c
not
in
string.printable:
return
False
return
True
def
dec_str():
func_addr
=
0x25CDC
all_used_addr
=
list
(CodeRefsTo(func_addr,
False
))
error_process_addr
=
[]
for
used_addr
in
all_used_addr:
try
:
uc_stata
=
emu_last_x_insn(used_addr, reg_info
=
{
"X0"
:
0
,
"X1"
:
0
,
"X2"
:
0
,
"X3"
:
0
})
x0
=
uc_stata.reg_read(arm64_const.UC_ARM64_REG_X0)
x1
=
uc_stata.reg_read(arm64_const.UC_ARM64_REG_X1)
x2
=
uc_stata.reg_read(arm64_const.UC_ARM64_REG_X2)
x3
=
uc_stata.reg_read(arm64_const.UC_ARM64_REG_X3)
out_addr, enc_addr, key, lens
=
x0, x1, x2, x3
if
is_valid_address(enc_addr):
curr_str_bytes
=
[]
for
i
in
range
(lens):
curr_char
=
get_wide_byte(enc_addr
+
i)
curr_char ^
=
key
key
+
=
3
key
%
=
256
curr_str_bytes.append(curr_char)
curr_str
=
bytearray(curr_str_bytes).decode(
'utf-8'
)
if
is_valid_address(out_addr):
for
k
in
range
(lens):
patch_byte(out_addr
+
k, curr_str_bytes[k])
create_strlit(out_addr,
0
,STRTYPE_C)
print
(f
"patched {hex(out_addr)} with {curr_str}"
)
else
:
error_process_addr.append(used_addr)
else
:
error_process_addr.append(used_addr)
except
Exception as e:
error_process_addr.append(used_addr)
print
()
for
addr
in
error_process_addr:
print
(
hex
(addr),end
=
' '
)