C++ windows下如何不创建新进程去执行其他程序

来源:互联网  责任编辑:小易  时间:2017/1/9 12:18:19
用户提出问题:C++ windows下如何不创建新进程去执行其他程序,具体如下: 进程创建

通过互联网整理获得以下解决方法:

=================1楼=====================

Excute

=================2楼=====================

引用 1 楼 jianwen0529 的回复:
Excute

调用其他exe还是会创建出一个进程

=================3楼=====================

引用 2 楼 qq_37271686 的回复:
Quote: 引用 1 楼 jianwen0529 的回复:

Excute

调用其他exe还是会创建出一个进程


当然啊,你还想把别人的exe当做你内部的东西么
又不是com组件

=================4楼=====================

由于依赖的属性不同,java需要java虚拟机支持,所以在java程序执行的时候必须在java虚拟机的环境中,而c++不需要,所以必然会创建一个新的进程.

=================5楼=====================

这是加壳的东西了

=================6楼=====================

肯定会创建新进程,但新进程是A的子进程即可进行管理

=================7楼=====================

肯定需要创建新进程
创建新进程的时候
系统会对程序依赖的模块进行加载
由于C++是以静态的地址偏移调用函数的
如果模块没有被正确地加载,或者和当前进程的地址冲突
运行的时候基本上就会崩溃
然后系统也会初始化模块的静态变量
比如用std::cin的地址,所以依赖于这部分的代码也会出错
而且对于C++程序,不能正确的关闭进程线程将会导致对象不会被正确析构

=================8楼=====================

引用 3 楼 jianwen0529 的回复:
Quote: 引用 2 楼 qq_37271686 的回复:

Quote: 引用 1 楼 jianwen0529 的回复:

Excute

调用其他exe还是会创建出一个进程


当然啊,你还想把别人的exe当做你内部的东西么
又不是com组件

也许是我没说清楚,我的意思是用C++写的启动器A所启动的javaw.exe程序,在任务管理器中显示在同一个进程内,类似这样:


引用 3 楼 jianwen0529 的回复:
Quote: 引用 2 楼 qq_37271686 的回复:

Quote: 引用 1 楼 jianwen0529 的回复:

Excute

调用其他exe还是会创建出一个进程


当然啊,你还想把别人的exe当做你内部的东西么
又不是com组件
可能是我没说清楚,我的意思是用C++写的启动器A所启动的javaw.exe程序,在任务管理器中显示在同一个进程内,类似这样:

=================9楼=====================

引用 7 楼 ID870177103 的回复:
肯定需要创建新进程
创建新进程的时候
系统会对程序依赖的模块进行加载
由于C++是以静态的地址偏移调用函数的
如果模块没有被正确地加载,或者和当前进程的地址冲突
运行的时候基本上就会崩溃
然后系统也会初始化模块的静态变量
比如用std::cin的地址,所以依赖于这部分的代码也会出错
而且对于C++程序,不能正确的关闭进程线程将会导致对象不会被正确析构

可能是我没说清楚,我的意思是用C++写的启动器A所启动的javaw.exe程序,在任务管理器中显示在同一个进程内,类似这样:

图里的black程序其实就是一个exe启动器,而下面的“开篇3 冲突 - 写作视图”实际上是个javaw.exe(也就是exe启动器所启动的jvm虚拟机),这个启动器是别人做的,我用着有些问题,现在想自己做一个,实现同样的效果,即exe启动器和所启动的javaw.exe在windows任务管理器里显示在同一个条目里

=================10楼=====================

引用 4 楼 u010095741 的回复:
由于依赖的属性不同,java需要java虚拟机支持,所以在java程序执行的时候必须在java虚拟机的环境中,而c++不需要,所以必然会创建一个新的进程.

可能是我没讲清楚需求,请参见下面的图片

=================11楼=====================

引用 10 楼 qq_37271686 的回复:
Quote: 引用 4 楼 u010095741 的回复:

由于依赖的属性不同,java需要java虚拟机支持,所以在java程序执行的时候必须在java虚拟机的环境中,而c++不需要,所以必然会创建一个新的进程.

可能是我没讲清楚需求,请参见下面的图片

你可以使用C++创建子进程,来进行操作

=================12楼=====================

你问得很清楚,但答案是不可能,再见。

=================13楼=====================

你自己写一个 PeLdr, 在自己的进程空间加载 javaw , 然后跳转到新 pe 的起始地址, 如果那个 javaw 没有做些特别的保护, 就可以跑起来了,  PeLdr 的代码网上很多,  抄一个就是了...  

=================14楼=====================

楼主可能不太清楚windows“进程”的概念。呵呵。你这个需求必然会启动新的进程,但是,新的进程是可以通过A来调度和管理的。如果你非要不创建新的进程,不是没有办法,办法就是你在A里自己写一个jar解析器,就是自己写java虚拟机,绝对不会创建新进程。

=================15楼=====================

不过,如果java虚拟机是个DLL的话,你可以通过加载JAVA虚拟机DLL而不创建新的进程。

=================16楼=====================

jvm host 

=================17楼=====================

仅供参考:

