mirror of
https://github.com/snowie2000/mactype.git
synced 2025-01-05 10:17:02 +08:00
306 lines
9.1 KiB
C++
306 lines
9.1 KiB
C++
#pragma once
|
|
|
|
#include <mmsystem.h> //mmioFOURCC
|
|
#define FOURCC_GDIPP mmioFOURCC('G', 'D', 'I', 'P')
|
|
|
|
typedef struct {
|
|
int dummy;
|
|
FOURCC magic;
|
|
// BYTE reserved[256];
|
|
} GDIPP_CREATE_MAGIC;
|
|
|
|
//参照
|
|
//http://www.catch22.net/tuts/undoc01.asp
|
|
|
|
#ifdef _GDIPP_EXE
|
|
template <typename _STARTUPINFO>
|
|
void FillGdiPPStartupInfo(_STARTUPINFO& si, GDIPP_CREATE_MAGIC& gppcm)
|
|
{
|
|
ZeroMemory(&gppcm, sizeof(GDIPP_CREATE_MAGIC));
|
|
gppcm.magic = FOURCC_GDIPP;
|
|
si.cbReserved2 = sizeof(GDIPP_CREATE_MAGIC);
|
|
si.lpReserved2 = (LPBYTE)&gppcm;
|
|
}
|
|
#endif
|
|
|
|
#ifdef _GDIPP_DLL
|
|
template <typename _STARTUPINFO>
|
|
bool IsGdiPPStartupInfo(const _STARTUPINFO& si)
|
|
{
|
|
if(si.cbReserved2 >= sizeof(int) + sizeof(FOURCC)) {
|
|
GDIPP_CREATE_MAGIC* pMagic = (GDIPP_CREATE_MAGIC*)si.lpReserved2;
|
|
if (pMagic->dummy == 0 && pMagic->magic == FOURCC_GDIPP) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
EXTERN_C BOOL WINAPI GdippInjectDLL(const PROCESS_INFORMATION* ppi);
|
|
EXTERN_C LPWSTR WINAPI GdippEnvironment(DWORD& dwCreationFlags, LPVOID lpEnvironment);
|
|
|
|
|
|
|
|
//子プロセスにも自動でgdi++適用
|
|
template <typename _TCHAR, typename _STARTUPINFO, class _Function>
|
|
BOOL _CreateProcessAorW(const _TCHAR* lpApp, _TCHAR* lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, const _TCHAR* lpDir, _STARTUPINFO* psi, LPPROCESS_INFORMATION ppi, _Function fn)
|
|
{
|
|
#ifdef _GDIPP_RUN_CPP
|
|
const bool hookCP = true;
|
|
const bool runGdi = true;
|
|
#else
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
const bool hookCP = pSettings->HookChildProcesses();
|
|
const bool runGdi = pSettings->RunFromGdiExe();
|
|
#endif
|
|
|
|
if (!hookCP || (!lpApp && !lpCmd) || (dwFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | DETACHED_PROCESS))/* || !psi || psi->cb < sizeof(_STARTUPINFO)*/) {
|
|
return fn(lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi);
|
|
}
|
|
|
|
PROCESS_INFORMATION _pi = { 0 };
|
|
if (!ppi) {
|
|
ppi = &_pi;
|
|
}
|
|
|
|
int szpsi = psi ? (psi->cb ? psi->cb: sizeof(_STARTUPINFO)) : sizeof(_STARTUPINFO);
|
|
_STARTUPINFO& si = *(_STARTUPINFO*)_alloca(szpsi);
|
|
memset(&si, 0, sizeof(si));
|
|
si.cb=szpsi;
|
|
if (psi && psi->cb)
|
|
memcpy(&si, psi, psi->cb);
|
|
psi = &si;
|
|
|
|
GDIPP_CREATE_MAGIC gppcm;
|
|
if (runGdi && !si.cbReserved2) {
|
|
FillGdiPPStartupInfo(si, gppcm);
|
|
}
|
|
|
|
LPWSTR pEnvW = GdippEnvironment(dwFlags, lpEnv);
|
|
if (pEnvW) {
|
|
lpEnv = pEnvW;
|
|
}
|
|
|
|
if (!fn(lpApp, lpCmd, pa, ta, bInherit, dwFlags | CREATE_SUSPENDED, lpEnv, lpDir, &si, ppi)) {
|
|
ZeroMemory(ppi, sizeof(*ppi));
|
|
free(pEnvW);
|
|
return FALSE;
|
|
}
|
|
|
|
GdippInjectDLL(ppi);
|
|
if (!(dwFlags & CREATE_SUSPENDED)) {
|
|
ResumeThread(ppi->hThread);
|
|
}
|
|
free(pEnvW);
|
|
return TRUE;
|
|
}
|
|
|
|
template <typename _TCHAR, typename _STARTUPINFO, class _Function>
|
|
BOOL _CreateProcessAsUserAorW(HANDLE hToken, const _TCHAR* lpApp, _TCHAR* lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, const _TCHAR* lpDir, _STARTUPINFO* psi, LPPROCESS_INFORMATION ppi, _Function fn)
|
|
{
|
|
#ifdef _GDIPP_RUN_CPP
|
|
const bool hookCP = true;
|
|
const bool runGdi = true;
|
|
#else
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstance();
|
|
const bool hookCP = pSettings->HookChildProcesses();
|
|
const bool runGdi = pSettings->RunFromGdiExe();
|
|
#endif
|
|
|
|
if (!hookCP || (!lpApp && !lpCmd) || (dwFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))/* || !psi || psi->cb < sizeof(_STARTUPINFO)*/) {
|
|
return fn(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi);
|
|
}
|
|
|
|
PROCESS_INFORMATION _pi = { 0 };
|
|
if (!ppi) {
|
|
ppi = &_pi;
|
|
}
|
|
int szpsi = psi ? (psi->cb ? psi->cb: sizeof(_STARTUPINFO)) : sizeof(_STARTUPINFO);
|
|
_STARTUPINFO& si = *(_STARTUPINFO*)_alloca(szpsi);
|
|
memset(&si, 0, sizeof(si));
|
|
si.cb=szpsi;
|
|
if (psi && psi->cb)
|
|
memcpy(&si, psi, psi->cb);
|
|
psi = &si;
|
|
|
|
GDIPP_CREATE_MAGIC gppcm;
|
|
if (runGdi && !si.cbReserved2) {
|
|
FillGdiPPStartupInfo(si, gppcm);
|
|
}
|
|
|
|
LPWSTR pEnvW = GdippEnvironment(dwFlags, lpEnv);
|
|
if (pEnvW) {
|
|
lpEnv = pEnvW;
|
|
}
|
|
|
|
if (!fn(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags | CREATE_SUSPENDED, lpEnv, lpDir, &si, ppi)) {
|
|
ZeroMemory(ppi, sizeof(*ppi));
|
|
free(pEnvW);
|
|
return FALSE;
|
|
}
|
|
|
|
GdippInjectDLL(ppi);
|
|
if (!(dwFlags & CREATE_SUSPENDED)) {
|
|
ResumeThread(ppi->hThread);
|
|
}
|
|
free(pEnvW);
|
|
return TRUE;
|
|
}
|
|
|
|
static wstring GetExeName(LPCTSTR lpApp, LPTSTR lpCmd)
|
|
{
|
|
// HANDLE logfile = CreateFile(_T("C:\\mt.log"), FILE_ALL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, NULL, NULL);
|
|
// SetFilePointer(logfile,0,NULL, FILE_END);
|
|
|
|
wstring ret;
|
|
// DWORD aa=0;
|
|
// if (GetFileSize(logfile, NULL)==0)
|
|
// WriteFile(logfile, "\xff\xfe", 2, &aa, NULL);
|
|
LPTSTR vlpApp = (LPTSTR)lpApp; //变成可以操作的参数
|
|
if (lpApp)
|
|
{
|
|
do
|
|
{
|
|
// WriteFile(logfile, L"lpApp=", 12, &aa, NULL);
|
|
// WriteFile(logfile, lpApp, _tcslen(lpApp)*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
vlpApp = _tcsstr(vlpApp+1, _T(" ")); //获得第一个空格所在的位置
|
|
ret.assign(lpApp);
|
|
if (vlpApp)
|
|
ret.resize(vlpApp-lpApp);
|
|
// WriteFile(logfile, ret.c_str(), ret.length()*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
DWORD fa = GetFileAttributes(ret.c_str());
|
|
if (fa!=INVALID_FILE_ATTRIBUTES && fa!=FILE_ATTRIBUTE_DIRECTORY) //文件是否存在
|
|
{
|
|
int p = ret.find_last_of(_T("\\"));
|
|
if (p!=-1)
|
|
ret.erase(0, p+1); //如果有路径就删掉路径
|
|
// WriteFile(logfile, ret.c_str(), ret.length()*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
// WriteFile(logfile, _T("==========\n"), 24, &aa, NULL);
|
|
// CloseHandle(logfile);
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
ret+=_T(".exe"); //加上.exe扩展名再试
|
|
DWORD fa = GetFileAttributes(ret.c_str());
|
|
if (fa!=INVALID_FILE_ATTRIBUTES && fa!=FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
int p = ret.find_last_of(_T("\\"));
|
|
if (p!=-1)
|
|
ret.erase(0, p+1); //如果有路径就删掉路径
|
|
// WriteFile(logfile, ret.c_str(), ret.length()*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
// WriteFile(logfile, _T("==========\n"), 24, &aa, NULL);
|
|
// CloseHandle(logfile);
|
|
return ret;
|
|
}
|
|
}
|
|
} while (vlpApp);
|
|
}
|
|
|
|
if (lpCmd)
|
|
{
|
|
// WriteFile(logfile, L"lpCmd=", 10, &aa, NULL);
|
|
// WriteFile(logfile, lpCmd, _tcslen(lpCmd)*2, &aa, NULL);
|
|
ret.assign(lpCmd);
|
|
int p=0;
|
|
if ((*lpCmd)==_T('\"'))
|
|
{
|
|
ret.erase(0,1); //删除第一个引号
|
|
p=ret.find_first_of(_T("\"")); //查找下一个引号
|
|
}
|
|
else
|
|
p=ret.find_first_of(_T(" "));
|
|
if (p>0)
|
|
ret.resize(p); //获得Cmd里面的文件名
|
|
// WriteFile(logfile, ret.c_str(), ret.length()*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
p = ret.find_last_of(_T("\\"));
|
|
if (p>0)
|
|
ret.erase(0, p+1); //如果有路径就删掉路径
|
|
// WriteFile(logfile, ret.c_str(), ret.length()*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
// WriteFile(logfile, _T("==========\n"), 24, &aa, NULL);
|
|
// CloseHandle(logfile);
|
|
return ret;
|
|
}
|
|
// WriteFile(logfile, ret.c_str(), ret.length()*2, &aa, NULL);
|
|
// WriteFile(logfile, _T("\n"), 2, &aa, NULL);
|
|
// WriteFile(logfile, _T("==========\n"), 24, &aa, NULL);
|
|
// CloseHandle(logfile);
|
|
return ret;
|
|
}
|
|
|
|
template <class _Function>
|
|
BOOL _CreateProcessInternalW(HANDLE hToken, LPCTSTR lpApp, LPTSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, \
|
|
DWORD dwFlags, LPVOID lpEnv, LPCTSTR lpDir, LPSTARTUPINFO psi, LPPROCESS_INFORMATION ppi , PHANDLE hNewToken, _Function fn)
|
|
{
|
|
#ifdef _GDIPP_RUN_CPP
|
|
const bool hookCP = true;
|
|
const bool runGdi = true;
|
|
#else
|
|
const CGdippSettings* pSettings = CGdippSettings::GetInstanceNoInit();
|
|
const bool hookCP = pSettings->HookChildProcesses();
|
|
const bool runGdi = pSettings->RunFromGdiExe();
|
|
#endif
|
|
|
|
#ifdef _GDIPP_EXE
|
|
if (!hookCP || (!lpApp && !lpCmd) || (dwFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) || !psi || psi->cb < sizeof(STARTUPINFO)) {
|
|
return fn(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, hNewToken);
|
|
}
|
|
|
|
STARTUPINFO& si = *(STARTUPINFO*)_alloca(psi->cb);
|
|
memcpy(&si, psi, psi->cb);
|
|
psi = &si;
|
|
|
|
GDIPP_CREATE_MAGIC gppcm;
|
|
if (runGdi && !si.cbReserved2) {
|
|
FillGdiPPStartupInfo(si, gppcm);
|
|
}
|
|
|
|
PROCESS_INFORMATION _pi = { 0 };
|
|
if (!ppi) {
|
|
ppi = &_pi;
|
|
}
|
|
|
|
LPWSTR pEnvW = GdippEnvironment(dwFlags, lpEnv);
|
|
if (pEnvW) {
|
|
lpEnv = pEnvW;
|
|
}
|
|
if (!fn(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags | CREATE_SUSPENDED, lpEnv, lpDir, psi, ppi, hNewToken)) {
|
|
ZeroMemory(ppi, sizeof(*ppi));
|
|
free(pEnvW);
|
|
return FALSE;
|
|
}
|
|
GdippInjectDLL(ppi);
|
|
if (!(dwFlags & CREATE_SUSPENDED)) {
|
|
ResumeThread(ppi->hThread);
|
|
}
|
|
free(pEnvW);
|
|
#else
|
|
wstring exe_name = GetExeName(lpApp, lpCmd);
|
|
if (!hookCP || (!lpApp && !lpCmd) || (dwFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) || IsExeUnload(exe_name.c_str())) {
|
|
return fn(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, hNewToken);
|
|
}
|
|
LPWSTR pEnvW = GdippEnvironment(dwFlags, lpEnv);
|
|
if (pEnvW) {
|
|
lpEnv = pEnvW;
|
|
}
|
|
if (!fn(hToken, lpApp, lpCmd, pa, ta, bInherit, dwFlags | CREATE_SUSPENDED, lpEnv, lpDir, psi, ppi, hNewToken)) {
|
|
free(pEnvW);
|
|
return FALSE;
|
|
}
|
|
GdippInjectDLL(ppi);
|
|
if (!(dwFlags & CREATE_SUSPENDED)) {
|
|
ResumeThread(ppi->hThread);
|
|
}
|
|
free(pEnvW);
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|