Macos 如何将函数名强制转换为地址并在LLDB中添加偏移量?
比如说,我在Mach-O可执行文件中有两个相邻的函数Macos 如何将函数名强制转换为地址并在LLDB中添加偏移量?,macos,debugging,lldb,Macos,Debugging,Lldb,比如说,我在Mach-O可执行文件中有两个相邻的函数subfunc()和main(),我想反汇编subfunc()到main()+0x10的所有指令。 我知道我可以使用`(void(*)()subfunc`)将函数强制转换为地址—难道没有更简单的方法吗 我的尝试如下,但我收到以下错误消息: dis-s`(void(*)()子功能`-e`(void(*)()main+0x10` 错误:错误:指向函数类型“void()”的指针上的算术运算 如何修复此问题?这似乎是正确的语法: dis --star
subfunc()
和main()
,我想反汇编subfunc()
到main()+0x10的所有指令。
我知道我可以使用`(void(*)()subfunc`
)将函数强制转换为地址—难道没有更简单的方法吗
我的尝试如下,但我收到以下错误消息:
dis-s`(void(*)()子功能`-e`(void(*)()main+0x10`
错误:错误:指向函数类型“void()”的指针上的算术运算
如何修复此问题?这似乎是正确的语法:
dis --start-address `(void(*)())main` --end-address `(void(*)())main`+0x10
此语法与您尝试的变体之间的一个非常小的区别是,+0x10
偏移量在反勾号字符之外,即偏移量在结束反勾号之后
FWIW该变体似乎也能正常工作:
dis --start-address `(void(*)())main` --end-address 0x10+`(void(*)())main`
发现过程:
- 我不熟悉您在原始问题中描述的“backtick”+函数类型转换,因此这是一个非常有用的起点
在我的例子中,我试图在共享库中的函数偏移量处设置断点,在搜索到您的问题之前,我已经做了这么多:
breakpoint set --shlib libexample.dylib --address `((void*)some_function)+81` error: error: function 'some_function' with unknown type must be given a function type error: 1 errors parsing expression
dis --start-address `(void(*)())some_function` --end-address `(void(*)())some_function`+81
- 函数强制转换提示的使用符合错误消息中所述的“函数类型”要求,因此我下一步能够:
print (void(*)())some_function (void (*)()) $38 = 0x00000001230094d0 (libexample.dylib`some_function)
- 然后,我尝试了backtick变量,该变量似乎有效,但我希望该值以十六进制显示:
print `(void(*)())some_function` (long) $2 = 4882207952
- 但是,当我尝试将
格式选项与打印一起使用时,我遇到了一个错误:-f hex
print -f hex `(void(*)())some_function` error: use of undeclared identifier 'f' error: 1 errors parsing expression
- 最后我注意到,
'print'是
输出底部“expression--”的缩写,我意识到这意味着它(显然是?)无法将替代显示格式与帮助打印
一起使用,因为它被转换为print
,这是无效的语法表达式--f hex…
- 最终,我找到了命令名、显示格式和“-”的必要位置和组合,以使其按需要显示:
expression -f hex -- `(void(*)())some_function` (long) $7 = 0x00000001230094d0
- 没有什么特别的原因(我记得),就是在这一点上,我试着把偏移量放在背刻度之外,结果成功了
expression -f hex -- `(void(*)())some_function`+81 (long) $12 = 0x0000000123009521
- 当我尝试使用断点时,它仍然有效:
breakpoint set --shlib libexample.dylib --address `(void(*)())some_function`+81 Breakpoint 6: where = libexample.dylib`some_function + 81, address = 0x0000000123009521
- 然后,我验证了它是否与原始问题中的
命令一起工作:dis
breakpoint set --shlib libexample.dylib --address `((void*)some_function)+81` error: error: function 'some_function' with unknown type must be given a function type error: 1 errors parsing expression
dis --start-address `(void(*)())some_function` --end-address `(void(*)())some_function`+81
- 并确认裸函数名不够:
dis --start-address some_function --end-address `(void(*)())some_function`+81 error: address expression "some_function" evaluation failed
- 我还再次确认,回勾之间的偏移不起作用:
- 正是在这一点上,我意识到我能够解析错误消息(据推测这是故意的): 根本问题是“指针上的算术”
- 进一步的研究表明,它“在函数类型指针上未定义”,并且可以作为gcc扩展提供:
- 这让我们回到@JasonMolenda和@JimIngham的评论,以及函数指针算术解析是如何特例的
在我看来,您收到的“错误:函数类型指针上的算术…”消息充其量是糟糕的UX,充其量是一个bug-
本身基本上以这种方式显示地址引用:lldb
我对0x1230094f9: jle 0x123009cc2 ; some_function + 2034
被显示但AFAICT没有被解析也有类似的感觉libexample.dylib`some_function+81
- 总之,此表格适用于:
现在我只需要弄清楚为什么一些函数没有做我认为应该做的事情……:)`(void(*)())some_function`+0x10
dis-s subfunc-e main+16
--但是我刚刚检查过,当lldb现在不知道这些是函数符号时,它看起来不起作用。显然,没有任何有效的C表达式可用于向函数名添加偏移量,因此lldb中有一些额外的技巧来允许使用这个(通常有用的)地址表达式。我不记得为什么它与一个参数一起工作,这个参数使用的是地址表达式,而不是反勾号eval r.n.@JasonMolenda-谢谢。地址表达式和反勾号求值不是一回事吗?你能给我指一下这些东西的文档吗?main+5不是一个有效的C表达式,但是它是一种非常方便的指定地址的方法。我们添加了“地址表达式”,而不是修改表达式解析器以接受这种形式(我们希望表达式解析器与源语言保持一致)。他们首先尝试将其参数作为表达式进行计算,如果计算失败,他们将解析形式为“symbolname+-offset”的简单表达式“help address expression”应该记录在文档中,但帮助字符串有点简洁…@JimIngham,在任何地方都没有关于地址表达式或backqoute表达式的详细文档吗?如果+-
工作,为什么main+5
不工作?main
不是一个符号吗?