一.脚本如下
#-*- coding=utf-8 -*-
from unicorn import *
from unicorn import arm_const
from unicorn.arm_const import *
from capstone import *
from capstone.arm import *
from keystone import *
def hook_code(uc, address, size, user_data):
global FindFlag
global Finding
global JMP_PC
ban_ins = ["bl"]
#print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
for ins in md.disasm(bin1[address:address+size],address):
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
print(">>> 0x%x:\t%s\t%s" % (ins.address, ins.mnemonic, ins.op_str))
print("")
if FindFlag:
if JMP_PC[Finding] == 0:
print("jmp is %x"%(ins.address))
JMP_PC[Finding]=ins.address
Finding=0
FindFlag=0
else:
input('Something is error')
flag_pass = False
for b in ban_ins:
if ins.mnemonic.find(b) != -1:
flag_pass = True
break
if ins.op_str=='#0x3f4':#this is jmp 0x3f4 0x3f4 is switch case
print("jmp switch")
Finding=ins.address
JMP_PC[Finding]=0
if ins.address==0x3F0:#first blood
print("jmp switch")
Finding=ins.address
JMP_PC[Finding] = 0
if Finding and ins.address==0x414:
print("ready to jmp")
FindFlag=1
if flag_pass:
print("will pass 0x%x:\t%s\t%s" % (ins.address, ins.mnemonic, ins.op_str))
uc.reg_write(UC_ARM_REG_PC, address + size)
return
def hook_mem_access(uc,type,address,size,value,userdata):
pc = uc.reg_read(UC_ARM_REG_PC)
print('pc:%x type:%d addr:%x size:%x' % (pc,type,address,size))
#uc.emu_stop()
return False
def hook_error(uc,type,address,size,value,userdata):
pc = uc.reg_read(UC_ARM_REG_PC)
print('pc:%x type:%d addr:%x size:%x' % (pc,type,address,size))
#uc.emu_stop()
return False
FindFlag=0
Finding=0
JMP_PC={}
md = Cs(CS_ARCH_ARM,CS_MODE_ARM)
md.detail = True #enable detail analyise
offset = 0x3D4 #function start
end = 0x600 #function end
f=open('C:/Users/wei/Desktop/KanXueCTF/unicorn/test_arm','rb')
bin1 = f.read()
f.close()
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
#init stack
mu.mem_map(0x80000000,0x10000 * 8)
mu.mem_map(0, 4 * 1024 * 1024)
mu.mem_write(0,bin1)
mu.reg_write(UC_ARM_REG_SP, 0x80000000 + 0x10000 * 6)
mu.reg_write(UC_ARM_REG_LR, end)#retn addr
mu.hook_add(UC_HOOK_CODE, hook_code)
mu.hook_add(UC_HOOK_MEM_UNMAPPED,hook_mem_access)
#mu.hook_add(UC_ERR_HOOK,hook_error)
mu.emu_start(offset,end)
print(JMP_PC)
ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)
patch_file=open('C:/Users/wei/Desktop/KanXueCTF/unicorn/patch_test_arm','wb')
bin_w=bytearray(bin1)
for key,value in JMP_PC.items():
jmp_addr=value
addr=key
print('{key}:{value}'.format(key=hex(addr), value=hex(jmp_addr)))
r=ks.asm('b 0x%x'%(jmp_addr),addr)[0]
print(list(map(hex,r)))
for i in range(len(r)):
bin_w[addr+i]=r[i]
patch_file.write(bin_w)
patch_file.close()
下面重点讲一下脚本的作用
核心就是,记录一下进入switch之前的分支和switch之后的分支
像那些bl,blx之类的都跳过
二.代码注释
def hook_code(uc, address, size, user_data):
global FindFlag #是否查找完毕
global Finding #是否正在查找
global JMP_PC #记录跳前和跳后的
ban_ins = ["bl"]
#print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
for ins in md.disasm(bin1[address:address+size],address):
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" % (address, size))
print(">>> 0x%x:\t%s\t%s" % (ins.address, ins.mnemonic, ins.op_str))
print("")
if FindFlag: #发现结束的标志
if JMP_PC[Finding] == 0:
print("jmp is %x"%(ins.address))
JMP_PC[Finding]=ins.address
Finding=0
FindFlag=0
else:
input('Something is error')
flag_pass = False #这一段是跳过 bl blr
for b in ban_ins:
if ins.mnemonic.find(b) != -1:
flag_pass = True
break
if ins.op_str=='#0x3f4':#这一段是 跳入swtich
print("jmp switch")
Finding=ins.address #finding 不为0 开始了
JMP_PC[Finding]=0
if ins.address==0x3F0:#这是第一次进入分支但是不是用的 b
print("jmp switch")
Finding=ins.address
JMP_PC[Finding] = 0
if Finding and ins.address==0x414: #结束查找了
print("ready to jmp")
FindFlag=1 #结束的标志 下一条指令就是了
if flag_pass:
print("will pass 0x%x:\t%s\t%s" % (ins.address, ins.mnemonic, ins.op_str))
uc.reg_write(UC_ARM_REG_PC, address + size)
return
这个使用具体实例patch的程序来自于
https://github.com/0x1shyboy1/uncorn-patch-easyollvm/blob/master/test_arm
patch前后代码对比
patch后
今天的文章ollvm混淆windows程序_ollvm混淆windows程序「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86977.html