我在使用VSCode编码C并使用GNU的gcc
编译的Ubuntu 18.04笔记本电脑上。
我正在用自己的C代码进行一些基础工程设计,我注意到一些有趣的细节,其中似乎[]A\A]A^A_
和;*3$"
对似乎出现在我的所有已编译C二进制文件中。它们之间通常是(或始终是)我为printf()
函数硬编码的字符串。
一个例子是这段简短的代码:
#include <stdio.h>
#include <stdbool.h>
int f(int i);
int main()
{
int x = 5;
int o = f(x);
printf("The factorial of %d is: %d\n", x, o);
return 0;
}
int f(int i)
{
if(i == 0)
{
return i;
}
else
{
return i*f(i-1);
}
}
...然后使用gcc test.c -o test
进行编译。
当我运行strings test
时,输出以下内容:
/lib64/ld-linux-x86-64.so.2
0HSn(
libc.so.6
printf
__cxa_finalize
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
AWAVI
AUATL
[]A\A]A^A_
The factorial of %d is: %d
;*3$"
GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.7697
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
test.c
__FRAME_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
_edata
printf@@GLIBC_2.2.5
__libc_start_main@@GLIBC_2.2.5
__data_start
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
__bss_start
main
__TMC_END__
_ITM_registerTMCloneTable
__cxa_finalize@@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.data
.bss
.comment
与我编写的其他脚本相同,总是弹出2个[]A\A]A^A_
和;*3$"
,在printf
所使用的字符串之前1个,紧随其后的一个。
我很好奇:这些字符串到底是什么意思?我猜想它们主要标志着硬编码输出字符串使用的开始和结束。
我们的数字计算机处理位,最常见的是聚集在每个包含8位的字节中。这种组合的含义取决于上下文和解释。
可能的解释的详尽列表是:
例如,十六进制值0x43可以看作:
现在strings
简单地(不是“原始地”)扫描给定的文件,并尝试将字节解释为printable ASCII字符的序列。默认情况下,序列必须至少包含4个字符,并且字节被解释为7位ASCII。顺便说一句,该文件不必是可执行文件。您可以扫描任何文件,但是如果默认情况下为它提供一个目标文件,它将仅扫描内存中加载的部分。
所以您看到的是字节序列,这些字节序列偶然是至少连续4个可打印字符。而且由于某些模式始终在可执行文件中,因此它们看起来似乎具有特殊含义。实际上,它们具有但不必与程序的字符串相关。
您可以使用strings
快速浏览文件以查找字符串,这些字符串可能会帮助您完成您要完成的所有任务。