From 38a57eb48005f5b7864394931357d476b2882d7a Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Fri, 11 May 2018 16:46:05 -0400 Subject: [PATCH] delete unused files and start cleaning up code --- gui/ProcessWindow.cpp | 5 +- gui/ProfileManager.cpp | 2 +- gui/command.cpp | 11 +- gui/main.cpp | 4 +- gui/window.cpp | 2 +- i18n/gui_korean/main.cpp | 4 +- vnr/ccutil/ccmacro.h | 5 + vnr/texthook/host/CMakeLists.txt | 12 - vnr/texthook/host/config.h | 2 - vnr/texthook/host/host.cc | 562 +++++++++-------------------- vnr/texthook/host/host.h | 10 +- vnr/texthook/host/host_p.h | 5 +- vnr/texthook/host/pipe.cc | 10 +- vnr/texthook/host/textthread.cc | 8 +- vnr/vnrhook/CMakeLists.txt | 5 - vnr/vnrhook/src/hijack/texthook.cc | 1 - vnr/windbg/hijack.cc | 89 ----- vnr/windbg/hijack.h | 25 -- vnr/windbg/inject.cc | 167 --------- vnr/windbg/inject.h | 56 --- vnr/windbg/unload.cc | 22 -- vnr/windbg/unload.h | 19 - vnr/windbg/util.cc | 61 ---- vnr/windbg/util.h | 34 -- vnr/windbg/windbg.h | 16 - vnr/windbg/windbg_p.h | 24 -- vnr/winkey/winkey.h | 32 -- vnr/winmaker/winmaker.cc | 46 --- vnr/winmaker/winmaker.h | 23 -- vnr/winseh/Makefile | 26 -- vnr/winseh/safeseh.asm | 21 -- vnr/winseh/winseh.cc | 52 --- vnr/winseh/winseh.h | 154 -------- vnr/winseh/winseh_safe.cc | 10 - vnr/winseh/winseh_unsafe.cc | 11 - vnr/wintimer/wintimer.cc | 49 --- vnr/wintimer/wintimer.h | 93 ----- vnr/wintimer/wintimerbase.cc | 73 ---- vnr/wintimer/wintimerbase.h | 68 ---- 39 files changed, 194 insertions(+), 1625 deletions(-) delete mode 100644 vnr/windbg/hijack.cc delete mode 100644 vnr/windbg/hijack.h delete mode 100644 vnr/windbg/inject.cc delete mode 100644 vnr/windbg/inject.h delete mode 100644 vnr/windbg/unload.cc delete mode 100644 vnr/windbg/unload.h delete mode 100644 vnr/windbg/util.cc delete mode 100644 vnr/windbg/util.h delete mode 100644 vnr/windbg/windbg.h delete mode 100644 vnr/windbg/windbg_p.h delete mode 100644 vnr/winkey/winkey.h delete mode 100644 vnr/winmaker/winmaker.cc delete mode 100644 vnr/winmaker/winmaker.h delete mode 100644 vnr/winseh/Makefile delete mode 100644 vnr/winseh/safeseh.asm delete mode 100644 vnr/winseh/winseh.cc delete mode 100644 vnr/winseh/winseh.h delete mode 100644 vnr/winseh/winseh_safe.cc delete mode 100644 vnr/winseh/winseh_unsafe.cc delete mode 100644 vnr/wintimer/wintimer.cc delete mode 100644 vnr/wintimer/wintimer.h delete mode 100644 vnr/wintimer/wintimerbase.cc delete mode 100644 vnr/wintimer/wintimerbase.h diff --git a/gui/ProcessWindow.cpp b/gui/ProcessWindow.cpp index b7906c9..bfa046b 100644 --- a/gui/ProcessWindow.cpp +++ b/gui/ProcessWindow.cpp @@ -75,9 +75,8 @@ void ProcessWindow::RefreshProcess() void ProcessWindow::AttachProcess() { DWORD pid = GetSelectedPID(); - if (Host_InjectByPID(pid)) + if (InjectProcessById(pid)) { - Host_HijackProcess(pid); RefreshThreadWithPID(pid, true); } } @@ -85,7 +84,7 @@ void ProcessWindow::AttachProcess() void ProcessWindow::DetachProcess() { DWORD pid = GetSelectedPID(); - if (Host_ActiveDetachProcess(pid) == 0) + if (DetachProcessById(pid) == 0) RefreshThreadWithPID(pid, false); } diff --git a/gui/ProfileManager.cpp b/gui/ProfileManager.cpp index f60d517..01a7742 100644 --- a/gui/ProfileManager.cpp +++ b/gui/ProfileManager.cpp @@ -156,7 +156,7 @@ DWORD WINAPI InjectThread(LPVOID lpThreadParameter) Sleep(inject_delay); if (man == NULL) return 0; - DWORD status = Host_InjectByPID(pid); + DWORD status = InjectProcessById(pid); if (!auto_insert) return status; if (status == -1) diff --git a/gui/command.cpp b/gui/command.cpp index bfd8220..b652bb7 100644 --- a/gui/command.cpp +++ b/gui/command.cpp @@ -32,17 +32,10 @@ DWORD ProcessCommand(const std::wstring& cmd, DWORD pid) using std::regex_match; std::match_results m; - if (regex_match(cmd, m, wregex(L"/pn(.+)", wregex::icase))) - { - pid = Host_GetPIDByName(m[1].str().c_str()); - if (pid == 0) - return 0; - Host_InjectByPID(pid); - } - else if (regex_match(cmd, m, wregex(L"/p(\\d+)", wregex::icase))) + if (regex_match(cmd, m, wregex(L"/p(\\d+)", wregex::icase))) { pid = std::stoul(m[1].str()); - Host_InjectByPID(pid); + InjectProcessById(pid); } else if (regex_match(cmd, m, wregex(L"/h(.+)", wregex::icase))) { diff --git a/gui/main.cpp b/gui/main.cpp index d48fd46..90292cc 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -246,7 +246,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (!IthInitSystemService()) TerminateProcess(GetCurrentProcess(), 0); CreateMutex(NULL, TRUE, L"ITH_MAIN_RUNNING"); - if (Host_Open()) + if (OpenHost()) { SetUnhandledExceptionFilter(UnhandledExcept); Host_GetHookManager(&man); @@ -280,7 +280,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine { FindITH(); } - Host_Close(); + CloseHost(); IthCloseSystemService(); TerminateProcess(GetCurrentProcess(), 0); } diff --git a/gui/window.cpp b/gui/window.cpp index 0f3a862..ab349b1 100644 --- a/gui/window.cpp +++ b/gui/window.cpp @@ -753,7 +753,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) man->RegisterProcessNewHookCallback(RefreshProfileOnNewHook); man->RegisterAddRemoveLinkCallback(AddRemoveLink); man->RegisterConsoleCallback(ConsoleOutput); - Host_Start(); + StartHost(); { static const WCHAR program_name[] = L"Interactive Text Hooker"; //static const WCHAR program_version[] = L"3.0"; diff --git a/i18n/gui_korean/main.cpp b/i18n/gui_korean/main.cpp index d48fd46..90292cc 100644 --- a/i18n/gui_korean/main.cpp +++ b/i18n/gui_korean/main.cpp @@ -246,7 +246,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (!IthInitSystemService()) TerminateProcess(GetCurrentProcess(), 0); CreateMutex(NULL, TRUE, L"ITH_MAIN_RUNNING"); - if (Host_Open()) + if (OpenHost()) { SetUnhandledExceptionFilter(UnhandledExcept); Host_GetHookManager(&man); @@ -280,7 +280,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine { FindITH(); } - Host_Close(); + CloseHost(); IthCloseSystemService(); TerminateProcess(GetCurrentProcess(), 0); } diff --git a/vnr/ccutil/ccmacro.h b/vnr/ccutil/ccmacro.h index a38febb..21be12f 100644 --- a/vnr/ccutil/ccmacro.h +++ b/vnr/ccutil/ccmacro.h @@ -4,6 +4,11 @@ // ccmacro.h // 12/9/2011 jichi +#include + +#define CONCAT_STR_NUM(_str, _num) (std::wstring(_str) + std::to_wstring(_num)).c_str() +#define CONCAT_STR_STR(_str1, _str2) (std::wstring(_str1) + std::wstring(_str2)).c_str() + #define CC_UNUSED(_var) (void)(_var) #define CC_NOP CC_UNUSED(0) diff --git a/vnr/texthook/host/CMakeLists.txt b/vnr/texthook/host/CMakeLists.txt index add5052..edf446a 100644 --- a/vnr/texthook/host/CMakeLists.txt +++ b/vnr/texthook/host/CMakeLists.txt @@ -19,23 +19,11 @@ set(vnrhost_src host.cc pipe.cc textthread.cc - ${PROJECT_SOURCE_DIR}/winmaker/winmaker.h - ${PROJECT_SOURCE_DIR}/winmaker/winmaker.cc ${PROJECT_SOURCE_DIR}/winmutex/winmutex.h # ${PROJECT_SOURCE_DIR}/wintimer/wintimer.h # ${PROJECT_SOURCE_DIR}/wintimer/wintimer.cc # ${PROJECT_SOURCE_DIR}/wintimer/wintimerbase.cc # ${PROJECT_SOURCE_DIR}/wintimer/wintimerbase.h - ${PROJECT_SOURCE_DIR}/windbg/windbg.h - ${PROJECT_SOURCE_DIR}/windbg/windbg_p.h - ${PROJECT_SOURCE_DIR}/windbg/inject.h - ${PROJECT_SOURCE_DIR}/windbg/inject.cc - ${PROJECT_SOURCE_DIR}/windbg/hijack.h - ${PROJECT_SOURCE_DIR}/windbg/hijack.cc - ${PROJECT_SOURCE_DIR}/windbg/util.h -# ${PROJECT_SOURCE_DIR}/windbg/util.cc - ${PROJECT_SOURCE_DIR}/windbg/unload.h - ${PROJECT_SOURCE_DIR}/windbg/unload.cc ${PROJECT_SOURCE_DIR}/sakurakit/skdebug.h ) diff --git a/vnr/texthook/host/config.h b/vnr/texthook/host/config.h index 6262cf1..7e1d50a 100644 --- a/vnr/texthook/host/config.h +++ b/vnr/texthook/host/config.h @@ -9,8 +9,6 @@ #define IHFAPI __stdcall #ifdef IHF # define IHFSERVICE __declspec(dllexport) -#else -# define IHFSERVICE __declspec(dllimport) #endif // EOF diff --git a/vnr/texthook/host/host.cc b/vnr/texthook/host/host.cc index 9340f3a..314a8a7 100644 --- a/vnr/texthook/host/host.cc +++ b/vnr/texthook/host/host.cc @@ -16,8 +16,6 @@ #include "vnrhook/include/defs.h" #include "vnrhook/include/types.h" #include "ithsys/ithsys.h" -#include "windbg/inject.h" -#include "winmaker/winmaker.h" #include "ccutil/ccmacro.h" #include @@ -28,446 +26,217 @@ #define DEBUG "vnrhost/host.cc" #include "sakurakit/skdebug.h" -namespace { // unnamed +namespace +{ // unnamed //enum { HOOK_TIMEOUT = -50000000 }; // in nanoseconds = 5 seconds -CRITICAL_SECTION cs; -//WCHAR exist[] = ITH_PIPEEXISTS_EVENT; -//WCHAR mutex[] = L"ITH_RUNNING"; -//WCHAR EngineName[] = ITH_ENGINE_DLL; -//WCHAR EngineNameXp[] = ITH_ENGINE_XP_DLL; -//WCHAR DllName[] = ITH_CLIENT_DLL; -//WCHAR DllNameXp[] = ITH_CLIENT_XP_DLL; -HANDLE hServerMutex; // jichi 9/28/2013: used to guard pipe -HANDLE hHookMutex; // jichi 9/28/2013: used to guard hook modification + CRITICAL_SECTION hostCs; + //WCHAR exist[] = ITH_PIPEEXISTS_EVENT; + //WCHAR mutex[] = L"ITH_RUNNING"; + //WCHAR EngineName[] = ITH_ENGINE_DLL; + //WCHAR EngineNameXp[] = ITH_ENGINE_XP_DLL; + //WCHAR DllName[] = ITH_CLIENT_DLL; + //WCHAR DllNameXp[] = ITH_CLIENT_XP_DLL; + HANDLE preventDuplicationMutex; // jichi 9/28/2013: used to guard pipe + HANDLE hookMutex; // jichi 9/28/2013: used to guard hook modification } // unnamed namespace //extern LPWSTR current_dir; -extern CRITICAL_SECTION detach_cs; +extern CRITICAL_SECTION detachCs; Settings *settings; -HWND hMainWnd; -HANDLE hPipeExist; +HWND dummyWindow; +HANDLE pipeExistsEvent; BOOL running; -#define ITH_SYNC_HOOK IthMutexLocker locker(::hHookMutex) +#define ITH_SYNC_HOOK IthMutexLocker locker(::hookMutex) -namespace { // unnamed +namespace +{ // unnamed -void GetDebugPriv() -{ - HANDLE hToken; - DWORD dwRet; - NTSTATUS status; + void GetDebugPrivileges() + { + HANDLE processToken; + TOKEN_PRIVILEGES Privileges = { 1, {0x14, 0, SE_PRIVILEGE_ENABLED} }; - TOKEN_PRIVILEGES Privileges = {1,{0x14,0,SE_PRIVILEGE_ENABLED}}; + OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken); + AdjustTokenPrivileges(processToken, FALSE, &Privileges, 0, nullptr, nullptr); + CloseHandle(processToken); + } - NtOpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); - - status = NtAdjustPrivilegesToken(hToken, 0, &Privileges, sizeof(Privileges), 0, &dwRet); - //if (STATUS_SUCCESS == status) - //{ - // admin = 1; - //} - //else - //{ - // WCHAR buffer[0x10]; - // swprintf(buffer, L"%.8X",status); - // MessageBox(0, NotAdmin, buffer, 0); - //} - NtClose(hToken); -} - -bool sendCommand(HANDLE hCmd, HostCommandType cmd) -{ - IO_STATUS_BLOCK ios; - //SendParam sp = {}; - //sp.type = cmd; - DWORD data = cmd; - return hCmd && NT_SUCCESS(NtWriteFile(hCmd, 0,0,0, &ios, &data, sizeof(data), 0,0)); -} - -// jichi 9/22/2013: Change current directory to the same as main module path -// Otherwise NtFile* would not work for files with relative paths. -//BOOL ChangeCurrentDirectory() -//{ -// if (const wchar_t *path = GetMainModulePath()) // path to VNR's python exe -// if (const wchar_t *base = wcsrchr(path, L'\\')) { -// size_t len = base - path; -// if (len < MAX_PATH) { -// wchar_t buf[MAX_PATH]; -// wcsncpy(buf, path, len); -// buf[len] = 0; -// return SetCurrentDirectoryW(buf); -// } -// } -// return FALSE; -//} - -#if 0 -bool injectUsingWin32Api(LPCWSTR path, HANDLE hProc) -{ return WinDbg::injectDllW(path, 0, hProc); } - -bool ejectUsingWin32Api(HANDLE hModule, HANDLE hProc) -{ return WinDbg::ejectDll(hModule, hProc); } - -// The original inject logic in ITH -bool injectUsingNTApi(LPCWSTR path, HANDLE hProc) -{ - LPVOID lpvAllocAddr = 0; - DWORD dwWrite = 0x1000; //, len = 0; - //if (IthIsWine()) - // lpvAllocAddr = VirtualAllocEx(hProc, nullptr, dwWrite, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - //else - NtAllocateVirtualMemory(hProc, &lpvAllocAddr, 0, &dwWrite, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - if (!lpvAllocAddr) - return false; - - CheckThreadStart(); - - //Copy module path into address space of target process. - //if (IthIsWine()) - // WriteProcessMemory(hProc, lpvAllocAddr, path, MAX_PATH << 1, &dwWrite); - //else - NtWriteVirtualMemory(hProc, lpvAllocAddr, (LPVOID)path, MAX_PATH << 1, &dwWrite); - HANDLE hTH = IthCreateThread(LoadLibraryW, (DWORD)lpvAllocAddr, hProc); - if (hTH == 0 || hTH == INVALID_HANDLE_VALUE) { - DOUT("ERROR: failed to create remote cli thread"); - //ConsoleOutput(ErrorRemoteThread); - return false; - } - // jichi 9/28/2013: no wait as it will not blocked - NtWaitForSingleObject(hTH, 0, nullptr); - THREAD_BASIC_INFORMATION info; - NtQueryInformationThread(hTH, ThreadBasicInformation, &info, sizeof(info), &dwWrite); - NtClose(hTH); - - // jichi 10/19/2014: Disable inject the second dll - //if (info.ExitStatus) { - // //IthCoolDown(); - // wcscpy(p, engine); - // //if (IthIsWine()) - // // WriteProcessMemory(hProc, lpvAllocAddr, path, MAX_PATH << 1, &dwWrite); - // //else - // NtWriteVirtualMemory(hProc, lpvAllocAddr, path, MAX_PATH << 1, &dwWrite); - // hTH = IthCreateThread(LoadLibraryW, (DWORD)lpvAllocAddr, hProc); - // if (hTH == 0 || hTH == INVALID_HANDLE_VALUE) { - // //ConsoleOutput(ErrorRemoteThread); - // ConsoleOutput("vnrhost:inject: ERROR: failed to create remote eng thread"); - // return error; - // } - // - // // jichi 9/28/2013: no wait as it will not blocked - // NtWaitForSingleObject(hTH, 0, nullptr); - // NtClose(hTH); - //} - - dwWrite = 0; - //if (IthIsWine()) - // VirtualFreeEx(hProc, lpvAllocAddr, dwWrite, MEM_RELEASE); - //else - NtFreeVirtualMemory(hProc, &lpvAllocAddr, &dwWrite, MEM_RELEASE); - return info.ExitStatus != -1; -} - -bool ejectUsingNTApi(HANDLE hModule, HANDLE hProc) -{ - //IthCoolDown(); -//#ifdef ITH_WINE // Nt series crash on wine -// hThread = IthCreateThread(FreeLibrary, engine, hProc); -//#else - HANDLE hThread = IthCreateThread(LdrUnloadDll, module, hProc); -//#endif // ITH_WINE - if (hThread == 0 || hThread == INVALID_HANDLE_VALUE) - return false; - // jichi 10/22/2013: Timeout might crash vnrsrv - //NtWaitForSingleObject(hThread, 0, (PLARGE_INTEGER)&timeout); - NtWaitForSingleObject(hThread, 0, nullptr); - //man->UnlockHookman(); - THREAD_BASIC_INFORMATION info; - NtQueryInformationThread(hThread, ThreadBasicInformation, &info, sizeof(info), 0); - NtClose(hThread); - NtSetEvent(hPipeExist, 0); - FreeThreadStart(hProc); - return info.ExitStatus; -} -#endif // 0 - -bool Inject(HANDLE hProc) -{ - //LPWSTR dllname = (IthIsWindowsXp() && !IthIsWine()) ? DllNameXp : DllName; - //LPCWSTR dllname = ITH_USE_XP_DLLS ? ITH_DLL_XP : ITH_DLL; - //LPCWSTR dllname = ITH_DLL; - //if (!IthCheckFile(dllname)) - // return error; - wchar_t path[MAX_PATH]; - size_t len = IthGetCurrentModulePath(path, MAX_PATH); - if (!len) - return false; - - wchar_t *p; - for (p = path + len; *p != L'\\'; p--); - p++; // ending with L"\\" - - //LPCWSTR mp = GetMainModulePath(); - //len = wcslen(mp); - //memcpy(path, mp, len << 1); - //memset(path + len, 0, (MAX_PATH - len) << 1); - //LPWSTR p; - //for (p = path + len; *p != L'\\'; p--); // Always a \ after drive letter. - //p++; - ::wcscpy(p, ITH_DLL); - - return WinDbg::injectDllW(path, 0, hProc); - //if (IthIsWindowsXp()) // && !IthIsWine()) - // return injectUsingWin32Api(path, hProc); - //else - // return injectUsingNTApi(path, hProc); -} + bool sendCommand(HANDLE commandPipe, HostCommandType command) + { + DWORD unused; + return commandPipe && WriteFile(commandPipe, &command, sizeof(command), &unused, nullptr); + } } // unnamed namespace void CreateNewPipe(); -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused) { - CC_UNUSED(lpvReserved); - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - LdrDisableThreadCalloutsForDll(hinstDLL); - InitializeCriticalSection(&::cs); - IthInitSystemService(); - GetDebugPriv(); - // jichi 12/20/2013: Since I already have a GUI, I don't have to InitCommonControls() - //Used by timers. - InitCommonControls(); - // jichi 8/24/2013: Create hidden window so that ITH can access timer and events - hMainWnd = CreateWindowW(L"Button", L"InternalWindow", 0, 0, 0, 0, 0, 0, 0, hinstDLL, 0); - //wm_register_hidden_class("vnrsrv.class"); - //hMainWnd = (HWND)wm_create_hidden_window("vnrsrv", "Button", hinstDLL); - //ChangeCurrentDirectory(); - break; - case DLL_PROCESS_DETACH: - if (::running) - Host_Close(); - DeleteCriticalSection(&::cs); - IthCloseSystemService(); - //wm_destroy_window(hMainWnd); - DestroyWindow(hMainWnd); - break; - default: - break; - } - return true; -} - -HANDLE IthOpenPipe(LPWSTR name, ACCESS_MASK direction) -{ - UNICODE_STRING us; - RtlInitUnicodeString(&us, name); - SECURITY_DESCRIPTOR sd = {1}; - OBJECT_ATTRIBUTES oa = {sizeof(oa), 0, &us, OBJ_CASE_INSENSITIVE, &sd, 0}; - HANDLE hFile; - IO_STATUS_BLOCK isb; - if (NT_SUCCESS(NtCreateFile(&hFile, direction, &oa, &isb, 0, 0, FILE_SHARE_READ, FILE_OPEN, 0, 0, 0))) - return hFile; - else - return INVALID_HANDLE_VALUE; + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + InitializeCriticalSection(&::hostCs); + IthInitSystemService(); + GetDebugPrivileges(); + // jichi 12/20/2013: Since I already have a GUI, I don't have to InitCommonControls() + //Used by timers. + InitCommonControls(); + // jichi 8/24/2013: Create hidden window so that ITH can access timer and events + dummyWindow = CreateWindowW(L"Button", L"InternalWindow", 0, 0, 0, 0, 0, 0, 0, hinstDLL, 0); + break; + case DLL_PROCESS_DETACH: + if (::running) + CloseHost(); + DeleteCriticalSection(&::hostCs); + IthCloseSystemService(); + DestroyWindow(dummyWindow); + break; + default: + break; + } + return true; } enum { IHS_SIZE = 0x80 }; -enum { IHS_BUFF_SIZE = IHS_SIZE - sizeof(HookParam) }; +enum { IHS_BUFF_SIZE = IHS_SIZE - sizeof(HookParam) }; struct InsertHookStruct { - SendParam sp; - BYTE name_buffer[IHS_SIZE]; + SendParam sp; + BYTE name_buffer[IHS_SIZE]; }; -IHFSERVICE void IHFAPI Host_Init() +IHFSERVICE bool IHFAPI OpenHost() { - InitializeCriticalSection(&::cs); - GetDebugPriv(); + bool success; + EnterCriticalSection(&::hostCs); + + preventDuplicationMutex = CreateMutexW(nullptr, TRUE, ITH_SERVER_MUTEX); + if (GetLastError() == ERROR_ALREADY_EXISTS || ::running) + { + GROWL_WARN(L"I am sorry that this game is attached by some other VNR ><\nPlease restart the game and try again!"); + success = false; + } + else + { + ::running = true; + ::settings = new Settings; + ::man = new HookManager; + InitializeCriticalSection(&detachCs); + ::hookMutex = CreateMutexW(nullptr, FALSE, ITH_SERVER_HOOK_MUTEX); + success = true; + } + LeaveCriticalSection(&::hostCs); + return success; } -IHFSERVICE void IHFAPI Host_Destroy() +IHFSERVICE void IHFAPI StartHost() { - InitializeCriticalSection(&::cs); + CreateNewPipe(); + ::pipeExistsEvent = CreateEventW(nullptr, TRUE, TRUE, ITH_PIPEEXISTS_EVENT); } -IHFSERVICE BOOL IHFAPI Host_Open() +IHFSERVICE void IHFAPI CloseHost() { - BOOL result = false; - EnterCriticalSection(&::cs); - DWORD present; - hServerMutex = IthCreateMutex(ITH_SERVER_MUTEX, 1, &present); - if (present) - //MessageBox(0,L"Already running.",0,0); - // jichi 8/24/2013 - GROWL_WARN(L"I am sorry that this game is attached by some other VNR ><\nPlease restart the game and try again!"); - else if (!::running) { - ::running = true; - ::settings = new Settings; - ::man = new HookManager; - //cmdq = new CommandQueue; - InitializeCriticalSection(&detach_cs); - - ::hHookMutex = IthCreateMutex(ITH_SERVER_HOOK_MUTEX, FALSE); - result = true; - } - LeaveCriticalSection(&::cs); - return result; + EnterCriticalSection(&::hostCs); + if (::running) + { + ::running = FALSE; + ResetEvent(::pipeExistsEvent); + delete man; + delete settings; + CloseHandle(::hookMutex); + CloseHandle(preventDuplicationMutex); + CloseHandle(::pipeExistsEvent); + DeleteCriticalSection(&detachCs); + } + LeaveCriticalSection(&::hostCs); } -IHFSERVICE DWORD IHFAPI Host_Start() +IHFSERVICE bool IHFAPI InjectProcessById(DWORD processId, DWORD timeout) { - //IthBreak(); - CreateNewPipe(); - ::hPipeExist = IthCreateEvent(ITH_PIPEEXISTS_EVENT); - NtSetEvent(::hPipeExist, nullptr); - return 0; -} + bool success = true; -IHFSERVICE DWORD IHFAPI Host_Close() -{ - BOOL result = FALSE; - EnterCriticalSection(&::cs); - if (::running) { - ::running = FALSE; - HANDLE hRecvPipe = IthOpenPipe(recv_pipe, GENERIC_WRITE); - NtClose(hRecvPipe); - NtClearEvent(::hPipeExist); - //delete cmdq; - delete man; - delete settings; - NtClose(::hHookMutex); - NtClose(hServerMutex); - NtClose(::hPipeExist); - DeleteCriticalSection(&detach_cs); - result = TRUE; - } - LeaveCriticalSection(&::cs); - return result; -} + if (processId == GetCurrentProcessId()) + { + success = false; + } -IHFSERVICE DWORD IHFAPI Host_GetPIDByName(LPCWSTR pwcTarget) -{ - DWORD dwSize = 0x20000, - dwExpectSize = 0; - LPVOID pBuffer = 0; - SYSTEM_PROCESS_INFORMATION *spiProcessInfo; - DWORD dwPid = 0; - DWORD dwStatus; + CloseHandle(CreateMutexW(nullptr, FALSE, CONCAT_STR_NUM(ITH_HOOKMAN_MUTEX_, processId))); + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + man->AddConsoleOutput(L"already locked"); + success = false; + } - NtAllocateVirtualMemory(NtCurrentProcess(), &pBuffer, 0, &dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - dwStatus = NtQuerySystemInformation(SystemProcessInformation, pBuffer, dwSize, &dwExpectSize); - if (!NT_SUCCESS(dwStatus)) { - NtFreeVirtualMemory(NtCurrentProcess(),&pBuffer,&dwSize,MEM_RELEASE); - if (dwStatus != STATUS_INFO_LENGTH_MISMATCH || dwExpectSize < dwSize) - return 0; - dwSize = (dwExpectSize | 0xFFF) + 0x4001; // - pBuffer = 0; - NtAllocateVirtualMemory(NtCurrentProcess(), &pBuffer, 0, &dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - dwStatus = NtQuerySystemInformation(SystemProcessInformation, pBuffer, dwSize, &dwExpectSize); - if (!NT_SUCCESS(dwStatus)) goto _end; - } + HMODULE textHooker = LoadLibraryExW(L"vnrhook", nullptr, DONT_RESOLVE_DLL_REFERENCES); + if (textHooker == nullptr) + { + success = false; + } + wchar_t textHookerPath[MAX_PATH]; + unsigned int textHookerPathSize = GetModuleFileNameW(textHooker, textHookerPath, MAX_PATH) * 2 + 2; + FreeLibrary(textHooker); - for (spiProcessInfo = (SYSTEM_PROCESS_INFORMATION *)pBuffer; spiProcessInfo->dNext;) { - spiProcessInfo = (SYSTEM_PROCESS_INFORMATION *) - ((DWORD)spiProcessInfo + spiProcessInfo -> dNext); - if (_wcsicmp(pwcTarget, spiProcessInfo -> usName.Buffer) == 0) { - dwPid = spiProcessInfo->dUniqueProcessId; - break; - } - } - if (!dwPid) - DOUT("pid not found"); - //if (dwPid == 0) ConsoleOutput(ErrorNoProcess); -_end: - NtFreeVirtualMemory(NtCurrentProcess(),&pBuffer,&dwSize,MEM_RELEASE); - return dwPid; -} + HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); + if (processHandle == INVALID_HANDLE_VALUE || processHandle == nullptr) + { + success = false; + } -IHFSERVICE bool IHFAPI Host_InjectByPID(DWORD pid) -{ - WCHAR str[0x80]; - if (!::running) - return 0; - if (pid == current_process_id) { - //ConsoleOutput(SelfAttach); - DOUT("refuse to inject myself"); - return false; - } - if (man->GetProcessRecord(pid)) { - //ConsoleOutput(AlreadyAttach); - DOUT("already attached"); - return false; - } - swprintf(str, ITH_HOOKMAN_MUTEX_ L"%d", pid); - DWORD s; - NtClose(IthCreateMutex(str, 0, &s)); - if (s) { - DOUT("already locked"); - return false; - } - CLIENT_ID id; - OBJECT_ATTRIBUTES oa = {}; - HANDLE hProc; - id.UniqueProcess = pid; - id.UniqueThread = 0; - oa.uLength = sizeof(oa); - if (!NT_SUCCESS(NtOpenProcess(&hProc, - PROCESS_QUERY_INFORMATION| - PROCESS_CREATE_THREAD| - PROCESS_VM_OPERATION| - PROCESS_VM_READ| - PROCESS_VM_WRITE, - &oa, &id))) { - //ConsoleOutput(ErrorOpenProcess); - DOUT("failed to open process"); - return false; - } + void* loadLibraryStartRoutine = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW"); - //if (!engine) - // engine = ITH_USE_XP_DLLS ? ITH_ENGINE_XP_DLL : ITH_ENGINE_DLL; - bool ok = Inject(hProc); - //NtClose(hProc); //already closed - if (!ok) { - DOUT("inject failed"); - return false; - } - //swprintf(str, FormatInject, pid, module); - //ConsoleOutput(str); - DOUT("inject succeed"); - return true; + if (success) + { + if (LPVOID remoteData = VirtualAllocEx(processHandle, nullptr, textHookerPathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) + { + if (WriteProcessMemory(processHandle, remoteData, textHookerPath, textHookerPathSize, nullptr)) + { + if (HANDLE thread = CreateRemoteThread(processHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)loadLibraryStartRoutine, remoteData, 0, nullptr)) + { + WaitForSingleObject(thread, timeout); + CloseHandle(thread); + } + else + { + success = false; + } + } + else + { + success = false; + } + VirtualFreeEx(processHandle, remoteData, textHookerPathSize, MEM_RELEASE); + } + else + { + success = false; + } + } + + if (!success) + { + man->AddConsoleOutput(L"error: could not inject"); + } + + CloseHandle(processHandle); + return success; } // jichi 7/16/2014: Test if process is valid before creating remote threads // See: http://msdn.microsoft.com/en-us/library/ms687032.aspx -static bool isProcessTerminated(HANDLE hProc) -{ return WAIT_OBJECT_0 == ::WaitForSingleObject(hProc, 0); } -//static bool isProcessRunning(HANDLE hProc) -//{ return WAIT_TIMEOUT == ::WaitForSingleObject(hProc, 0); } +static bool isProcessTerminated(HANDLE processHandle) +{ + return WAIT_OBJECT_0 == ::WaitForSingleObject(processHandle, 0); +} -// jichi 7/16/2014: Test if process is valid before creating remote threads -//static bool isProcessRunning(DWORD pid) -//{ -// bool ret = false; -// HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); -// if (hProc) { -// DWORD status; -// if (::GetExitCodeProcess(hProc, &status)) { -// ret = status == STILL_ACTIVE; -// ::CloseHandle(hProc); -// } else -// ret = true; -// } -// return ret; -//} - -IHFSERVICE bool IHFAPI Host_ActiveDetachProcess(DWORD pid) +IHFSERVICE bool IHFAPI DetachProcessById(DWORD pid) // Todo: clean this up { ITH_SYNC_HOOK; @@ -543,13 +312,6 @@ IHFSERVICE bool IHFAPI Host_GetSettings(Settings **p) return false; } -IHFSERVICE bool IHFAPI Host_HijackProcess(DWORD pid) -{ - //ITH_SYNC_HOOK; - HANDLE hCmd = man->GetCmdHandleByPID(pid); - return hCmd && sendCommand(hCmd, HOST_COMMAND_HIJACK_PROCESS); -} - IHFSERVICE DWORD IHFAPI Host_InsertHook(DWORD pid, HookParam *hp, LPCSTR name) { ITH_SYNC_HOOK; diff --git a/vnr/texthook/host/host.h b/vnr/texthook/host/host.h index 8864ade..f503af8 100644 --- a/vnr/texthook/host/host.h +++ b/vnr/texthook/host/host.h @@ -14,14 +14,14 @@ struct HookParam; IHFSERVICE void IHFAPI Host_Init(); IHFSERVICE void IHFAPI Host_Destroy(); -IHFSERVICE DWORD IHFAPI Host_Start(); -IHFSERVICE BOOL IHFAPI Host_Open(); -IHFSERVICE DWORD IHFAPI Host_Close(); +IHFSERVICE void IHFAPI StartHost(); +IHFSERVICE bool IHFAPI OpenHost(); +IHFSERVICE void IHFAPI CloseHost(); IHFSERVICE DWORD IHFAPI Host_GetHookManager(HookManager **hookman); IHFSERVICE bool IHFAPI Host_GetSettings(Settings **settings); IHFSERVICE DWORD IHFAPI Host_GetPIDByName(LPCWSTR pwcTarget); -IHFSERVICE bool IHFAPI Host_InjectByPID(DWORD pid); -IHFSERVICE bool IHFAPI Host_ActiveDetachProcess(DWORD pid); +IHFSERVICE bool IHFAPI InjectProcessById(DWORD pid, DWORD timeout = 5000); +IHFSERVICE bool IHFAPI DetachProcessById(DWORD pid); IHFSERVICE bool IHFAPI Host_HijackProcess(DWORD pid); IHFSERVICE DWORD IHFAPI Host_InsertHook(DWORD pid, HookParam *hp, LPCSTR name = nullptr); IHFSERVICE DWORD IHFAPI Host_ModifyHook(DWORD pid, HookParam *hp); diff --git a/vnr/texthook/host/host_p.h b/vnr/texthook/host/host_p.h index 1645426..a2356a1 100644 --- a/vnr/texthook/host/host_p.h +++ b/vnr/texthook/host/host_p.h @@ -3,6 +3,7 @@ // 8/24/2013 jichi // Branch IHF/main.h, rev 111 #include +#include #define GLOBAL extern #define SHIFT_JIS 0x3A4 @@ -23,12 +24,12 @@ GLOBAL HookManager *man; GLOBAL SettingManager *setman; GLOBAL WCHAR recv_pipe[]; GLOBAL WCHAR command[]; -GLOBAL HANDLE hPipeExist; +GLOBAL HANDLE pipeExistsEvent; GLOBAL DWORD split_time, cyclic_remove, clipboard_flag, global_filter; -GLOBAL CRITICAL_SECTION detach_cs; +GLOBAL CRITICAL_SECTION detachCs; DWORD WINAPI RecvThread(LPVOID lpThreadParameter); DWORD WINAPI CmdThread(LPVOID lpThreadParameter); diff --git a/vnr/texthook/host/pipe.cc b/vnr/texthook/host/pipe.cc index eaa1a30..748dc06 100644 --- a/vnr/texthook/host/pipe.cc +++ b/vnr/texthook/host/pipe.cc @@ -69,9 +69,9 @@ const BYTE *Filter(const BYTE *str, int len) wchar_t recv_pipe[] = ITH_TEXT_PIPE; wchar_t command_pipe[] = ITH_COMMAND_PIPE; -CRITICAL_SECTION detach_cs; // jichi 9/27/2013: also used in main +CRITICAL_SECTION detachCs; // jichi 9/27/2013: also used in main //HANDLE hDetachEvent; -extern HANDLE hPipeExist; +extern HANDLE pipeExistsEvent; void CreateNewPipe() { @@ -176,7 +176,7 @@ void DetachFromProcess(DWORD pid) //NtSetEvent(hDetachEvent, 0); if (::running) - NtSetEvent(hPipeExist, 0); + NtSetEvent(pipeExistsEvent, 0); } // jichi 9/27/2013: I don't need this @@ -291,7 +291,7 @@ DWORD WINAPI RecvThread(LPVOID lpThreadParameter) } } - EnterCriticalSection(&detach_cs); + EnterCriticalSection(&detachCs); HANDLE hDisconnect = IthCreateEvent(nullptr); @@ -310,7 +310,7 @@ DWORD WINAPI RecvThread(LPVOID lpThreadParameter) //NtClearEvent(hDetachEvent); - LeaveCriticalSection(&detach_cs); + LeaveCriticalSection(&detachCs); delete[] buff; if (::running) diff --git a/vnr/texthook/host/textthread.cc b/vnr/texthook/host/textthread.cc index 6f200c2..53fe518 100644 --- a/vnr/texthook/host/textthread.cc +++ b/vnr/texthook/host/textthread.cc @@ -31,7 +31,7 @@ static DWORD MIN_REDETECT = 0x80; DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr,DWORD max); extern Settings *settings; -extern HWND hMainWnd; +extern HWND dummyWindow; void CALLBACK NewLineBuff(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { KillTimer(hwnd,idEvent); @@ -103,7 +103,7 @@ TextThread::TextThread(DWORD id, DWORD hook, DWORD retn, DWORD spl, WORD num) : } TextThread::~TextThread() { - //KillTimer(hMainWnd,timer); + //KillTimer(dummyWindow,timer); RepeatCountNode *t = head, *tt; while (t) { @@ -744,9 +744,9 @@ void TextThread::SetNewLineTimer() { if (thread_number == 0) // jichi 10/27/2013: Not used - timer = 0; //SetTimer(hMainWnd,(UINT_PTR)this, settings->splittingInterval, NewLineConsole); + timer = 0; //SetTimer(dummyWindow,(UINT_PTR)this, settings->splittingInterval, NewLineConsole); else - timer = SetTimer(hMainWnd, (UINT_PTR)this, settings->splittingInterval, NewLineBuff); + timer = SetTimer(dummyWindow, (UINT_PTR)this, settings->splittingInterval, NewLineBuff); } DWORD TextThread::GetThreadString(LPSTR str, DWORD max) diff --git a/vnr/vnrhook/CMakeLists.txt b/vnr/vnrhook/CMakeLists.txt index b1c1986..74df062 100644 --- a/vnr/vnrhook/CMakeLists.txt +++ b/vnr/vnrhook/CMakeLists.txt @@ -59,13 +59,8 @@ set(vnrhook_src ${PROJECT_SOURCE_DIR}/memdbg/memsearch.h ${PROJECT_SOURCE_DIR}/ntinspect/ntinspect.cc ${PROJECT_SOURCE_DIR}/ntinspect/ntinspect.h - ${PROJECT_SOURCE_DIR}/winkey/winkey.h ${PROJECT_SOURCE_DIR}/winversion/winversion.cc ${PROJECT_SOURCE_DIR}/winversion/winversion.h - ${PROJECT_SOURCE_DIR}/winseh/winseh.h - ${PROJECT_SOURCE_DIR}/winseh/winseh.cc - ${PROJECT_SOURCE_DIR}/winseh/winseh_safe.cc - ${PROJECT_SOURCE_DIR}/winseh/safeseh.asm ${PROJECT_SOURCE_DIR}/mono/monoobject.h ${PROJECT_SOURCE_DIR}/mono/monotype.h ) diff --git a/vnr/vnrhook/src/hijack/texthook.cc b/vnr/vnrhook/src/hijack/texthook.cc index 27f4f20..544e9c9 100644 --- a/vnr/vnrhook/src/hijack/texthook.cc +++ b/vnr/vnrhook/src/hijack/texthook.cc @@ -15,7 +15,6 @@ #include "src/main.h" #include "include/const.h" #include "ithsys/ithsys.h" -#include "winkey/winkey.h" #include "disasm/disasm.h" //#include "winseh/winseh.h" diff --git a/vnr/windbg/hijack.cc b/vnr/windbg/hijack.cc deleted file mode 100644 index dafe371..0000000 --- a/vnr/windbg/hijack.cc +++ /dev/null @@ -1,89 +0,0 @@ -// hijack.cc -// 1/27/2013 jichi -#include "windbg/hijack.h" -#include "windbg/windbg_p.h" - -#ifdef _MSC_VER -# pragma warning (disable:4996) // C4996: use POSIX function (stricmp) -#endif // _MSC_VER - -//#define DEBUG "winsec" -#include "sakurakit/skdebug.h" - -WINDBG_BEGIN_NAMESPACE - -// - Inline Hook - -// See: http://asdf.wkeya.com/code/apihook6.html -PVOID overrideFunctionA(HMODULE stealFrom, LPCSTR oldFunctionModule, LPCSTR functionName, LPCVOID newFunction) -{ - if (!stealFrom) - return nullptr; - //HMODULE oldModule = GetModuleHandleA(oldFunctionModule); - //if (!oldModule) - // return nullptr; - //void *originalAddress = GetProcAddress(oldModule, functionName); - LPVOID originalAddress = details::getModuleFunctionAddressA(functionName, oldFunctionModule); - if (!originalAddress) - return nullptr; - IMAGE_DOS_HEADER *dosHeader = reinterpret_cast(stealFrom); - char *base = reinterpret_cast(stealFrom); - if (::IsBadReadPtr(dosHeader, sizeof(IMAGE_DOS_HEADER)) || dosHeader->e_magic != IMAGE_DOS_SIGNATURE) - return nullptr; - IMAGE_NT_HEADERS *ntHeader = - reinterpret_cast(base + dosHeader->e_lfanew); - if (::IsBadReadPtr(ntHeader, sizeof(IMAGE_NT_HEADERS)) || ntHeader->Signature != IMAGE_NT_SIGNATURE) - return nullptr; - if (!ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) - return nullptr; - // See: http://msdn.microsoft.com/en-us/magazine/cc301808.aspx - IMAGE_IMPORT_DESCRIPTOR *import = - reinterpret_cast(base + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); - - // scan memory - // TODO: add a maximum loop counter here! - while (import->Name) { - char *name = base + import->Name; - if (!::stricmp(name, oldFunctionModule)) - break; - import++; - } - if (!import->Name) - return nullptr; - IMAGE_THUNK_DATA *thunk = reinterpret_cast(base + import->FirstThunk); - while (thunk->u1.Function) { - if ((ULONG_PTR)thunk->u1.Function == (ULONG_PTR)originalAddress) { - ULONG_PTR *addr = reinterpret_cast(&thunk->u1.Function); - - // See: http://asdf.wkeya.com/code/apihook6.html - // Inline hook mechanism: - // - // LPVOID InlineHook3( PUINT8 mem, DWORD dwLen, PUINT8 pfOld, PUINT8 pfNew ) - // { - // DWORD dwOldProtect; - // VirtualProtect( ( PUINT8 )( pfOld ), dwLen, PAGE_READWRITE, &dwOldProtect ); - // // 関数のエントリーから指定したbyte数をメモリの前方にコピー - // // メモリの数byte後方からオリジナルへのジャンプを作成 - // // 指定の関数アドレスから5byteをフックへのjmp命令に書き換え - // VirtualProtect( ( PUINT8 )( pfOld ), dwLen, dwOldProtect, &dwOldProtect ); - // return ( PVOID )mem; - // } - - MEMORY_BASIC_INFORMATION mbi; - if (::VirtualQuery((LPVOID)addr, &mbi, sizeof(mbi)) == sizeof(mbi)) { - DWORD dwOldProtect; - if (::VirtualProtect(mbi.BaseAddress, ((ULONG_PTR)addr + 8)-(ULONG_PTR)mbi.BaseAddress, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { - *addr = (ULONG_PTR)newFunction; - ::VirtualProtect(mbi.BaseAddress, ((ULONG_PTR)addr + 8)-(ULONG_PTR)mbi.BaseAddress, dwOldProtect, &dwOldProtect); - return originalAddress; - } - } - - } - thunk++; - } - return nullptr; -} - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/hijack.h b/vnr/windbg/hijack.h deleted file mode 100644 index 7896195..0000000 --- a/vnr/windbg/hijack.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -// hijack.h -// 1/27/2013 jichi - -#include "windbg/windbg.h" -#include - -WINDBG_BEGIN_NAMESPACE - -/** - * Replace the named function entry with the new one. - * @param stealFrom instance of target module - * @param oldFunctionModule TODO - * @param functionName name of the target function - * @return the orignal address if succeed, else nullptr - * - * See: http://www.codeproject.com/KB/DLL/DLL_Injection_tutorial.aspx - */ -PVOID overrideFunctionA(_In_ HMODULE stealFrom, _In_ LPCSTR oldFunctionModule, - _In_ LPCSTR functionName, _In_ LPCVOID newFunction); - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/inject.cc b/vnr/windbg/inject.cc deleted file mode 100644 index c9e9078..0000000 --- a/vnr/windbg/inject.cc +++ /dev/null @@ -1,167 +0,0 @@ -// inject.cc -// 1/27/2013 jichi -#include "windbg/inject.h" -#include "windbg/windbg_p.h" -#include // for wcslen - -//#define DEBUG "windbg::inject" -#include "sakurakit/skdebug.h" - -WINDBG_BEGIN_NAMESPACE - -// - Remote Injection - - -BOOL InjectFunction1(LPCVOID addr, LPCVOID data, SIZE_T dataSize, DWORD pid, HANDLE hProcess, INT timeout) -{ - DOUT("enter: pid =" << pid); - if (hProcess == INVALID_HANDLE_VALUE && pid) { - hProcess = ::OpenProcess(PROCESS_INJECT_ACCESS, FALSE, pid); - // TODO: Privilege elevation is not implemented. See: skwinsec.py. - //if (!hProcess) { - // priv = SkProcessElevator('SeDebugPrivilege') - // if not priv.isEmpty(): - // handle = win32api.OpenProcess(PROCESS_INJECT_ACCESS, 0, pid) - //} - } - if (hProcess == INVALID_HANDLE_VALUE) { - DOUT("exit: error: failed to get process handle"); - return FALSE; - } - - BOOL ret = FALSE; - if (LPVOID remoteData = ::VirtualAllocEx(hProcess, nullptr, dataSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)) { - if (::WriteProcessMemory(hProcess, remoteData, data, dataSize, nullptr)) - if (HANDLE hThread = ::CreateRemoteThread( - hProcess, - nullptr, 0, - reinterpret_cast(addr), - remoteData, - 0, nullptr)) { - ::WaitForSingleObject(hThread, timeout); - ::CloseHandle(hThread); - ret = TRUE; - } - ::VirtualFreeEx(hProcess, remoteData, dataSize, MEM_RELEASE); - } - ::CloseHandle(hProcess); - DOUT("exit: ret =" << ret); - return ret; -} - -BOOL injectDllW(LPCWSTR dllPath, DWORD pid, HANDLE hProcess, INT timeout) -{ - DOUT("enter: pid =" << pid); - LPCVOID fun = details::getModuleFunctionAddressA("LoadLibraryW", "kernel32.dll"); - if (!fun) { - DOUT("exit error: cannot find function"); - return FALSE; - } - LPCVOID data = dllPath; - SIZE_T dataSize = ::wcslen(dllPath) * 2 + 2; // L'\0' - BOOL ok = InjectFunction1(fun, data, dataSize, pid, hProcess, timeout); - DOUT("exit: ret =" << ok); - return ok; -} - -BOOL ejectDll(HANDLE hDll, DWORD pid, HANDLE hProcess, INT timeout) -{ - DOUT("enter: pid =" << pid); - LPCVOID fun = details::getModuleFunctionAddressA("FreeLibrary", "kernel32.dll"); - if (!fun) { - DOUT("exit error: cannot find function"); - return FALSE; - } - LPCVOID data = &hDll; - SIZE_T dataSize = sizeof(hDll); - BOOL ok = InjectFunction1(fun, data, dataSize, pid, hProcess, timeout); - DOUT("exit: ret =" << ok); - return ok; -} - -WINDBG_END_NAMESPACE - -// EOF - -/* -enum { CREATE_THREAD_ACCESS = (PROCESS_CREATE_THREAD | - PROCESS_QUERY_INFORMATION | - PROCESS_VM_OPERATION | - PROCESS_VM_WRITE | - PROCESS_VM_READ ) }; - - -int InjectDll(HANDLE hProcess, HINSTANCE hInst) { - HANDLE hThread; - - wchar_t dllFile[2*MAX_PATH]; - if (GetModuleFileNameW(hInst, dllFile, sizeof(dllFile)/2) > sizeof(dllFile)/2) return 0; - - void *loadLibraryW = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"); - if (!loadLibraryW) return 0; - - wchar_t *name; - if (!(name = wcsrchr(dllFile, '\\'))) return 0; - name ++; - wcscpy(name, DLL_NAME); - if (GetFileAttributes(dllFile) == INVALID_FILE_ATTRIBUTES) return 0; - - size_t len = sizeof(wchar_t)*(1+wcslen(dllFile)); - void *remoteString = (LPVOID)VirtualAllocEx(hProcess, - NULL, - len, - MEM_RESERVE|MEM_COMMIT, - PAGE_READWRITE - ); - if (remoteString) { - if (WriteProcessMemory(hProcess, (LPVOID)remoteString, dllFile, len, NULL)) { - if (hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)loadLibraryW, (LPVOID)remoteString, 0,0)) { - WaitForSingleObject(hThread, 3000); - CloseHandle(hThread); - VirtualFreeEx(hProcess, remoteString, len, MEM_FREE); - // Make sure it's injected before resuming. - return 1; - } - } - VirtualFreeEx(hProcess, remoteString, len, MEM_FREE); - } - return 0; -} - -int getPriv(const char * name) { - HANDLE hToken; - LUID seValue; - TOKEN_PRIVILEGES tkp; - - if (!LookupPrivilegeValueA(NULL, name, &seValue) || - !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { - return 0; - } - - tkp.PrivilegeCount = 1; - tkp.Privileges[0].Luid = seValue; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - int res = AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL); - - CloseHandle(hToken); - return res; -} - -inline int getDebugPriv() { - return getPriv("SeDebugPrivilege"); -} - -int InjectIntoProcess(int pid) { - HANDLE hProcess = OpenProcess(CREATE_THREAD_ACCESS, 0, pid); - if (hProcess == 0) { - getDebugPriv(); - hProcess = OpenProcess(CREATE_THREAD_ACCESS, 0, pid); - if (!hProcess) return 0; - } - - int out = InjectDll(hProcess); - - CloseHandle(hProcess); - return out; -} -*/ diff --git a/vnr/windbg/inject.h b/vnr/windbg/inject.h deleted file mode 100644 index 46878c7..0000000 --- a/vnr/windbg/inject.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -// inject.h -// 1/27/2013 jichi - -#include "windbg/windbg.h" - -#include - -WINDBG_BEGIN_NAMESPACE - -enum { PROCESS_INJECT_ACCESS = PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ }; -enum { INJECT_TIMEOUT = 3000 }; // wait at most 3 seconds for creating remote threads - -/** - * Inject function with 1 argument - * Either pid or the process handle should be specified - * @param addr LONG function memory address - * @param arg LPVOID arg1 data - * @param argSize int arg1 data size - * @param pid process id - * @param hProcess process handle - * @param timeout msec - * @return BOOL - */ -BOOL injectFunction1(_In_ LPCVOID addr, _In_ LPCVOID arg, _In_ SIZE_T argSize, - _In_ DWORD pid = 0, _In_ HANDLE hProcess = INVALID_HANDLE_VALUE, - _In_ INT timeout = INJECT_TIMEOUT); - -/** - * Either pid or the process handle should be specified - * @param dllpath ABSOLUTE path to dll - * @param pid process id - * @param hProcess process handle - * @param timeout msec - * @return BOOL - */ -BOOL injectDllW(_In_ LPCWSTR dllPath, - _In_ DWORD pid = 0, _In_ HANDLE hProcess = INVALID_HANDLE_VALUE, - _In_ INT timeout = INJECT_TIMEOUT); - -/** - * Either pid or the process handle should be specified - * @param hDll dll module handle - * @param pid process id - * @param hProcess process handle - * @param timeout msec - * @return BOOL - */ -BOOL ejectDll(_In_ HANDLE hDll, - _In_ DWORD pid = 0, _In_ HANDLE hProcess = INVALID_HANDLE_VALUE, - _In_ INT timeout = INJECT_TIMEOUT); - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/unload.cc b/vnr/windbg/unload.cc deleted file mode 100644 index a09ecb2..0000000 --- a/vnr/windbg/unload.cc +++ /dev/null @@ -1,22 +0,0 @@ -// unload.cc -// 5/2/2014 jichi -#include "windbg/unload.h" - -WINDBG_BEGIN_NAMESPACE - -EXTERN_C IMAGE_DOS_HEADER __ImageBase; -// See: http://stackoverflow.com/questions/3410130/dll-unloading-itself -BOOL unloadCurrentModule() -{ - auto fun = ::FreeLibrary; - //auto fun = ::LdrUnloadDll; - if (HANDLE h = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fun, &__ImageBase, 0, NULL)) { - ::CloseHandle(h); - return TRUE; - } - return FALSE; -} - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/unload.h b/vnr/windbg/unload.h deleted file mode 100644 index 9a90055..0000000 --- a/vnr/windbg/unload.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -// unload.h -// 5/2/2014 jichi - -#include "windbg/windbg.h" -#include - -WINDBG_BEGIN_NAMESPACE - -/** - * Unload current injected DLL. - * @return BOOL - */ -BOOL unloadCurrentModule(); - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/util.cc b/vnr/windbg/util.cc deleted file mode 100644 index 43a2dbe..0000000 --- a/vnr/windbg/util.cc +++ /dev/null @@ -1,61 +0,0 @@ -// windbg/util.cc -// 1/27/2013 jichi -#include "windbg/util.h" -#include -#include -#include - -WINDBG_BEGIN_NAMESPACE - -class ThreadsSuspenderPrivate -{ -public: - std::list threads; -}; - -ThreadsSuspender::ThreadsSuspender(bool autoSuspend) - : d_(new D) -{ if (autoSuspend) suspend(); } - -ThreadsSuspender::~ThreadsSuspender() -{ - resume(); - delete d_; -} - -void ThreadsSuspender::suspend() -{ - HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if (hSnap == INVALID_HANDLE_VALUE) - return; - THREADENTRY32 entry; - entry.dwSize = sizeof(entry); - DWORD pid = ::GetCurrentProcessId(); - DWORD tid = ::GetCurrentThreadId(); - if (::Thread32First(hSnap, &entry)) - do if (entry.dwSize >= 4 * sizeof(DWORD) && entry.th32OwnerProcessID == pid && entry.th32ThreadID != tid) { - if (HANDLE hThread = ::OpenThread(THREAD_SUSPEND_RESUME, 0, entry.th32ThreadID)) { - if (::SuspendThread(hThread) != DWORD(-1)) - d_->threads.push_back(hThread); - else - ::CloseHandle(hThread); - } - entry.dwSize = sizeof(entry); - } while (::Thread32Next(hSnap, &entry)); - ::CloseHandle(hSnap); -} - -void ThreadsSuspender::resume() -{ - if (!d_->threads.empty()) { - BOOST_FOREACH (HANDLE hThread, d_->threads) { - ::ResumeThread(hThread); - ::CloseHandle(hThread); - } - d_->threads.clear(); - } -} - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/util.h b/vnr/windbg/util.h deleted file mode 100644 index bf512fd..0000000 --- a/vnr/windbg/util.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -// windbg/util.h -// 1/27/2013 jichi - -#include "windbg/windbg.h" -#include "sakurakit/skglobal.h" - -#include - -WINDBG_BEGIN_NAMESPACE - -class ThreadsSuspenderPrivate; -/** - * When created, automatically suspends all threads in the current process. - * When destroyed, resume suspended threads. - */ -class ThreadsSuspender -{ - SK_CLASS(ThreadsSuspender) - SK_DISABLE_COPY(ThreadsSuspender) - SK_DECLARE_PRIVATE(ThreadsSuspenderPrivate) - -public: - explicit ThreadsSuspender(bool autoSuspend = true); - ~ThreadsSuspender(); - - void resume(); ///< Manually resume all threads - void suspend(); ///< Manually suspend all threads -}; - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/windbg.h b/vnr/windbg/windbg.h deleted file mode 100644 index 0bb771c..0000000 --- a/vnr/windbg/windbg.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -// windbg.h -// 1/27/2013 jichi - -#ifndef WINDBG_BEGIN_NAMESPACE -# define WINDBG_BEGIN_NAMESPACE namespace WinDbg { -#endif -#ifndef WINDBG_END_NAMESPACE -# define WINDBG_END_NAMESPACE } // namespace WinDbg -#endif - -WINDBG_BEGIN_NAMESPACE -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/windbg/windbg_p.h b/vnr/windbg/windbg_p.h deleted file mode 100644 index a534e58..0000000 --- a/vnr/windbg/windbg_p.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -// windbg_p.h -// 1/27/2013 jichi - -#include "windbg/windbg.h" -#include - -WINDBG_BEGIN_NAMESPACE - -namespace details { // unnamed - -/// Return the address of func in module. -inline FARPROC getModuleFunctionAddressA(LPCSTR func, LPCSTR module = nullptr) -{ return ::GetProcAddress(::GetModuleHandleA(module), func); } - -inline FARPROC getModuleFunctionAddressW(LPCSTR func, LPCWSTR module = nullptr) -{ return ::GetProcAddress(::GetModuleHandleW(module), func); } - -} // unamed namespace details - -WINDBG_END_NAMESPACE - -// EOF diff --git a/vnr/winkey/winkey.h b/vnr/winkey/winkey.h deleted file mode 100644 index d179c30..0000000 --- a/vnr/winkey/winkey.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// winkey.h -// 7/21/2011 - -#include - -#ifndef WINKEY_BEGIN_NAMESPACE -# define WINKEY_BEGIN_NAMESPACE namespace WinKey { -#endif -#ifndef WINKEY_END_NAMESPACE -# define WINKEY_END_NAMESPACE } // namespace WinKey -#endif - - -WINKEY_BEGIN_NAMESPACE - -inline bool isKeyPressed(int vk) { return ::GetKeyState(vk) & 0xf0; } -inline bool isKeyToggled(int vk) { return ::GetKeyState(vk) & 0x0f; } - -inline bool isKeyReturnPressed() { return isKeyPressed(VK_RETURN); } -inline bool isKeyControlPressed() { return isKeyPressed(VK_CONTROL); } -inline bool isKeyShiftPressed() { return isKeyPressed(VK_SHIFT); } -inline bool isKeyAltPressed() { return isKeyPressed(VK_MENU); } -//inline bool sKeyCapslockToggled() { return isKeyToggled(VK_CAPITAL); } -inline bool isKeyWinPressed() { return isKeyPressed(VK_LWIN) || isKeyPressed(VK_RWIN); } - -inline bool isMouseLeftButtonPressed() { return isKeyPressed(VK_LBUTTON); } -inline bool isMouseMiddleButtonPressed() { return isKeyPressed(VK_MBUTTON); } -inline bool isMouseRightButtonPressed() { return isKeyPressed(VK_RBUTTON); } - -WINKEY_END_NAMESPACE diff --git a/vnr/winmaker/winmaker.cc b/vnr/winmaker/winmaker.cc deleted file mode 100644 index d9bbef8..0000000 --- a/vnr/winmaker/winmaker.cc +++ /dev/null @@ -1,46 +0,0 @@ -// winmaker.cc -// 2/1/2013 jichi - -#include "winmaker/winmaker.h" -#include -//#include - -#ifdef _MSC_VER -# pragma warning (disable:4800) // C4800: forcing value to bool -#endif // _MSC_VER - -// See: http://www.codeguru.com/cpp/w-p/dll/tips/article.php/c3635/Tip-Detecting-a-HMODULEHINSTANCE-Handle-Within-the-Module-Youre-Running-In.htm -extern "C" IMAGE_DOS_HEADER __ImageBase; -namespace { // unnamed - inline HMODULE _get_module() { return reinterpret_cast(&__ImageBase); } -} // unnamed - -bool wm_register_hidden_class(LPCWSTR className) -{ - WNDCLASSEX wx = {}; - wx.cbSize = sizeof(wx); - wx.lpfnWndProc = ::DefWindowProc; - wx.hInstance = ::GetModuleHandle(nullptr); - wx.lpszClassName = className; - return ::RegisterClassEx(&wx); -} - -wm_window_t wm_create_hidden_window(LPCWSTR windowName, LPCWSTR className, wm_module_t dllHandle) -{ - //return ::CreateWindowExA(0, className, windowName, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, dllHandle, nullptr); - HINSTANCE module = reinterpret_cast(dllHandle); - if (!module) - module = _get_module(); - return ::CreateWindowEx(0, className, windowName, 0, 0, 0, 0, 0, 0, NULL, module, NULL); -} - -bool wm_destroy_window(wm_window_t hwnd) -{ return ::DestroyWindow(reinterpret_cast(hwnd)); } - - -// EOF -// -//void wm_init() { ::InitCommonControls(); } -//void wm_destroy() {} -//bool wm_destroy_window() { return ::DestroyWindow(hwnd); } - diff --git a/vnr/winmaker/winmaker.h b/vnr/winmaker/winmaker.h deleted file mode 100644 index 9980869..0000000 --- a/vnr/winmaker/winmaker.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -// winmaker.h -// 2/1/2013 jichi - -#include -typedef void *wm_window_t; // HWMD -typedef void *wm_module_t; // HMODULE - -bool wm_register_hidden_class(LPCWSTR className = L"hidden_class"); - -wm_window_t wm_create_hidden_window( - LPCWSTR windowName = L"hidden_window", - LPCWSTR className = L"Button", // bust be one of the common control widgets - wm_module_t dllHandle = nullptr); - -bool wm_destroy_window(wm_window_t hwnd); - -// EOF - -//#ifdef QT_CORE_LIB -//#include -//WId wm_create_hidden_window(const char *className = "Button", const char *windowName = "hidden_window"); diff --git a/vnr/winseh/Makefile b/vnr/winseh/Makefile deleted file mode 100644 index 1c876ae..0000000 --- a/vnr/winseh/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile -# 12/13/2013 jichi -# This file is for Windows only. -# Compile SAFESEH table from the ASM file. -# See: http://stackoverflow.com/questions/19722308/exception-handler-not-called-in-c -# See: http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh -# See: http://msdn.microsoft.com/en-us/library/16aexws6.aspx - -BUILDDIR = ../../../build -OBJ = $(BUILDDIR)/safeseh.obj - -ML = ml -CFLAGS = - -.PHONY: all compile clean - -all: compile - -compile: $(OBJ) - -$(OBJ): safeseh.asm - $(ML) $(CFLAGS) -Fo $@ -c -safeseh $^ - -clean: - -# EOF diff --git a/vnr/winseh/safeseh.asm b/vnr/winseh/safeseh.asm deleted file mode 100644 index d672999..0000000 --- a/vnr/winseh/safeseh.asm +++ /dev/null @@ -1,21 +0,0 @@ -; safeseh.asm -; 12/13/2013 jichi -; see: http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh -; see: http://code.metager.de/source/xref/WebKit/Source/WebCore/platform/win/makesafeseh.asm -; see: http://jpassing.com/2008/05/20/fun-with-low-level-seh/ -.386 -.model flat, stdcall -option casemap :none - -; The symbol name can be found out using: dumpbin /symbols winseh.obj -extern _seh_handler:near ; defined in winseh.cc - -_seh_asm_handler proto -.safeseh _seh_asm_handler - -.code -_seh_asm_handler proc -jmp _seh_handler -_seh_asm_handler endp - -end diff --git a/vnr/winseh/winseh.cc b/vnr/winseh/winseh.cc deleted file mode 100644 index 275589f..0000000 --- a/vnr/winseh/winseh.cc +++ /dev/null @@ -1,52 +0,0 @@ -// winseh.cc -// 12/13/2013 jichi - -#include "winseh/winseh.h" -#include "ntdll/ntdll.h" -//#include - -// - Define global variables - - -seh_dword_t seh_esp[seh_capacity], - seh_eip[seh_capacity], - seh_eh[seh_capacity]; -seh_dword_t seh_count; - -// - Exception handlers - - -// VC 2013: http://msdn.microsoft.com/en-us/library/b6sf5kbd.aspx -// typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) ( -// _In_ PEXCEPTION_RECORD ExceptionRecord, -// _In_ ULONG64 EstablisherFrame, -// _Inout_ PCONTEXT ContextRecord, -// _Inout_ PDISPATCHER_CONTEXT DispatcherContext -// ); -// -// winnt.h: http://www.codemachine.com/downloads/win81/ntdef.h -// typedef -// __drv_sameIRQL -// __drv_functionClass(EXCEPTION_ROUTINE) -// EXCEPTION_DISPOSITION -// NTAPI -// EXCEPTION_ROUTINE ( -// _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord, -// _In_ PVOID EstablisherFrame, -// _In_ struct _CONTEXT *ContextRecord, -// _In_ PVOID DispatcherContext -// ); -extern "C" EXCEPTION_DISPOSITION _seh_handler( // extern C is needed to avoid name hashing in C++ - _In_ PEXCEPTION_RECORD ExceptionRecord, - _In_ PVOID EstablisherFrame, // do not work if I use ULONG64 - _Inout_ PCONTEXT ContextRecord, - _In_ PVOID DispatcherContext) // PDISPATCHER_CONTEXT is not declared in windows.h, use PVOID instead -{ - //assert(::seh_count > 0); - ContextRecord->Esp = ::seh_esp[::seh_count - 1]; - ContextRecord->Eip = ::seh_eip[::seh_count - 1]; - //printf("seh_handler:%i,%x,%x\n", ::seh_count, ContextRecord->Esp, ContextRecord->Eip); - return ::seh_eh[::seh_count - 1] ? - reinterpret_cast(::seh_eh[::seh_count - 1])(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext) : - ExceptionContinueExecution; -} - -// EOF diff --git a/vnr/winseh/winseh.h b/vnr/winseh/winseh.h deleted file mode 100644 index 72997f3..0000000 --- a/vnr/winseh/winseh.h +++ /dev/null @@ -1,154 +0,0 @@ -#pragma once - -// winseh.h -// 12/13/2013 jichi -// See: http://code.metager.de/source/xref/WebKit/Source/WebCore/platform/win/makesafeseh.asm -// See: http://jpassing.com/2008/05/20/fun-with-low-level-seh/ - -#ifdef _MSC_VER -# pragma warning (disable:4733) // C4733: Inline asm assigning to 'FS:0' : handler not registered as safe handler -#endif // _MSC_VER - -#define SEH_RAISE (*(int*)0 = 0) // raise C000005, for debugging only - -// Maximum number of nested SEH -// Default nested function count is 100, see: http://stackoverflow.com/questions/8656089/solution-for-fatal-error-maximum-function-nesting-level-of-100-reached-abor -#ifndef SEH_CAPACITY -# define SEH_CAPACITY 100 -#endif // SEH_CAPACITY - -enum { seh_capacity = SEH_CAPACITY }; - -typedef unsigned long seh_dword_t; // DWORD in - -// 12/13/2013 jichi -// The list implementation is not thread-safe -extern seh_dword_t - seh_count // current number of exception handlers - , seh_handler // extern PEXCEPTION_ROUTINE seh_handler; - , seh_esp[seh_capacity] // LPVOID, current stack - , seh_eip[seh_capacity] // LPVOID, current IP address - , seh_eh[seh_capacity] // EXCEPTION_ROUTINE, current exception handler function address -; - -/** - * Push SEH handler - * @param _label exception recover label which should be the same as seh_pop_ - * @param _eh EXCEPTION_ROUTINE or 0 - * @param _r1 scalar register name, such as eax - * @param _r2 counter register name, such as ecx - * - * Note: __asm prefix is needed to allow inlining macro - * I didn't pushad and popad which seems to be not needed - * - * For SEH, see: - * http://www.codeproject.com/Articles/82701/Win32-Exceptions-OS-Level-Point-of-View - * http://sploitfun.blogspot.com/2012/08/seh-exploit-part1.html - * http://sploitfun.blogspot.com/2012/08/seh-exploit-part2.html - * - * fs:0x0 on Windows is the pointer to ExceptionList - * http://stackoverflow.com/questions/4657661/what-lies-at-fs0x0-on-windows - * - * EPB and ESP - * http://stackoverflow.com/questions/1395591/what-is-exactly-the-base-pointer-and-stack-pointer-to-what-do-they-point - * - * TODO: get sizeof dword instead of hardcode 4 - */ -#define seh_push_(_label, _eh, _r1, _r2) \ - { \ - __asm mov _r1, _eh /* move new handler address */ \ - __asm mov _r2, seh_count /* get current seh counter */ \ - __asm mov dword ptr seh_eh[_r2*4], _r1 /* set recover exception hander */ \ - __asm mov _r1, _label /* move jump label address */ \ - __asm mov dword ptr seh_eip[_r2*4], _r1 /* set recover eip as the jump label */ \ - __asm push seh_handler /* push new safe seh handler */ \ - __asm push fs:[0] /* push old fs:0 */ \ - __asm mov dword ptr seh_esp[_r2*4], esp /* safe current stack address */ \ - __asm mov fs:[0], esp /* change fs:0 to the current stack */ \ - __asm inc seh_count /* increase number of seh */ \ - } - -/** - * Restore old SEH handler - * @param _label exception recover label which should be the same as seh_push_ - */ -#define seh_pop_(_label) \ - { \ - __asm _label: /* the exception recover label */ \ - __asm pop dword ptr fs:[0] /* restore old fs:0 */ \ - __asm add esp, 4 /* pop seh_handler */ \ - __asm dec seh_count /* decrease number of seh */ \ - } - -// Define seh_exit as the shared exit label -#define seh_pop() seh_pop_(seh_exit) -#define seh_push() seh_push_(seh_exit, 0, eax, ecx) // use ecx as counter better than ebx - -/** - * @param _eh EXCEPTION_ROUTINE or 0 - */ -#define seh_push_eh(_eh) seh_push_(seh_exit, _eh, eax, ecx) - -/** - * Wrap the code block with SEH handler - * @param* any code block. The colon for the last expression is optional. - */ -#define seh_with(...) \ - { \ - seh_push() \ - __VA_ARGS__ \ - ; /* allow __VA_ARGS__ to be an expression */ \ - seh_pop() \ - } - -/** - * Wrap the code block with SEH handler - * @param _eh EXCEPTION_ROUTINE or 0 - * @param* any code block. The colon for the last expression is optional. - */ -#define seh_with_eh(_eh, ...) \ - { \ - seh_push_eh(_eh) \ - __VA_ARGS__ \ - ; /* allow __VA_ARGS__ to be an expression */ \ - seh_pop() \ - } - -// EOF - -//#define seh_push_front() \ -// { \ -// __asm mov eax, seh_exit \ -// __asm mov seh_eip, eax \ -// __asm push seh_handler \ -// __asm push fs:[0] \ -// __asm mov seh_esp, esp \ -// __asm mov fs:[0], esp \ -// } -// -//#define seh_pop_front() \ -// { \ -// __asm seh_exit: \ -// __asm mov eax, [esp] \ -// __asm mov fs:[0], eax \ -// __asm add esp, 8 \ -// } -// -//#define seh_push_back() \ -// { \ -// __asm mov eax, seh_exit \ -// __asm mov ecx, seh_capacity - 1 \ -// __asm mov DWORD PTR seh_eip[ecx*4], eax \ -// __asm push seh_handler \ -// __asm push fs:[0] \ -// __asm mov DWORD PTR seh_esp[ecx*4], esp \ -// __asm mov fs:[0], esp \ -// } -// -//#define seh_pop_back() \ -// { \ -// __asm seh_exit: \ -// __asm mov eax, [esp] \ -// __asm mov fs:[0], eax \ -// __asm add esp, 8 \ -// } diff --git a/vnr/winseh/winseh_safe.cc b/vnr/winseh/winseh_safe.cc deleted file mode 100644 index 69c6d14..0000000 --- a/vnr/winseh/winseh_safe.cc +++ /dev/null @@ -1,10 +0,0 @@ -// winseh_safe.cc -// 12/13/2013 jichi -// See: http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh - -#include "winseh/winseh.h" - -extern "C" int __stdcall _seh_asm_handler(); -seh_dword_t seh_handler = reinterpret_cast(_seh_asm_handler); - -// EOF diff --git a/vnr/winseh/winseh_unsafe.cc b/vnr/winseh/winseh_unsafe.cc deleted file mode 100644 index 303a41a..0000000 --- a/vnr/winseh/winseh_unsafe.cc +++ /dev/null @@ -1,11 +0,0 @@ -// winseh_unsafe.cc -// 12/13/2013 jichi -// See: http://stackoverflow.com/questions/19722308/exception-handler-not-called-in-c - -#include "winseh/winseh.h" -#include - -extern "C" EXCEPTION_DISPOSITION _seh_handler(PEXCEPTION_RECORD, PVOID, PCONTEXT, PVOID); -seh_dword_t seh_handler = reinterpret_cast(_seh_handler); - -// EOF diff --git a/vnr/wintimer/wintimer.cc b/vnr/wintimer/wintimer.cc deleted file mode 100644 index b8c22e0..0000000 --- a/vnr/wintimer/wintimer.cc +++ /dev/null @@ -1,49 +0,0 @@ -// wintimer.cc -// 6/6/2012 jichi - -#include "wintimer/wintimer.h" - -//#define DEBUG "wintimer.cc" -#include "sakurakit/skdebug.h" -#include -WINTIMER_BEGIN_NAMESPACE - -void WinTimer::singleShot(int msecs, const function_type &f, WId parent) -{ - Self *t = new Self(parent); - t->setInterval(msecs); - t->setSingleShot(true); - t->setFunction([=] { // Copy function f instead of pass by reference. - f(); - delete t; - }); - t->start(); -} - -WINTIMER_END_NAMESPACE - -// EOF - -/* -// - Single shot - - -namespace { // unnamed - -class apply_delete -{ - typedef WinTimer::function_type function_type; - function_type f_; - WinTimer *t_; -public: - apply_delete(const function_type &f, WinTimer *t) - : f_(f), t_(t) { Q_ASSERT(t); } - - void operator()() - { - f_(); - delete t_; - } -}; - -} // unnamed namespace -*/ diff --git a/vnr/wintimer/wintimer.h b/vnr/wintimer/wintimer.h deleted file mode 100644 index 8605854..0000000 --- a/vnr/wintimer/wintimer.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -// wintimer.h -// 6/6/2012 jichi -// -// A light-weighted native windows timer as a replacement of QTimer from Qt. -// Implementation is based on Windows Messaging. A visible parent hwnd is required. -// -// This timer is critical where QTimer or event loop are not available, or need to -// warp to different event loop. Some usage cases follow: -// - Used by texthook as a replacement of QTimer in non-QThread -// - Used by qapplicationloader to implement pseudo event loop -// - Used by winhook to synchronize with window event loop across threads - -#include "wintimer/wintimerbase.h" -#include - -/** - * @brief A light-weighted native windows timer as a replacement of QTimer. - * - * Needed when in a thread where event loop is not accessible. - * Implemented using extensive inlining over pimp, so that the entire class - * could be put on the stack without heap. - * - * Each timer requires an valid visible window's handle to synchronize with. - * Either specify the window handle with the parent window or a global window. - */ -class WinTimer : protected WinTimerBase -{ - SK_EXTEND_CLASS(WinTimer, WinTimerBase) - SK_DISABLE_COPY(WinTimer) - - // - Construction - -public: - //typedef std::function function_type; - using Base::function_type; ///< std::function - - /// Default parent window of all timers. - static WId globalWindow() { return Base::globalWindow; } - static void setGlobalWindow(WId winId) { Base::globalWindow = winId; } - - //static WId createHiddenWindow(); - -public: - /// Construct a timer with the parent window handle. - explicit WinTimer(WId parentWindow = 0) { setParentWindow(parentWindow); } - - static void singleShot(int msecs, const function_type &f, WId parent = 0); - - // - Properties - -public: - using Base::isActive; - using Base::isSingleShot; - - void setSingleShot(bool t) { Base::singleShot = t; } - - //bool isEmpty() const { return Base::function.empty(); } - - WId parentWindow() const { return Base::parentWindow; } - void setParentWindow(WId winId) { Base::parentWindow = winId ? winId : Base::globalWindow; } - - int interval() const { return Base::interval; } - void setInterval(int msecs) { Base::interval = msecs; } - - /// Timeout callback when trigger. - void setFunction(const function_type &f) { Base::function = f; } - - /// @overload Set callback to a class method - template - void setMethod(Class *obj, Member mfunc) - { setFunction(boost::bind(mfunc, obj)); } - - /// @overload Set callback to a const class method - template - void setMethod(const Class *obj, Member mfunc) - { setFunction(boost::bind(mfunc, obj)); } - - // - Actions - -public: - /// Start TimerProc - using Base::start; - - /// Stop TimerProc - using Base::stop; - - /// Reset interval and start TimerProc - void start(int interval) { setInterval(interval); start(); } - - /// Invoke the callback. This function is the callback of the underlying TimerProc - using Base::trigger; -}; - -WINTIMER_END_NAMESPACE diff --git a/vnr/wintimer/wintimerbase.cc b/vnr/wintimer/wintimerbase.cc deleted file mode 100644 index ac4fd95..0000000 --- a/vnr/wintimer/wintimerbase.cc +++ /dev/null @@ -1,73 +0,0 @@ -// wintimerbase.cc -// 6/6/2012 jichi - -#include "wintimer/wintimerbase.h" -#ifdef QT_CORE_LIB -# include -#else -# include -#endif // QT_CORE_LIB -#include "ccutil/ccmacro.h" - -//#define DEBUG "wintimerbase.cc" -#include "sakurakit/skdebug.h" - -static VOID CALLBACK WinTimerProc( - HWND hwnd, // ウィンドウのハンドル - UINT uMsg, // WM_TIMER メッセージ - UINT_PTR idEvent, // Timer ID - DWORD dwTime // 現在のシステム時刻 -) -{ - Q_UNUSED(hwnd) - Q_UNUSED(dwTime) - Q_UNUSED(uMsg) - Q_ASSERT(idEvent); - if (CC_UNLIKELY(!idEvent)) - return; - DOUT("enter"); - WinTimerBase *t = reinterpret_cast(idEvent); - - if (t->isSingleShot() && t->isActive()) - t->stop(); - t->trigger(); - DOUT("leave"); -} - -WINTIMER_BEGIN_NAMESPACE - -// - Construction - - -WId WinTimerBase::globalWindow; - -//WId WinTimer::createHiddenWindow() -//{ -// DOUT("enter: warning: hidden window used"); -// QWidget *w = new QWidget; -// w->resize(QSize()); -// w->show(); -// DOUT("leave"); -// return w->winId(); -//} - -// - Timer - - -void WinTimerBase::start() -{ - DOUT("enter: active =" << active << ", interval =" << interval); - active = true; - ::SetTimer(parentWindow, reinterpret_cast(this), interval, WinTimerProc); - DOUT("leave"); -} - -void WinTimerBase::stop() -{ - DOUT("enter: active =" << active); - active = false; - ::KillTimer(parentWindow, reinterpret_cast(this)); - DOUT("leave"); -} - -WINTIMER_END_NAMESPACE - -// EOF diff --git a/vnr/wintimer/wintimerbase.h b/vnr/wintimer/wintimerbase.h deleted file mode 100644 index b1999f7..0000000 --- a/vnr/wintimer/wintimerbase.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -// wintimerbase.h -// 6/6/2012 jichi -// -// Internal header for wintimer base class. - -#include "sakurakit/skglobal.h" -#include - -#ifdef QT_CORE_LIB -# include -#else -# include -#endif // QT_CORE_LIB - -#ifndef WINTIMER_BEGIN_NAMESPACE -# define WINTIMER_BEGIN_NAMESPACE -#endif -#ifndef WINTIMER_END_NAMESPACE -# define WINTIMER_END_NAMESPACE -#endif - -WINTIMER_BEGIN_NAMESPACE - -/// Internal base class for WinTimer -class WinTimerBase -{ - SK_CLASS(WinTimerBase) - SK_DISABLE_COPY(WinTimerBase) - - // - Types - -public: - typedef std::function function_type; -#ifndef QT_CORE_LIB - typedef HWND WId; -#endif // QT_CORE_LIB - - // - Methods - -public: - /// Construct a timer with the parent window handle. - WinTimerBase() - : parentWindow(0), // use 0 instead of nullptr to be consistent with Qt5 - interval(0), singleShot(false), active(false) {} - - bool isSingleShot() const { return singleShot; } - bool isActive() const { return active; } - - /// Start TimerProc - void start(); - /// Stop TimerProc - void stop(); - /// Invoke the callback. This function is the callback of the underlying TimerProc - void trigger() { function(); } - - // - Fields - -protected: - static WId globalWindow; - - WId parentWindow; - int interval; - bool singleShot; - bool active; - function_type function; - -}; - -WINTIMER_END_NAMESPACE