如何使用python通过LLDB读写一个寄存器?
How to use python to read and write a register via LLDB?
我正在尝试使用 python 到 read/write 一个寄存器,当它到达断点时。
我能够在触发断点时执行一个简单的 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 寄存器值吗?
SBFrames 上的 registers
属性 是一个 SBValueList
,用于存储寄存器组(GPR 等)。每个寄存器集都是一个 SBValue,各个寄存器表示为寄存器集的子项,子项名称是寄存器名称。 x1
是 GPR,GPR 始终是 registers
中设置的第一个寄存器。 SBValueList
也 GetFirstValueByName
按名称获取元素,因此您还可以通过编程方式查找 "General Purpose Register"。
所以你会做这样的事情:
error = lldb.SBError()
did_change = lldb.frame.registers[0].GetChildMemberWithName('x1').SetValueFromCString("0x12345",error)
SetValueFromCString
returns True
如果能够更改值,如果不能,原因将存储在 error
参数中.
请注意,像 x1
这样的易失性寄存器不会跨函数调用存储,因此您只能在当前执行的帧中访问或更改它们的值。
SBValues 描述如下:
https://lldb.llvm.org/python_reference/lldb.SBValue-class.html
如果您想知道您还可以用它们做什么。
registers
属性 的替代方法是 register
属性。通过名称访问寄存器很方便。例如:
(lldb) script print lldb.frame.register["x1"].value
(lldb) script lldb.frame.register["x1"].value = "0"
@Dave Lee 的回答在 lldb
的 script
界面有效。
当我在完整脚本中尝试相同操作时,我得到的是空寄存器值。
文档https://lldb.llvm.org/use/python-reference.html 解释了所有内容。您需要传入 exe_ctx 才能获得正确的 context
。这是 lldb.SBExecutionContext
.
def YDFooBarFunction(debugger, command, exe_ctx, result, internal_dict):
"""
Reads and writes a register.
"""
frame = exe_ctx.frame
error = lldb.SBError()
disposition = frame.FindRegister("rsi")
print("[*]Original register: " + str(disposition))
if disposition.unsigned == 2:
print "[!]found 2 in the register"
result = frame.registers[0].GetChildMemberWithName('rsi').SetValueFromCString("0x1", error)
messages = {None: 'error', True: 'pass', False: 'fail'}
print ("[*]PATCHING result: " + messages[result])
thread = frame.GetThread()
process = thread.GetProcess()
process.Continue()
我希望这可以节省人们打猎的时间。
请注意,我使用了伟人 (@Jim Ingham) 的部分答案来编写寄存器。
我正在尝试使用 python 到 read/write 一个寄存器,当它到达断点时。
我能够在触发断点时执行一个简单的 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 寄存器值吗?
SBFrames 上的 registers
属性 是一个 SBValueList
,用于存储寄存器组(GPR 等)。每个寄存器集都是一个 SBValue,各个寄存器表示为寄存器集的子项,子项名称是寄存器名称。 x1
是 GPR,GPR 始终是 registers
中设置的第一个寄存器。 SBValueList
也 GetFirstValueByName
按名称获取元素,因此您还可以通过编程方式查找 "General Purpose Register"。
所以你会做这样的事情:
error = lldb.SBError()
did_change = lldb.frame.registers[0].GetChildMemberWithName('x1').SetValueFromCString("0x12345",error)
SetValueFromCString
returns True
如果能够更改值,如果不能,原因将存储在 error
参数中.
请注意,像 x1
这样的易失性寄存器不会跨函数调用存储,因此您只能在当前执行的帧中访问或更改它们的值。
SBValues 描述如下:
https://lldb.llvm.org/python_reference/lldb.SBValue-class.html
如果您想知道您还可以用它们做什么。
registers
属性 的替代方法是 register
属性。通过名称访问寄存器很方便。例如:
(lldb) script print lldb.frame.register["x1"].value
(lldb) script lldb.frame.register["x1"].value = "0"
@Dave Lee 的回答在 lldb
的 script
界面有效。
当我在完整脚本中尝试相同操作时,我得到的是空寄存器值。
文档https://lldb.llvm.org/use/python-reference.html 解释了所有内容。您需要传入 exe_ctx 才能获得正确的 context
。这是 lldb.SBExecutionContext
.
def YDFooBarFunction(debugger, command, exe_ctx, result, internal_dict):
"""
Reads and writes a register.
"""
frame = exe_ctx.frame
error = lldb.SBError()
disposition = frame.FindRegister("rsi")
print("[*]Original register: " + str(disposition))
if disposition.unsigned == 2:
print "[!]found 2 in the register"
result = frame.registers[0].GetChildMemberWithName('rsi').SetValueFromCString("0x1", error)
messages = {None: 'error', True: 'pass', False: 'fail'}
print ("[*]PATCHING result: " + messages[result])
thread = frame.GetThread()
process = thread.GetProcess()
process.Continue()
我希望这可以节省人们打猎的时间。
请注意,我使用了伟人 (@Jim Ingham) 的部分答案来编写寄存器。