如何反汇编、修改然后重新组装 Linux 可执行文件?

2024-05-27

无论如何,这可以做到吗?我使用过 objdump,但它不会产生我所知道的任何汇编器都可以接受的汇编输出。我希望能够更改可执行文件中的指令,然后对其进行测试。


我认为没有任何可靠的方法可以做到这一点。机器代码格式非常复杂,比汇编文件还要复杂。实际上不可能采用已编译的二进制文件(例如,ELF 格式)并生成将编译为相同(或足够相似)的二进制文件的源汇编程序。要了解差异,请将 GCC 直接编译的输出与汇编器进行比较(gcc -S)与可执行文件上 objdump 的输出(objdump -D).

我能想到有两个主要的并发症。首先,由于指针偏移等原因,机器代码本身与汇编代码并不是一一对应的。

例如,考虑 Hello world 的 C 代码:

int main()
{
    printf("Hello, world!\n");
    return 0;
}

编译为 x86 汇编代码:

.LC0:
    .string "hello"
    .text
<snip>
    movl    $.LC0, %eax
    movl    %eax, (%esp)
    call    printf

其中.LCO是命名常量,printf是共享库符号表中的符号。与 objdump 的输出进行比较:

80483cd:       b8 b0 84 04 08          mov    $0x80484b0,%eax
80483d2:       89 04 24                mov    %eax,(%esp)
80483d5:       e8 1a ff ff ff          call   80482f4 <printf@plt>

首先,常量 .LC0 现在只是内存中某处的一些随机偏移量 - 很难创建在正确位置包含此常量的汇编源文件,因为汇编器和链接器可以自由选择这些常量的位置。

其次,我对此并不完全确定(这取决于位置无关代码之类的事情),但我相信对 printf 的引用实际上根本没有在该代码中的指针地址处进行编码,但是 ELF 标头包含一个查找表在运行时动态替换其地址。因此,反汇编代码与源汇编代码并不完全对应。

综上所述,源程序集有symbols虽然编译后的机器代码有地址这是很难扭转的。

第二个主要的复杂性是汇编源文件无法包含原始 ELF 文件头中存在的所有信息,例如要动态链接的库以及原始编译器放置在那里的其他元数据。重建这个是很困难的。

正如我所说,一种特殊的工具可能可以操纵所有这些信息,但不太可能简单地生成可以重新组装回可执行文件的汇编代码。

