sun博客

记录点滴!

注意:nop(00bf)指令可能在unicorn中不会进入hook_code回调,此时可以使用mov r0,r0(0046)指令替换。在这里卡了很久,断点一直进入不了。也没在网上找到文档。

文件及代码来自看雪3万班unicorn-unidbg目录中第三节课程。hanbinle大神写的代码在我本地已经跑不成功了。可能是unicorn 版本的问题。

以下是自写跑成功的源码,重点之一在于对指针如何传参及如何补环境,其二是看看so层汇编代码查看多于4个参数时的堆栈分配:

import binascii
import struct

from unicorn import *
from capstone import *
mu=Uc(UC_ARCH_ARM,UC_MODE_THUMB)
CP=Cs(CS_ARCH_ARM,CS_MODE_THUMB)
# start_addr=0x59928
# end_addr=0x59CD0
start_addr=0x854C
end_addr=0x85D8
stack_base=0x1000
stack_size=10*1024*1024
def printArm32Regs(mu):
    for i in range(66,78):
        print("R%d,value:%x"%(i-66,mu.reg_read(i)))
    print("SP->value:%x" % (mu.reg_read(arm_const.UC_ARM_REG_SP)))
    print("PC->value:%x" % (mu.reg_read(arm_const.UC_ARM_REG_PC)))

def readstring(mu,address):
    result=''
    tmp=mu.mem_read(address,1)
    while(tmp[0]!=0):
        result=result+chr(tmp[0])
        address=address+1
        tmp = mu.mem_read(address, 1)
    return result

def hook_code(mu,address,size,userdata):
    co = mu.mem_read(address, size)
    print("value: %x"%(address-stack_base))
    if address-stack_base == 0x859A:
    #if(address-stack_base==0x859A):
        print("enter....")
        arg0str=readstring(mu,mu.reg_read(arm_const.UC_ARM_REG_R0))
        arg1str = readstring(mu, mu.reg_read(arm_const.UC_ARM_REG_R1))
        print(arg0str + "---" + arg1str)
        find=arg0str.find(arg1str)
       # mu.mem_write(address-stack_base,b'\x00\xbf\x00\xbf')
        if(find==-1):
            mu.reg_write(arm_const.UC_ARM_REG_R0,0)
        else:
            mu.reg_write(arm_const.UC_ARM_REG_R0, find)

    print("hook_code start-----------------------------")

    for i in CP.disasm(co, 0, len(co)):
        print("[hook_code addr:%x opcode:%s]:%s %s\n" % (address-stack_base, binascii.b2a_hex(co),i.mnemonic, i.op_str))

    printArm32Regs(mu)
    print("hook_code end-----------------------------")
    return
def hook_mem(mu,type,address,size,value,user_data):
    if type==UC_MEM_WRITE:
       print("write addr:0x%x,size:%d,value:0x%x"%(address,size,value))
    if type==UC_MEM_READ:
       print("read addr:0x%x,size:%d,value:0x%x"%(address,size,value))
    print("hook_mem type:%d addr:0x%x,size:%d,value:0x%x"%(type,address,size,value))
    return
def unmapped(mu,address,size):
    print("UC_ERR_READ_UNMAPPED-----------------------------")
    print("%d"%address)
    co = mu.mem_read(address, size)
    for i in CP.disasm(code, 0, len(co)):
        print("[UC_ERR_READ_UNMAPPED addr:%x]:%s %s\n" % (address, i.mnemonic, i.op_str))

    # printArm32Regs(mu)
    print("UC_ERR_READ_UNMAPPED-----------------------------")
    return

def fetch_unmapped(mu,address,size,user_data):
    print("UC_ERR_fetch_UNMAPPED-----------------------------")
    print("%x %x" %(address,size))
    errbyte=mu.mem_read(address,size)
    for i in  CP.disasm(errbyte,0,len(errbyte)):
        print("opcode: %s %s %s" % (binascii.b2a_hex(errbyte),i.mnemonic,i.op_str))
    return False



if __name__ == '__main__':
    #testthumb_arg2()
    with open("D:\\backend\\xmlysign\\capstone\\callstrstr.so", "rb") as sofile:
        code = sofile.read()

        for i in CP.disasm(code[start_addr:end_addr], 0, 20):
            print("[addr] %x]:%s %s\n" % (i.address, i.mnemonic, i.op_str))

        mu.mem_map(stack_base, stack_size)
        mu.mem_write(stack_base, code)

        stack_top = stack_base + stack_size - 0x400
        mu.reg_write(arm_const.UC_ARM_REG_SP, stack_top)
        mu.reg_write(arm_const.UC_ARM_REG_LR, stack_base + 0x1000)

        addr_r0 = stack_base + stack_size + 0x1000
        mu.mem_map(addr_r0, 1024)
        mu.mem_write(addr_r0, b"flag4")

        bytes = mu.mem_read(addr_r0, 5)

        print(binascii.b2a_hex(bytes))
        # mu.mem_map(ADDRESS + SIZE + 0x1000, 1024)
        # mu.mem_write(ADDRESS + SIZE + 0x1000, b'flag4')
        # bytes = mu.mem_read(ADDRESS + SIZE + 0x1000, 5)
        # print(binascii.b2a_hex(bytes))




        mu.reg_write(arm_const.UC_ARM_REG_R0, addr_r0)

        mu.reg_write(arm_const.UC_ARM_REG_R1, 0x2)
        mu.reg_write(arm_const.UC_ARM_REG_R2, 0x3)
        mu.reg_write(arm_const.UC_ARM_REG_R3, 0x4)

        # mu.mem_write(stack_base + 0x859A, b"\x00\xbf\x00\xbf")
        mu.mem_write(stack_base + 0x859A, b'\x00\x46\x00\x46')

        mu.mem_write(stack_top, struct.pack('I', 5))
        mu.mem_write(stack_top + 0x4, struct.pack('I', 6))

        mu.hook_add(UC_HOOK_CODE, hook_code)
        # mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem)

        # mu.hook_add(UC_ERR_READ_UNMAPPED, unmapped)
        #   mu.hook_add(UC_ERR_FETCH_UNMAPPED,fetch_unmapped)

        mu.emu_start(stack_base + start_addr + 1, stack_base + end_addr)
        # r3 = mu.reg_read(arm_const.UC_ARM_REG_R3)
        printArm32Regs(mu)

5+6=11=0xb,结果正确。

使用版本

C:\Users\86153>pyenv global 3.8.6

C:\Users\86153>pip list
Package         Version
--------------- -------
androidemu      0.0.2
capstone        5.0.1
hexdump         3.3
keystone-engine 0.9.2
pip             20.2.1
pyelftools      0.27
setuptools      49.2.1
unicorn         1.0.3
WARNING: You are using pip version 20.2.1; however, version 23.2.1 is available.
You should consider upgrading via the 'd:\app\pyenv\.pyenv\pyenv-win\versions\3.8.6\python.exe -m pip install --upgrade pip' command.

https://wenku.baidu.com/view/21903bbc5cbfc77da26925c52cc58bd6318693ab.html?wkts=1696251118411&bdQuery=ARM+nop%E6%8C%87%E4%BB%A4&needWelcomeRecommand=1

发表评论

邮箱地址不会被公开。 必填项已用*标注