我正在尝试在通过对象转储我的二进制文件获得的地址处设置断点。所以我的主要开始于0x0000000100000f10 <_main>:
使用示例here并替换
main_bp = target.BreakpointCreateByName ("main", target.GetExecutable().GetFilename())
与
main_bp = target.BreakpointCreateByAddress(0x0000000100000f10)
我启动目标后得到process.state = 10 (== lldb.eStateExited)
,所以它没有达到我的断点。我认为这是因为二进制文件实际上不在此位置(PIC)。
直接使用lldb
$ lldb a.out
(lldb) b *0x0000000100000f10
(lldb) r
它停在正确的位置。那么如何使用python绑定重现'真实'lldb的行为?
lldb版本:lldb-340.4.110(lldb由Xcode提供)
OS:Mac(约塞米蒂)
Python 2.7.10
答案 0 :(得分:1)
看起来LaunchSimple没有设置&#34; lldb.eLaunchFlagDisableASLR&#34; SBLaunchInfo选项中的标志。你也可以通过设置符号&#34; main&#34;来测试它。断点。我确实击中了断点,但是当我检查断点的地址时,它不是二进制中记录的主符号的地址。这是因为二进制在启动时滑动(这是ASLR所做的。)
这对我来说似乎是一个错误,因为默认的LaunchInfo选项会禁用ASLR,请将其与lldb.llvm.org上的bugzilla一起提交。
如果我使用更完整的启动API:
launch_info = lldb.SBLaunchInfo(None)
launch_info.SetExecutableFile (lldb.SBFileSpec(exe), True)
error = lldb.SBError()
process = target.Launch (launch_info, error)
然后 - 至少对我来说 - 二进制文件没有滑动,我点击了我在主符号地址上设置的地址断点。
注意,通过预加载地址设置断点仅适用于主可执行文件。大多数库都是从零开始构建的,因此它们必须滑动或者它们会相互加载。关闭ASLR后,这些库最终将在同一地址运行,但它们会滑动一些。
Jonas还询问如何手动解析正在运行的程序中的地址,您可以按照以下步骤进行操作。
首先,术语:&#34;运行之前的lldb术语&#34;并且&#34;在跑步时#34;二进制文件中相同位置的地址是&#34; file&#34;和#34;加载&#34;地址分别。此外,lldb会调用程序中的所有可加载二进制文件&#34; modules&#34; ...
因此,如果您要在某个模块中解析某个数字(lldb :: addr_t)文件地址,则可以分两步完成。首先使用SBAddress
API将文件地址转换为SBModule::ResolveFileAddress
。您可以使用SBTarget::FindModule
找到该模块。然后,一旦程序运行并加载了您感兴趣的模块,您可以使用SBAddress::GetLoadAddress
获取加载地址,并使用它来设置断点。
唯一不好的部分是你无法获得加载地址,直到程序运行(显然),所以你必须有另一种方法来阻止程序才能击中你要打破的地址。通常你可以做一些事情,比如在main
上放一个断点然后做这个工作。当然,如果你想以这种方式解决main
的地址,那你就不走运了。但是大概有一些东西比main
更有趣......
这应该更容易,因为应该有一个API来使用上面提到的SBAddress
来设置按地址断点。然后lldb可以在其底层模块加载时为你解决它。我已经有了一个错误,但尚未获得它。大多数人都会在符号或源位置上设置断点,因此按地址断点并没有引起人们的注意。