1.前言
公司需要将两个程序合并成一个,一个我们自己的,一个客户的,运行的时候先运行我们的再运行客户的,否则无法进入游戏。现在有一个问题就是说部分客户需要在哪里打开在哪里运行,这样如果采用和原来一样的释放打开的方式,就可能会出现玩家放在桌面上的时候直接点击客户的,导致无法正常进入。故这里打算采用一种黑技术来实现,我运行的时候将客户的程序,直接运行在内存中,而不是将其释放出来。
2.解决
大致思路:我运行一个傀儡程序,然后将其挂起,用新程序填充原程序空间,然后运行即可。
2.1 运行傀儡程序
BOOL CreateChild(char *Cmd, CONTEXT &Ctx, HANDLE &ProcHnd, HANDLE &ThrdHnd,
unsigned long &ProcId, unsigned long &BaseAddr, unsigned long &ImageSize)
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
unsigned long old;
MEMORY_BASIC_INFORMATION MemInfo;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
BOOL res = CreateProcessA(NULL, Cmd, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
if(res){
ProcHnd = pi.hProcess;
ThrdHnd = pi.hThread;
ProcId = pi.dwProcessId;
Ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(ThrdHnd, &Ctx);
ReadProcessMemory(ProcHnd, (void *)(Ctx.Ebx+8), &BaseAddr, sizeof(unsigned long), &old);
void *p = (void *)BaseAddr;
while(VirtualQueryEx(ProcHnd, p, &MemInfo, sizeof(MemInfo)))
{
if(MemInfo.State = MEM_FREE) break;
p = (void *)((unsigned long)p + MemInfo.RegionSize);
}
ImageSize = (unsigned long)p - (unsigned long)BaseAddr;
}
return res;
}
2.2 获取新程序的信息