Avatar——执行

在目标集和内存布局被定义后,Avatar²的真正分析部分就可以进行了,我们可以将之表示为execution-phase执行阶段

为了告知Avatar²安装阶段已经完成而且实际执行可以开始了,目标需要首先被初始化。

from avatar2 import *

avatar = Avatar()

# Target setup
[...]

# Memory setup
[...]

# Initialize all targets and prepare for execution
avatar.init_targets()

在安装阶段,Avatar²可以与每个目标交互以控制其执行或修改内存与寄存器值。

控制目标执行

通过使用一组和传统调试器提供的功能相似的功能,Avatar²可以控制目标的执行。尤其是,所有的目标支持基础功能例如持续执行,执行下一步,停止执行。此外,只要潜在目标支持这些特性,断点和观察点也可以被设置。

然而,与传统调试器相比,当目标执行时Avatar²不会挂起,因为分析师可能想要建立复杂的并行执行编排方案。因此,目标提供了一个wait()方法,强制要求avatar脚本等到目标停止执行。

让我们看看目标执行在Avatar² 脚本中是如何实现的:

# 获取一个之前初始化了的目标
qemu = avatar.targets['QemuTarget0']

# 设置断点
bkpt = qemu.set_breakpoint(0x800e34)

# 继续执行
qemu.cont()

# 在做其他事前,等待断点被触发
qemu.wait()

# 移除断点
qemu.remove_breakpoint(bkpt)

# 执行一条指令
qemu.step()

控制目标寄存器

Avatar可以用非常简单的方式检查并修改一个目标的寄存器状态:

# 获取寄存器值
r0 = qemu.regs.r0

# 设置寄存器值
qemu.regs.r0 = 0x41414141

在该封装下,分别会调用函数 read_registerwrite_register, 当然直接调用它们也是可以的。

# Get the content of a register
r0 = qemu.read_register("r0")

# Set the content of a register
qemu.write_register("r0", 0x41414141)

# 同样功能的缩写
r0 = qemu.rr("r0")
qemu.wr("r0", 0x41414141)

控制目标内存

与目标的寄存器状态相似,常常也需要获得或修改目标的内存内容,这与读写寄存器一样简单:

# read 4 bytes from addres 0x20000000
qemu.read_memory(0x20000000, 4)

# write 4 bytes to address 0x20000000
qemu.write_memory(0x20000000, 4, 0xdeadbeef)

# 缩写
qemu.rm(0x20000000, 4)
qemu.wm(0x20000000, 4, 0xdeadbeef)

在目标间转移执行状态

Avatar²的一个更有趣的特性就是能够在执行期间转移目标间的状态,以允许一个成功的编排。看看下面这个例子,它包括目标设置,内存布局说明,以及从一个目标到另一个目标的执行(与状态)的转移:

from avatar2 import *

sample = 'firmware.bin'
openocd_conf = 'nucleo-l152re.cfg'

# 用惯例输出目录创造avatar实例
avatar = Avatar(output_directory='/tmp/myavatar')

# 增加第一个目标
qemu = avatar.add_target(QemuTarget, 
                          gdb_executable="arm-none-eabi-gdb",
                          firmware=sample, cpu_model="cortex-m3",
                          executable="targets/qemu/arm-softmmu/qemu-system-")

# 增加第二个目标
nucleo = avatar.add_target(OpenOCDTarget,
                           gdb_executable="arm-none-eabi-gdb", 
                           openocd_script=openocd_conf)

# 设置惯例gdb端口避免冲突
qemu.gdb_port = 1234
nucleo.gdb_port = 1235

# 指定第一片内存范围
rom  = avatar.add_memory_range(0x08000000, 0x1000000, name='rom', 
                                   file=sample)
# 指定第二片内存范围
ram  = avatar.add_memory_range(0x20000000, 0x14000, name='ram')

# 初始化目标
avatar.init_targets()

# 在nucleo上执行到一个特定地址
nucleo.set_breakpoint(0x800B570)
nucleo.cont()
nucleo.wait()

# 转移状态到qemu上
avatar.transfer_state(nucleo, qemu, sync_regs=True, synced_ranges=[ram])

# 继续在qemu上执行
qemu.cont()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值