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

标签 c compilation reverse-engineering binaryfiles decompiler

我在 Ubuntu 18.04 笔记本电脑上使用 VSCode 进行 C 编码,并使用 GNU 的 gcc 进行编译。

我正在对自己的 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$",前面 1 段与 printf 一起使用的字符串以及紧随其后的一个字符串。

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

最佳答案

我们的数字计算机以位为单位进行工作,最常见的是以字节为单位聚集,每个字节包含 8 位。这种组合的含义取决于上下文和解释

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

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

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

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

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

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

您可以使用字符串快速查看文件,以查找可能对您想要完成的任务有帮助的字符串。

关于c - 已编译的 C 二进制文件中的 []A\A]A^A_ 和 ;*3$",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58447147/

相关文章:

linux - 只从 backports 编译一个特定的驱动程序?

c - 了解简单 C 程序的汇编

maven - 使用自定义 ReverseEgineeringStrategy 进行逆向工程

c - 我正在 build 一个小 shell 。如何将两个进程的标准输入和输出设置为管道,以便它们可以通信?

C#:并非所有代码路径都返回一个值

c - 在 BST 中插入节点的问题(迭代方法)

scala - 如何在 Maven 3 中指定插件的顺序(绑定(bind)到同一阶段)?

c# - .NET 程序集的强名称签名

c - 如何从 DHCP 数据包中提取客户端数据?

在 Ubuntu 中使用 C 创建文件