如何使用python通过LLDB读写寄存器?

时间:2019-04-03 18:14:39

标签: python ios debugging trace lldb

我正在尝试使用python在遇到断点时读取/写入寄存器。

触发断点后,我能够执行一个简单的python脚本。

我遇到的问题是读写单个寄存器。我可以获得一个寄存器列表,但没有一个寄存器。

* thread #1, stop reason = signal SIGSTOP
    frame #0: 0x000000010521562c dyld` ImageLoaderMachO::usablePrebinding(ImageLoader::LinkContext const&) const  + 56
dyld`ImageLoaderMachO::usablePrebinding:
->  0x10521562c <+56>: ldrb   w8, [x19, #0x76]
    0x105215630 <+60>: ldrh   w9, [x19, #0x74]
    0x105215634 <+64>: bfi    w9, w8, #16, #8
    0x105215638 <+68>: tbz    w9, #0x9, 0x105215694     ; <+160>
    0x10521563c <+72>: ldr    x8, [x19]
    0x105215640 <+76>: ldr    x8, [x8, #0x378]
    0x105215644 <+80>: mov    x0, x19
    0x105215648 <+84>: blr    x8
Target 0: (BBM) stopped.
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> print lldb.frame.registers

有人可以帮助我使用哪个python API来更改x1寄存器的值吗?

3 个答案:

答案 0 :(得分:2)

SBFrames上的registers属性是一个SBValueList,用于存储寄存器集(GPR等)。每个寄存器集都是一个SBValue,各个寄存器表示为该寄存器集的子级,其中子级名称为寄存器名。 x1是GPR,并且GPR始终是registers中设置的第一个寄存器。 SBValueListGetFirstValueByName也可以通过名称获取元素,因此您还可以通过编程方式找到“通用寄存器”。

因此,您将执行以下操作:

error = lldb.SBError()
did_change = lldb.frame.registers[0].GetChildMemberWithName('x1').SetValueFromCString("0x12345",error)

SetValueFromCString如果可以更改值,则返回True,如果不能更改,则将原因存储在error参数中。

请注意,像x1这样的易失性寄存器不会在函数调用之间存储,因此您只能在当前执行的帧中访问或更改它们的值。

SBValues在这里描述:

documentation

如果您想知道还可以对他们做什么。

答案 1 :(得分:0)

registers属性是register属性的替代方法。通过名称访问寄存器很方便。例如:

(lldb) script print lldb.frame.register["x1"].value
(lldb) script lldb.frame.register["x1"].value = "0"

答案 2 :(得分:0)

@Dave Lee的答案在impactOccured()的{​​{1}}界面中起作用。

当我在完整脚本中尝试相同操作时,我得到的是空寄存器值。

文档https://lldb.llvm.org/use/python-reference.html解释了所有内容。您需要传入 exe_ctx 才能获得正确的script。这就是lldb

context

我希望这可以节省人们的狩猎时间。

请注意,我使用了伟人(@Jim Ingham的答案)的一部分来写寄存器。