闲着没事,看到有新游出来,于是简单的分析学习一下。
由于时间和水平有限,本文会存在诸多不足,欢迎补充指正。
样本:xqtd
加固:mtp
工具:ida、010、jadx、frida
第一种,流程很清晰,比较好处理
ida
脚本,如遇到报错需要修改脚本
处理前
处理后
第二种,有点像做了流水线优化,不太好处理
在方法sub_985D4
反射调用isDebuggerConnected
在方法sub_9843C
使用socket
连接了127.0.0.1:23946
在方法sub_98B34
遍历maps
查找frida-gadget
、frida-agent
在方法sub_994A8
使用socket
连接了127.0.0.1:27402
记得比较流水账,大佬们将就看。
import
idautils
import
idc
import
idaapi
import
ida_ua
from
keystone
import
*
g_reg
=
[
0
]
*
40
reg_base
=
129
g_cond_info
=
list
()
ldr_reg
=
-
1
add_reg
=
-
1
ks
=
keystone.Ks(keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN)
def
get_opcode(ea):
opcode
=
None
disasm
=
idc.GetDisasm(ea)
if
disasm.find(
'LT'
) !
=
-
1
:
opcode
=
'blt'
elif
disasm.find(
'EQ'
) !
=
-
1
:
opcode
=
'beq'
elif
disasm.find(
'CC'
) !
=
-
1
:
opcode
=
'bcc'
elif
disasm.find(
'GT'
) !
=
-
1
:
opcode
=
'bgt'
elif
disasm.find(
'NE'
) !
=
-
1
:
opcode
=
'bne'
elif
disasm.find(
'GE'
) !
=
-
1
:
opcode
=
'bge'
elif
disasm.find(
'HI'
) !
=
-
1
:
opcode
=
'bhi'
return
opcode
def
do_patch(patch_1, patch_2, opcode, cond_jmp_addr, uncond_jmp_addr):
print
(
"patch_1=0x%x patch_1=0x%x opcode=%s cond_jmp_addr=0x%x uncond_jmp_addr=0x%x"
%
(patch_1, patch_2, opcode, cond_jmp_addr, uncond_jmp_addr))
jump_offset
=
" ({:d})"
.
format
(cond_jmp_addr
-
patch_1)
repair_opcode
=
opcode
+
jump_offset
encoding, count
=
ks.asm(repair_opcode)
idaapi.patch_byte(patch_1, encoding[
0
])
idaapi.patch_byte(patch_1
+
1
, encoding[
1
])
idaapi.patch_byte(patch_1
+
2
, encoding[
2
])
idaapi.patch_byte(patch_1
+
3
, encoding[
3
])
jump_offset
=
" ({:d})"
.
format
(uncond_jmp_addr
-
patch_2)
repair_opcode
=
'b'
+
jump_offset
encoding, count
=
ks.asm(repair_opcode)
idaapi.patch_byte(patch_2, encoding[
0
])
idaapi.patch_byte(patch_2
+
1
, encoding[
1
])
idaapi.patch_byte(patch_2
+
2
, encoding[
2
])
idaapi.patch_byte(patch_2
+
3
, encoding[
3
])
def
do_deobf(ea):
opcode
=
get_opcode(ea)
if
opcode
is
None
:
print
(
"opcode:unknown opcode 0x%x"
%
ea)
return
ea
cond_reg
=
-
1
uncond_reg
=
-
1
cond_data
=
-
1
uncond_data
=
-
1
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'CSEL'
:
cond_reg
=
idc.get_operand_value(ea,
1
)
uncond_reg
=
idc.get_operand_value(ea,
2
)
elif
mnem
=
=
'CSET'
:
cond_data
=
1
uncond_data
=
0
ea
=
idc.next_head(ea)
ldr_reg
=
-
1
lsl_value
=
-
1
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'LSL'
:
lsl_value
=
idc.get_operand_value(ea,
2
)
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem !
=
'LDR'
:
print
(
"LDR:0x%x -> %s"
%
(ea, mnem))
return
ea
operand_type
=
idc.get_operand_type(ea,
1
)
if
operand_type
=
=
idc.o_phrase:
insn
=
ida_ua.insn_t()
ida_ua.decode_insn(insn, ea)
ldr_reg
=
insn.Op2.reg
if
lsl_value
=
=
-
1
:
lsl_value
=
insn.Op2.value
else
:
return
ea
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'MOV'
:
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem !
=
'ADD'
:
print
(
"ADD:0x%x -> %s"
%
(ea, mnem))
return
ea
op_3
=
idc.print_operand(ea,
2
)
op_3
=
op_3[
1
:]
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem !
=
'BR'
:
print
(
"BR:0x%x -> %s"
%
(ea, mnem))
return
ea
if
cond_data !
=
-
1
and
uncond_data !
=
-
1
:
print
(lsl_value)
cond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(cond_data << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
uncond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(uncond_data << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
else
:
cond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(g_reg[cond_reg
-
reg_base] << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
uncond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(g_reg[uncond_reg
-
reg_base] << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
do_patch(idc.prev_head(ea), ea, opcode, cond_jmp_addr, uncond_jmp_addr)
return
ea
def
deobf(ea):
off_reg
=
-
1
off_data
=
-
1
while
True
:
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'RET'
:
break
elif
mnem
=
=
'MOV'
:
op_1_type
=
idc.get_operand_type(ea,
0
)
op_2_type
=
idc.get_operand_type(ea,
1
)
if
(op_1_type
=
=
idc.o_reg)
and
(op_2_type
=
=
idc.o_imm):
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
g_reg[op_1
-
reg_base]
=
op_2
elif
mnem
=
=
'MOVK'
:
op_1_type
=
idc.get_operand_type(ea,
0
)
op_2_type
=
idc.get_operand_type(ea,
1
)
op_3_type
=
idc.get_operand_type(ea,
2
)
if
(op_1_type
=
=
idc.o_reg)
and
(op_2_type
=
=
idc.o_imm):
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
g_reg[op_1
-
reg_base]
=
(op_2 <<
16
) | (g_reg[op_1
-
reg_base] &
0xffff
)
elif
mnem
=
=
'ADRP'
:
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
off_reg
=
op_1
off_data
=
op_2
elif
mnem
=
=
'ADD'
:
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
op_3
=
idc.get_operand_value(ea,
2
)
op_3_type
=
idc.get_operand_type(ea,
2
)
if
(op_1
=
=
off_reg)
and
(op_2
=
=
off_reg)
and
(op_3_type
=
=
idc.o_imm):
off_data
=
off_data
+
op_3
ldr_reg
=
off_reg
-
reg_base
g_reg[ldr_reg]
=
off_data
elif
(mnem
=
=
'CSEL'
)
or
(mnem
=
=
'CSINC'
)
or
(mnem
=
=
'CSET'
)
or
(mnem
=
=
'CINC'
):
ea
=
do_deobf(ea)
continue
ea
=
idc.next_head(ea)
def
test():
for
i
in
range
(
len
(g_reg)):
print
(
"%d:0x%x"
%
(i, g_reg[i]))
def
main():
ea
=
idc.get_screen_ea()
func
=
idaapi.get_func(ea)
ea
=
func.start_ea
print
(
"start deobf fun:0x%x"
%
(ea))
deobf(ea)
print
(
"deobf ok!"
)
pass
if
__name__
=
=
"__main__"
:
main()
import
idautils
import
idc
import
idaapi
import
ida_ua
from
keystone
import
*
g_reg
=
[
0
]
*
40
reg_base
=
129
g_cond_info
=
list
()
ldr_reg
=
-
1
add_reg
=
-
1
ks
=
keystone.Ks(keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN)
def
get_opcode(ea):
opcode
=
None
disasm
=
idc.GetDisasm(ea)
if
disasm.find(
'LT'
) !
=
-
1
:
opcode
=
'blt'
elif
disasm.find(
'EQ'
) !
=
-
1
:
opcode
=
'beq'
elif
disasm.find(
'CC'
) !
=
-
1
:
opcode
=
'bcc'
elif
disasm.find(
'GT'
) !
=
-
1
:
opcode
=
'bgt'
elif
disasm.find(
'NE'
) !
=
-
1
:
opcode
=
'bne'
elif
disasm.find(
'GE'
) !
=
-
1
:
opcode
=
'bge'
elif
disasm.find(
'HI'
) !
=
-
1
:
opcode
=
'bhi'
return
opcode
def
do_patch(patch_1, patch_2, opcode, cond_jmp_addr, uncond_jmp_addr):
print
(
"patch_1=0x%x patch_1=0x%x opcode=%s cond_jmp_addr=0x%x uncond_jmp_addr=0x%x"
%
(patch_1, patch_2, opcode, cond_jmp_addr, uncond_jmp_addr))
jump_offset
=
" ({:d})"
.
format
(cond_jmp_addr
-
patch_1)
repair_opcode
=
opcode
+
jump_offset
encoding, count
=
ks.asm(repair_opcode)
idaapi.patch_byte(patch_1, encoding[
0
])
idaapi.patch_byte(patch_1
+
1
, encoding[
1
])
idaapi.patch_byte(patch_1
+
2
, encoding[
2
])
idaapi.patch_byte(patch_1
+
3
, encoding[
3
])
jump_offset
=
" ({:d})"
.
format
(uncond_jmp_addr
-
patch_2)
repair_opcode
=
'b'
+
jump_offset
encoding, count
=
ks.asm(repair_opcode)
idaapi.patch_byte(patch_2, encoding[
0
])
idaapi.patch_byte(patch_2
+
1
, encoding[
1
])
idaapi.patch_byte(patch_2
+
2
, encoding[
2
])
idaapi.patch_byte(patch_2
+
3
, encoding[
3
])
def
do_deobf(ea):
opcode
=
get_opcode(ea)
if
opcode
is
None
:
print
(
"opcode:unknown opcode 0x%x"
%
ea)
return
ea
cond_reg
=
-
1
uncond_reg
=
-
1
cond_data
=
-
1
uncond_data
=
-
1
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'CSEL'
:
cond_reg
=
idc.get_operand_value(ea,
1
)
uncond_reg
=
idc.get_operand_value(ea,
2
)
elif
mnem
=
=
'CSET'
:
cond_data
=
1
uncond_data
=
0
ea
=
idc.next_head(ea)
ldr_reg
=
-
1
lsl_value
=
-
1
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'LSL'
:
lsl_value
=
idc.get_operand_value(ea,
2
)
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem !
=
'LDR'
:
print
(
"LDR:0x%x -> %s"
%
(ea, mnem))
return
ea
operand_type
=
idc.get_operand_type(ea,
1
)
if
operand_type
=
=
idc.o_phrase:
insn
=
ida_ua.insn_t()
ida_ua.decode_insn(insn, ea)
ldr_reg
=
insn.Op2.reg
if
lsl_value
=
=
-
1
:
lsl_value
=
insn.Op2.value
else
:
return
ea
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'MOV'
:
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem !
=
'ADD'
:
print
(
"ADD:0x%x -> %s"
%
(ea, mnem))
return
ea
op_3
=
idc.print_operand(ea,
2
)
op_3
=
op_3[
1
:]
ea
=
idc.next_head(ea)
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem !
=
'BR'
:
print
(
"BR:0x%x -> %s"
%
(ea, mnem))
return
ea
if
cond_data !
=
-
1
and
uncond_data !
=
-
1
:
print
(lsl_value)
cond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(cond_data << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
uncond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(uncond_data << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
else
:
cond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(g_reg[cond_reg
-
reg_base] << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
uncond_jmp_addr
=
(idc.get_qword(g_reg[ldr_reg
-
reg_base]
+
(g_reg[uncond_reg
-
reg_base] << lsl_value))
+
g_reg[
int
(op_3)]) &
0xffffffffffffffff
do_patch(idc.prev_head(ea), ea, opcode, cond_jmp_addr, uncond_jmp_addr)
return
ea
def
deobf(ea):
off_reg
=
-
1
off_data
=
-
1
while
True
:
mnem
=
idc.ida_ua.ua_mnem(ea)
if
mnem
=
=
'RET'
:
break
elif
mnem
=
=
'MOV'
:
op_1_type
=
idc.get_operand_type(ea,
0
)
op_2_type
=
idc.get_operand_type(ea,
1
)
if
(op_1_type
=
=
idc.o_reg)
and
(op_2_type
=
=
idc.o_imm):
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
g_reg[op_1
-
reg_base]
=
op_2
elif
mnem
=
=
'MOVK'
:
op_1_type
=
idc.get_operand_type(ea,
0
)
op_2_type
=
idc.get_operand_type(ea,
1
)
op_3_type
=
idc.get_operand_type(ea,
2
)
if
(op_1_type
=
=
idc.o_reg)
and
(op_2_type
=
=
idc.o_imm):
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
g_reg[op_1
-
reg_base]
=
(op_2 <<
16
) | (g_reg[op_1
-
reg_base] &
0xffff
)
elif
mnem
=
=
'ADRP'
:
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
off_reg
=
op_1
off_data
=
op_2
elif
mnem
=
=
'ADD'
:
op_1
=
idc.get_operand_value(ea,
0
)
op_2
=
idc.get_operand_value(ea,
1
)
op_3
=
idc.get_operand_value(ea,
2
)
op_3_type
=
idc.get_operand_type(ea,
2
)
if
(op_1
=
=
off_reg)
and
(op_2
=
=
off_reg)
and
(op_3_type
=
=
idc.o_imm):
off_data
=
off_data
+
op_3
ldr_reg
=
off_reg
-
reg_base
g_reg[ldr_reg]
=
off_data
elif
(mnem
=
=
'CSEL'
)
or
(mnem
=
=
'CSINC'
)
or
(mnem
=
=
'CSET'
)
or
(mnem
=
=
'CINC'
):
ea
=
do_deobf(ea)
continue
ea
=
idc.next_head(ea)
def
test():
for
i
in
range
(
len
(g_reg)):
print
(
"%d:0x%x"
%
(i, g_reg[i]))
def
main():
ea
=
idc.get_screen_ea()
func
=
idaapi.get_func(ea)
ea
=
func.start_ea
print
(
"start deobf fun:0x%x"
%
(ea))
deobf(ea)
print
(
"deobf ok!"
)
pass
if
__name__
=
=
"__main__"
:
main()
import
idautils
import
idc
import
idaapi
decrypt_fun_list
=
dict
()
def
get_code_refs_to_list(addr):
result
=
list
(idautils.CodeRefsTo(addr,
True
))
return
result
def
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_addr):
flag
=
idc.get_wide_byte(src_addr)
str_len
=
flag ^ (idc.get_wide_byte(src_addr
+
1
))
final_str
=
''
for
i
in
range
(str_len):
v4
=
idc.get_wide_byte(src_addr
+
2
+
i)
v5
=
(flag
+
i) ^ eor_data
final_str
+
=
chr
((v4 ^ flag) &
0xff
)
flag
=
v5
+
add_data
decrypt_fun_list[call_addr]
=
final_str
+
" "
+
str
(
hex
(offset))
print
(
'decrypt_addr=0x%x offset=0x%x, final_str=%s'
%
(call_addr, offset, final_str))
def
decrpt_str():
decrypt_fun_list.clear()
tmp_list
=
[
7
,
6
,
5
,
4
,
3
,
2
,
1
]
fun_list
=
get_code_refs_to_list(
0x106C54
)
if
not
fun_list:
return
for
i
in
range
(
len
(fun_list)):
call_addr
=
fun_list[i]
call_addr_start
=
idc.get_func_attr(call_addr, idc.FUNCATTR_START)
caller_fun_list
=
get_code_refs_to_list(call_addr_start)
for
j
in
range
(
len
(caller_fun_list)):
call_decryptStr_addr
=
caller_fun_list[j]
arg_addr
=
idc.prev_head(call_decryptStr_addr)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
while
True
:
if
(register
=
=
129
)
and
(mnem
=
=
'MOV'
):
break
arg_addr
=
idc.prev_head(arg_addr)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
offset
=
idc.get_operand_value(arg_addr,
1
)
if
offset
=
=
0xa0
:
offset
=
0
src_addr
=
0x1250D8
+
offset
dst_addr
=
0x15E778
+
offset
index
=
offset
%
100
eor_data
=
index
add_data
=
tmp_list[(index
%
7
)]
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_decryptStr_addr)
pass
def
main():
decrpt_str()
if
__name__
=
=
"__main__"
:
main()
import
idautils
import
idc
import
idaapi
decrypt_fun_list
=
dict
()
def
get_code_refs_to_list(addr):
result
=
list
(idautils.CodeRefsTo(addr,
True
))
return
result
def
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_addr):
flag
=
idc.get_wide_byte(src_addr)
str_len
=
flag ^ (idc.get_wide_byte(src_addr
+
1
))
final_str
=
''
for
i
in
range
(str_len):
v4
=
idc.get_wide_byte(src_addr
+
2
+
i)
v5
=
(flag
+
i) ^ eor_data
final_str
+
=
chr
((v4 ^ flag) &
0xff
)
flag
=
v5
+
add_data
decrypt_fun_list[call_addr]
=
final_str
+
" "
+
str
(
hex
(offset))
print
(
'decrypt_addr=0x%x offset=0x%x, final_str=%s'
%
(call_addr, offset, final_str))
def
decrpt_str():
decrypt_fun_list.clear()
tmp_list
=
[
7
,
6
,
5
,
4
,
3
,
2
,
1
]
fun_list
=
get_code_refs_to_list(
0x106C54
)
if
not
fun_list:
return
for
i
in
range
(
len
(fun_list)):
call_addr
=
fun_list[i]
call_addr_start
=
idc.get_func_attr(call_addr, idc.FUNCATTR_START)
caller_fun_list
=
get_code_refs_to_list(call_addr_start)
for
j
in
range
(
len
(caller_fun_list)):
call_decryptStr_addr
=
caller_fun_list[j]
arg_addr
=
idc.prev_head(call_decryptStr_addr)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
while
True
:
if
(register
=
=
129
)
and
(mnem
=
=
'MOV'
):
break
arg_addr
=
idc.prev_head(arg_addr)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
offset
=
idc.get_operand_value(arg_addr,
1
)
if
offset
=
=
0xa0
:
offset
=
0
src_addr
=
0x1250D8
+
offset
dst_addr
=
0x15E778
+
offset
index
=
offset
%
100
eor_data
=
index
add_data
=
tmp_list[(index
%
7
)]
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_decryptStr_addr)
pass
def
main():
decrpt_str()
if
__name__
=
=
"__main__"
:
main()
__loader_dlopen
__loader_android_dlopen_ext
rtld_db_dlactivity
/
/
在非调试模式下为空函数,如果程序被调试则会被修改为对应的断点指令
__loader_dlopen
__loader_android_dlopen_ext
rtld_db_dlactivity
/
/
在非调试模式下为空函数,如果程序被调试则会被修改为对应的断点指令
cc
/
binmt
/
signature
/
PmsHookApplication
com
/
cloudinject
/
feature
/
App
np
/
manager
/
FuckSign
bin
/
mt
/
apksignaturekillerplus
/
HookApplication
cc
/
binmt
/
signature
/
PmsHookApplication
com
/
cloudinject
/
feature
/
App
np
/
manager
/
FuckSign
bin
/
mt
/
apksignaturekillerplus
/
HookApplication
/
init.vbox86.rc
/
dev
/
socket
/
genyd
/
data
/
data
/
com.tencent.tinput
init.android_x86.rc
ueventd.android_x86.rc
/
system
/
framework
/
x86
/
init.vbox86.rc
/
dev
/
socket
/
genyd
/
data
/
data
/
com.tencent.tinput
init.android_x86.rc
ueventd.android_x86.rc
/
system
/
framework
/
x86
import
idautils
import
idc
import
idaapi
decrypt_fun_list
=
dict
()
def
get_code_refs_to_list(addr):
result
=
list
(idautils.CodeRefsTo(addr,
True
))
return
result
def
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_addr):
flag
=
idc.get_wide_byte(src_addr)
str_len
=
flag ^ (idc.get_wide_byte(src_addr
+
1
))
final_str
=
''
for
i
in
range
(str_len):
v10
=
idc.get_wide_byte(src_addr
+
2
+
i) ^ flag
flag
=
((i
+
flag) ^ eor_data)
+
add_data
final_str
+
=
chr
(v10 &
0xff
)
decrypt_fun_list[call_addr]
=
final_str
+
" "
+
str
(
hex
(offset))
print
(
'call_addr=0x%x, offset=0x%x, eor_data=0x%x, add_data=0x%x, final_str=%s'
%
(call_addr, offset, eor_data, add_data, final_str))
def
decrpt_str():
decrypt_fun_list.clear()
tmp_list
=
[
7
,
6
,
5
,
4
,
3
,
2
,
1
]
fun_list
=
get_code_refs_to_list(
0x27E724
)
if
not
fun_list:
return
for
i
in
range
(
len
(fun_list)):
arg_addr
=
fun_list[i]
call_addr
=
arg_addr
fun_start
=
idc.get_func_attr(arg_addr, idc.FUNCATTR_START)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
while
arg_addr >
=
fun_start:
if
(register
=
=
129
)
and
(mnem
=
=
'MOV'
):
offset
=
idc.get_operand_value(arg_addr,
1
)
break
arg_addr
=
idc.prev_head(arg_addr)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
if
offset
=
=
0xa0
:
offset
=
0
index
=
offset
%
100
eor_data
=
index
add_data
=
tmp_list[(index
%
7
)]
src_addr
=
0x3880E4
+
offset
dst_addr
=
0x4C9B78
+
offset
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_addr)
def
main():
decrpt_str()
if
__name__
=
=
"__main__"
:
main()
import
idautils
import
idc
import
idaapi
decrypt_fun_list
=
dict
()
def
get_code_refs_to_list(addr):
result
=
list
(idautils.CodeRefsTo(addr,
True
))
return
result
def
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_addr):
flag
=
idc.get_wide_byte(src_addr)
str_len
=
flag ^ (idc.get_wide_byte(src_addr
+
1
))
final_str
=
''
for
i
in
range
(str_len):
v10
=
idc.get_wide_byte(src_addr
+
2
+
i) ^ flag
flag
=
((i
+
flag) ^ eor_data)
+
add_data
final_str
+
=
chr
(v10 &
0xff
)
decrypt_fun_list[call_addr]
=
final_str
+
" "
+
str
(
hex
(offset))
print
(
'call_addr=0x%x, offset=0x%x, eor_data=0x%x, add_data=0x%x, final_str=%s'
%
(call_addr, offset, eor_data, add_data, final_str))
def
decrpt_str():
decrypt_fun_list.clear()
tmp_list
=
[
7
,
6
,
5
,
4
,
3
,
2
,
1
]
fun_list
=
get_code_refs_to_list(
0x27E724
)
if
not
fun_list:
return
for
i
in
range
(
len
(fun_list)):
arg_addr
=
fun_list[i]
call_addr
=
arg_addr
fun_start
=
idc.get_func_attr(arg_addr, idc.FUNCATTR_START)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
while
arg_addr >
=
fun_start:
if
(register
=
=
129
)
and
(mnem
=
=
'MOV'
):
offset
=
idc.get_operand_value(arg_addr,
1
)
break
arg_addr
=
idc.prev_head(arg_addr)
mnem
=
idc.ida_ua.ua_mnem(arg_addr)
register
=
idc.get_operand_value(arg_addr,
0
)
if
offset
=
=
0xa0
:
offset
=
0
index
=
offset
%
100
eor_data
=
index
add_data
=
tmp_list[(index
%
7
)]
src_addr
=
0x3880E4
+
offset
dst_addr
=
0x4C9B78
+
offset
do_decrypt(src_addr, dst_addr, offset, eor_data, add_data, call_addr)
def
main():
decrpt_str()
if
__name__
=
=
"__main__"
:
main()
__int64 __fastcall sub_26A218(__int64 result)
{
v1
=
result;
if
( !
*
(_QWORD
*
)(result
+
8
) )
{
v11
=
sub_27E724(
0x1ADE
);
v12
=
0
;
v13[
0
]
=
(__int64)sub_26E5D8;
v13[
1
]
=
sub_27E724(
0x1AEB
);
v14
=
0
;
v15
=
sub_26E644;
v16
=
sub_27E724(
0x1AF9
);
v17
=
0
;
v18
=
sub_26E700;
v19
=
sub_27E724(
0x147E
);
v20
=
13
;
v21
=
sub_26B698;
v22
=
sub_27E724(
5260
);
v23
=
11
;
v24
=
sub_26B398;
v25
=
sub_27E724(
5266
);
v26
=
4
;
v27
=
sub_26B714;
v28
=
sub_27E724(
5276
);
v29
=
4
;
v30
=
sub_26B748;
v31
=
sub_27E724(
5286
);
v32
=
2
;
v33
=
sub_26B76C;
v34
=
sub_27E724(
5299
);
v35
=
3
;
v36
=
sub_26B79C;
v37
=
sub_27E724(
5312
);
v38
=
3
;
v39
=
&sub_26B824;
v40
=
sub_27E724(
5322
);
v41
=
14
;
v42
=
sub_26CC04;
v43
=
sub_27E724(
5330
);
v44
=
3
;
v45
=
&sub_26B8A0;
v46
=
sub_27E724(
5341
);
v47
=
3
;
v48
=
sub_26B918;
v49
=
sub_27E724(
5356
);
v50
=
5
;
v51
=
sub_26BB7C;
v52
=
sub_27E724(
5370
);
v53
=
3
;
v54
=
sub_26BACC;
v55
=
sub_27E724(
5384
);
v56
=
4
;
v57
=
sub_26BD10;
v58
=
sub_27E724(
5398
);
v59
=
4
;
v60
=
sub_26BDE8;
v61
=
sub_27E724(
5413
);
v62
=
5
;
v63
=
sub_26BEBC;
v64
=
sub_27E724(
5428
);
v65
=
5
;
v66
=
sub_26BF74;
v67
=
sub_27E724(
5443
);
v68
=
5
;
v69
=
sub_26C02C;
v70
=
sub_27E724(
5458
);
v71
=
2
;
v72
=
sub_26C0E4;
v73
=
sub_27E724(
5465
);
v74
=
3
;
v75
=
sub_26C128;
v76
=
sub_27E724(
5478
);
v77
=
3
;
v78
=
sub_26C208;
v79
=
sub_27E724(
5491
);
v80
=
3
;
v81
=
sub_26C1C8;
v82
=
sub_27E724(
5504
);
v83
=
3
;
v84
=
sub_26C248;
v85
=
sub_27E724(
5521
);
v86
=
3
;
v87
=
sub_26C288;
v88
=
sub_27E724(
5539
);
v89
=
3
;
v90
=
sub_26C338;
v91
=
sub_27E724(
5553
);
v92
=
3
;
v93
=
sub_26C3AC;
v94
=
sub_27E724(
5566
);
v95
=
3
;
v96
=
sub_26C45C;
v97
=
sub_27E724(
5579
);
v98
=
3
;
v99
=
sub_26C404;
v100
=
sub_27E724(
5592
);
v101
=
3
;
v102
=
sub_26B934;
v103
=
sub_27E724(
5605
);
v104
=
3
;
v105
=
sub_26B9BC;
v106
=
sub_27E724(
5618
);
v107
=
3
;
v108
=
sub_26BA44;
v109
=
sub_27E724(
5631
);
v110
=
17
;
v111
=
sub_26CC54;
v112
=
sub_27E724(
5645
);
v113
=
18
;
v114
=
sub_26CC98;
v115
=
sub_27E724(
5661
);
v116
=
19
;
v117
=
sub_26CCF4;
v118
=
sub_27E724(
5681
);
v119
=
15
;
v120
=
sub_26C4B4;
v121
=
sub_27E724(
5700
);
v122
=
20
;
v123
=
sub_26CD64;
v124
=
sub_27E724(
5713
);
v125
=
3
;
v126
=
sub_26CE88;
v127
=
sub_27E724(
5730
);
v128
=
3
;
v129
=
sub_26CF3C;
v130
=
sub_27E724(
0x1678
);
v131
=
3
;
v132
=
sub_26CFF0;
v133
=
sub_27E724(
5768
);
v134
=
6
;
v135
=
sub_26D08C;
v136
=
sub_27E724(
5780
);
v137
=
6
;
v138
=
sub_26D1C8;
v139
=
sub_27E724(
5796
);
v140
=
7
;
v141
=
sub_26D334;
v142
=
sub_27E724(
5809
);
v143
=
7
;
v144
=
sub_26D33C;
v145
=
sub_27E724(
6915
);
v146
=
2
;
v147
=
sub_26D344;
v148
=
sub_27E724(
5826
);
v149
=
2
;
v150
=
sub_26D3B8;
v151
=
sub_27E724(
5840
);
v152
=
2
;
v153
=
sub_26D3E8;
v154
=
sub_27E724(
5858
);
v155
=
1
;
v156
=
sub_26DA50;
v157
=
sub_27E724(
5870
);
v158
=
1
;
v159
=
sub_26DA5C;
v160
=
sub_27E724(
5882
);
v161
=
7
;
v162
=
sub_26DC8C;
v163
=
sub_27E724(
5897
);
v164
=
7
;
v165
=
sub_26DC94;
v166
=
sub_27E724(
5916
);
v167
=
3
;
v168
=
sub_26DC9C;
v169
=
sub_27E724(
6460
);
v170
=
3
;
v171
=
sub_26DCB8;
v172
=
sub_27E724(
6669
);
v173
=
1
;
v174
=
sub_26C598;
v175
=
sub_27E724(
5934
);
v176
=
15
;
v177
=
sub_26C5C4;
v178
=
sub_27E724(
5949
);
v179
=
7
;
v180
=
sub_26E1B0;
v181
=
sub_27E724(
5974
);
v182
=
7
;
v183
=
sub_26E1B8;
v184
=
sub_27E724(
6003
);
v185
=
1
;
v186
=
sub_26C5B4;
v187
=
sub_27E724(
6012
);
v188
=
1
;
v189
=
sub_26C5BC;
v190
=
sub_27E724(
6021
);
v191
=
15
;
v192
=
sub_26C5DC;
v193
=
sub_27E724(
6032
);
v194
=
15
;
v195
=
sub_26C660;
v196
=
sub_27E724(
6042
);
v197
=
14
;
v198
=
sub_26C6E4;
v199
=
sub_27E724(
6058
);
v200
=
3
;
v201
=
sub_26C780;
v202
=
sub_27E724(
6388
);
v203
=
3
;
v204
=
sub_26C7D4;
v205
=
sub_27E724(
6074
);
v206
=
15
;
v207
=
sub_26D418;
v208
=
sub_27E724(
6085
);
v209
=
5
;
v210
=
sub_26D5AC;
v211
=
sub_27E724(
6098
);
v212
=
5
;
v213
=
sub_26D5EC;
v214
=
sub_27E724(
6115
);
v215
=
5
;
v216
=
sub_26D62C;
v217
=
sub_27E724(
6129
);
v218
=
5
;
v219
=
sub_26D704;
v220
=
sub_27E724(
6143
);
v221
=
5
;
v222
=
sub_26D6C0;
v223
=
sub_27E724(
6157
);
v224
=
3
;
v225
=
sub_26D748;
v226
=
sub_27E724(
6175
);
v227
=
5
;
v228
=
sub_26D870;
v229
=
sub_27E724(
6194
);
v230
=
5
;
v231
=
sub_26D8B0;
v232
=
sub_27E724(
6368
);
v233
=
1
;
v234
=
sub_26E1C0;
v235
=
sub_27E724(
6378
);
v236
=
2
;
v237
=
&sub_26E1D8;
v238
=
sub_27E724(
6482
);
v239
=
1
;
v240
=
sub_26DE88;
v241
=
sub_27E724(
6506
);
v242
=
3
;
v243
=
sub_26E264;
v244
=
sub_27E724(
6533
);
v245
=
2
;
v246
=
&sub_26E360;
v247
=
sub_27E724(
6561
);
v248
=
2
;
v249
=
&sub_26E3C8;
v250
=
sub_27E724(
6590
);
v251
=
1
;
v252
=
sub_26E430;
v253
=
sub_27E724(
6604
);
v254
=
1
;
v255
=
sub_26E438;
v256
=
sub_27E724(
6628
);
v257
=
1
;
v258
=
sub_26E450;
v259
=
sub_27E724(
6647
);
v260
=
2
;
v261
=
sub_26E46C;
v262
=
sub_27E724(
6783
);
v263
=
1
;
v264
=
sub_26E538;
v265
=
sub_27E724(
6802
);
v266
=
3
;
v267
=
&sub_26E540;
v268
=
sub_27E724(
6823
);
v269
=
1
;
v270
=
sub_26E5BC;
v271
=
sub_27E724(
6274
);
v272
=
5
;
v273
=
sub_26C828;
v274
=
sub_27E724(
6292
);
v275
=
1
;
v276
=
sub_26C8C4;
v277
=
sub_27E724(
6302
);
v278
=
1
;
v279
=
sub_26C8E0;
v280
=
sub_27E724(
6312
);
v281
=
3
;
v282
=
sub_26C8FC;
v283
=
sub_27E724(
6326
);
v284
=
3
;
v285
=
sub_26C97C;
v286
=
sub_27E724(
6340
);
v287
=
4
;
v288
=
sub_26CA00;
v289
=
sub_27E724(
6929
);
v290
=
3
;
v291
=
sub_26CA44;
v292
=
sub_27E724(
6939
);
v293
=
3
;
v294
=
sub_26CAC4;
v295
=
sub_27E724(
6949
);
v296
=
4
;
v297
=
sub_26CB48;
v298
=
sub_27E724(
6357
);
v299
=
2
;
v300
=
&sub_26CB90;
v301
=
sub_27E724(
6405
);
v302
=
3
;
v303
=
sub_26DD1C;
v304
=
sub_27E724(
6428
);
v305
=
3
;
v306
=
sub_26DD7C;
v307
=
sub_27E724(
6442
);
v308
=
3
;
v309
=
sub_26DE00;
v310
=
sub_27E724(
6695
);
v311
=
1
;
v312
=
sub_26DE08;
v313
=
sub_27E724(
6714
);
v314
=
1
;
v315
=
sub_26DE38;
v316
=
sub_27E724(
6733
);
v317
=
1
;
v318
=
sub_26DE68;
v319
=
sub_27E724(
6766
);
v320
=
1
;
v321
=
sub_26DE84;
v322
=
sub_27E724(
6836
);
v323
=
3
;
v324
=
&sub_26DF54;
v325
=
sub_27E724(
6851
);
v326
=
4
;
v327
=
&sub_26DFBC;
v328
=
sub_27E724(
6962
);
v329
=
14
;
v330
=
sub_26E044;
v331
=
sub_27E724(
6978
);
v332
=
5
;
v2
=
0LL
;
v333
=
sub_26E058;
do
{
v3
=
*
(unsigned __int8
*
*
)((char
*
)&v11
+
v2
*
8
);
v4
=
strlen_sub_2398FC((__int64)v3);
v5
=
crc32_sub_22B670(v3, v4);
v6
=
v13[v2];
v7
=
*
(_OWORD
*
)((char
*
)&v11
+
v2
*
8
);
v8
=
v5;
v10
=
v6;
v9
=
v7;
result
=
sub_26B030(v1, &v8);
v2
+
=
3LL
;
}
while
( v2 !
=
324
);
}
return
result;
}
__int64 __fastcall sub_26A218(__int64 result)
{
v1
=
result;
if
( !
*
(_QWORD
*
)(result
+
8
) )
{
v11
=
sub_27E724(
0x1ADE
);
v12
=
0
;
v13[
0
]
=
(__int64)sub_26E5D8;
v13[
1
]
=
sub_27E724(
0x1AEB
);
v14
=
0
;
v15
=
sub_26E644;
v16
=
sub_27E724(
0x1AF9
);
v17
=
0
;
v18
=
sub_26E700;
v19
=
sub_27E724(
0x147E
);
v20
=
13
;
v21
=
sub_26B698;
v22
=
sub_27E724(
5260
);
v23
=
11
;
v24
=
sub_26B398;
v25
=
sub_27E724(
5266
);
v26
=
4
;
v27
=
sub_26B714;
v28
=
sub_27E724(
5276
);
v29
=
4
;
v30
=
sub_26B748;
v31
=
sub_27E724(
5286
);
v32
=
2
;
v33
=
sub_26B76C;
v34
=
sub_27E724(
5299
);
v35
=
3
;
v36
=
sub_26B79C;
v37
=
sub_27E724(
5312
);
v38
=
3
;
v39
=
&sub_26B824;
v40
=
sub_27E724(
5322
);
v41
=
14
;
v42
=
sub_26CC04;
v43
=
sub_27E724(
5330
);
v44
=
3
;
v45
=
&sub_26B8A0;
v46
=
sub_27E724(
5341
);
v47
=
3
;
v48
=
sub_26B918;
v49
=
sub_27E724(
5356
);
v50
=
5
;
v51
=
sub_26BB7C;
v52
=
sub_27E724(
5370
);
v53
=
3
;
v54
=
sub_26BACC;
v55
=
sub_27E724(
5384
);
v56
=
4
;
v57
=
sub_26BD10;
v58
=
sub_27E724(
5398
);
v59
=
4
;
v60
=
sub_26BDE8;
v61
=
sub_27E724(
5413
);
v62
=
5
;
v63
=
sub_26BEBC;
v64
=
sub_27E724(
5428
);
v65
=
5
;
v66
=
sub_26BF74;
v67
=
sub_27E724(
5443
);
v68
=
5
;
v69
=
sub_26C02C;
v70
=
sub_27E724(
5458
);
v71
=
2
;
v72
=
sub_26C0E4;
v73
=
sub_27E724(
5465
);
v74
=
3
;
v75
=
sub_26C128;
v76
=
sub_27E724(
5478
);
v77
=
3
;
v78
=
sub_26C208;
v79
=
sub_27E724(
5491
);
v80
=
3
;
v81
=
sub_26C1C8;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2023-5-31 09:37
被2beNo2编辑
,原因: 补充内容