如何运行资源内的exe 以线程运行exe
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何运行资源内的exe 以线程运行exe相关的知识,希望对你有一定的参考价值。
问题1、程序内以资源形式包含一个exe,如何在不释放这个exe的情况下运行资源内的exe (以资源路径运行)
问题2、运行一个外部程序,被调用的程序是以主程序的一个线程被运行
问题补充:Window API
这还用你回答,起码给个思路或例子啊
但如果你非要不释放就运行的话,我也可以给你个思路
不过,你的以资源路径运行的要求很难实现,我最后再讲。
首先,你必须非常了解PE文件格式和WINDOWS可执行文件的加载过程
具体实现:
先假设包含另外EXE文件的程序为A,被包含的程序为B
1.编译的时候,将A的基地址设置的大于B的内存地址的上限。
2.申请开始地址为B程序基地址(一般为400000)的内存空间,并将其属
性改为可读可写可执行。
3.COPY B的全部代码过去
4.跟据B的导入表,加载各个DLL,并填写IAT的地址。
5.在A程序中创建一新的线程,基地址为B的入口。
这样如果没有意外的话,B就以A的一个的线程的形式运行了
但B结束时可能会把A也一块结束掉(可以通过一些操作解决)
关于以资源路径运行:
我想你的意思应该是有个API可以直接,或者很简单的运行资源或者任
意内存中的EXE格式的程序
但据我所知,并没有这样的API
而且不用API也未必就能实现
要想让EXE格式(正式叫法应该是PE)程序在任意内存地址运行,程序
必须是可重定位的(自已重定位,或者依靠重定位表)
但多数EXE格式的WINDOWS程序并没有重定位表,也不会自己重定位。
所以说很难实现
如果你要运行的EXE文件能够重定位,则可以先将对应内存地址改为可
读可写可执行,然后重定位(需要的话),然后填入导入表,最后创建
新线程运行。
以上只是我的思路,没有实践过,这几天忙考试也没时间搞这个。
另外第二步可能会申请失败,如果不行的话可的程序的第一个SECTION
先预留足够多的空间。 参考技术A 这就要用到病毒技术了,
就是嵌入EXE进程
每个EXE都有一个程序入口地址,通过修改这个入口地址,调用另外编写的验证程序,成功则返回地址继续运行,否则强行终止进程!
(个人思路,没有实际进行过) 参考技术B 这就要用到病毒技术了,
就是嵌入EXE进程
每个EXE都有一个程序入口地址,通过修改这个入口地址,调用另外编写的验证程序,成功则返回地址继续运行,否则强行终止进程!
(个人思路,没有实际进行过) 参考技术C 将该exe后缀的扩展名改掉或者试试批处理等,你的问题我不是很理解,只好这么回答了
参考资料:CWINNT5
参考技术D www.diannao.com使用 windows api 和 C++,我如何从硬盘驱动器加载 exe 并在自己的线程中运行它?
【中文标题】使用 windows api 和 C++,我如何从硬盘驱动器加载 exe 并在自己的线程中运行它?【英文标题】:Using the windows api and C++, how could I load an exe from the hard drive and run it in its own thread? 【发布时间】:2011-01-10 07:18:26 【问题描述】:为了学习,我正在尝试执行操作系统在启动程序时所做的事情,即。解析PE文件并给它一个执行线程。
如果我有两个 exe,一个叫做 foo.exe,另一个叫做 bar.exe,我怎么能让 foo.exe 将 bar.exe 的内容加载到内存中,然后让它在自己的线程中执行?我知道如何使用 MapViewOfFile 或简单地将硬盘驱动器上的内容加载到缓冲区中来将其放入内存。我假设只是将磁盘上 bar.exe 的内容复制到它自己的挂起线程中并运行它是行不通的。我对PE文件内部结构半熟悉。非常感谢所有帮助,当然:)
【问题讨论】:
虽然我可能是错的,但我不认为你可以手动加载可执行文件并期望它在调用时能够工作......通常有很多关于成为主要运行者的假设的当前进程,我认为如果您尝试将其托管在另一个进程中,事情将无法正常工作。 @Lambert:如果不是线程,那么进程会工作吗?使用 CreateProcess。 @returneax:嗯……为什么不呢?这不是正确的做法吗? @Lambert : “手工”....哈哈! @Lambert:好吧,如果它可以在进程中工作,为什么它不能在线程中工作?从根本上说,进程不是执行的主线程。如果您可以提供一个执行线程并保证与任何其他线程不冲突,那么线程和进程之间有什么不同? 【参考方案1】:首先,兰伯特是正确的。 EXE 在自己的进程中运行。 EXE 无法加载到另一个进程的原因是因为它们不是为相对寻址而编译的,并且不能轻易地将其代码重新映射到另一个地址。开发人员使用 Win32 系统调用“CreateProcess”启动其他 EXE 程序。但我不认为这是你的问题......
我想您想知道如何手动将代码从二进制文件加载到正在运行的进程中(并让它在专用线程上运行)。大多数开发人员只是调用 LoadLibrary/GetProcessAddress 将 DLL 映射到进程空间并调用 CreateThread 来启动线程。
所以我认为您基本上要问的是,“我如何实现内核和操作系统的核心组件,即加载程序?”或者换一种说法,“我如何自己实现 CreateProcess 和 LoadLibrary?”
操作系统加载器不仅仅将二进制文件解析到内存中,并将指令指针设置为第一行代码。它还加载其他相关的 DLL。因为进程可能已经分配了其他代码以在 DLL 编译到的目标地址处运行,所以它可能还必须修复 DLL 的地址以将其加载到另一个地址。我可能会遗漏许多其他步骤,包括为二进制代码本身分配虚拟内存。
我确实建议查看Richter book 中有关进程、线程和 DLL 的部分。他讨论了这一点以及解析 DLL 的 PE 格式的一些细节。
研究如何将 .SO 文件加载到进程空间的 Linux 内核实现也可能是值得研究的。
【讨论】:
如果我没记错的话,这主要是加载时 DLL 的问题,对吧?如果所有 DLL 都在运行时加载到程序中,则可以避免很多这些问题。还是我误会了? Edit:我基于我最近了解到的情况:程序绝对会使用的 DLL 以硬编码方式存储在导入地址表中。 @returneax:即使是那些也需要检查;你不能假设他们声明的基地址是可用的。您在内存 COW 中加载 DLL,这就是为什么最好将它们加载到它们的首选基地址:无需修补即可保存 COW 副本。【参考方案2】:可执行文件始终作为单独的进程运行。它不能在其他一些进程的线程中运行。但是,您可以将可执行文件作为进程从其他进程的线程中运行。看看CreateProcess()函数!
【讨论】:
技术上可能不是,但这里有一个非常简单的例子。想象一个“Hello, world”程序。现在,如果我们提取所述程序中所有功能的操作码……主要是打印“Hello, world”。如果我们将提取的操作码放入它们自己的挂起线程并恢复该线程,我们将拥有与“Hello, world”相同的功能。在磁盘上,对吧? @returneax:对。但是怎么做呢?我不认为 Windows API 可以帮助您提取操作码。您需要编写自己的 API 来解析可执行文件并提取操作码。但这本身就是一个巨大的项目! @returneax:您确实知道您需要手动重新构建 EXE 的基础,对吗? (不是说不可能,但也许不实用。) @Lambert:是的,但这可能不是最难的部分。 最困难的部分是尝试在 ReactOS 上获得准确的代码以使其工作(我之前尝试过但失败了)......其他一切(调整它等.) 可以稍后来...【参考方案3】:由于我个人不喜欢“你为什么要这样做?”的答案,here is a link 这将非常有帮助。但请注意,您可能不会成功,因为 EXE 根本不希望在另一个进程的线程中运行。
【讨论】:
谢谢,这是一个很棒的链接。我认为这很可能是因为 PE 文件中的元数据不是太大。似乎大多数问题都在于加载正确的 DLL,这可以通过使用 LoadLibrary 等来避免。以上是关于如何运行资源内的exe 以线程运行exe的主要内容,如果未能解决你的问题,请参考以下文章