我自己编译了docker,做了一些修改。我想对二进制文件进行一些静态分析。主要是看代码的哪些部分占用了更多内存,等等。它在 linux (elf) 上。有什么建议我应该使用哪些免费工具?我无权访问 IDA。
我会比以下更具体的东西:
size -A -d mydocker
我自己编译了docker,做了一些修改。我想对二进制文件进行一些静态分析。主要是看代码的哪些部分占用了更多内存,等等。它在 linux (elf) 上。有什么建议我应该使用哪些免费工具?我无权访问 IDA。
我会比以下更具体的东西:
size -A -d mydocker
恐怕您要查找内存使用情况的意图可能需要静态和动态分析。运行时事件可能会导致更多或更少的内存使用。我将写下我关于逆向 Go 二进制文件的一般发现,你可以从下面选择你的应用程序特定的解决方案。
Go语言没有可用的反编译工具。尽管根据此讨论,您可以从主要基于 DWARF 调试信息的 Go 二进制文件中识别高级结构。
您可以使用具有 Go 运行时支持的objdump和GDB等传统工具。安装 Go 工具包后:
echo add-auto-load-safe-path /usr/share/go-1.6/src/runtime/runtime-gdb.py >> ~/.gdbinit
为简单起见,我开始研究函数示例。我用标准构建编译了函数示例。Go 编译器的默认构建包含大量 DWARF 信息。您可以看到objdump源代码-程序集混合在使用 Go 语法导入、包和函数表示方面非常成功。
0000000000401000 <main.main>:
func plusPlus(a, b, c int) int {
return a + b + c
}
func main() {
401000: 64 48 8b 0c 25 f8 ff mov %fs:0xfffffffffffffff8,%rcx
401007: ff ff
401009: 48 8d 44 24 d0 lea -0x30(%rsp),%rax
40100e: 48 3b 41 10 cmp 0x10(%rcx),%rax
401012: 0f 86 f1 02 00 00 jbe 401309 <main.main+0x309>
401018: 48 81 ec b0 00 00 00 sub $0xb0,%rsp
res := plus(1, 2)
40101f: 48 c7 c3 01 00 00 00 mov $0x1,%rbx
401026: 48 c7 c0 02 00 00 00 mov $0x2,%rax
40102d: 48 01 c3 add %rax,%rbx
401030: 48 89 d8 mov %rbx,%rax
fmt.Println("1+2 =", res)
401033: 48 8d 1d 6e b3 0f 00 lea 0xfb36e(%rip),%rbx # 4fc3a8 <go.string.*+0x3b0>
...
401159: e8 82 97 05 00 callq 45a8e0 <fmt.Println>
res = plusPlus(1,2,3)
40115e: 48 c7 c3 01 00 00 00 mov $0x1,%rbx
401165: 48 c7 c1 02 00 00 00 mov $0x2,%rcx
40116c: 48 c7 c0 03 00 00 00 mov $0x3,%rax
401173: 48 01 cb add %rcx,%rbx
401176: 48 01 c3 add %rax,%rbx
401179: 48 89 d8 mov %rbx,%rax
fmt. Println("1+2+3 =", res)
40117c: 48 8d 1d 2d b2 0f 00 lea 0xfb22d(%rip),%rbx # 4fc3b0 <go.string.*+0x3b8>
如果您有机会从源代码构建应用程序,我强烈建议您按照 文档中的建议使用 -ldflags "-w" 参数
您可以使用GDB轻松调试和逆向 Go 程序。除非您使用调试信息构建它,否则GDB无法找到用户定义的函数,但是,您可以使用 main 函数来跟踪程序流程。
gdb-peda$ list main.main
9
10 func plusPlus(a, b, c int) int {
11 return a + b + c
12 }
13
14 func main() {
15 res := plus(1, 2)
16 fmt.Println("1+2 =", res)
17
18 res = plusPlus(1,2,3)
我假设您使用调试信息构建它:
void main(void);
void main.init(void);
void main.main(void);
void runtime.main(void);
void runtime.main.func1(void);
void runtime.main.func2(bool *);
0x0000000000401000 main.main
0x0000000000401320 main.init
0x0000000000429a20 runtime.main
0x000000000044aba0 runtime.main.func1
0x000000000044abe0 runtime.main.func2
0x0000000000456520 main
您可以在这篇关于 Go 堆栈实现的博客文章部分的帮助下检查函数并跟踪它们的堆栈使用情况。在要检查和函数的开头设置一个断点runtime.morestack_noctxt堆栈和runtime.mallocinit为堆分配。
另一种非常简单的方法是使用pprof包,您可以在此处找到相关文档。