版本DP11.30.13。本打算unidbg练手模拟调用mtgsig,结果失败了。只有静态分析有点儿学习成果。
使用ida静态分析过程中遇到如下问题:
查看汇编信息,观察为什么导致这部分无法正常反汇编:
从上面可以看出jumpout位置是一些无法被识别的数据导致ida无法正常分析。从此函数函数开始分析,一开始保存X0
和X30[LR]
接着就是给X0赋值,接着跳转到另一个代码块,此代码块中只有一个函数调用sub_25D00
。
sub_2D500
函数比较简单只有几句话,首先是保存X0,X1
寄存器的值,接着读取X30 + 4 * W0
的值到W0
,再给X30
加上刚刚对去的值,最后恢复X0,X1
的值。逻辑比较简单就是利用进入sub_25D00
时链接寄存器的值为初始地址,再利用参数X0
的值作为偏移读取本文件里的偏移量,通过修改LR链接寄存器的值完成间接跳转,正好导致ida无法正常分析。猜测之前jumpout的地址估计就是偏移表。
因为逻辑简单,涉及到的汇编语句也不多,简单的使用unicorn模拟执行验证上面的分析是否正确。
如上图所示简单执行之后和之前分析的逻辑一致。
修复逻辑也比较简单,就是手动计算真实跳转地址,修改进入sub_25D00
跳转代码块之前的那个直接跳转地址即可。
下面是ida修复代码:
使用上面脚本能全部清理。清理后结果:
到此结束,这个so可以直接放到unidbg中模拟执行。但是我没有完成main(1)初始化,如果有大佬完成了给点提示。
mu
=
Uc(UC_ARCH_ARM64, UC_MODE_ARM)
BASE_ADDR
=
0x40000000
BASE_SIZE
=
4
*
1024
*
1024
mu.mem_map(BASE_ADDR, BASE_SIZE)
STACK_ADDR
=
0x10000000
STACK_SIZE
=
0x00100000
mu.mem_map(STACK_ADDR, STACK_SIZE)
logger.debug(f
"Memory map {hex(STACK_ADDR)} - {hex(STACK_ADDR + STACK_SIZE)}"
)
mu.reg_write(UC_ARM64_REG_SP, STACK_ADDR
+
STACK_SIZE)
ks
=
Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
assembly_code
=
';'
.join([
'STP X0, X30, [SP,#-0x50]'
,
'LDR W0, =2'
,
'STP X0, X1, [SP,#-0x10]!'
,
'LDR W0, [X30,W0,UXTW#2]'
,
'ADD X30, X30, W0,UXTW'
,
'LDP X0, X1, [SP],#0x10'
,
])
encoding, count
=
ks.asm(assembly_code.strip())
logger.debug(f
"Assembly code {bytes(encoding).hex()}, bytes count {count}"
)
mu.mem_write(BASE_ADDR, bytes(encoding))
def
hook_code(uc: Uc, address:
int
, size:
int
, user_data):
inst
=
uc.mem_read(address, size)
md
=
Cs(CS_ARCH_ARM64, CS_MODE_ARM)
for
i
in
md.disasm(inst, address):
logger.debug(f
">>> {hex(i.address)}:\t{i.mnemonic}\t{i.op_str}"
)
mu.hook_add(UC_HOOK_CODE, hook_code)
def
hook_mem_read_unmapped(uc: Uc, access:
int
, address:
int
, size:
int
, value, user_data):
logger.debug(f
">>> Tracing memory read at {hex(address)}, size: {hex(size)}"
)
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read_unmapped)
def
hook_mem_read(uc: Uc, access:
int
, address:
int
, size:
int
, value, user_data):
data
=
uc.mem_read(address, size)
logger.debug(f
">>> Tracing memory read at {hex(address)}, size: {hex(size)}, data: {data.hex()}"
)
mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read)
mu.reg_write(UC_ARM64_REG_X30,
0x40000000
)
mu.emu_start(BASE_ADDR, BASE_ADDR
+
(
4
*
count))
sp_value
=
mu.reg_read(UC_ARM64_REG_SP)
logger.debug(f
"After simulate sp value: {hex(sp_value)}"
)
logger.debug(f
"After simulate X0 value: {hex(mu.reg_read(UC_ARM64_REG_X0))}"
)
logger.debug(f
"After simulate X30 value: {hex(mu.reg_read(UC_ARM64_REG_X30))}"
)
mu
=
Uc(UC_ARCH_ARM64, UC_MODE_ARM)
BASE_ADDR
=
0x40000000
BASE_SIZE
=
4
*
1024
*
1024
mu.mem_map(BASE_ADDR, BASE_SIZE)
STACK_ADDR
=
0x10000000
STACK_SIZE
=
0x00100000
mu.mem_map(STACK_ADDR, STACK_SIZE)
logger.debug(f
"Memory map {hex(STACK_ADDR)} - {hex(STACK_ADDR + STACK_SIZE)}"
)
mu.reg_write(UC_ARM64_REG_SP, STACK_ADDR
+
STACK_SIZE)
ks
=
Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
assembly_code
=
';'
.join([
'STP X0, X30, [SP,#-0x50]'
,
'LDR W0, =2'
,
'STP X0, X1, [SP,#-0x10]!'
,
'LDR W0, [X30,W0,UXTW#2]'
,
'ADD X30, X30, W0,UXTW'
,
'LDP X0, X1, [SP],#0x10'
,
])
encoding, count
=
ks.asm(assembly_code.strip())
logger.debug(f
"Assembly code {bytes(encoding).hex()}, bytes count {count}"
)
mu.mem_write(BASE_ADDR, bytes(encoding))
def
hook_code(uc: Uc, address:
int
, size:
int
, user_data):
inst
=
uc.mem_read(address, size)
md
=
Cs(CS_ARCH_ARM64, CS_MODE_ARM)
for
i
in
md.disasm(inst, address):
logger.debug(f
">>> {hex(i.address)}:\t{i.mnemonic}\t{i.op_str}"
)
mu.hook_add(UC_HOOK_CODE, hook_code)
def
hook_mem_read_unmapped(uc: Uc, access:
int
, address:
int
, size:
int
, value, user_data):
logger.debug(f
">>> Tracing memory read at {hex(address)}, size: {hex(size)}"
)
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read_unmapped)
def
hook_mem_read(uc: Uc, access:
int
, address:
int
, size:
int
, value, user_data):
data
=
uc.mem_read(address, size)
logger.debug(f
">>> Tracing memory read at {hex(address)}, size: {hex(size)}, data: {data.hex()}"
)
mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read)
mu.reg_write(UC_ARM64_REG_X30,
0x40000000
)
mu.emu_start(BASE_ADDR, BASE_ADDR
+
(
4
*
count))
sp_value
=
mu.reg_read(UC_ARM64_REG_SP)
[注意]APP应用上架合规检测服务,协助应用顺利上架!