#ifndef _GDIPP_EXE #include "settings.h" #include "override.h" #include #include //DLLVERSIONINFO #include "undocAPI.h" #include #include #include #include #include #include "wow64ext.h" #include #include "crc32.h" // win2k以降 //#pragma comment(linker, "/subsystem:windows,5.0") #ifndef _WIN64 #ifdef DEBUG #pragma comment(lib, "wow64ext_dbg.lib") #else #pragma comment(lib, "wow64ext.lib") #endif #endif EXTERN_C LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam) { //何もしない return CallNextHookEx(NULL, code, wParam, lParam); } EXTERN_C HRESULT WINAPI GdippDllGetVersion(DLLVERSIONINFO* pdvi) { if (!pdvi || pdvi->cbSize < sizeof(DLLVERSIONINFO)) { return E_INVALIDARG; } const UINT cbSize = pdvi->cbSize; ZeroMemory(pdvi, cbSize); pdvi->cbSize = cbSize; HRSRC hRsrc = FindResource(GetDLLInstance(), MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); if (!hRsrc) { return E_FAIL; } HGLOBAL hGlobal = LoadResource(GetDLLInstance(), hRsrc); if (!hGlobal) { return E_FAIL; } const WORD* lpwPtr = (const WORD*)LockResource(hGlobal); if (lpwPtr[1] != sizeof(VS_FIXEDFILEINFO)) { return E_FAIL; } const VS_FIXEDFILEINFO* pvffi = (const VS_FIXEDFILEINFO*)(lpwPtr + 20); if (pvffi->dwSignature != VS_FFI_SIGNATURE || pvffi->dwStrucVersion != VS_FFI_STRUCVERSION) { return E_FAIL; } //8.0.2006.1027 // -> Major: 8, Minor: 2006, Build: 1027 pdvi->dwMajorVersion = HIWORD(pvffi->dwFileVersionMS); pdvi->dwMinorVersion = LOWORD(pvffi->dwFileVersionMS) * 10 + HIWORD(pvffi->dwFileVersionLS); pdvi->dwBuildNumber = LOWORD(pvffi->dwFileVersionLS); pdvi->dwPlatformID = DLLVER_PLATFORM_NT; if (pdvi->cbSize < sizeof(DLLVERSIONINFO2)) { return S_OK; } DLLVERSIONINFO2* pdvi2 = (DLLVERSIONINFO2*)pdvi; pdvi2->ullVersion = MAKEDLLVERULL(pdvi->dwMajorVersion, pdvi->dwMinorVersion, pdvi->dwBuildNumber, 2); return S_OK; } #endif //!_GDIPP_EXE extern LONG interlock; extern LONG g_bHookEnabled; #include "gdiPlusFlat2.h" #ifdef USE_DETOURS //detours #include "detours.h" // #define HOOK_MANUALLY(rettype, name, argtype, arglist) ; #define HOOK_DEFINE(rettype, name, argtype, arglist) \ DetourDetach(&(PVOID&)ORIG_##name, IMPL_##name); LONG hook_term() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); #include "hooklist.h" LONG error = DetourTransactionCommit(); if (error != NOERROR) { TRACE(_T("hook_term error: %#x\n"), error); } return error; } #undef HOOK_DEFINE #undef HOOK_MANUALLY #else #include "easyhook.h" #define HOOK_MANUALLY(rettype, name, argtype, arglist) ; #define HOOK_DEFINE(rettype, name, argtype, arglist) \ ORIG_##name = name; #pragma optimize("s", on) static LONG hook_term() { #include "hooklist.h" LhUninstallAllHooks(); return LhWaitForPendingRemovals(); } #pragma optimize("", on) #undef HOOK_DEFINE #undef HOOK_MANUALLY #endif HMODULE GetSelfModuleHandle() { MEMORY_BASIC_INFORMATION mbi; return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0) ? (HMODULE) mbi.AllocationBase : NULL); } EXTERN_C void WINAPI CreateControlCenter(IControlCenter** ret) { *ret = (IControlCenter*)new CControlCenter; } EXTERN_C void WINAPI ReloadConfig() { CControlCenter::ReloadConfig(); } extern HINSTANCE g_dllInstance; EXTERN_C void SafeUnload() { static BOOL bInited = false; if (bInited) return; //防重入 bInited = true; while (CThreadCounter::Count()) Sleep(0); CCriticalSectionLock * lock = new CCriticalSectionLock; BOOL last; if (last=InterlockedExchange(&g_bHookEnabled, FALSE)) { if (hook_term()!=NOERROR) { InterlockedExchange(&g_bHookEnabled, last); bInited = false; delete lock; ExitThread(ERROR_ACCESS_DENIED); } } delete lock; while (CThreadCounter::Count()) Sleep(10); Sleep(0); do { Sleep(10); } while (CThreadCounter::Count()); //double check for xp bInited = false; FreeLibraryAndExitThread(g_dllInstance, 0); } void ChangeFileName(LPWSTR lpSrc, int nSize, LPCWSTR lpNewFileName) { for (int i = nSize; i > 0; --i){ if (lpSrc[i] == L'\\') { lpSrc[i + 1] = L'\0'; break; } } wcscat(lpSrc, lpNewFileName); } std::string WstringToString(const std::wstring str) {// wstringתstring unsigned len = str.size() * 4; setlocale(LC_CTYPE, ""); char *p = new char[len]; wcstombs(p, str.c_str(), len); std::string str1(p); delete[] p; return str1; } // make a unique name with fullname + crc32_of_fullname + familyname +stylename std::wstring MakeUniqueFontName(const std::wstring strFullName, const std::wstring strFamilyName, const std::wstring strStyleName) { return strFullName + to_wstring(crc32::getCrc32(0, strFullName.c_str(), strFullName.length() * sizeof(WCHAR))) + strFamilyName + strStyleName; } #ifndef Assert #include #define Assert _ASSERTE #endif //!Assert #include "array.h" #include #include #include "dll.h" //kernel32専用GetProcAddressモドキ FARPROC K32GetProcAddress(LPCSTR lpProcName) { #ifndef _WIN64 //序数渡しには対応しない Assert(!IS_INTRESOURCE(lpProcName)); //kernel32のベースアドレス取得 LPBYTE pBase = (LPBYTE)GetModuleHandleA("kernel32.dll"); //この辺は100%成功するはずなのでエラーチェックしない PIMAGE_DOS_HEADER pdosh = (PIMAGE_DOS_HEADER)pBase; Assert(pdosh->e_magic == IMAGE_DOS_SIGNATURE); PIMAGE_NT_HEADERS pnth = (PIMAGE_NT_HEADERS)(pBase + pdosh->e_lfanew); Assert(pnth->Signature == IMAGE_NT_SIGNATURE); const DWORD offs = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; const DWORD size = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; if (offs == 0 || size == 0) { return NULL; } PIMAGE_EXPORT_DIRECTORY pdir = (PIMAGE_EXPORT_DIRECTORY)(pBase + offs); DWORD* pFunc = (DWORD*)(pBase + pdir->AddressOfFunctions); WORD* pOrd = (WORD*)(pBase + pdir->AddressOfNameOrdinals); DWORD* pName = (DWORD*)(pBase + pdir->AddressOfNames); for(DWORD i=0; iNumberOfFunctions; i++) { for(DWORD j=0; jNumberOfNames; j++) { if(pOrd[j] != i) continue; if(strcmp((LPCSTR)pBase + pName[j], lpProcName) != 0) continue; return (FARPROC)(pBase + pFunc[i]); } } return NULL; #else Assert(!IS_INTRESOURCE(lpProcName)); //kernel32のベースアドレス取得 WCHAR sysdir[MAX_PATH]; GetWindowsDirectory(sysdir, MAX_PATH); if (GetModuleHandle(_T("kernelbase.dll"))) //查看自己是否加载了Kernelbase.dll文件,存在则说明是win7系统 wcscat(sysdir, L"\\SysWow64\\kernelbase.dll"); else wcscat(sysdir, L"\\SysWow64\\kernel32.dll"); //不存在就是vista HANDLE hFile = CreateFile(sysdir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (hFile == INVALID_HANDLE_VALUE) return NULL; DWORD dwSize = GetFileSize(hFile, NULL); BYTE* pMem = new BYTE[dwSize]; //分配内存 ReadFile(hFile, pMem, dwSize, &dwSize, NULL);//读取文件 CloseHandle(hFile); CMemLoadDll MemDll; MemDll.MemLoadLibrary(pMem, dwSize, false, false); delete[] pMem; return FARPROC((DWORD_PTR)MemDll.MemGetProcAddress(lpProcName)-MemDll.GetImageBase()); //返回偏移值 #endif } typedef struct _UNICODE_STRING64 { USHORT Length; USHORT MaximumLength; DWORD64 Buffer; } UNICODE_STRING64, *PUNICODE_STRING64; #include class opcode_data { private: BYTE code[0x100]; //注: dllpathをWORD境界にしないと場合によっては正常に動作しない WCHAR dllpath[MAX_PATH]; UNICODE_STRING64 uniDllPath; DWORD64 hDumyDllHandle; public: opcode_data() { //int 03hで埋める FillMemory(this, sizeof(*this), 0xcc); } bool initWow64(LPDWORD remoteaddr, LONG orgEIP) //Wow64初始化 { //WORD境界チェック C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0); register BYTE* p = code; #define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t) #define emit_db(b) emit_(BYTE, b) #define emit_dw(w) emit_(WORD, w) #define emit_dd(d) emit_(DWORD, d) //なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので //kernel32のヘッダから自前で取得する FARPROC pfn = K32GetProcAddress("LoadLibraryExW"); if(!pfn) return false; emit_db(0x60); //pushad /* mov eax,fs:[0x30] mov eax,[eax+0x0c] mov esi,[eax+0x1c] lodsd move ax,[eax+$08]//这个时候eax中保存的就是k32的基址了 在win7获得的是KernelBase.dll的地址 */ emit_db(0x64); emit_db(0xA1); emit_db(0x30); emit_db(00); emit_db(00); emit_db(00); emit_db(0x8B); emit_db(0x40); emit_db(0x0C); emit_db(0x8B); emit_db(0x70); emit_db(0x1C); emit_db(0xAD); emit_db(0x8B); emit_db(0x40); emit_db(0x08); //use assemble to fetch kernel base emit_dw(0x006A); //push 0 emit_dw(0x006A); //push 0 emit_db(0x68); //push dllpath emit_dd((LONG)remoteaddr + offsetof(opcode_data, dllpath)); emit_db(0x05); //add eax, LoadLibraryExW offset emit_dd(pfn); emit_dw(0xD0FF); //call eax emit_db(0x61); //popad emit_db(0xE9); //jmp original_EIP emit_dd(orgEIP - (LONG)remoteaddr - (p - code) - sizeof(LONG)); // gdi++.dllのパス int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH); if (nSize) { ChangeFileName(dllpath, nSize, L"MTBootStrap.dll"); } return !!nSize; } bool init32(LPDWORD remoteaddr, LONG orgEIP) //32位程序初始化 { //WORD境界チェック C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0); register BYTE* p = code; #define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t) #define emit_db(b) emit_(BYTE, b) #define emit_dw(w) emit_(WORD, w) #define emit_dd(d) emit_(DWORD, d) //なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので //kernel32のヘッダから自前で取得する FARPROC pfn = K32GetProcAddress("LoadLibraryW"); if(!pfn) return false; emit_db(0x60); //pushad #if _DEBUG emit_dw(0xC033); //xor eax, eax emit_db(0x50); //push eax emit_db(0x50); //push eax emit_db(0x68); //push dllpath emit_dd((LONG)remoteaddr + offsetof(opcode_data, dllpath)); emit_db(0x50); //push eax emit_db(0xB8); //mov eax, MessageBoxW emit_dd((LONG)MessageBoxW); emit_dw(0xD0FF); //call eax #endif emit_db(0x68); //push dllpath emit_dd((LONG)remoteaddr + offsetof(opcode_data, dllpath)); emit_db(0xB8); //mov eax, LoadLibraryW emit_dd(pfn); emit_dw(0xD0FF); //call eax emit_db(0x61); //popad emit_db(0xE9); //jmp original_EIP emit_dd(orgEIP - (LONG)remoteaddr - (p - code) - sizeof(LONG)); // gdi++.dllのパス int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH); if (nSize) { ChangeFileName(dllpath, nSize, L"MTBootStrap.dll"); } return !!nSize; } bool init64From32(DWORD64 remoteaddr, DWORD64 orgEIP) { C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0); register BYTE* p = code; #define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t) #define emit_db(b) emit_(BYTE, b) #define emit_dw(w) emit_(WORD, w) #define emit_dd(d) emit_(DWORD, d) #define emit_ddp(dp) emit_(DWORD64, dp) //なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので //kernel32のヘッダから自前で取得する WCHAR x64Addr[30] = { 0 }; if (!GetEnvironmentVariable(L"MACTYPE_X64ADDR", x64Addr, 29)) return false; DWORD64 pfn = wcstoull(x64Addr, NULL, 10); //DWORD64 pfn = getenv("MACTYPE_X64ADDR"); //GetProcAddress64(GetModuleHandle64(L"kernelbase.dll"), "LoadLibraryW"); if (!pfn) return false; emit_db(0x50); //push rax emit_db(0x51); //push rcx emit_db(0x52); //push rdx emit_db(0x53); //push rbx emit_dd(0x28ec8348); //sub rsp,28h emit_db(0x48); //mov rcx, dllpath emit_db(0xB9); emit_ddp((DWORD64)remoteaddr + offsetof(opcode_data, dllpath)); emit_db(0x48); //mov rsi, LoadLibraryW emit_db(0xBE); emit_ddp(pfn); //emit_db(0x48); emit_db(0xFF); //call rdi emit_db(0xD6); emit_dd(0x28c48348); //add rsp,28h emit_db(0x5B); emit_db(0x5A); emit_db(0x59); emit_db(0x58); //popad emit_db(0x48); //mov rdi, orgRip emit_db(0xBE); emit_ddp(orgEIP); emit_db(0xFF); //jmp rdi emit_db(0xE6); // gdi++.dllのパス int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH); if (nSize) { ChangeFileName(dllpath, nSize, L"MTBootStrap64.dll"); } return !!nSize; } bool init64From32(DWORD64 remoteaddr, DWORD64 orgEIP, DWORD dwLoaderOffset) { C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0); int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH); if (nSize) { ChangeFileName(dllpath, nSize, L"MTBootStrap64.dll"); } if (!nSize) return false; uniDllPath.Length = wcslen(dllpath)*sizeof(WCHAR); uniDllPath.MaximumLength = uniDllPath.Length+2; uniDllPath.Buffer = remoteaddr + (DWORD64)offsetof(opcode_data, dllpath); //prepare PUNICODE_STRING for remote process register BYTE* p = code; #define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t) #define emit_db(b) emit_(BYTE, b) #define emit_dw(w) emit_(WORD, w) #define emit_dd(d) emit_(DWORD, d) #define emit_ddp(dp) emit_(DWORD64, dp) //get ntdll.dll imagebase //credit to http://www.52pojie.cn/thread-162625-1-1.html /*asm: mov rsi, [gs:60h] ; peb from teb mov rsi, [rsi+18h] ;_peb_ldr_data from peb mov rsi, [rsi+30h] ;InInitializationOrderModuleList.Flink, ntdll.dll ;mov rsi, [rsi] ;kernelbase.dll ;mov rsi, [rsi] ;kernel32.dll (not used for win7+) mov rsi, [rsi+10h] */ // emit_db(0xEB); // emit_db(0xFE); // make a dead loop emit_db(0x65); emit_db(0x48); emit_db(0x8B); emit_db(0x34); emit_db(0x25); emit_db(0x60); emit_db(0x00); emit_db(0x00); emit_db(0x00); emit_db(0x48); emit_db(0x8B); emit_db(0x76); emit_db(0x18); emit_db(0x48); emit_db(0x8B); emit_db(0x76); emit_db(0x30); // emit_db(0x48); // emit_db(0x8B); // emit_db(0x36); emit_db(0x48); emit_db(0x8B); emit_db(0x76); emit_db(0x10); //rsi = ntdll.dll baseaddress emit_db(0x50); //push rax emit_db(0x51); //push rcx emit_db(0x52); //push rdx emit_db(0x53); //push rbx emit_dd(0x28ec8348); //sub rsp,28h emit_db(0x48); emit_db(0x31); emit_db(0xc9); //xor rcx, rcx emit_db(0x48); emit_db(0x31); emit_db(0xd2); //xor rdx, rdx emit_db(0x49); emit_db(0xB8); emit_ddp((DWORD64)remoteaddr + offsetof(opcode_data, uniDllPath));//mov r8, uniDllPath emit_db(0x49); emit_db(0xB9); emit_ddp((DWORD64)remoteaddr + offsetof(opcode_data, hDumyDllHandle));//mov r9, hDumyDllHandle //emit_db(0x48); //mov rsi, LdrLoadDll //emit_db(0xBE); emit_db(0x48); emit_db(0x81); emit_db(0xC6); //add rsi, offset LdrLoadDll emit_dd(dwLoaderOffset); //emit_db(0x48); emit_db(0xFF); //call rsi emit_db(0xD6); emit_dd(0x28c48348); //add rsp,28h emit_db(0x5B); emit_db(0x5A); emit_db(0x59); emit_db(0x58); //popad emit_db(0x48); //mov rdi, orgRip emit_db(0xBE); emit_ddp(orgEIP); emit_db(0xFF); //jmp rdi emit_db(0xE6); // gdi++.dllのパス return !!nSize; } bool init(DWORD_PTR* remoteaddr, DWORD_PTR orgEIP) { //WORD境界チェック C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0); register BYTE* p = code; #undef emit_ddp #define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t) #define emit_db(b) emit_(BYTE, b) #define emit_dw(w) emit_(WORD, w) #define emit_dd(d) emit_(DWORD, d) #define emit_ddp(dp) emit_(DWORD_PTR, dp) //なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので //kernel32のヘッダから自前で取得する FARPROC pfn = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW"); //if(!pfn) // return false; //emit_db(0xEB); //emit_db(0xFE); // make a dead loop emit_db(0x50); //push rax emit_db(0x51); //push rcx emit_db(0x52); //push rdx emit_db(0x53); //push rbx /* #ifdef DEBUG emit_dd(0x28ec8348); emit_db(0x48); emit_db(0x31); emit_db(0xD0); //xor rax,rax emit_db(0x48); emit_db(0x31); emit_db(0xC9); //xor rcx,rcx emit_db(0x48); emit_db(0x31); emit_db(0xD2); //xor rdx,rdx emit_db(0x45); emit_db(0x31); emit_db(0xC0); //xor r8d,r8d emit_db(0x45); emit_db(0x31); emit_db(0xC9); //xor r9d,r9d emit_db(0x48); //mov rsi, MessageBoxW emit_db(0xBE); emit_ddp((DWORD_PTR)MessageBoxW); emit_db(0xFF); emit_db(0xD6); emit_dd(0x28c48348); #endif*/ /* //Debug function2, Sleep for 10sec. emit_dd(0x28ec8348); emit_db(0x48); //mov rsi, MessageBoxW emit_db(0xBE); emit_ddp((DWORD_PTR)Sleep); emit_db(0x48); emit_db(0xc7); emit_db(0xc1); emit_db(0x10); emit_db(0x27); emit_db(0x00); emit_db(0x00); emit_db(0xFF); emit_db(0xD6); emit_dd(0x28c48348); */ emit_dd(0x28ec8348); //sub rsp,28h emit_db(0x48); //mov rcx, dllpath emit_db(0xB9); emit_ddp((DWORD_PTR)remoteaddr + offsetof(opcode_data, dllpath)); emit_db(0x48); //mov rsi, LoadLibraryW emit_db(0xBE); emit_ddp(pfn); //emit_db(0x48); emit_db(0xFF); //call rdi emit_db(0xD6); emit_dd(0x28c48348); //add rsp,28h emit_db(0x5B); emit_db(0x5A); emit_db(0x59); emit_db(0x58); //popad emit_db(0x48); //mov rdi, orgRip emit_db(0xBE); emit_ddp(orgEIP); emit_db(0xFF); //jmp rdi emit_db(0xE6); // gdi++.dllのパス int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH); if (nSize) { ChangeFileName(dllpath, nSize, L"MTBootStrap64.dll"); } return !!nSize; } }; #include // 安全的取得真实系统信息 VOID SafeGetNativeSystemInfo(__out LPSYSTEM_INFO lpSystemInfo) { if (NULL == lpSystemInfo) return; typedef VOID(WINAPI *LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo); LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(_T("kernel32")), "GetNativeSystemInfo");; if (NULL != fnGetNativeSystemInfo) { fnGetNativeSystemInfo(lpSystemInfo); } else { GetSystemInfo(lpSystemInfo); } } // 获取操作系统位数 int GetSystemBits() { SYSTEM_INFO si; SafeGetNativeSystemInfo(&si); if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { return 64; } return 32; } static bool bIsOS64 = GetSystemBits() == 64; // check if running in a x64 system. #ifdef _M_IX86 // 止めているプロセスにLoadLibraryするコードを注入 EXTERN_C BOOL WINAPI GdippInjectDLL(const PROCESS_INFORMATION* ppi) { BOOL bIsX64Proc = false; if (bIsOS64 && IsWow64Process(ppi->hProcess, &bIsX64Proc) && !bIsX64Proc) { //x86 process launches a x64 process _CONTEXT64 ctx = { 0 }; ctx.ContextFlags = CONTEXT_CONTROL; if (!GetThreadContext64(ppi->hThread, &ctx)) return false; static bool bTryLoadDll64 = false; static DWORD dwLoaderOffset = 0; if (!bTryLoadDll64) { bTryLoadDll64 = true; GetEnvironmentVariable(L"MACTYPE_X64ADDR", NULL, 0); if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { DWORD64 hNtdll = 0; hNtdll = GetModuleHandle64(L"ntdll.dll"); if (hNtdll) { DWORD64 pfnLdrAddr = GetProcAddress64(hNtdll, "LdrLoadDll"); if (pfnLdrAddr) { dwLoaderOffset = (DWORD)(pfnLdrAddr - hNtdll); } } } } opcode_data local; DWORD64 remote = VirtualAllocEx64(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!remote) return false; bool basmIniter = dwLoaderOffset ? local.init64From32(remote, ctx.Rip, dwLoaderOffset) : local.init64From32(remote, ctx.Rip); if (!basmIniter || !WriteProcessMemory64(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) { VirtualFreeEx64(ppi->hProcess, remote, 0, MEM_RELEASE); return false; } //FlushInstructionCache64(ppi->hProcess, remote, sizeof(opcode_data)); //FARPROC a=(FARPROC)remote; //a(); ctx.Rip = (DWORD64)remote; return !!SetThreadContext64(ppi->hThread, &ctx); } else { CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_CONTROL; if (!GetThreadContext(ppi->hThread, &ctx)) return false; opcode_data local; opcode_data* remote = (opcode_data*)VirtualAllocEx(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!remote) return false; if (!local.init32((LPDWORD)remote, ctx.Eip) || !WriteProcessMemory(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) { VirtualFreeEx(ppi->hProcess, remote, 0, MEM_RELEASE); return false; } FlushInstructionCache(ppi->hProcess, remote, sizeof(opcode_data)); ctx.Eip = (DWORD)remote; return !!SetThreadContext(ppi->hThread, &ctx); } } #else EXTERN_C BOOL WINAPI GdippInjectDLL(const PROCESS_INFORMATION* ppi) { BOOL bWow64 = false; IsWow64Process(ppi->hProcess, &bWow64); if (bWow64) { WOW64_CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_CONTROL; //CREATE_SUSPENDEDなので基本的に成功するはず if(!Wow64GetThreadContext(ppi->hThread, &ctx)) return false; opcode_data local; LPVOID remote = VirtualAllocEx(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(!remote) return false; if(!local.initWow64((LPDWORD)remote, ctx.Eip) || !WriteProcessMemory(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) { VirtualFreeEx(ppi->hProcess, remote, 0, MEM_RELEASE); return false; } FlushInstructionCache(ppi->hProcess, remote, sizeof(opcode_data)); //FARPROC a=(FARPROC)remote; //a(); ctx.Eip = (DWORD)remote; return !!Wow64SetThreadContext(ppi->hThread, &ctx); } else { CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_CONTROL; //CREATE_SUSPENDEDなので基本的に成功するはず if(!GetThreadContext(ppi->hThread, &ctx)) return false; opcode_data local; LPVOID remote = VirtualAllocEx(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(!remote) return false; if(!local.init((DWORD_PTR*)remote, ctx.Rip) || !WriteProcessMemory(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) { VirtualFreeEx(ppi->hProcess, remote, 0, MEM_RELEASE); return false; } FlushInstructionCache(ppi->hProcess, remote, sizeof(opcode_data)); //FARPROC a=(FARPROC)remote; //a(); ctx.Rip = (DWORD_PTR)remote; return !!SetThreadContext(ppi->hThread, &ctx); } } #endif template int strlendb(const _TCHAR* psz) { const _TCHAR* p = psz; while (*p) { for (; *p; p++); p++; } return p - psz + 1; } template _TCHAR* strdupdb(const _TCHAR* psz, int pad) { int len = strlendb(psz); _TCHAR* p = (_TCHAR*)calloc(sizeof(_TCHAR), len + pad); if(p) { memcpy(p, psz, sizeof(_TCHAR) * len); } return p; } bool MultiSzToArray(LPWSTR p, CArray& arr) { for (; *p; ) { LPWSTR cp = _wcsdup(p); if(!cp || !arr.Add(cp)) { free(cp); return false; } for (; *p; p++); p++; } return true; } LPWSTR ArrayToMultiSz(CArray& arr) { size_t cch = 1; for (int i=0; i& arr, LPWSTR dir, int dirlen) { for (int i=0; i