[Mac 10.7.1 Lion Intel-based x64 gcc4.2.1]
Q: 有的时候,记得在某个目录下写过某个变量或者其它什么文本形式的东西,但是后来忘记写在哪个文件里了,怎么找到?
A: 这个就需要用到grep命令了。它很强大,尤其对于开发或者寻找某个东西在哪里的时候。举个例子,有个目录里面有一些文件:
而且,有一些文件里面含有main字符串,现在需要把它们找出来:
很可惜,在mac10.7.1下面,grep的一个参数-r似乎无效,不能递归到子目录下搜索;不过在cygwin里面是ok的;bug列表中没有找到,但是实践确实无效,也许是个bug吧。
上面测试用的grep版本是2.5.1.
当然,它还支持很多参数,比如-i忽略大小写,-E进行egrep扩展等等。
Q: 经常会遇到,创建一个进程,但是后来想把它关闭,ps -ax命令得到一堆进程,不便于寻找,怎么快速能定位它?
A: 同样可以使用上面的grep命令。例如,需要寻找系统是否启动了httpd进程:
Q: 有时,需要分析一个生成的可执行文件的内部结构,怎么办?
A: 使用otool命令,它异常的强大。它支持很多参数,帮您将可执行文件,也包括中间文件、库等文件的内部展示地一览无余。
Q: 我需要查看一个可执行文件的mach头,怎么办?
A: 可以使用-h参数。如下,写一个简单的代码,保存为hello.c:
#include <stdio.h> int main() { int i = 2; printf("%d\n", i); return 0; }
用它和系统的mach header头文件结构对应,就可以得到它的具体含义。同理,使用-l命令可以得到mach-o格式文件的load commands.
Q: 我想得到某个可执行文件依赖哪些动态库,怎么办?
A: 可以使用otool命令的-L参数即可。同上使用上面的hello文件,
Q: 我想知道一个可执行文件它的代码段,怎么办?
A: 可以使用otool命令的-t参数。同样使用上面的可执行文件hello,
不过,它是二进制形式的。
Q: 怎么才能显示上面的二进制形式的汇编形式代码?
A: 可以配合-V命令或者-v命令(二者有一定区别)。
xichenMac:c_simple xichen$ otool -Vt hello hello: (__TEXT,__text) section start: 0000000100000eb0 pushq $0x00 0000000100000eb2 movq %rsp,%rbp 0000000100000eb5 andq $0xf0,%rsp 0000000100000eb9 movq 0x08(%rbp),%rdi 0000000100000ebd leaq 0x10(%rbp),%rsi 0000000100000ec1 movl %edi,%edx 0000000100000ec3 addl $0x01,%edx 0000000100000ec6 shll $0x03,%edx 0000000100000ec9 addq %rsi,%rdx 0000000100000ecc movq %rdx,%rcx 0000000100000ecf jmp 0x100000ed5 0000000100000ed1 addq $0x08,%rcx 0000000100000ed5 cmpq $0x00,(%rcx) 0000000100000ed9 jne 0x100000ed1 0000000100000edb addq $0x08,%rcx 0000000100000edf callq _main 0000000100000ee4 movl %eax,%edi 0000000100000ee6 callq 0x100000f2e ; symbol stub for: _exit 0000000100000eeb hlt 0000000100000eec nop 0000000100000eed nop 0000000100000eee nop 0000000100000eef nop _main: 0000000100000ef0 pushq %rbp 0000000100000ef1 movq %rsp,%rbp 0000000100000ef4 subq $0x10,%rsp 0000000100000ef8 movl $0x00000002,0xf4(%rbp) 0000000100000eff movl 0xf4(%rbp),%eax 0000000100000f02 xorb %cl,%cl 0000000100000f04 leaq 0x00000055(%rip),%rdx 0000000100000f0b movq %rdx,%rdi 0000000100000f0e movl %eax,%esi 0000000100000f10 movb %cl,%al 0000000100000f12 callq 0x100000f34 ; symbol stub for: _printf 0000000100000f17 movl $0x00000000,0xf8(%rbp) 0000000100000f1e movl 0xf8(%rbp),%eax 0000000100000f21 movl %eax,0xfc(%rbp) 0000000100000f24 movl 0xfc(%rbp),%eax 0000000100000f27 addq $0x10,%rsp 0000000100000f2b popq %rbp 0000000100000f2c ret xichenMac:c_simple xichen$可以看到,对应的汇编已经出来了。
Q: 我想查看__TEXT段的字符串字面量,怎么查看?
A: 可以使用-sv __TEXT __cstring参数来得到。修改hello.c, 如下:
#include <stdio.h> int g_i = 0xAA; const int g_j = 0xBB; char *str = "hello"; int main() { int i = 2; printf("%d\n", i); return 0; }编译成hello.
可以看到,全局的str对应的hello\0和printf输出的%d\n\0字符串被显示了
Q: 我想查看数据区__DATA里面的数据(__data),怎么办?
A: 可以使用-sv __DATA __data参数来得到。使用上面的hello,
可以看到前4个字节对应的全局变量g_i在此被显示。如果使用otool -d hello会查看hello的__DATA区的数据。
Q: 我想查看全局const变量g_i对应的数据,怎么查看?
A: 可以使用-sv __TEXT __const参数来查看。
可以看到0xBB变量的数据在此展示了。
Q: 我只想查看某个函数的汇编形式,怎么办?
A: 可以使用-p参数来指定查看的函数。如下:
上面查看了hello中的main函数的汇编形式(注意,虽然代码中是main函数,但是在可执行文件的符号表中,可能会被改变,这依赖编译器).
Q: 有的可执行文件支持不止一种硬件架构的代码,如何查看包含哪些?
A: 可以使用file命令查看。如上,查看上面的hello文件的信息:
可以看到它是64位运行于x64平台上的可执行文件。
Q: 如何编译得到一个可执行文件,它是通用的,可以包含几种架构代码的?
A: 使用gcc的-arch参数功能来实现。依然使用上面的hello.c代码:
再运行file命令:
可以看到,文件包含了两种架构体系代码。
Q: 看到很多逆向工具,可以修改特定的目标文件实现特定的目的,是否可以修改hello文件来得到希望的执行效果?
A: 是的。我并不善于修改汇编代码,我们可以修改数据段来查看效果。
修改上面的hello.c代码如下:
#include <stdio.h> int g_i = 0xAA; const int g_j = 0xBB; char *str = "hello"; int main() { int i = 2; printf("%s %d\n", str, i); return 0; }
下面就使用vi来修改可执行文件的hello字符串为iello, 最后查看执行效果。使用vi打开hello文件,定位到hello字符串的位置:
修改hello的h为i:
保存,然后执行hello:
可以看到,执行结果已经变了。
Q: 有时,需要查看一个目标文件中各个段的大小,如何查看?
A: 可以使用size命令。
Q: 有时,需要查看目标文件中可打印的字符串有哪些,如何查看?
A: 可以使用strings命令。
Q: 很多编译好的程序,里面包含了符号表或者一些调试信息,如何去除它们?
A: 可以使用strip命令。
使用strip命令后:
可以看到,符号信息确实少了。
Q: 上面提到的nm命令,它是做什么的?
A: 它是可以查看目标文件中包含的符号信息的。
xichen
2012-5-25 12:50:52