从C / C库中的拆包可执行++
-
20-08-2019 - |
题
我开发使用一种或多种辅助可执行做业务的过程库。我目前的实现要求用户在已知位置安装在系统上的帮手可执行文件。对于库函数得当助手应用程序必须是在正确的位置,成为正确的版本。
我想删除的系统在上述的方式来配置的要求。
有没有办法捆绑在图书馆助手可执行文件,例如,它可以在运行时进行解压缩,安装在一个临时目录,用于一个运行的时间?在运行结束时,临时可执行可以被移除。
我已经考虑自动生成含有包含可执行的文本为unsigned char阵列的文件。这将在编译时完成作为构建过程的一部分。在运行时该字符串就被写入从而一个文件创建可执行文件。
这将有可能做这样的任务,而无需编写可执行程序到磁盘(可能是某种RAM盘的)?我可以想象某些杀毒软件和其他安全软件反对这样的操作。是否有其他问题我应该担心?
该库在C / C ++对在Windows和Linux的跨平台使用正在开发中。
解决方案
可以使用 xxd
以二进制文件转换为C头文件。
$ echo -en "\001\002\005" > x.binary
$ xxd -i x.binary
unsigned char x_binary[] = {
0x01, 0x02, 0x05
};
unsigned int x_binary_len = 3;
xxd
是在* nix系统非常标准的,并且它适用于Windows使用Cygwin或MinGW的,或Vim中其包括在标准安装为好。这是一个极其跨平台的方式来包括二进制数据转换成编译代码。
另一种方法是使用 objcopy
追加到可执行文件的末尾数据 - IIRC你的可以的获得objcopy
,并用它在Windows PE的。
一个方法,我喜欢比好一点的只是原始数据直接添加到您的可执行文件的末尾。在可执行文件,你寻找到文件的末尾,并在读取数量,说明所附的二进制数据的大小。然后你寻求向后很多字节,并fread
数据和复制出来的文件系统,在那里你可以把它作为一个可执行文件。这是偶然了许多,如果不是办法所有,自解压缩可执行文件创建。
如果您追加二进制数据,它的工作原理与Windows PE文件和* nix ELF文件 - 他们都不看过去的可执行文件的“限制”
当然,如果需要追加多个文件,你可以一个tar / zip文件附加到你的exe文件,或者你需要一个稍微提前的数据结构,读什么的被追加。
您也可能会想 UPX 您的可执行您附加在他们面前。
您可能也有兴趣在 LZO库,这是一个报道最快的解压缩库。他们有,你可以使用一个非常轻量级的解压缩器MiniLZO库。然而,LZO库GPL许可,使的可能的意思是,除非你的代码GPL协议,以及你不能将其包含在你的源代码。在另一方面,也有商业许可证可用。
其他提示
“A聪明人解决了一个问题。甲 明智的人避免它。” - 爱因斯坦
在这句话的精神,我建议你干脆捆绑这个可执行随着终端应用。
只是我的2美分。
稍微不同的方法比使用无符号字符*阵列是把整个可执行二进制作为DLL的资源。在运行时,可以将二进制数据保存在本地临时文件并执行应用程序。我不知道是否有执行内存中的可执行文件的方式,虽然。
有关库正常工作 该助手应用程序必须是正确的 位置
在Windows中,会是这样的Program Files目录或System32目录?
这可能是一个问题。当安装一个应用程序,特别是在企业环境中,它通常发生在具有管理权限的范围内。在Vista和更高版本启用UAC(默认值),这是必要的写某些目录。而大多数Unix系统有这样懂事的限制,只要每个人都记住。
所以,如果你试图在主机应用程序调用库中的时间去做,那可能不是具有足够权限的情况下安装文件,所以您的图书馆会把制约主机应用程序。
(将要排除的另一件事是注册表更改,或在各种Unix系统的配置文件更新,如果主机应用程序不必过程提升到一个行政级别的能力。)
说了这么多,你说你正在考虑拆包助手到一个临时目录,所以也许这一切都是没有实际意义。
Qt拥有实现这一目标的一个极好的方法,包括: QResource
“Qt的资源系统是用于存储在应用程序的可执行二进制文件独立于平台的机构。”
如果您正在使用Qt你不说,但你说:“C ++在Windows和Linux的跨平台使用”,所以即使你不使用它,你可能要考虑开始。
有是Windows的方式,而不将其写入磁盘运行从存储器内的可执行文件。问题是,由于现代安全系统(DEP),这可能不会在所有的系统工作,几乎所有的反恶意软件扫描仪将检测到它,并警告用户。
我的建议是简单地将可执行文件打包到您的发行,它肯定是实现这一目标的最可靠的方式。
好了,我首先想到的是:请问这个帮手可执行做到这一点无法将你的库代码本身内进行,如果需要,还可以使用辅助线程。这可能是值得考虑的。
但对于实际问题...如果你的“库”实际上是捆绑起来作为一个dll(甚至一个exe),那么至少是Windows对您的库中嵌入文件相对simpe支持。
在资源机制,允许之类的东西的版本信息和图标将要被嵌入的可执行文件内也可以允许数据的任意块。因为我不知道你正在使用的开发环境,我不能说究竟是如何做到这一点。但大致说来,你需要创建一个自定义资源与类型“文件”或懂事的东西是一样的,在要嵌入exe文件指向它。
然后,当你要提取它,你会喜欢写东西。
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_MY_EMBEDDED_FILE), "FILE");
HGLOBAL hResourceData = LoadResource(NULL, hResource);
LPVOID pData = LockResource(hResourceData);
HANDLE hFile = CreateFile("DestinationPath\\Helper.exe", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwBytesWritten = 0;
WriteFile(hFile, pData, SizeofResource(NULL, hResource), &dwBytesWritten, NULL);
CloseHandle(hFile);
(在自己期望的路径,文件名填充,当然任何合适的错误检查)
在此之后,辅助EXE存在作为一个正常的exe文件等都可以然而执行它通常那样。
有关使用后删除文件,你应该调查CreateFile
标志,特别FILE_FLAG_DELETE_ON_CLOSE
。你也可以看看结合MoveFileEx
标志时与空被传为新的文件名使用MOVEFILE_DELAY_UNTIL_REBOOT
。当然,你总是可以删除它在自己的代码,如果你能告诉当可执行已经结束。
我不知道有足够的了解Linux的可执行文件,所以我不知道是否有类似的功能,请在那里。
如果Linux没有提供任何方便的机制和/或如果这种想法不适合在Windows您的需求,那么我想你产生从助手EXE文件的内容unsigned char型数组的想法是下一个最好的方式嵌入exe文件在您的图书馆。