此样本主要使用间接跳转
可以利用unicorn模拟执行来确定x13的值,然后修改成直接跳转或者条件跳转,
本文的重点不在这里,不在多叙。本文的重点是如何识别这些垃圾指令,
因为光恢复它的跳转,ida还是不能反编译,它指令膨胀的非常严重,将max_func_size设置成4096也不行,所以对于BR x13这种指令,需要识别x13是由哪些指令生成的,将这些指令全部nop掉,才能减少方法的size。
如上图,代码中的所有跳转全部为BR指令,包括条件跳转和直接跳转,其中还包括不透明谓词
一种是自下而上进行活跃变量分析,将BR x8 patch成b 0x1000后,将x8认为是不活跃变量,然后就可以进行活跃变量分析,然后根据ud链,找到定义x8的地方,将这个定义也删除掉。这个定义语句也会使用到变量,此时它使用到的变量也属于不活跃变量,所以可以继续向上分析,这种方式只是我理论想出来的,并没有实践
第二种是我用到的方法,污点分析,将mov x8,0x234234,这种指令的x8定义为污染源,然后向下分析,将污染过得指令全部nop掉。我觉得这种方式处理起来比较简单,对于br,bl这种跳转语句不执行,还有return块也不执行,这样就可以把整个方法当做一个巨大的代码块,由上而下的执行,将特征指令会赋值的寄存器设置成污染源,这样也可以处理这种特殊情况,在方法序言处将一个常数写入栈,在后面的代码块中从栈里面读取这个值,再使用计算,这个可以避免自己再做上下文的分析,污点分析能直接定位到。
github地址https://github.com/JonathanSalwan/Triton.git
这个工具很强大,有污点分析和符号执行两个功能,我这次只使用到了它的污点分析功能
安装 pip install tritondse
还是利用上面的那段代码,执行完1E7D00后,将w8寄存器设置为污染源
其中的大部分代码都是模板代码,主要有用的是这两句代码,将w8设置为污染源
看下效果
在1e7d68处使用到了w8,并且将cpsr污染了,所以下一句cset指令也是污染的,
继续向下分析,可以看到间接引用w8寄存器的指令都识别出来了。
注意1e7d94处,虽然x13寄存器是被污染的,但是这条指令并没有被污染。
Triton将这种问题留给我们自己来处理,就是如果寄存器是被污染的,那么需要我们根据实际情况,来决定是否将寄存器指向的内存污染掉,上代码
这个脚本多了这几句代码
作用也很简单,执行完这句代码后,将x13指向的内存也污染掉
看下效果
可以看到又多识别出来一些垃圾指令
那我们继续分别将代码块开始的几个寄存器,w8,w9,w10,w11,w12都给污染掉,上代码
看下效果
可以看到又多识别了一些垃圾指令。
还有一种特殊的栈变量,比如1E7D34处的指令,这种如何识别呢,其实在最开始已经谈到过这种情况的处理方式,这种栈变量的赋值方式一般是在方法序言处
在这里给x4赋值
在这里写到栈上
所以我们可以在0x1E4DB8处,将x4寄存器也给污染掉,上代码
这个脚本相比之前多了这几句代码,目的是跳过所有的跳转指令,将整个方法当成一个方法块来处理,这样会简单很多,此处我没有处理ret代码块,实际使用中,还需要跳过ret代码块,不然运行过程中pc会跑飞
在这里将x4寄存器和它指向的内存污染掉
看下效果
可以看到将对栈变量的处理也识别到了。
其实讲到这里已经差不多了,剩下的就是全局扫描识别mov adrp 这种指令,当然需要过滤掉其中的正常指令,然后适配上面的代码,就可以将大部分的垃圾指令识别到,然后nop掉。对于强迫症患者来说,也是一个福音。
代码就不上传了,文章中的代码运行应该都没问题
Triton.setArchitecture(ARCH.AARCH64)设置架构
Triton.setConcreteMemoryAreaValue(
0
, bin1) 写入具体内存
Triton.taintRegister() 设置寄存器为污染源
Triton.taintMemory()设置内存地址为污染源
Triton.getConcreteRegisterValue()获取寄存器的值
Triton.untaintRegister()对寄存器进行去污染处理
Triton.untaintMemory()对内存进行去污染处理
Instruction.setOpcode()设置字节码
Instruction.setAddress()设置指令地址
Triton.processing() 执行一条语句
Triton.setArchitecture(ARCH.AARCH64)设置架构
Triton.setConcreteMemoryAreaValue(
0
, bin1) 写入具体内存
Triton.taintRegister() 设置寄存器为污染源
Triton.taintMemory()设置内存地址为污染源
Triton.getConcreteRegisterValue()获取寄存器的值
Triton.untaintRegister()对寄存器进行去污染处理
Triton.untaintMemory()对内存进行去污染处理
Instruction.setOpcode()设置字节码
Instruction.setAddress()设置指令地址
Triton.processing() 执行一条语句
from
triton
import
*
import
idc
import
ida_bytes
from
capstone
import
*
from
capstone.arm64
import
*
cs
=
Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
cs.detail
=
True
def
get_insn2(opcode0, addr):
insns
=
cs.disasm(opcode0, addr)
for
i
in
insns:
return
i
def
taint_analysis2(start, end):
Triton
=
TritonContext()
with
open
(
'C:\\Users\\lj\\Desktop\\junks\\test1\\CoreBook2'
,
'rb'
) as f:
bin1
=
f.read()
Triton.setArchitecture(ARCH.AARCH64)
Triton.setConcreteMemoryAreaValue(
0
, bin1)
sp
=
0x100000000
Triton.setConcreteRegisterValue(Triton.registers.x29, sp)
Triton.setConcreteRegisterValue(Triton.registers.sp, sp)
pc
=
start
nop_addrs
=
[]
while
pc:
inst
=
Instruction()
opcode0
=
ida_bytes.get_bytes(pc,
4
)
cs_insn: CsInsn
=
get_insn2(opcode0, pc)
inst.setOpcode(opcode0)
inst.setAddress(pc)
Triton.processing(inst)
print
(
str
(inst))
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
if
inst.isTainted():
idc.set_color(pc, idc.CIC_ITEM,
0xffe699
)
nop_addrs.append(pc)
if
pc >
=
end:
break
pc
=
pc
+
4
if
__name__
=
=
'__main__'
:
taint_analysis2(
0x1E7D00
,
0x1E7D98
)
from
triton
import
*
import
idc
import
ida_bytes
from
capstone
import
*
from
capstone.arm64
import
*
cs
=
Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
cs.detail
=
True
def
get_insn2(opcode0, addr):
insns
=
cs.disasm(opcode0, addr)
for
i
in
insns:
return
i
def
taint_analysis2(start, end):
Triton
=
TritonContext()
with
open
(
'C:\\Users\\lj\\Desktop\\junks\\test1\\CoreBook2'
,
'rb'
) as f:
bin1
=
f.read()
Triton.setArchitecture(ARCH.AARCH64)
Triton.setConcreteMemoryAreaValue(
0
, bin1)
sp
=
0x100000000
Triton.setConcreteRegisterValue(Triton.registers.x29, sp)
Triton.setConcreteRegisterValue(Triton.registers.sp, sp)
pc
=
start
nop_addrs
=
[]
while
pc:
inst
=
Instruction()
opcode0
=
ida_bytes.get_bytes(pc,
4
)
cs_insn: CsInsn
=
get_insn2(opcode0, pc)
inst.setOpcode(opcode0)
inst.setAddress(pc)
Triton.processing(inst)
print
(
str
(inst))
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
if
inst.isTainted():
idc.set_color(pc, idc.CIC_ITEM,
0xffe699
)
nop_addrs.append(pc)
if
pc >
=
end:
break
pc
=
pc
+
4
if
__name__
=
=
'__main__'
:
taint_analysis2(
0x1E7D00
,
0x1E7D98
)
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
from
triton
import
*
import
idc
import
ida_bytes
from
capstone
import
*
from
capstone.arm64
import
*
cs
=
Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
cs.detail
=
True
def
get_insn2(opcode0, addr):
insns
=
cs.disasm(opcode0, addr)
for
i
in
insns:
return
i
def
taint_analysis2(start, end):
Triton
=
TritonContext()
with
open
(
'C:\\Users\\lj\\Desktop\\junks\\test1\\CoreBook2'
,
'rb'
) as f:
bin1
=
f.read()
Triton.setArchitecture(ARCH.AARCH64)
Triton.setConcreteMemoryAreaValue(
0
, bin1)
sp
=
0x100000000
Triton.setConcreteRegisterValue(Triton.registers.x29, sp)
Triton.setConcreteRegisterValue(Triton.registers.sp, sp)
pc
=
start
nop_addrs
=
[]
while
pc:
inst
=
Instruction()
opcode0
=
ida_bytes.get_bytes(pc,
4
)
inst.setOpcode(opcode0)
inst.setAddress(pc)
Triton.processing(inst)
print
(
str
(inst))
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
if
pc
=
=
0x1e7d90
:
Triton.taintMemory(Triton.getConcreteRegisterValue(Triton.registers.x13))
if
inst.isTainted():
idc.set_color(pc, idc.CIC_ITEM,
0xffe699
)
nop_addrs.append(pc)
if
pc >
=
end:
break
pc
=
pc
+
4
if
__name__
=
=
'__main__'
:
taint_analysis2(
0x1E7D00
,
0x1E7D9c
)
from
triton
import
*
import
idc
import
ida_bytes
from
capstone
import
*
from
capstone.arm64
import
*
cs
=
Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
cs.detail
=
True
def
get_insn2(opcode0, addr):
insns
=
cs.disasm(opcode0, addr)
for
i
in
insns:
return
i
def
taint_analysis2(start, end):
Triton
=
TritonContext()
with
open
(
'C:\\Users\\lj\\Desktop\\junks\\test1\\CoreBook2'
,
'rb'
) as f:
bin1
=
f.read()
Triton.setArchitecture(ARCH.AARCH64)
Triton.setConcreteMemoryAreaValue(
0
, bin1)
sp
=
0x100000000
Triton.setConcreteRegisterValue(Triton.registers.x29, sp)
Triton.setConcreteRegisterValue(Triton.registers.sp, sp)
pc
=
start
nop_addrs
=
[]
while
pc:
inst
=
Instruction()
opcode0
=
ida_bytes.get_bytes(pc,
4
)
inst.setOpcode(opcode0)
inst.setAddress(pc)
Triton.processing(inst)
print
(
str
(inst))
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
if
pc
=
=
0x1e7d90
:
Triton.taintMemory(Triton.getConcreteRegisterValue(Triton.registers.x13))
if
inst.isTainted():
idc.set_color(pc, idc.CIC_ITEM,
0xffe699
)
nop_addrs.append(pc)
if
pc >
=
end:
break
pc
=
pc
+
4
if
__name__
=
=
'__main__'
:
taint_analysis2(
0x1E7D00
,
0x1E7D9c
)
if
pc
=
=
0x1e7d90
:
Triton.taintMemory(Triton.getConcreteRegisterValue(Triton.registers.x13))
if
pc
=
=
0x1e7d90
:
Triton.taintMemory(Triton.getConcreteRegisterValue(Triton.registers.x13))
from
triton
import
*
import
idc
import
ida_bytes
from
capstone
import
*
from
capstone.arm64
import
*
cs
=
Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN)
cs.detail
=
True
def
get_insn2(opcode0, addr):
insns
=
cs.disasm(opcode0, addr)
for
i
in
insns:
return
i
def
taint_analysis2(start, end):
Triton
=
TritonContext()
with
open
(
'C:\\Users\\lj\\Desktop\\junks\\test1\\CoreBook2'
,
'rb'
) as f:
bin1
=
f.read()
Triton.setArchitecture(ARCH.AARCH64)
Triton.setConcreteMemoryAreaValue(
0
, bin1)
sp
=
0x100000000
Triton.setConcreteRegisterValue(Triton.registers.x29, sp)
Triton.setConcreteRegisterValue(Triton.registers.sp, sp)
pc
=
start
nop_addrs
=
[]
while
pc:
inst
=
Instruction()
opcode0
=
ida_bytes.get_bytes(pc,
4
)
cs_insn: CsInsn
=
get_insn2(opcode0, pc)
inst.setOpcode(opcode0)
inst.setAddress(pc)
Triton.processing(inst)
print
(
str
(inst))
if
pc
=
=
0x1E7D00
:
Triton.taintRegister(Triton.registers.w8)
if
pc
=
=
0x1E7D08
:
Triton.taintRegister(Triton.registers.w9)
if
pc
=
=
0x1E7D10
:
Triton.taintRegister(Triton.registers.w10)
if
pc
=
=
0x1E7D18
:
Triton.taintRegister(Triton.registers.w11)
if
pc
=
=
0x1E7D20
:
Triton.taintRegister(Triton.registers.w12)
if
pc
=
=
0x1e7d90
:
Triton.taintMemory(Triton.getConcreteRegisterValue(Triton.registers.x13))
if
inst.isTainted():
idc.set_color(pc, idc.CIC_ITEM,
0xffe699
)
nop_addrs.append(pc)
if
pc >
=
end:
break
pc
=
pc
+
4
if
__name__
=
=
'__main__'
:
taint_analysis2(
0x1E7D00
,
0x1E7D98
)
from
triton
import
*
import
idc
import
ida_bytes
from
capstone
import
*
from
capstone.arm64
import
*
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2023-6-20 22:43
被普通人张三编辑
,原因: