将功能注入二进制文件的最佳方式



将功能插入二进制应用程序的最佳方式是什么(3d方,封闭源代码)。

目标应用程序位于OSX上,并且似乎是使用gcc3+编译的。我可以看到二进制文件中实现的函数列表,并调试和隔离了一个我想远程调用的特定函数。

具体来说,当我从复杂的HIDevice接收到某些数据时,我想调用这个函数——让我们称之为void zoomByFactor(x,y)

我可以很容易地修改或将指令注入二进制文件本身(即,补丁不需要只在RAM中发生)。

你会推荐什么方法来"很好地"做到这一点?

编辑:

我确实需要整个申请。所以我不能放弃它而使用图书馆。(对于那些需要道德解释的人来说:这是一款专有的CAD软件,其公司网站自2006年以来一直没有更新。我已经为这个产品支付了费用(真的是花了很多钱),并且有项目数据,我不能轻易地从中迁移出去。这个产品很适合我,但我想使用我最近得到的一个新HID。我已经检查了应用程序的内部结构,我非常有信心能够用相关数据调用正确的函数,并使其正常工作)。

以下是我迄今为止所做的工作,非常令人兴奋。

我已经通过这个过程修改了部分应用程序:

xxd-g 0二进制>二进制.hexcat binary.hex|awk"替代工作">已修改.hexxxd-r已修改.hex>新二进制chmod 777新手

我在做这种跳跃,因为二进制几乎有100兆欧大。

我想的是,我会在主应用程序循环中的某个地方进行jmp,启动一个线程,然后返回到主函数。

现在,问题是:我可以在哪里插入新代码?我需要修改符号表吗?或者,我怎么能自动加载dylib,这样我唯一需要做的"黑客攻击"就是将对正常加载的dylib的调用插入到主函数中?

对于那些对我最终所做的事情感兴趣的人,这里有一个总结:

我已经考虑了几种可能性。它们分为运行时修补和静态二进制文件修补。

就文件修补而言,我基本上尝试了两种方法:

  1. 修改代码中的程序集二进制文件的段(__TEXT)。

  2. 在中修改加载命令mach收割台。

第一个方法需要有可用空间,或者可以覆盖的方法。它的可维护性也非常差。任何新的二进制文件都需要再次手动修补,尤其是在源代码发生轻微更改的情况下。

第二种方法是尝试将LC_LOAD_DYLIB条目添加到mach头中。没有太多mach-o编辑器,所以很麻烦,但我实际上修改了结构,使otool -l可以看到我的条目。然而,这实际上并不起作用,因为在运行时有一个dyld: bad external relocation length。我想我需要处理导入表等。如果没有编辑器,这太难了。

第二条路径是在运行时注入代码。没有什么可做的。即使是你可以控制的应用程序(即你启动的子应用程序)。也许有一种方法可以到达fork()并启动初始化过程,但我从来没有这样做过。

有SIMBL,但这需要您的应用程序是Cocoa,因为SIMBL将充当系统范围的InputManager并选择性地加载捆绑包。我对此不屑一顾,因为我的应用程序不是Cocoa,此外,我不喜欢系统范围内的东西。

接下来是mach_inject和mach_star项目。还有一个名为PlugSuit托管在谷歌,它似乎只不过是mach_inject的一个薄薄的包装。

Mach_inject提供了一个API来执行名称所暗示的操作。不过,我确实在代码中发现了一个问题。在10.5.4中,mach_inject.c文件中的mmap方法要求有一个MAP_ SHARED或带有MAP_READ的'd,否则mmap将失败。

除此之外,整个事情实际上就像广告中说的那样。我最终使用mach_inject_bundle来完成我原本打算做的事情,在mach头中静态添加一个DYLIB:即在模块init上启动一个新线程,该线程做它的脏事务。

无论如何,我已经把它做成了一个维基。请随意添加、更正或更新信息。在OSX上几乎没有关于这类工作的信息。信息越多越好。

在10.5之前的MacOS X版本中,您可以使用Input Manager扩展来执行此操作。Input Manager旨在处理非罗马语言的输入等问题,扩展程序可以弹出一个窗口输入适当的字形,然后将完成的文本传递给应用程序。该应用程序只需要确保它是Unicode干净的,不必担心每种语言和地区的确切细节。

Input Manager被广泛滥用,将各种不相关的功能补丁到应用程序中,并经常破坏应用程序的稳定。它也正在成为特洛伊木马的攻击向量,如"Oompa-Loompa"。MacOS10.5收紧了对输入管理器的限制:它不会在root或wheel拥有的进程中运行输入管理器,也不会在修改了uid的进程中执行输入管理器。最重要的是,10.5不会将输入管理器加载到64位进程中,并表示即使是32位的使用也不受支持,将在未来的版本中删除。

所以,如果你能忍受这些限制,输入管理器可以做你想做的事。未来的MacOS版本几乎肯定会引入另一种(更安全、更有限)的方式来实现这一点,因为语言输入支持确实需要这种功能。

我相信您也可以使用DYLD_INSERT_LIBRARIES方法。

这篇帖子也与你试图做的事情有关;

我最近尝试使用mach_star源进行注入/覆盖。我最终为它写了一个教程,因为这些东西的文档总是很粗略,而且经常过时。

http://soundly.me/osx-injection-override-tutorial-hello-world/

有趣的问题。如果我理解正确,您希望添加在运行的可执行文件中远程调用函数的功能。

如果你并不真的需要整个应用程序,你可以去掉主函数,把它变成一个可以链接的库文件。这将取决于您来弄清楚如何确保所有必需的初始化都发生。

另一种方法可能是像病毒一样行动。注入一个处理远程调用的函数,可能在另一个线程中。您需要通过将一些代码注入主函数或其他合适的地方来启动此线程。您很可能会遇到初始化、线程安全和/或维护正确程序状态方面的主要问题。

如果可以的话,最好的选择是让应用程序的供应商公开一个插件API,让你以受支持的方式干净可靠地完成这项工作。

如果你使用任何一种破解二进制路径,都会很耗时,而且很脆弱,但在这个过程中你会学到很多。

在Windows上,这很简单,实际上做得很广泛,被称为DLL/代码注入。

有一个用于OSX的商业SDK可以做到这一点:Application Enhancer(非商业用途免费)。

最新更新