[[] A \ A] A ^ A_和; * 3 $“在已编译的C二进制文件中

问题描述 投票:-1回答:1

我在使用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个,紧随其后的一个。

我很好奇:这些字符串到底是什么意思?我猜想它们主要标志着硬编码输出字符串使用的开始和结束。

c compilation reverse-engineering binaryfiles decompiler
1个回答
0
投票

我们的数字计算机处理位,最常见的是聚集在每个包含8位的字节中。这种组合的含义取决于上下文和解释

可能的解释的详尽列表是:

  • 仅在0时才忽略或接受第八位的ASCII字符;
  • 有符号或无符号8位整数;
  • 一种特定机器语言的操作代码(或其一部分),每个处理器(系列)都有自己不同的集合。

例如,十六进制值0x43可以看作:

  1. ASCII字符'C';
  2. [无符号8位整数67(如果使用2的补码,则有符号相同);
  3. Z80 CPU的操作代码“ LD B,E”(请参阅​​,我真的很老,并且已经深入了解该处理器);
  4. ARM CPU的操作代码“ EORS ari”。

现在strings简单地(不是“原始地”)扫描给定的文件,并尝试将字节解释为printable ASCII字符的序列。默认情况下,序列必须至少包含4个字符,并且字节被解释为7位ASCII。顺便说一句,该文件不必是可执行文件。您可以扫描任何文件,但是如果默认情况下为它提供一个目标文件,它将仅扫描内存中加载的部分。

所以您看到的是字节序列,这些字节序列偶然是至少连续4个可打印字符。而且由于某些模式始终在可执行文件中,因此它们看起来似乎具有特殊含义。实际上,它们具有但不必与程序的字符串相关。

您可以使用strings快速浏览文件以查找字符串,这些字符串可能会帮助您完成您要完成的所有任务。

© www.soinside.com 2019 - 2024. All rights reserved.