关注分享主机优惠活动
国内外VPS云服务器

linux二进制文件是什么意思(linux二进制打开文件)

本文中,主机频道详细介绍了“linux二进制文件是什么意思”。内容详细,步骤清晰,细节处理得当。希望这篇文章《linux二进制文件是什么意思》能帮你解决疑惑。让我们按照主机频道的思路,一起学习新知识。

在linux中,二进制文件是指一个文件,它是根据文件在外部设备中的存储形式是二进制而命名的。二进制文件编码可变,灵活利用率高,而解码难度较大。不同的二进制文件有不同的解码方法。Linux中的可执行文件(不包括脚本、文本模式的批处理文件)是二进制格式的。

什么是二进制文件?常规文件:它是一个经常被访问的文件。ls -al显示的属性中,第一个属性是[-],比如[-rwxrwxrwx]。另外,根据文件的内容,大致可以分为:

1.纯文本文件(ASCII):这是Unix系统中最常见的文件类型,因为内容可以直接读取,如数字、字母等,所以称为纯文本文件。几乎所有的安装文件都属于这种文件类型。例如,使用命令“cat ~/。bashrc”来查看文件的内容(cat是读取文件的内容)。

2.二进制文件:其实系统只知道并能执行二进制文件。Linux中的可执行文件(不包括脚本、文本模式的批处理文件)就是这种格式。例如,命令cat是一个二进制文件。

广义的二进制文件是指文件,因文件在外部设备中的存储形式为二进制而得名。狭义的二进制文件是指文本文件以外的文件。文本文件是由多行字符组成的计算机文件。文本文件存在于计算机系统中,通常在文本文件的最后一行放置文件结束标志。文本文件的编码基于固定长度的字符,解码相对容易;二进制文件编码可变,灵活利用率高,而解码难度较大。不同的二进制文件有不同的解码方法。

3.数据格式文件:有些程序在运行过程中会读取一定格式的文件,那些一定格式的文件可以称为数据文件。例如,当用户登录时,Linux会将登录数据记录在/var/log/wtmp文件中,这是一个可以由最后一个命令读取的数据文件。但是使用cat时,会读取linux系统的乱码。因为它属于特殊格式文件。

Linux上分析二进制文件的10种方法“这个世界上有10种人:懂二进制的和不懂的。”

我们每天都要和二进制文件打交道,但对二进制文件却知之甚少。我所说的二进制文件是指您每天运行的可执行文件,从命令行工具到成熟的应用程序。

Linux提供了一套丰富的工具,使得分析二进制文件变得很容易。无论你的工作角色是什么,如果你在Linux上工作,了解这些工具的基本知识将有助于你更好地理解你的系统。

在本文中,我们将介绍一些最流行的Linux工具和命令,其中大部分都是Linux发行版的一部分。如果您没有找到它们,您总是可以使用您的包管理器来安装和探索它们。记住:学会在正确的地方使用正确的工具需要大量的耐心和练习。

文件

它的功能:帮助确定文件类型。

这将是你二元分析的起点。我们每天都要处理文件。并非所有文件都是可执行类型,但有各种文件类型。在开始之前,您需要知道要分析的文件类型。是二进制文件、库文件、ASCII文本文件、视频文件、图片文件、PDF文件、数据文件等吗?

file命令将帮助您确定正在处理的文件的类型。

$ file /bin/ls
/bin/ls: ELF 64位LSB可执行文件,x86-64,版本1 (SYSV),动态链接(使用共享库),对于GNU/Linux 2.6.32,BuildID[sha1]= 94943 a 89d 17 e 9d 373 b 2794 DC B1 f 7 e 38 c 95 b 66 c 86,已剥离
$
$ file /etc/passwd
/etc/passwd: ASCII文本
$ldd

它的功能:打印共享对象的依赖关系。

如果您在一个可执行的二进制文件上使用了上面的file命令,您肯定会在输出中看到消息“动态链接”。这是什么意思?

