是否可以用已编译的二进制文件中的虚拟函数替换特定函数的每个实例?

2024-01-07

是否可以改变现有 x86-64 二进制文件引用和/或调用某个特定函数的方式。具体来说,是否有可能改变二进制文件而不发生任何事情(类似于nop)在该函数通常会执行的时间?

我意识到有强大的专业工具(即反编译器/反汇编器)可以完成此类任务,但我真正想知道的是可执行格式是否“足够”人类可读,能够完成此类任务只需 vim 和一个十六进制编辑器就可以了(至少在小程序上)。

某些可执行文件格式(例如 mach-o、elf、Windows 使用的任何文件等等)是否比其他格式更具可读性?难道它们全都是完全无法理解的胡言乱语吗?任何专家观点和/或良好的起点/参考文献将不胜感激。

免责声明

有人过来并很快对这个问题的初始版本投了反对票,所以我想完全清楚地表明这一点:我对禁用任何串行或安全检查或任何类似的东西不感兴趣。最初我想要一个程序停止发出真正令人恼火的噪音,但现在我只是好奇编译器和可执行文件是如何工作的。

我这样做是为了教育价值,我认为 SE 上的其他人也会对答案感兴趣。然而,我知道其他人可能不太喜欢这个话题。如果您对我所说的内容有疑问,请发表评论,我保证我会更改我的帖子。


当相关函数位于二进制文件本身并使用标准调用约定时,这很简单。例子:

void make_noise() { printf("Quack!\n"); }
int fn1() { puts("fn1"); make_noise(); return 1; }
int fn2() { puts("fn2"); make_noise(); return 2; }
int main() { puts("main"); return fn1() + fn2() - 3; }

gcc -w t.c -o a.out && ./a.out

输出(预期):

main
fn1
Quack!
fn2
Quack!

现在让我们消除噪音:

gdb -q --write ./a.out
(gdb) disas/r make_noise
Dump of assembler code for function make_noise:
  0x000000000040052d <+0>:     55      push   %rbp
  0x000000000040052e <+1>:     48 89 e5        mov    %rsp,%rbp
  0x0000000000400531 <+4>:     bf 34 06 40 00  mov    $0x400634,%edi
  0x0000000000400536 <+9>:     e8 d5 fe ff ff  callq  0x400410 <puts@plt>
  0x000000000040053b <+14>:    5d      pop    %rbp
  0x000000000040053c <+15>:    c3      retq   
End of assembler dump. 

这告诉我们一些事情:

  1. 我们想要删除的函数从地址开始0x40052d
  2. 操作码为retq指令是0xC3.

我们来打补丁retq作为第一条指令make_noise,看看会发生什么:

(gdb) set *(char*)0x40052d = 0xc3
(gdb) disas make_noise
Dump of assembler code for function make_noise:
  0x000000000040052d <+0>:     retq   
  0x000000000040052e <+1>:     mov    %rsp,%rbp
  0x0000000000400531 <+4>:     mov    $0x400634,%edi
  0x0000000000400536 <+9>:     callq  0x400410 <puts@plt>
  0x000000000040053b <+14>:    pop    %rbp
  0x000000000040053c <+15>:    retq   
End of assembler dump.

有效!

(gdb) q
Segmentation fault (core dumped)   ## This is a long-standing GDB bug

现在让我们运行修补后的二进制文件:

$ ./a.out
main
fn1
fn2

瞧!无噪音。

如果该函数位于不同的二进制文件中,LD_PRELOADFlorian Weimer 提到的技术通常比二进制修补更容易。

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

