使用Python从lldb中的核心文件中的某个地址读取字符串

问题描述 投票:0回答:1

我想在 lldb 中使用 Python 从核心文件中的地址读取字符串。问题是我正在使用核心文件,因此没有实时进程。

我可以使用普通的 lldb 很好地获取字符串:

(lldb) p (char*)0x56039e6d71b0
(char *) $20 = 0x000056039e6d71b0 "nop"
(lldb)

我想要的字符串是

"nop"
。但是,我似乎无法从 lldb Python 获取这个字符串。

这是我迄今为止尝试过的:

评估表达

Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> lldb.frame.EvaluateExpression("(char*)0x56039e6d71b0").GetValue()
'0x000056039e6d71b0'

创建地址并询问值:

>>> addr = lldb.SBAddress(0x56039e6d71b0, lldb.target)
>>> char = lldb.target.GetBasicType(lldb.eBasicTypeChar)
>>> val  = lldb.target.CreateValueFromAddress("name", addr, char.GetPointerType())
>>> val.GetSummary()
>>> val.GetValue()
>>> val.GetValueAsUnsigned()
0

process.ReadMemory

>>> error = lldb.SBError()
>>> lldb.process.ReadMemory(0x56039e6d71b0, 3, error)
>>> error.Success()
False
>>> str(error)
'error: core file does not contain 0x56039e6d71b0'
>>> 

我似乎无法找出正确的 API 来在 Python 中获取此信息。任何帮助将不胜感激!

python lldb coredump
1个回答
1
投票

如果您不需要将其作为 lldb.SBValue,您可以只要求进程从内存中读取 C 字符串:

s = lldb.process.ReadCStringFromMemory(0x56039e6d71b0, 32, lldb.SBError());

如果你想创建一个 SBValue,你几乎就做对了,只需使用 AddressOf() 并且不要获取指针类型。使用交互式解释器我们可以看到出了什么问题:

>>> addr = lldb.SBAddress(0x00007ffeefbff980, lldb.target)
>>> print(addr)
0x7ffeefbff980
>>> char = lldb.target.GetBasicType(lldb.eBasicTypeChar)
>>> val  = lldb.target.CreateValueFromAddress("name", addr, char.GetPointerType())
>>> print(val)
(char *) name = 0x672f73726573552f ""

按照您的方式,您指定的地址是指针的地址,而不是它指向的数据的地址。我们可以看到,在这种情况下,指针值是字符串本身,因为指针中的所有十六进制值都是有效的 ASCII 字符。为了解决这个问题,我们只需使用 SBValue::AddressOf() 运算符来获取我们指定的地址处的字符地址,并创建正确的 lldb.SBValue()。请注意,我还传递“char”作为类型,并且在指定类型时不会调用 GetPointerType() :

>>> val  = lldb.target.CreateValueFromAddress("name", addr, char).AddressOf()
>>> print(val)
(char *) &name = 0x00007ffeefbff980 "/tmp/a.out"

执行此操作并获取 lldb.SBValue 的最简单方法是让表达式解析器为您完成此操作:

v = lldb.frame.EvaluateExpression('(const char *)0x00007ffeefbff980')
(const char *) $1 = 0x00007ffeefbff980 "/tmp/a.out"

即使有核心文件,这也应该可以工作。如果表达式的 IR 易于解释,则通常无需实时流程即可完成简单表达式。简单的转换和成员访问 (x->y.z) 通常属于这一类。

© www.soinside.com 2019 - 2024. All rights reserved.