在开发软件的时候,我们尽量不去重建轮子。大多数软件程序都需要一组常见的任务,如打印输出或读取标准输入/打开文件。所有这些常见的任务都被抽象成一组常见的函数,然后每个人都可以使用它们,而不用编写自己的变体。这些常用的函数放在一个名为libc或glibc的库中。

如何找到可执行程序所依赖的库?这就是ldd命令的作用。在动态链接的二进制文件上运行该命令将显示所有相关的库及其路径。

$ ldd /bin/ls
Linux-vdso . so . 1 = & gt;(0x00007ffef5ba1000)
libselinux . so . 1 = & gt;/lib 64/libselinux . so . 1(0x 00007 fea9f 854000)
lib cap . so . 2 = & gt;/lib 64/lib cap . so . 2(0x 00007 FEA 9 f 64 f 000)
libacl . so . 1 = & gt;/lib 64/libacl . so . 1(0x 00007 fea9f 446000)
libc . so . 6 = & gt;/lib 64/libc . so . 6(0x 00007 fea9f 079000)
libpcre . so . 1 = & gt;/lib 64/libpcre . so . 1(0x 00007 FEA 9 ee 17000)
libdl . so . 2 = & gt;/lib 64/libdl . so . 2(0x 00007 FEA 9 EC 13000)
/lib 64/LD-Linux-x86-64 . so . 2(0x 00007 Fe a9 fa 7b 000)
libattr . so . 1 = & gt;/lib 64/libattr . so . 1(0x 00007 FEA 9 ea 0 e 000)
libpthread . so . 0 = & gt;/lib 64/libpthread . so . 0(0x 00007 FEA 9e 7f 2000)
$ltrace

作用:库调用追踪器。

我们现在知道了如何使用ldd命令来查找可执行程序所依赖的库。然而,一个库可以包含数百个函数。在这数百个函数中,哪些是我们的二进制程序正在使用的实际函数?

ltrace命令可以显示运行时从库中调用的所有函数。在下面的示例中,您可以看到被调用函数的名称以及传递给它的参数。您还可以在输出的最右边看到这些函数返回的内容。

