将功能注入二进制文件的最佳方法 [英] Best way to inject functionality into a binary

查看:157
本文介绍了将功能注入二进制文件的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What would be the best way of inserting functionality into a binary application (3d party, closed source).

目标应用程序在OSX上,似乎已使用gcc 3+进行了编译.我可以看到以二进制形式实现的功能列表,并且调试并隔离了一个我想远程调用的特定功能.

The target application is on OSX and seems to have been compiled using gcc 3+. I can see the listing of functions implemented in the binary and have debugged and isolated one particular function which I would like to remotely call.

具体来说,我想调用此函数-当我从复杂的HIDevice接收某些数据时,将其称为void zoomByFactor(x,y).

Specifically, I would like to call this function - let's call it void zoomByFactor(x,y) - when I receive certain data from a complex HIDevice.

我可以轻松地将指令修改或注入二进制文件本身(即,修补不需要仅在RAM中进行).

I can easily modify or inject instructions into the binary file itself (ie. the patching does not need to occur only in RAM).

您会建议如何"做到这一点?

What would you recommend as a way of "nicely" doing this?

我确实确实需要整个应用程序.所以我不能抛弃它并使用一个库. (对于需要道德解释的人:这是CAD软件的专有组件,其公司网站自2006年以来未进行过更新.我已经为该产品付款(确实很多钱),并且拥有项目我无法轻易地从中迁移出的数据.该产品非常适合我,但是我想使用我最近获得的新HID.我已经检查了应用程序的内部结构,并且我相当有信心我可以使用相关数据调用正确的函数并使它正常工作.

I do indeed need to entire application. So I can't ditch it and use a library. (For those who need an ethical explanation: this is a proprietary piece of CAD software whose company website hasn't been updated since 2006. I have paid for this product (quite a lot of money for what it is, really) and have project data which I can not easily migrate away from it. The product suits me just fine as it is, but I want to use a new HID which I recently got. I've examined the internals of the application, and I'm fairly confident that I can call the correct function with the relevant data and get it to work properly).

这是我到目前为止所做的,而且非常贫民窟.

Here's what I've done so far, and it is quite gheto.

我已经通过此过程修改了应用程序的某些部分:

I've already modified parts of the application through this process:


xxd -g 0 binary > binary.hex
cat binary.hex | awk 'substitute work' > modified.hex
xxd -r modified.hex > newbinary
chmod 777 newbinary

我正在做这种跳跃,因为二进制文件的大小几乎是100兆.

I'm doing this kind of jumping through hoops because the binary is almost 100 megs large.

我在想的主要目的是我将在主应用程序循环中的某个位置进行jmp,启动一个线程,然后返回到main函数.

The jist of what I'm thinking is that I'd jmp somewhere in the main application loop, launch a thread, and return to the main function.

现在,问题是:我可以在哪里插入新代码?我需要修改符号表吗?或者,如何使dylib自动加载,以使我唯一需要做的黑客行为"是将对通常加载的dylib的调用插入到主函数中?

Now, the questions are: where can I insert the new code? do I need to modify symbol tables? alternatively, how could I make a dylib load automatically so that the only "hacking" I need to do is inserting a call to a normally loaded dylib into the main function?

推荐答案

对于那些对我最终所做的事情感兴趣的人,以下为摘要:

For those interested in what I've ended up doing, here's a summary:

我研究了几种可能性.它们分为运行时修补和静态二进制文件修补.

I've looked at several possibilities. They fall into runtime patching, and static binary file patching.

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

As far as file patching is concerned, I essentially tried two approaches:

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

  1. modifying the assembly in the code segments (__TEXT) of the binary.

在 马赫标题.

第一种方法需要有可用空间,或者可以覆盖的方法.它还具有极差的可维护性.任何新的二进制文件都需要再次手动打补丁,尤其是在其源代码甚至略有更改的情况下.

The first method requires there to be free space, or methods you can overwrite. It also suffers from extremely poor maintainability. Any new binaries will require hand patching them once again, especially if their source code has even slightly changed.

第二种方法是尝试将LC_ LOAD_ DYLIB条目添加到mach标头中.那里没有太多的mach-o编辑器,所以很毛茸茸,但是我实际上修改了结构,以使otool -l可以看到我的输入.但是,这实际上不起作用,因为在运行时有一个dyld: bad external relocation length.我以为我需要弄乱导入表等.这是在没有编辑器的情况下花费太多精力的事情.

The second method was to try and add a LC_ LOAD_ DYLIB entry into the mach header. There aren't many mach-o editors out there, so it's hairy, but I actually modified the structures so that my entry was visible by otool -l. However, this didn't actually work as there was a dyld: bad external relocation length at runtime. I'm assuming I need to muck around with import tables etc. And this is way too much effort to get right without an editor.

第二条路径是在运行时注入代码.没有太多的事情要做.即使对于您可以控制的应用程序(即您启动的子应用程序).也许有一种方法可以启动fork()并启动初始化过程,但是我从来没有这样做.

Second path was to inject code at runtime. There isn't much out there to do this. Even for apps you have control over (ie. a child application you launch). Maybe there's a way to fork() and get the initialization process launched, but I never go that.

有SIMBL,但是这要求您的应用程序为Cocoa,因为SIMBL将构成系统范围的InputManager并有选择地加载捆绑软件.我拒绝此操作是因为我的应用程序不是Cocoa,而且我不喜欢系统范围的内容.

There is SIMBL, but this requires your app to be Cocoa because SIMBL will pose as a system wide InputManager and selectively load bundles. I dismissed this because my app was not Cocoa, and besides, I dislike system wide stuff.

接下来是mach_ inject和mach_star项目.还有一个较新的项目叫做 托管在Google上的PlugSuit似乎只不过是mach_inject周围的薄包装.

Next up was mach_ inject and the mach_star project. There is also a newer project called PlugSuit hosted at google which seems to be nothing more than a thin wrapper around mach_inject.

Mach_inject提供一个API来执行其名称所暗示的功能.我确实在代码中发现了问题.在10.5.4上,mach_inject.c文件中的mmap方法要求必须有MAP_SHARED或与MAP_READ配合使用,否则mmap将会失败.

Mach_inject provides an API to do what the name implies. I did find a problem in the code though. On 10.5.4, the mmap method in the mach_inject.c file requires there to be a MAP_ SHARED or'd with the MAP_READ or else the mmap will fail.

除此之外,整个过程实际上如广告中所述.我最终使用了mach_ inject_ bundle来完成向mach标头中静态添加DYLIB的意图:即在模块初始化中启动一个新线程,以完成其肮脏的业务.

Aside from that, the whole thing actually works as advertised. I ended up using mach_ inject_ bundle to do what I had intended to do with the static addition of a DYLIB to the mach header: namely launching a new thread on module init that does its dirty business.

无论如何,我已将其设为Wiki.随时添加,更正或更新信息.在OSX上几乎没有有关此类工作的信息.信息越多越好.

Anyways, I've made this a wiki. Feel free to add, correct or update information. There's practically no information available on this kind of work on OSX. The more info, the better.

这篇关于将功能注入二进制文件的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