mactype/run.cpp
MacType 07a1eee62c Initial release. Some files may missing, please report.
Dependency not included.

Deps: EasyHook, FreeType
2016-05-30 17:12:15 +08:00

281 lines
6.5 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// dll injection
#define _CRT_SECURE_NO_DEPRECATE 1
#define WINVER 0x500
#define _WIN32_WINNT 0x500
#define _WIN32_IE 0x601
#define WIN32_LEAN_AND_MEAN 1
#define UNICODE 1
#define _UNICODE 1
#include <Windows.h>
#include <ShellApi.h>
#include <ComDef.h>
#include <ShlObj.h>
#include <ShLwApi.h>
#include <tchar.h>
#include "array.h"
#include <strsafe.h>
#include "gdiexe.rc"
// _vsnwprintf—p
#include <wchar.h>
#include <stdarg.h>
#define _CRTDBG_MAP_ALLOC
#include <cstdlib>
#include <malloc.h>
#include <crtdbg.h>
#define for if(0);else for
#ifndef _countof
#define _countof(array) (sizeof(array) / sizeof((array)[0]))
#endif
#pragma comment(linker, "/subsystem:windows,5.0")
#pragma comment(lib, "Kernel32.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "ShLwApi.lib")
#pragma comment(lib, "Ole32.lib")
static void errmsg(UINT id, DWORD code)
{
char buffer [512];
char format [128];
LoadStringA(GetModuleHandleA(NULL), id, format, 128);
wnsprintfA(buffer, 512, format, code);
MessageBoxA(NULL, buffer, "MacType ERROR", MB_OK|MB_ICONSTOP);
}
inline HRESULT HresultFromLastError()
{
DWORD dwErr = GetLastError();
return HRESULT_FROM_WIN32(dwErr);
}
//#include <detours.h>
HINSTANCE hinstDLL;
#include <stddef.h>
#define GetDLLInstance() (hinstDLL)
#define _GDIPP_EXE
#define _GDIPP_RUN_CPP
#include "supinfo.h"
static BOOL (WINAPI * ORIG_CreateProcessW)(LPCWSTR lpApp, LPWSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, LPCWSTR lpDir, LPSTARTUPINFOW psi, LPPROCESS_INFORMATION ppi)
= CreateProcessW;
static BOOL WINAPI IMPL_CreateProcessW(LPCWSTR lpApp, LPWSTR lpCmd, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta, BOOL bInherit, DWORD dwFlags, LPVOID lpEnv, LPCWSTR lpDir, LPSTARTUPINFOW psi, LPPROCESS_INFORMATION ppi)
{
return _CreateProcessAorW(lpApp, lpCmd, pa, ta, bInherit, dwFlags, lpEnv, lpDir, psi, ppi, ORIG_CreateProcessW);
}
//#define OLD_PSDK
#ifdef OLD_PSDK
extern "C" {
HRESULT WINAPI _SHILCreateFromPath(LPCWSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgflnOut)
{
if (!pszPath || !ppidl) {
return E_INVALIDARG;
}
LPSHELLFOLDER psf;
HRESULT hr = ::SHGetDesktopFolder(&psf);
if (hr != NOERROR) {
return hr;
}
ULONG chEaten;
LPOLESTR lpszDisplayName = ::StrDupW(pszPath);
hr = psf->ParseDisplayName(NULL, NULL, lpszDisplayName, &chEaten, ppidl, rgflnOut);
::LocalFree(lpszDisplayName);
psf->Release();
return hr;
}
void WINAPI _SHFree(void *pv)
{
if (!pv) {
return;
}
LPMALLOC pMalloc = NULL;
if (::SHGetMalloc(&pMalloc) == NOERROR) {
pMalloc->Free(pv);
pMalloc->Release();
}
}
}
#else
#define _SHILCreateFromPath SHILCreateFromPath
#define _SHFree SHFree
#endif
// PÂÚ̈ø<CB86>¾¯ƒtƒ@ƒCƒÆµÄˆµ¢<E2809A>AŽÀ<C5BD>s·é<E2809A>B
//
// ƒRƒ}ƒ“ƒhÍ ±ñÈŠ´Å˜³êÜ·<E2809A>B
// exe linkpath linkarg cmdarg2 cmdarg3 cmdarg4 ...
//
static HRESULT HookAndExecute(int show)
{
int argc = 0;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if(!argv) {
return HresultFromLastError();
}
if(argc <= 1) {
char buffer [256];
LoadStringA(GetModuleHandleA(NULL), IDS_USAGE, buffer, 256);
MessageBoxA(NULL,
buffer
,"MacType", MB_OK|MB_ICONINFORMATION);
LocalFree(argv);
return S_OK;
}
int i;
size_t length = 1;
for(i=2; i<argc; i++) {
length += wcslen(argv[i]) + 3;
}
LPWSTR cmdline = (WCHAR*)calloc(sizeof(WCHAR), length);
if(!cmdline) {
LocalFree(argv);
return E_OUTOFMEMORY;
}
LPWSTR p = cmdline;
*p = L'\0';
for(i=2; i<argc; i++) {
const bool dq = !!wcschr(argv[i], L' ');
if (dq) {
*p++ = '"';
length--;
}
StringCchCopyExW(p, length, argv[i], &p, &length, STRSAFE_NO_TRUNCATION);
if (dq) {
*p++ = '"';
length--;
}
*p++ = L' ';
length--;
}
*CharPrevW(cmdline, p) = L'\0';
WCHAR file[MAX_PATH], dir[MAX_PATH];
GetCurrentDirectoryW(_countof(dir), dir);
StringCchCopyW(file, _countof(file), argv[1]);
if(PathIsRelativeW(file)) {
PathCombineW(file, dir, file);
} else {
WCHAR gdippDir[MAX_PATH];
GetModuleFileNameW(NULL, gdippDir, _countof(gdippDir));
PathRemoveFileSpec(gdippDir);
// ƒJƒŒƒ“ƒgƒfƒBƒŒƒNƒgƒŠªgdi++.exeÌu©êÄ¢éƒfƒBƒŒƒNƒgƒŠÆ“¯¾Á½ç<E2809A>A
// N“®µæ¤ÆµÄ¢éEXẼtƒƒpƒX©ç”²«<E2809A>oµ½ƒfƒBƒŒƒNƒgƒŠ¼ðƒJƒŒƒ“ƒg
// ƒfƒBƒŒƒNƒgƒŠÆµÄN“®·é<E2809A>B(ƒJƒŒƒ“ƒgƒfƒBƒŒƒNƒgƒŠªEXEÆ“¯<E2809A>ê<EFBFBD>ŠÅ é
// OñÅ<E2809A>ìçêÄ¢éƒAƒvƒŠÎ<E28098>ô)
if (wcscmp(dir, gdippDir) == 0) {
StringCchCopyW(dir, _countof(dir), argv[1]);
PathRemoveFileSpec(dir);
}
}
LocalFree(argv);
argv = NULL;
#ifdef _DEBUG
if((GetAsyncKeyState(VK_CONTROL) & 0x8000)
&& MessageBoxW(NULL, cmdline, NULL, MB_YESNO) != IDYES) {
free(cmdline);
return NOERROR;
}
#endif
LPITEMIDLIST pidl = NULL;
HRESULT hr;
//filẽAƒCƒeƒ€IDƒŠƒXƒgðŽæ“¾
hr = _SHILCreateFromPath(file, &pidl, NULL);
if(SUCCEEDED(hr) && pidl) {
//SEE_MASK_INVOKEIDLISTðŽg¤Æ
//explorerŃNƒŠƒbƒNµÄN“®µ½ÌÆ“¯¶“®<E2809C>ìÉÈé
SHELLEXECUTEINFOW sei = { sizeof(SHELLEXECUTEINFOW) };
sei.fMask = SEE_MASK_INVOKEIDLIST
| SEE_MASK_CONNECTNETDRV
| SEE_MASK_FLAG_DDEWAIT
| SEE_MASK_DOENVSUBST
| SEE_MASK_WAITFORINPUTIDLE;
sei.hwnd = GetDesktopWindow();
sei.lpParameters = cmdline;
sei.lpDirectory = dir;
sei.nShow = show;
sei.lpIDList = pidl;
//ShellExecuteExWª“à•”ÅŒÄÑ<E2809A>o·CreateProcessWðƒtƒbƒNµÄ
//HookChildProcessesŠ“Ì<E2809A>ˆ<CB86>ð<E2809A>s¤
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)ORIG_CreateProcessW, IMPL_CreateProcessW);
hr = DetourTransactionCommit();
if(hr == NOERROR) {
if(ShellExecuteExW(&sei)) {
hr = S_OK;
} else {
hr = HresultFromLastError();
}
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)ORIG_CreateProcessW, IMPL_CreateProcessW);
DetourTransactionCommit();
}
if(pidl)
_SHFree(pidl);
free(cmdline);
return hr;
}
int WINAPI wWinMain(HINSTANCE ins, HINSTANCE prev, LPWSTR cmd, int show)
{
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
OleInitialize(NULL);
WCHAR path [MAX_PATH];
if(GetModuleFileNameW(NULL, path, _countof(path))) {
PathRenameExtensionW(path, L".dll");
//DONT_RESOLVE_DLL_REFERENCESðŽwè·éƈ˶ŠÖŒW̉ðŒˆâ
//DllMainÌŒÄÑ<E2809A>oµª<E2809A>síêÈ¢
hinstDLL = LoadLibraryExW(path, NULL, DONT_RESOLVE_DLL_REFERENCES);
}
if(!hinstDLL) {
errmsg(IDS_DLL, HresultFromLastError());
} else {
PathRemoveFileSpecW(path);
SetCurrentDirectoryW(path);
HRESULT hr = HookAndExecute(show);
if(hr != S_OK) {
errmsg(IDC_EXEC, hr);
}
}
OleUninitialize();
return 0;
}
//EOF