$ ltrace ls
__libc_start_main(0x4028c0,1,0x7ffd94023b88,0x412950 & lt未完成的...& gt
strr chr(& quot;ls & quot, '/')=零
setlocale(LC_ALL,& quot")= & quot美国。UTF-8 & quot;
bindtextdomain(& quot;coreutils & quot,& quot/usr/share/locale & quot;)= & quot/usr/share/locale & quot;
textdomain(&quotcoreutils & quot)= & quotcoreutils & quot
__cxa_atexit(0x40a930,0,0,0x736c6974756572) = 0
isatty(1) = 1
getenv(& quot;QUOTING _ STYLE & quot)=零
getenv(& quot;列& quot)=零
ioctl(1,21523,0x7ffd94023a50) = 0
& lt& ltsnip & gt& gt
fflush(0x7ff7baae61c0) = 0
fclose(0x7ff7baae61c0) = 0
+++已退出(状态0) ++
$hexdump

它的功能是以ASCII、十进制、十六进制或八进制显示文件内容。

通常,当你用一个应用程序打开一个文件,而它不知道如何处理它时,就会发生这种情况。尝试用vim打开一个可执行文件或视频文件,屏幕上只会看到抛出的乱码。

在hexdump中打开一个未知文件,可以帮助你看到文件的具体内容。您还可以选择使用一些命令行选项来查看ASCII文件数据。这可能有助于您了解它是什么类型的文件。

$ hexdump -C /bin/ls | head
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00。极低频............|
00000010 02 00 3e 00 01 00 00 00 D4 42 40 00 00 00 00 00 00 00 |..& gt......B@.....|
00000020 40 00 00 00 00 00 00 00 F0 C3 01 00 00 00 00 00 00 00 | @...............|
00000030 00 00 00 00 40 00 38 00 09 00 40 00 1f 00 1e 00 |....@.8...@.....|
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 |........@.......|
00000050 40 00 40 00 00 00 00 00 40 00 40 00 00 00 00 00 |@.@.....@.@.....|
00000060 F8 01 00 00 00 00 00 00 F8 01 00 00 00 00 00 00 00 |................|
00000070 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 |................|
00000080 38 02 00 00 00 00 00 00 38 02 40 00 00 00 00 00 |8.......8.@.....|
00000090 38 02 40 00 00 00 00 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 | 8。@.............|
$字符串

它的功能是:在文件中打印一串可打印的字符。

如果您只是在二进制中寻找可打印的字符,那么hexdump对于您的使用场景来说似乎有点大材小用,所以您可以使用strings命令。

开发软件时,会在里面加入各种文本/ASCII信息,比如打印信息、调试信息、帮助信息、错误等等。只要该信息存在于二进制文件中,您就可以使用strings命令将其转储到屏幕上。

$ strings /bin/lsreadelf

它的功能:显示ELF文件的信息。

ELF(可执行可链接文件格式)是可执行文件或二进制文件的主流格式,不仅适用于Linux系统,也适用于各种UNIX系统。如果您已经使用了类似file命令的工具,它告诉您文件是ELF格式的,那么下一步就是使用readelf命令及其各种选项来进一步分析文件。

使用readELF命令时,参考实际的ELF规范非常有用。你可以在这里找到规格。

$ readelf -h /bin/ls
ELF标题:
魔法:7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
类别:ELF64
数据:2 & # 39;s补码,小端
版本:1(当前)
操作系统/ABI: UNIX - System V
ABI版本:0
类型:EXEC(可执行文件)
机器:高级微设备公司X86-64
版本:0x1
入口点地址:0x4042d4
程序头开始:64(文件中的字节数)
段头的开始:115696(文件中的字节数)
标志:0x0
这个头的大小:64(字节)
程序头大小:56(字节)
节目头数:9
节头的大小:64(字节)
区段标题数量:31
节标题字符串表索引:30
$objdump

它的功能是显示目标文件中的信息。

二进制文件是由你写的源代码创建的,这些代码将由一个叫做编译器的工具编译。这个编译器会生成相对于源代码的机器语言指令,然后CPU会执行特定的任务。这些机器语言代码可以用称为汇编语言的助记符来解释。汇编语言是一组指令,可以帮助你理解程序执行的操作,最终在CPU上执行。

objdump实用程序读取二进制或可执行文件,并将汇编语言指令转储到屏幕上。汇编语言知识对于理解objdump命令的输出非常重要。

记住:汇编语言是特定于架构的。

$ objdump -d /bin/ls | head

/bin/ls:文件格式elf64-x86-64

拆卸部分。初始化:

0000000000402150 & lt_ init @ @ Base & gt:
402150: 48 83 ec 08 sub $0x8,%rsp
402154:48 8b 05 6d 8e 21 00 mov 0x 218 e6d(% rip),% rax # 61afc8 & lt_ _ gmon _ start _ _ & gt
40215b: 48 85 c0测试%rax,%rax
$strace

它的功能:跟踪系统调用和信号。

如果你用过上面提到的ltrace,可以把strace想成类似的。唯一的区别是strace工具不是一个跟踪调用的库,而是跟踪系统调用。系统调用是你与内核对接完成工作的时候。

比如你想在屏幕上打印一些东西,你会使用标准库libc中的printf或者puts函数;但是,在底层,最终会有一个名为write的系统调用来将东西实际打印到屏幕上。

$ strace -f /bin/ls
exec ve(& quot;/bin/ls & quot;,[& quot;/bin/ls & quot;],[/* 17 vars */]) = 0
brk(NULL) = 0x686000
mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f967956a000
访问(& quot/etc/ld.so.preload&quot,R_OK) = -1 ENOENT(没有这样的文件或目录)
打开(& quot/etc/ld.so.cache&quot,O_RDONLY|O_CLOEXEC) = 3
fstat(3,{st_mode=S_IFREG|0644,st_size=40661,...}) = 0
mmap(NULL,40661,PROT _读取,映射_私有,3,0) = 0x7f9679560000
close(3) = 0
& lt& ltsnip & gt& gt
fstat(1,{st_mode=S_IFCHR|0620,st_rdev=makedev(136,1),...}) = 0
mmap(NULL,4096,PROT _读| PROT _写,地图_私人|地图_匿名,-1,0) = 0x7f9679569000
写(1,& quotR2 RH \ n & quot;,7R2 RH
) = 7
close(1) = 0
munmap(0x7f9679569000,4096) = 0
close(2) = 0
exit_group(0) =?
+++用0 ++退出
美元纳米

它的功能是列出目标文件中的符号。

如果您正在使用的二进制文件没有被剥离,nm命令将在编译期间为您提供嵌入在二进制文件中的有价值的信息。Nm可以帮助你从二进制文件中识别变量和函数。可想而知,如果无法访问二进制文件的源代码,那会有多有用。

为了展示nm,我们很快写了一个小程序,用-g选项编译,我们会看到这个二进制文件没有被剥离。

$ cat hello.c
# include & ltstdio.h & gt

int main() {
printf(& quot;你好世界!");
返回0;
}
$
$ gcc -g hello.c -o hello
$
$ file你好
您好:ELF 64位LSB可执行文件,x86-64,版本1 (SYSV),动态链接(使用共享库),针对GNU/Linux 2.6.32,BuildID[sha1]= 3 de 46 c 8 efb 98 BC E4 ad 525d 3328121568 ba 3d 8 a5d,未剥离
$
$ ./你好
你好世界!$
$

$ nm hello | tail
0000000000600e20 d _ _ JCR _ END _ _
0000000000600e20 d _ _ JCR _ LIST _ _
000000000004005 B0 T _ _ libc _ CSU _ fini
0000000000400540T _ _ libc _ CSU _ init
u _ _ libc _ start _ main @ @ GLIBC _ 2 . 2 . 5
00000000040051d T main
U printf@@GLIBC_2.2.5
0000000000400490 t寄存器_ tm _克隆
0000000000400430 T _start
00000000000601030D _ _ TMC _ END _ _
$广发银行

它的作用:GNU调试器。

嗯,并不是二进制文件中的所有内容都可以进行静态分析。我们确实执行了一些命令来运行二进制文件(用于分析),比如ltrace和strace;然而,软件由可能导致不同备选路径的各种条件组成。

分析这些路径的唯一方法是在运行时环境中的任何给定位置停止或暂停程序,并能够在继续之前分析信息。

这是调试器的功能。在Linux上,gdb是调试器事实上的标准。它可以帮助你加载程序,在特定的地方设置断点,分析内存和CPU的寄存器,以及更多的功能。它补充了上面提到的其他工具,并允许您进行更多的运行时分析。

需要注意的一点是,一旦你用gdb加载一个程序,你会看到它自己的(gdb)提示。所有进一步的命令都将在这个gdb命令提示符下运行,直到您退出。

我们将使用之前编译的hello程序和gdb来看看它是如何工作的。

$ GD b-q ./你好
从/home/flash/hello中读取符号...完成了。
(gdb)断开主电源
0x400521处的断点1:文件hello.c,第4行。
(gdb)信息中断
Num类型Disp Enb地址什么
1断点将y 0x0000000000400521保留在hello.c:4的main中
(广东发展银行)运行
启动程序:/home/flash/。/你好

断点1,hello.c:4处的main()
4 printf(& quot;你好世界!");
缺少单独的debuginfo,请使用:debug info-install glibc-2.17-260 . el7 _ 6.6 . x86 _ 64
(广发银行)英国电信
#0 main()位于hello.c:4
(广发银行)c
继续。
你好世界![下级1(进程29620)正常退出]
(广发银行)问
$

未经允许不得转载:主机频道 » linux二进制文件是什么意思(linux二进制打开文件)

评论 抢沙发

评论前必须登录!