是否可以用已编译的二进制文件中的虚拟函数替换特定函数的每个实例? 的相关文章

  • retq 和 ret 有什么区别?

    让我们考虑以下程序 它计算参数的无符号平方 global foo text foo mov rdi rax mul rdi ret 这是正确编译的as 但反汇编为 0000000000000000
  • 保护 .NET 代码免遭逆向工程?

    混淆是一种方法 但它不能防止破坏应用程序的盗版保护安全 如何确保应用程序不被篡改 如何确保注册机制无法被逆向工程 还可以将 C 应用程序转换为本机代码 并且Xenocode http en wikipedia org wiki Spoon
  • 在 x86-64 上,“movnti”指令是原子指令吗?

    在 x86 64 CPU Intel 或 AMD 上 将 4 8 字节写入 32 64 位对齐地址的 movnti 指令是原子的吗 Yes movnti在自然对齐的地址上是原子的 就像 x86 上所有其他自然对齐的 8 16 32 64b
  • 逆向工程的汇编语言[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 EXE 文件末尾写入字节安全吗?

    我听说如果我们在 EXE 文件末尾附加一些字节 它仍然可以正常工作 在所有情况下都是如此吗 这是一种安全的方法吗 我打算使用程序执行文件中的数据来编写演示 因此它可以是安全的 至少对普通用户而言 并且我不必将数据存储在其他地方 这是不可能用
  • x86-64 Linux 中不再允许使用 32 位绝对地址?

    64 位 Linux 默认使用小内存模型 将所有代码和静态数据置于 2GB 地址限制以下 这确保您可以使用 32 位绝对地址 旧版本的 gcc 对静态数组使用 32 位绝对地址 以便节省相对地址计算的额外指令 然而 这不再有效 如果我尝试在
  • 推送 64 位 intel osx

    我想将 64 位地址压入堆栈 如下所示 asm pushq 0x1122334455667788 但我得到编译错误 我只能按以下方式推送 asm pushq 0x11223344 有人可以帮助我理解我的错误吗 我是装配新手 所以如果我的问题
  • 无法拦截Android应用程序的流量

    最近 我正在尝试测试和拦截来自开发的应用程序的流量罗莫比尔 我设置了一个代理burp 当然 我已经在我的设备上安装了 burp 证书 因此我可以拦截设备上的其他应用程序 但我无法在 burp suite 上看到相关应用程序的流量 相反 该应
  • 无法在 Apple Calendar 中绑定()套接字(dylib 注入)

    我正在尝试检查 iOS 8 1苹果日历 MobileCal app on Reveal http www revealapp com下列的本指南 http petersteinberger com blog 2013 how to insp
  • x86-64 上这个语句有什么问题?

    该函数的目的是获取堆栈的起始地址 unsigned long find start void asm movq rsp eax 当我编译它时 出现错误 Error suffix or operands invalid for movq mo
  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • 更改 elf 调试信息中列出的源文件

    基本上我希望能够更改 elf 二进制文件中 debug dwarf 部分中源文件的路径 基本上我希望能够更改 elf 二进制文件中 debug dwarf 部分中源文件的路径 什么东西阻止你 该路径存储在 debug str二进制文件的一部
  • 如何手动加载并执行 ELF 二进制可执行文件?

    假设二进制文件是PIC 如何将其加载到内存并执行入口点 我这样做是为了熟悉 ELF 所以execve不允许 这些是基本步骤 阅读程序头以查找 LOAD 指令并确定您需要的映射的总长度 以页为单位 将最低地址的 LOAD 指令映射到总长度 可
  • 用于生成 C++ 代码轮廓/图的工具 - 有这样的东西吗? [复制]

    这个问题在这里已经有答案了 我需要深入研究用 C 编写的软件组件并对其进行一些修改 我幻想生成一些代码映射 它将显示类之间的关系并引导我完成方法的流程 调用图 有这个工具吗 几年前 我使用 Rational Rose 建模工具 该工具具有对
  • 查找手动注册(混淆)的本机函数地址

    我试图理解一个 Android 应用程序 其中包含一个名为foo在班上com app Bar 课堂内Bar有一个加载共享对象的静态子句System loadLibrary libfoo so 我认为是用它构建的 f可见性 隐藏 https
  • 加载器如何引用共享库中的变量?

    我现在了解如何通过过程链接表引用动态函数 如下所示 Dump of assembler code for function foo plt 0x0000000000400528
  • 对 C# 解决方案进行逆向工程

    我知道 Visual Studio 2010 Ultimate 有一些功能 我通常会凭本能这样做 但我的日程安排非常紧张 我还安装了 Visio 2010 并将其集成到 VS 中 但它的逆向工程功能似乎没有多大作用 并且必须在每个项目的基础
  • 在 xCode 6 中发现意外的 Mach-O 标头代码:1918975009

    导致错误的原因是什么 Found an unexpected Mach O header code 1918975009 in xCode 6 我将我的项目存档并作为ad hoc构建并且它构建 链接 存档很好但是当我在xCode组织者和选择
  • 这个反斜杠在这段汇编代码中起什么作用?

    我不确定这些推线有什么区别 修剪下来来自 Linux 的 x86 entry calling h https github com torvalds linux blob 241e39004581475b2802cd63c111fec43b
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c

随机推荐

  • TranslateAccelerator 和禁用的菜单项

    在我的应用程序中 我根据上下文启用 禁用菜单项 如果文本区域具有焦点 我会禁用与导航键冲突的加速器 例如 Ctrl 左 右 根据微软的文档 http msdn microsoft com en us library windows desk
  • 锚标记转到网页的错误部分

    这是问题所在的实际视频记录 我不想以任何方式做广告 https www youtube com watch v 7b38cQ0VGWI https www youtube com watch v 7b38cQ0VGWI 所以我创建一个网站只
  • 如何提高C++中merkle根计算的速度?

    我正在尝试尽可能优化默克尔根计算 到目前为止 我用 Python 实现了它 结果是这个问题 https stackoverflow com questions 67355203 how to improve the speed of mer
  • 如何防止按钮提交表单

    在下一页中 使用 Firefox 删除按钮会提交表单 但添加按钮不会提交表单 我该如何预防remove提交表单的按钮 function addItem var v form hidden last attr name var n input
  • 托管WPF插件跨进程问题

    我使用类似的方法http www codeproject com Articles 516431 Baktun Shell Hosting WPF Child Windows in Another http www codeproject
  • 检测到 HTML 文本框的拖放?

    我的网页上有一个正常的搜索框 它充满了文字 Search this website 当您单击框中输入搜索查询时 此文本将被删除 onfocus if this value Search this website this value 但是
  • 如何在Mac终端中使用SoX从文本文件中修剪特定时间的音频文件?

    我有一个文本文件 如下所示文本文件 https i stack imgur com iDm8k png 我想使用 sox 根据文本文件中的时间修剪音频文件 这样我就可以有从 0 0 到 6 16 6 16 到 13 44 13 44 到 1
  • 使用 selenium Java 或 cypress 中的 e2e 进行 Angular/SPA 应用程序的代码覆盖率

    我们想要测量 Angular 8 应用程序代码覆盖率 我们有一个用 selenium java 编写的 e2e 测试用例 它加载部署在浏览器中另一台机器上的 Angular 应用程序 并运行一些 e2e 测试用例集 问题是我如何测量 Ang
  • 字节序理论和概念

    这不是任何编程语言特有的问题 假设您在大端机器上编写了一些文件 并且您知道这一点 如果两个单字节值被连续写入 你怎么知道 Big endian 颠倒了 16 32 和 64 位值的顺序 那么您如何知道需要将其作为单个字节读取呢 例如 您写入
  • pygame中显示网格时角色移动缓慢

    我正在 pygame 中制作贪吃蛇游戏 我注意到了一件奇怪的事情 每当我显示网格时 我的角色都会缓慢运行 这是我的程序的主要功能 我刚刚开始学习pygame def main global SCREEN CLOCK pygame init
  • React 同一组件的多个实例获得相同的状态

    我有一个 React 组件 我正在创建它的 2 个副本 然而 当其中 1 个状态更新时 第 2 个状态也会更新 我不确定是什么原因造成的 这是我的代码 这是我使用两个组件的地方 this state selectedTab 0
  • 替换所有高于阈值的 RGB 值

    我有一个充满 RGB 值的 numpy 3d 数组 例如 形状 高度 宽度 3 matrix np array 0 0 5 0 6 0 9 1 2 0 如果任何值高于阈值 我必须替换 RGB 值 例如阈值 0 8 替换 2 2 2 然后 m
  • 使用 Database First 方法选择性禁用延迟加载

    我对禁用整个上下文的延迟加载不感兴趣 我只想选择性地禁用一些关键导航属性的延迟加载 随着代码优先方法 我了解如何有选择地禁用延迟加载 public virtual Person Requestor get set lazy loading
  • 隐藏 div 上的 Google Map API V3(jquery-ui 选项卡)

    我知道这个问题很古老 但我似乎找不到明确的说明 问题的要点是 当 Google 地图加载到隐藏 显示 无 div 上时 它不会完全加载 部分显示 例如jQuery 选项卡等 API V3 不再接受 checkResize left 1000
  • Elasticsearch 索引最大结果窗口配置异常

    当我将此配置添加到 etc elasticsearch elasticsearch yml在ubuntu虚拟机中 index max result window 1000000 执行此配置后 当我重新启动 Elasticsearch 时 会
  • 在 Common Lisp 中使用外部库或包的示例

    在 Common Lisp 中 quicklisp 是一种流行的库管理工具 我将使用该工具 并尝试使用 CL WHO 我使用 SBCL 1 0 57 实现 我将在下面回答我自己的问题 作为初学者 并不清楚 ASDF 和 Quicklisp
  • 调试和发布模式之间的异常堆栈跟踪差异

    下面的代码在调试和发布模式下生成不同的异常堆栈跟踪 static class ET public static void E1 throw new Exception E1 public static void E2 try E1 catc
  • Javadoc 和 RuntimeException

    我很好奇我是否应该添加throws ExceptionClass或不在方法签名之后 ExceptionClass 扩展 RuntimeException 例如 public void foo throws ExceptionClass th
  • 如何从 Perl 读取 Gmail 帐户中的邮件?

    我已经使用了该模块邮件 网页邮件 Gmail http search cpan org dist Mail Webmail Gmail阅读我的 Gmail 帐户中的新邮件 为此 我编写了以下代码 use strict use warning
  • 是否可以用已编译的二进制文件中的虚拟函数替换特定函数的每个实例?

    是否可以改变现有 x86 64 二进制文件引用和 或调用某个特定函数的方式 具体来说 是否有可能改变二进制文件而不发生任何事情 类似于nop 在该函数通常会执行的时间 我意识到有强大的专业工具 即反编译器 反汇编器 可以完成此类任务 但我真