import
unicorn
import
binascii
import
threading
import
subprocess
from
capstone
import
*
from
capstone.arm64
import
*
inscnt
=
0
start_addr
=
0
end_addr
=
0
stop_addr
=
0
stop_addr_list
=
[]
def
hook_code(uc, address, size, user_data):
global
inscnt
global
end_addr
global
stop_addr
global
stop_addr_list
md
=
Cs(CS_ARCH_ARM64, CS_MODE_ARM)
for
ins
in
md.disasm(sodata[address:address
+
size], address):
stop_addr
=
ins.address
if
ins.address
in
stop_addr_list:
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_PC, address
+
size)
return
inscnt
=
inscnt
+
1
if
(inscnt >
500
):
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_PC,
0xffffffff
)
return
if
ins.mnemonic.find(
"b."
) !
=
-
1
:
print
(
"will pass 0x%x:\t%s\t%s"
%
(ins.address, ins.mnemonic, ins.op_str))
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_PC, address
+
size)
return
if
ins.mnemonic.find(
"bl"
) !
=
-
1
:
print
(
"will pass 0x%x:\t%s\t%s"
%
(ins.address, ins.mnemonic, ins.op_str))
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_PC, address
+
size)
return
if
ins.op_str
in
[
"x0"
,
"x1"
,
"x2"
,
"x3"
]:
X1
=
uc.reg_read(unicorn.arm64_const.UC_ARM64_REG_X1)
if
X1 >
0x105A88
:
print
(
"will pass 0x%x:\t%s\t%s"
%
(ins.address, ins.mnemonic, ins.op_str))
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_PC, address
+
size)
return
if
ins.op_str.startswith(
"#0x"
):
addr
=
int
(ins.op_str[
3
:],
16
)
if
(addr >
0x14E50
and
addr <
0x15820
) \
or
addr
=
=
0x186C4
\
or
addr >
0x105A88
:
print
(
"will pass 0x%x:\t%s\t%s"
%
(ins.address, ins.mnemonic, ins.op_str))
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_PC, address
+
size)
return
def
call_prepare_arg():
global
inscnt
global
start_addr
global
end_addr
global
stop_addr
global
stop_addr_list
inscnt
=
0
uc
=
unicorn.Uc(unicorn.UC_ARCH_ARM64, unicorn.UC_MODE_ARM)
code_addr
=
0x0
code_size
=
8
*
0x1000
*
0x1000
uc.mem_map(code_addr, code_size)
stack_addr
=
code_addr
+
code_size
stack_size
=
0x1000000
stack_top
=
stack_addr
+
stack_size
-
0x8
uc.mem_map(stack_addr, stack_size)
uc.hook_add(unicorn.UC_HOOK_CODE, hook_code)
uc.mem_write(code_addr, sodata)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X29, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X28, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X27, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X26, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X25, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X24, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X23, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X22, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X21, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X20, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X19, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X18, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X17, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X16, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X15, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X14, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X13, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X12, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X11, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X10, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X9, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X8, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X7, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X6, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X5, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X4, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X3, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X2, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X1, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_X0, stack_addr)
uc.reg_write(unicorn.arm64_const.UC_ARM64_REG_SP, stack_top)
uc.emu_start(start_addr, end_addr)
X0
=
uc.reg_read(unicorn.arm64_const.UC_ARM64_REG_X0)
decstr
=
uc.mem_read(X0,
80
)
end_index
=
decstr.find(bytearray(b
'\x00'
),
1
)
decstr
=
decstr[:end_index]
decstr
=
binascii.b2a_hex(decstr)
decstr
=
decstr.decode(
'utf-8'
)
X1
=
uc.reg_read(unicorn.arm64_const.UC_ARM64_REG_X1)
X2
=
uc.reg_read(unicorn.arm64_const.UC_ARM64_REG_X2)
pi
=
subprocess.Popen([
'C:\\Python38\\python.exe'
,
'decstr.py'
, decstr,
hex
(X1),
hex
(X2)], stdout
=
subprocess.PIPE)
output
=
pi.stdout.read()
print
(output)
def
loop_call_prepare_arg1():
global
inscnt
global
end_addr
global
stop_addr
global
stop_addr_list
loopcnt
=
0
stop_addr_list
=
[]
while
True
:
try
:
loopcnt
=
loopcnt
+
1
if
(loopcnt >
200
):
break
call_prepare_arg()
except
unicorn.unicorn.UcError:
print
(
"adding...."
)
print
(
hex
(stop_addr))
stop_addr_list.append(stop_addr)
else
:
break
def
loop_call_prepare_arg2():
global
inscnt
global
end_addr
global
stop_addr
global
stop_addr_list
global
start_addr
loopcnt
=
0
stop_addr_list
=
[]
while
True
:
try
:
loopcnt
=
loopcnt
+
1
if
(loopcnt >
200
):
break
call_prepare_arg()
except
unicorn.unicorn.UcError:
start_addr
=
stop_addr
+
4
else
:
break
with
open
(
"C:\\Users\\hjy\\Downloads\\out1.fix.so"
,
"rb"
) as f:
sodata
=
f.read()
all_addr
=
[]
with
open
(
'xref_decstr.txt'
,
'r'
, encoding
=
'utf-8'
) as f:
for
line
in
f:
addr
=
"0x"
+
line[
2
:]
addr
=
int
(addr,
16
)
all_addr.append(addr)
for
i
in
all_addr:
print
(
"i:"
)
print
(
hex
(i))
end_addr
=
i
CODE
=
sodata[i
-
4
:i]
md
=
Cs(CS_ARCH_ARM64, CS_MODE_ARM)
for
x
in
md.disasm(CODE, i
-
4
):
mnemonic
=
x.mnemonic
while
mnemonic !
=
"ret"
\
and
mnemonic !
=
"b"
\
and
mnemonic !
=
"br"
\
and
mnemonic !
=
"cbz"
\
and
mnemonic !
=
"cbnz"
:
i
=
i
-
4
CODE
=
sodata[i
-
4
:i]
for
x
in
md.disasm(CODE, i
-
4
):
mnemonic
=
x.mnemonic
start_addr
=
i
print
(
"start_addr:"
)
print
(
hex
(start_addr))
print
(
"end_addr:"
)
print
(
hex
(end_addr))
loop_call_prepare_arg1()
loop_call_prepare_arg2()