如果您只想修改可执行文件的一小部分,我建议您采用比重新编译整个应用程序更微妙的方法。使用 objdump 获取您感兴趣的函数的汇编代码。手动将其转换为“源汇编语法”(在这里,我希望有一个工具能够以与输入相同的语法实际产生反汇编) ,然后根据需要进行修改。完成后,重新编译这些函数并使用 objdump 找出修改后的程序的机器代码。然后,使用十六进制编辑器手动将新机器代码粘贴到原始程序相应部分的顶部,注意新代码与旧代码的字节数完全相同(否则所有偏移量都会错误) )。如果新代码较短,您可以使用 NOP 指令将其填充。如果它更长,您可能会遇到麻烦,并且可能必须创建新函数并调用它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何反汇编、修改然后重新组装 Linux 可执行文件? 的相关文章

  • 任何退出 bash 脚本但不退出终端的方法

    当我使用exitshell 脚本中的命令 该脚本将终止终端 提示符 有什么方法可以终止脚本然后停留在终端中吗 我的剧本run sh预计通过直接获取或从另一个脚本获取来执行 编辑 更具体地说 有两个脚本run2 sh as run sh ec
  • 如何在C(Linux utf8终端)中打印“盒子抽屉”Unicode字符?

    我正在尝试显示 方框图范围 2500 257F 中的 Unicode 字符 它应该是标准 utf8 Unicode 标准 版本 6 2 我根本做不到 我首先尝试使用旧的 ASCII 字符 但 Linux 终端以 utf8 显示 并且没有显示
  • Vagrant 遇到问题 - “404 - 未找到”

    我正在尝试使用 Vagrant 制作一个 LAMP 盒子 有人告诉我它使用起来非常简单 我对网络和虚拟机完全陌生 对 Linux Ubuntu 的经验也很少 我目前已尝试按照官方文档页面上的教程进行操作 http docs vagrantu
  • 动态模拟iOS动态类型系统文本大小(UIContentSizeCategory)

    我想使用不同的系统文本大小选择 包括辅助功能大小 轻松测试我的应用程序 这些可以在 设置 应用程序中进行设置 显示和亮度 gt 文本大小或常规 gt 辅助功能 gt 较大文本 目前我能找到的唯一方法是进入 设置 并使用 UI 更改值 编辑
  • 为什么 OS X 和 Linux 之间的 UTF-8 文本排序顺序不同?

    我有一个包含 UTF 8 编码文本行的文本文件 mac os x cat unsorted txt foo foo 津 如果它有助于重现问题 这里是文件中确切字节的校验和和转储 以及如何自己生成文件 在 Linux 上 使用base64 d
  • (nasm x86实模式)如何在引导加载的扇区中写入/读取字符串?

    我正在使用 NASM 为 x86 实模式编写一个最小操作系统 用于教育目的 我想使用 512 字节引导扇区加载包含操作系统其余部分的更大扇区 我已经成功创建了一个加载另一个扇区的引导扇区 但我似乎无法在加载的扇区中写入 读取字符串 这是我的
  • Ruby:在 Ubuntu 上安装 rmagick

    我正在尝试在 Ubuntu 10 04 上安装 RMagick 看起来here https stackoverflow com questions 1482823 is there an easy way to install rmagic
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • 正则表达式删除块注释也删除 * 选择器

    我正在尝试使用 bash 从 css 文件中删除所有块注释 我有以下 sed 命令的正则表达式 sed r s w s w d 这可以很好地去除块注释 例如 This is a comment this is another comment
  • LINUX:如何锁定内存中进程的页面

    我有一个 LINUX 服务器 运行一个具有大量内存占用的进程 某种数据库引擎 该进程分配的内存太大 需要将其中一部分换出 换出 我想做的是将所有其他进程 或正在运行的进程的子集 的内存页面锁定在内存中 以便只有数据库进程的页面被换出 例如
  • 使用 GNU C 内联汇编在 VGA 内存中绘制字符

    我正在学习使用 C 和内联汇编在 DOS 中进行一些低级 VGA 编程 现在我正在尝试创建一个在屏幕上打印出字符的函数 这是我的代码 This is the characters BITMAPS uint8 t characters 464
  • 如何从 C++ 程序中重新启动 Linux?

    我有一个 Qt 4 GUI 我需要在下拉菜单中提供一个选项 允许用户选择重新启动计算机 我意识到这对于以其他方式重新启动计算机的能力来说似乎是多余的 但选择需要保留在那里 我尝试使用 system 来调用以下内容 suid root she
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li
  • grep 排除文件的数组参数

    我想从我的文件中排除一些文件grep命令 为此我使用参数 exclude excluded file ext 为了更容易阅读 我想使用包含排除文件的 bash 数组 EXCLUDED FILES excluded file ext 然后将
  • awk 在循环中使用时不打印任何内容[重复]

    这个问题在这里已经有答案了 我有一堆使用 file 1 a 1 txt 格式的文件 如下所示 A 1 B 2 C 3 D 4 并使用以下命令添加包含每个文件名称的新列 awk print FILENAME NF t 0 file 1 a 1
  • 在内核代码中查找函数的最佳方法[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我开始浏览内核代码 遇到的一件事是如何跟踪函数调用 结构定义等 有没有一种好的方法可以快速跳转到函数定义并退出 我尝试过 Source N
  • 汇编程序中的过程调用如何工作?

    我刚刚开始摆弄 ASM 我不确定我对过程调用的理解是否正确 假设代码中的某个时刻有一个过程调用 call dword ptr 123 该过程仅包含一个命令 ret ret 0004 该过程调用的效果是什么 返回值将存储在哪里 我在某处读到
  • x86 中有加速 SHA (SHA1/2/256/512) 编码的指令吗?

    一个例子 在x86 是硬件加速 AES 的指令集 http en wikipedia org wiki AES instruction set 但是x86中是否有加速SHA SHA1 2 256 512 编码的指令 以及在x86上编码SHA
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下

随机推荐