显示已编译二进制文件中的字符串

马丁·维格特

假设我有一个简单的C程序,并使用gcc -o hello hello.c以下命令进行编译

#include<stdio.h>

main()
{
    printf("hello");
}

现在,我想用该strings实用程序显示“字符串”

$ strings hello
/lib64/ld-linux-x86-64.so.2
__gmon_start__
libc.so.6
printf
__libc_start_main
GLIBC_2.2.5
fffff.
l$ L
t$(L
|$0H
hello
;*3$"

和预期的一样,我可以在二进制文件中看到字符串“ hello”。

但是,当我修改C程序并将“ hello”作为常量时:

#include<stdio.h>

char s[6] = {'h','e','l','l','o','\0' } ;

main()
{
    printf("%s\n", s);
}

我不再在二进制文件中看到字符串“ hello”。

有人可以解释为什么吗?

格热哥兹·斯佩特科夫斯基

来自man 1 strings(强调我的):

对于给定的每个文件,GNU字符串将打印至少4个字符长(或下面的选项提供的数字)的可打印字符序列,后跟不可打印字符。默认情况下,它仅打印目标文件的初始化和加载部分中的字符串对于其他类型的文件,它将打印整个文件中的字符串。

C语言没有将字符串定义为一等公民。它们表示字符串数组字符串文字例如,在这样的基本程序中:

#include <stdio.h>

int main(void)
{
    char s[] = "my string";

    printf("%s\n", s);

    return 0;
}

我们可以合理地说s数组包含一个字符串。请注意,这是在堆栈上分配的。它具有自动存储期限,与您的问题示例相反,在(和任何)函数s之外明确定义了存储期限main

现在,回到您的问题,两个程序中的两个基础对象都具有相同的特征:

  • 它们的类型char[6]和内容相同(C11§6.2.5/ p20),
  • 它们具有静态的存储期限,这意味着它们必须在程序执行之前在概念上进行初始化(C11§5.1.2/ p1)。

唯一的区别是修改字符串文字会调用未定义的行为,因此编译器可以选择将它们放置在单独的(例如,只读的)内存位置。

C11§6.2.5/ p20类型

数组类型描述具有特定成员对象类型(称为元素类型)连续分配的非空对象集。

C11§5.1.2/ p1执行环境

程序启动前,所有具有静态存储持续时间的对象都应初始化(设置为其初始值)。

从更实际的角度来看,除了该strings命令之外,您还可以使用gdb调试器(更具体地说是使用x/s命令)来分析程序这是基本插图:

$ gcc -g hello.c -o hello
$ gdb -q hello
Reading symbols from /home/grzegorz/hello...done.
(gdb) disas /m main
Dump of assembler code for function main:
6   {
   0x00000000004004c4 <+0>: push   %rbp
   0x00000000004004c5 <+1>: mov    %rsp,%rbp

7       printf("%s\n", s);
   0x00000000004004c8 <+4>: mov    $0x60086c,%edi
   0x00000000004004cd <+9>: callq  0x4003b8 <puts@plt>

8   }
   0x00000000004004d2 <+14>:    leaveq 
   0x00000000004004d3 <+15>:    retq   

End of assembler dump.
(gdb) x/s 0x60086c
0x60086c <s>:    "hello"

您可能要比较disas程序命令结果,看看它们之间是否存在差异。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何从已编译的二进制文件(.so)中删除字符串

替换二进制文件中的字符串

将二进制字符串(ASCII)转换为二进制文件

将大二进制字符串写入二进制文件

将二进制文件读入字符串

预览二进制文件时显示的字符串格式是什么?

在字符串中翻转二进制

从字符串中获取二进制数据

从二进制字符串中获取模式

JavaScript中的二进制到字符串

Python中字符串的二进制移位

从字符串中写入二进制数据

从二进制文件列表中打印包含特定 ascii 字符串的文件

Laravel Nova:如何显示二进制字符串中的图像?

使用外部文件中的二进制数据(utf-8中的字符串)

如何将二进制文件的内容放在c中的字符串中?

使用C ++在二进制文件中搜索字符串

如何从二进制文件中读取以nul结尾的字符串

什么时候可以在可执行二进制文件中编辑字符串?

如何检查二进制文件中是否存在字符串?

二进制文件中ASCII字符串的“ grep”偏移量

在Ruby中以字符串形式读取二进制文件

如何获取大(二进制)文件中字符串的偏移量?

使用 C# 在文件中存储字符串索引的二进制数据

使用二进制模式字符串从文件中删除行

将字符串作为二进制写入/读取到随机访问的文件中

从C中的二进制文件读取字符串时发生访问冲突

关闭程序后如何从二进制文件中读取字符串

二进制到字符串/字符串到二进制