[TOC]

0x00 快速入门

编程相关缩写
缩写 | 全称 | 说明
— | — | —
cc | C Compiler |
gcc | Gnu Compiler Collection | 作为一个软件集被你下载下来编译安装的时候
gcc | Gnu C Compiler | 作为一个软件被你调用来编译C程序的时候
g++ | Gnu c++ compiler | 其实g++只是调用gcc,然后连接c++的库,并且作相应的一些编译设置而已
gcj | Gnu Compiler for Java |
gdb | Gnu DeBug |

file命令

描述:用来探测给定文件的类型,file命令对文件的检查分为文件系统、魔法幻数检查和语言检查3个过程.

1
2
#基础语法和参参数
file (选项) (参数) # parameters-> 文件:要确定类型的文件列表,多个文件之间使用空格分开,可以使用shell通配符匹配多个文件

WeiyiGeek.参数

WeiyiGeek.参数

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#示例1.显示文件类型
$file anaconda-ks.cfg
anaconda-ks.cfg: ASCII text
$file PentextBox.zip
PentextBox.zip: Zip archive data, at least v2.0 to extract

$file -b PentextBox.zip #不显示文件名称
Zip archive data, at least v2.0 to extract

$file -b -i PentextBox.zip #显示MIME类别
application/zip; charset=binary
$file -b -i anaconda-ks.cfg
text/plain; charset=us-ascii


#示例2.判断当前系统的位数(运行的平台,以及架构和是不是支持裁剪stripped,)
$file /bin/ls
/bin/ls: [关键点]ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=ceaf496f3aec08afced234f4f36330d3d13a657b, stripped


#示例3.显示符合链接的文件类型以及目录
$file anaconda-ks.ln
anaconda-ks.ln: symbolic link to `anaconda-ks.cfg`
$file /root/
/root/: directory


size 命令

描述:分析Linux程序内存段分布,但它的输出不包括stack和heap的部分,只包括文本段(text), 代码段(data),未初始化数据段(bss)三部分。

  • 1、文本段:包含程序的指令,它在程序的执行过程中一般不会改变。
  • 2、数据段:包含了经过初始化的全局变量和静态变量,以及他们的值。
  • 3、BSS段:包含未经初始化的全局变量和静态变量。
  • 4、堆栈段:包含了函数内部声明的局部变量。当然上面段的作用不仅于此具体的作用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#示例1.以C脚本来分析
[[email protected] ccodes]# cat test.c

// 论1:未初始化的全局变量保存在BSS段
int g_data; //4B(由于整型占用了4B)

//论2:经过初始化的全局变量保存在数据段中
int gg_data=1;

// 论6:const修饰的全局变量保存在文本段
const int g_data=1;

//论8:字符串常量保存在文本段/数据data段
char *pstr="123456789"; //文本占用9B,数据data段4B
//char ptrs[10]="123456789"; //这个只增加数据data段

int main()
{
//论3:未初始化的静态变量保存在BSS段中
static int sg_data;

//论4:经过初始化的静态变量保存在数据段中
static int sgg_data = 2;

//结论7:const修饰的局部变量保存在文本段
const int i_data=1;

return 1;
}
WeiyiGeek.案例演示

WeiyiGeek.案例演示


0x01 应用依赖查看

ldd 命令

描述:用于打印程序或者库文件所依赖的共享库列表。值得注意的是ldd不是一个可执行程序而只是一个shell脚本: cat whereis ldd | cut -f 2 -d ' ',ldd显示可执行模块的dependency(所属)的工作原理,其实质是通过ld-linux.so(elf动态库的装载器)来实现的;

它能够显示可执行模块的dependency(所属)(所属),其原理是通过设置一系列的环境变量,如下:LD_TRACE_LOADED_OBJECTS、LD_WARN、LD_BIND_NOW、LD_LIBRARY_VERSION、LD_VERBOSE等。

当LD_TRACE_LOADED_OBJECTS环境变量不为空时,任何可执行程序在运行时,它都会只显示模块的dependency(所属),而程序并不真正执行。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ export LD_TRACE_LOADED_OBJECTS=0
$ ls (实际上命令并未执行)
linux-vdso.so.1 => (0x00007fffcb2ff000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f236c95d000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f236c758000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007f236c54f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f236c181000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f236bf1f000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f236bd1b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f236cb84000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f236bb16000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f236b8fa000)
$ unset LD_TRACE_LOADED_OBJECTS
$ ls
aio.h bits dlfcn.h

Q:那为何会如此?
我们知道ld-linux.so模块会先于executable模块程序工作,并获得控制权,因此当上述的那些环境变量被设置时ld-linux.so选择了显示可执行模块的dependency(所属)。
实际上可以直接执行ld-linux.so模块,如:/lib/ld-linux.so.2 --list program(这相当于ldd program)

基础语法:

1
2
3
4
5
ldd (选项) (参数-指定可执行程序或者文库)
-v:详细信息模式,打印所有相关信息;
-u:打印未使用的直接依赖;
-d:执行重定位和报告任何丢失的对象;
-r:执行数据对象和函数的重定位,并且报告任何丢失的对象和函数;

基础实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#1.显示su应用依赖的动态链接库
ldd `whereis sudo|cut -f2 -d ' '`
linux-vdso.so.1 => (0x00007ffceeb96000)
libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f1b92599000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f1b92372000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f1b9216f000)
libsudo_util.so.0 => /usr/libexec/sudo/libsudo_util.so.0 (0x00007f1b91f5c000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f1b91d58000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1b9198a000)
libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007f1b91784000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f1b91522000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1b929e7000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f1b91306000)


#2.详细依赖查看
$ ldd -v `whereis sudo|cut -f2 -d ' '`
linux-vdso.so.1 => (0x00007fff4269e000)
libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f7efb74f000)
Version information:
/usr/bin/sudo:
libutil.so.1 (GLIBC_2.2.5) => /lib64/libutil.so.1
libc.so.6 (GLIBC_2.9) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.14) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.8) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.6) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.11) => /lib64/libc.so.6


#3.当应用报错时候可以采用ldd来查看缺少的so链接库(比如下图)
#解决程式因缺少某个库文件而不能运行的一些问题
ln -s /usr/lib/i386-linux-gnu/libpangoxft-1.0.so.0.3800.1 /usr/lib/libpangoxft-1.0.so.0

WeiyiGeek.

WeiyiGeek.

注意事项:

    1. ldd的标准版本和glibc2一起提供, Libc5和老版本以前提供在一些系统中还存在。
    • 在libc5版本中长选项不支持
    • glibc2版本不支持-V选项,只提供等价的–version选项。
    1. 如果命令行中给定的库名字包含/,这个程式的libc5版本将使用他作为库名字;否则他将在标准位置搜索库;
    1. 注意ldd不能工作在a.out格式的共享库上,调试异常。