/*
    Application:    Code Injection in Explorer
    Author:     @_RT
    Compiled on:    Feb 2014
    URL:http://www.codeproject.com/Tips/732044/Code-Injection-2

    We will see the different steps involved to perform a code injection into an already running process.

    Following are the quick steps through the process of injection.
    1.Get the API addresses that you will be calling from the injected code.
    2.Prepare shell code of your function that you want to get executed from the injected process.
    3.Get the process ID of the running process that you wish to inject into by enumerating through the
      list of processes or by finding the process's window (in case it's a GUI application) by class name or title.
    4.Open the process using its Pid with All Access rights.
    5.Allocate different memory spaces in the process that you are going to inject to with desired access
      rights for holding different segments of your shell code.
        Code part (executable instructions)
        Data part (strings, function parameters, etc.)
    6.Write the allocated memories with the respective values (code and data).
    7.Call CreateRemoteThread API and pass to it the start of allocated memory address where you have
      written your shell code from the process we are injecting.
*/

#include <windows.h>
#pragma comment(lib,"user32.lib")

LPVOID addr;
LPVOID addr2;

BOOL InjectExecutable(DWORD dwPid,LPVOID si,LPVOID pi,int sisize,int pisize)
{
    LPVOID hNewModule;
    HANDLE hProcess;
    CHAR S[]    = { "C:\\Windows\\system32\\notepad.exe" };
    BYTE byt[]  = {0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68};
                 //push  0   , push     0, push     0, push     1, push     0, push     0, push     0, push 0xXXXXXXXX
    BYTE byt2[] = {0xE8};//call 0xXXXXXXXX
    BYTE byt3[] = {0x68};//push 0xXXXXXXXX

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    if (hProcess == NULL)
    {
        return FALSE;
    }

    LPVOID staddr = VirtualAllocEx(hProcess, NULL, sizeof(S), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, staddr, S, sizeof(S), NULL);
    LPVOID fnaddr = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, fnaddr, pi, sisize, NULL);
    LPVOID fnaddr2 = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, fnaddr2, si, pisize, NULL);

    hNewModule = VirtualAllocEx(hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (hNewModule == NULL)
    {
        return FALSE;
    }
    LPTHREAD_START_ROUTINE strtaddr = (LPTHREAD_START_ROUTINE)hNewModule;

    WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
    WriteProcessMemory(hProcess, hNewModule, &fnaddr, sizeof(fnaddr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr));                    // push &pi ;lpProcessInformation
    WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
    WriteProcessMemory(hProcess, hNewModule, &fnaddr2, sizeof(fnaddr2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr2));                   // push &si ;lpStartupInfo
    WriteProcessMemory(hProcess, hNewModule, byt, sizeof(byt), NULL);           // push 0 , push 0, push 0, push 1, push 0, push 0, push 0, push 0xXXXXXXXX==&S[0];"C:\\Windows\\system32\\notepad.exe"
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt));                       // lpCurrentDirectory,lpEnvironment,dwCreationFlags,bInheritHandles,lpThreadAttributes,lpProcessAttributes,lpCommandLine,lpApplicationName
    WriteProcessMemory(hProcess, hNewModule, &staddr, sizeof(staddr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(staddr));
    WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));                      // call CreateProcessA
    addr = (LPVOID)((int)addr - ((int)hNewModule + 4));
    WriteProcessMemory(hProcess, hNewModule, &addr, sizeof(addr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(addr));
    WriteProcessMemory(hProcess, hNewModule, byt, 2, NULL);
    hNewModule = (LPVOID)((int)hNewModule + 2);                                 // push 0 ;DWORD dwExitCode   // exit code for this thread
    WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));                      // call ExitThread
    addr2 = (LPVOID)((int)addr2 - ((int)hNewModule + 4));
    WriteProcessMemory(hProcess, hNewModule, &addr2, sizeof(addr2), NULL);

    CreateRemoteThread(hProcess, 0, 0, strtaddr, NULL, 0, NULL);
    return TRUE;
}

int main()
{
    _STARTUPINFOA si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    DWORD dwPid;
    HMODULE ldlib = LoadLibraryA("Kernel32.dll");
    addr = GetProcAddress(ldlib, "CreateProcessA");
    addr2 = GetProcAddress(ldlib, "ExitThread");
    HWND hWnd1=FindWindow(NULL, "Program Manager");
    if (NULL==hWnd1) {
        return 1;
    }
    GetWindowThreadProcessId(hWnd1, &dwPid);

    InjectExecutable(dwPid,&si,&pi,sizeof(si),sizeof(pi));

    return 0;
}

=================18楼=====================

引用 15 楼 sdhexu 的回复:
不过,如果java虚拟机是个DLL的话,你可以通过加载JAVA虚拟机DLL而不创建新的进程。

你的话让我突然想起来java虚拟机的可执行程序javac或javaw都不过是个外壳程序,它们都是通过加载jvm.dll来启动虚拟机的,或许我也应该直接加载jvm.dll,非常感谢你的回答!也感谢其他朋友的热心帮助!祝好!

如果您还有更好的解决方法,请在最下面评论中留下您的解决方法


  • 本文相关:
  • 站长必读,如何真正写好一篇原创文章
  • 互联网之路细嗅蔷薇 资深站长分享掘金之道
  • 企业站的站长的工作重心究竟有哪些
  • 浅析:行业门户网站的一些盈利模式
  • 3000IP的企业网站每天订单不到30个的苦恼
  • 网站想内外兼修?先学习提高网站可用性的6大原则
  • 浅谈网页设计中的简约之美
  • 网页改版实战:日本设计师如何彻底优化旅游网站?
  • 网页改版实战!日本设计师如何彻底优化招聘网站?
  • 2015年值得关注的21个网页设计趋势
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2015 www.zgxue.com All Rights Reserved