diff --git a/.gitignore b/.gitignore index dfcfd56..85dbf90 100644 --- a/.gitignore +++ b/.gitignore @@ -348,3 +348,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# MyLib +Share/ \ No newline at end of file diff --git a/Simple/BuildEvent.bat b/Simple/BuildEvent.bat new file mode 100644 index 0000000..915e12f --- /dev/null +++ b/Simple/BuildEvent.bat @@ -0,0 +1,4 @@ +set PROJECTNAME=%1 +set HEADERNAME=%PROJECTNAME% +xcopy "..\%PROJECTNAME%64\*.h" "..\Share\Simple\" /Y +xcopy "..\Release\%PROJECTNAME%.lib" "..\Share\Simple\" /Y \ No newline at end of file diff --git a/Simple/BuildEvent64.bat b/Simple/BuildEvent64.bat new file mode 100644 index 0000000..ab1f909 --- /dev/null +++ b/Simple/BuildEvent64.bat @@ -0,0 +1,4 @@ +set PROJECTNAME=%1 +set HEADERNAME=%PROJECTNAME:~,-2% +xcopy "..\%PROJECTNAME%\*.h" "..\Share\Simple\" /Y +xcopy "..\Release\%PROJECTNAME%.lib" "..\Share\Simple\" /Y \ No newline at end of file diff --git a/Simple/Readme.md b/Simple/Readme.md new file mode 100644 index 0000000..f92d273 --- /dev/null +++ b/Simple/Readme.md @@ -0,0 +1,19 @@ +# Simple +## Simple ++ テストコード + +## SimpleGUI ++ 簡単なGUI生成 + +## SimplePipe ++ パイプ + +## SimpleMemory ++ 単純なメモリ操作 + +## SimpleHook ++ APIや関数のフック ++ 外部ライブラリに依存 + +## SimpleInjector ++ DLL Injection \ No newline at end of file diff --git a/Simple/Simple.sln b/Simple/Simple.sln new file mode 100644 index 0000000..77c6705 --- /dev/null +++ b/Simple/Simple.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.2017 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simple", "Simple\Simple.vcxproj", "{F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simple64", "Simple64\Simple64.vcxproj", "{98F6E054-7F18-4800-86A0-873485E7CBF9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Debug|x64.ActiveCfg = Debug|x64 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Debug|x64.Build.0 = Debug|x64 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Debug|x86.ActiveCfg = Debug|Win32 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Debug|x86.Build.0 = Debug|Win32 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Release|x64.ActiveCfg = Release|Win32 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Release|x64.Build.0 = Release|Win32 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Release|x86.ActiveCfg = Release|Win32 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B}.Release|x86.Build.0 = Release|Win32 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Debug|x64.ActiveCfg = Debug|x64 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Debug|x64.Build.0 = Debug|x64 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Debug|x86.ActiveCfg = Debug|Win32 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Debug|x86.Build.0 = Debug|Win32 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Release|x64.ActiveCfg = Release|x64 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Release|x64.Build.0 = Release|x64 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Release|x86.ActiveCfg = Release|x64 + {98F6E054-7F18-4800-86A0-873485E7CBF9}.Release|x86.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D28D3743-CFA5-4175-B9C1-B318BE563478} + EndGlobalSection +EndGlobal diff --git a/Simple/Simple/Simple.vcxproj b/Simple/Simple/Simple.vcxproj new file mode 100644 index 0000000..19dee31 --- /dev/null +++ b/Simple/Simple/Simple.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + 15.0 + {F6E8E5F8-3292-413E-9848-0F8B7DAE8D0B} + Win32Proj + Simple + 10.0.17763.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Level3 + Disabled + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + Disabled + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + MaxSpeed + true + true + true + SIMPLE_LIB;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + ../BuildEvent.bat $(ProjectName) + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/Simple/Simple/Simple.vcxproj.filters b/Simple/Simple/Simple.vcxproj.filters new file mode 100644 index 0000000..01b748b --- /dev/null +++ b/Simple/Simple/Simple.vcxproj.filters @@ -0,0 +1,78 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + \ No newline at end of file diff --git a/Simple/Simple64/Simple.cpp b/Simple/Simple64/Simple.cpp new file mode 100644 index 0000000..82a5aba --- /dev/null +++ b/Simple/Simple64/Simple.cpp @@ -0,0 +1,93 @@ +#include"Simple.h" + +std::wstring BYTEtoString(BYTE b) { + std::wstring wb; + WCHAR high = (b >> 4) & 0x0F; + WCHAR low = b & 0x0F; + + high += (high <= 0x09) ? 0x30 : 0x37; + low += (low <= 0x09) ? 0x30 : 0x37; + + wb.push_back(high); + wb.push_back(low); + + return wb; +} + +std::wstring WORDtoString(WORD w) { + std::wstring ww; + + ww += BYTEtoString((w >> 8) & 0xFF); + ww += BYTEtoString(w & 0xFF); + + return ww; +} + +std::wstring DWORDtoString(DWORD dw) { + std::wstring wdw; + + wdw += BYTEtoString((dw >> 24) & 0xFF); + wdw += BYTEtoString((dw >> 16) & 0xFF); + wdw += BYTEtoString((dw >> 8) & 0xFF); + wdw += BYTEtoString(dw & 0xFF); + + return wdw; +} + +std::wstring DatatoString(BYTE *b, ULONG_PTR Length, bool space) { + std::wstring wdata; + + for (ULONG_PTR i = 0; i < Length; i++) { + if (space) { + if (i) { + wdata.push_back(L' '); + } + } + wdata += BYTEtoString(b[i]); + } + + return wdata; +} + +#ifdef _WIN64 +std::wstring QWORDtoString(ULONG_PTR u) { + std::wstring wdw; + + wdw += BYTEtoString((u >> 56) & 0xFF); + wdw += BYTEtoString((u >> 48) & 0xFF); + wdw += BYTEtoString((u >> 40) & 0xFF); + wdw += BYTEtoString((u >> 32) & 0xFF); + wdw += BYTEtoString((u >> 24) & 0xFF); + wdw += BYTEtoString((u >> 16) & 0xFF); + wdw += BYTEtoString((u >> 8) & 0xFF); + wdw += BYTEtoString(u & 0xFF); + + return wdw; +} +#endif + +bool GetDir(std::wstring &wDir, std::wstring wDll) { + WCHAR wcDir[MAX_PATH] = { 0 }; + + if (wDll.length()) { + if (!GetModuleFileNameW(GetModuleHandleW(wDll.c_str()), wcDir, _countof(wcDir))) { + return false; + } + } + else { + if (!GetModuleFileNameW(GetModuleHandleW(NULL), wcDir, _countof(wcDir))) { + return false; + } + } + + std::wstring dir = wcDir; + size_t pos = dir.rfind(L"\\"); + + if (pos == std::wstring::npos) { + return false; + } + + dir = dir.substr(0, pos + 1); + wDir = dir; + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/Simple.h b/Simple/Simple64/Simple.h new file mode 100644 index 0000000..6d18f4b --- /dev/null +++ b/Simple/Simple64/Simple.h @@ -0,0 +1,53 @@ +#ifndef __SIMPLE__H__ +#define __SIMPLE__H__ + +#ifndef SIMPLE_LIB +#ifndef _WIN64 +#pragma comment(lib, "../Share/Simple/Simple.lib") +#else +#pragma comment(lib, "../Share/Simple/Simple64.lib") +#endif +#else +#endif + +#include +#include +#pragma comment(lib,"comctl32.lib") +#include +#include +#include +#include + +#include"SimpleGUI.h" +#include"SimpleMemory.h" +#include"SimpleConfig.h" +#include"SimplePipe.h" +#include"SimpleInjector.h" + +#define DEBUG(msg) \ +{\ +std::wstring wmsg = L"[Maple] ";\ +wmsg += msg;\ +OutputDebugStringW(wmsg.c_str());\ +} + +#ifdef _WIN64 +#define SCANRES(msg) DEBUG(L""#msg" = " + QWORDtoString(msg)) +#else +#define SCANRES(msg) DEBUG(L""#msg" = " + DWORDtoString(msg)) +#endif + +std::wstring BYTEtoString(BYTE b); +std::wstring WORDtoString(WORD w); +std::wstring DWORDtoString(DWORD dw); +std::wstring DatatoString(BYTE *b, ULONG_PTR Length, bool space = false); + +#ifdef _WIN64 +std::wstring QWORDtoString(ULONG_PTR u); +#else +#define QWORDtoString(u) DWORDtoString(u) +#endif + +bool GetDir(std::wstring &wDir, std::wstring wDll = L""); + +#endif \ No newline at end of file diff --git a/Simple/Simple64/Simple64.vcxproj b/Simple/Simple64/Simple64.vcxproj new file mode 100644 index 0000000..38d899e --- /dev/null +++ b/Simple/Simple64/Simple64.vcxproj @@ -0,0 +1,176 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {98F6E054-7F18-4800-86A0-873485E7CBF9} + Win32Proj + Simple64 + 10.0.17763.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + true + + + true + + + false + $(SolutionDir)$(Configuration)\ + + + + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + Disabled + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + Disabled + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + MaxSpeed + true + true + true + SIMPLE_LIB;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + ../BuildEvent64.bat $(ProjectName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Simple/Simple64/Simple64.vcxproj.filters b/Simple/Simple64/Simple64.vcxproj.filters new file mode 100644 index 0000000..436b8c3 --- /dev/null +++ b/Simple/Simple64/Simple64.vcxproj.filters @@ -0,0 +1,87 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {d4eca0df-7fa5-4f26-aaef-18ed271a17e8} + + + {914f70c9-da56-4dc4-be6c-dbfe5ec6ece7} + + + {c103ca26-f35e-476c-9338-66935c4f17e0} + + + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル\Pipe + + + ソース ファイル\Pipe + + + ソース ファイル\Pipe + + + ソース ファイル\GUI + + + ソース ファイル\GUI + + + ソース ファイル\GUI + + + ソース ファイル\GUI + + + ソース ファイル\Memory + + + ソース ファイル\Memory + + + ソース ファイル\Memory + + + ソース ファイル + + + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + \ No newline at end of file diff --git a/Simple/Simple64/SimpleConfig.cpp b/Simple/Simple64/SimpleConfig.cpp new file mode 100644 index 0000000..2cdffd5 --- /dev/null +++ b/Simple/Simple64/SimpleConfig.cpp @@ -0,0 +1,50 @@ +#include"Simple.h" + +Config::Config(std::wstring wFileName) { + SetConfigFile(wFileName, GetModuleHandleW(NULL)); +} + +Config::Config(std::wstring wFileName, HMODULE hDll) { + SetConfigFile(wFileName, hDll); +} + +bool Config::SetConfigFile(std::wstring wFileName, HMODULE hModule) { + WCHAR wcDir[MAX_PATH] = { 0 }; + + if (!GetModuleFileNameW(hModule, wcDir, _countof(wcDir))) { + return false; + } + + std::wstring dir = wcDir; + size_t pos = dir.rfind(L"\\"); + + if (pos == std::wstring::npos) { + return false; + } + + dir = dir.substr(0, pos + 1); + + config_file_name = dir + wFileName; + return true; +} + +bool Config::Read(std::wstring wSection, std::wstring wKey, std::wstring &wValue) { + WCHAR wcValue[MAX_PATH * 2]; + memset(wcValue, 0, sizeof(wcValue)); + + if (GetPrivateProfileStringW(wSection.c_str(), wKey.c_str(), NULL, wcValue, _countof(wcValue), config_file_name.c_str()) <= 0) { + Update(wSection.c_str(), wKey.c_str(), L""); + return false; + } + + wValue = wcValue; + return true; +} + +bool Config::Update(std::wstring wSection, std::wstring wKey, std::wstring wValue) { + if (!WritePrivateProfileStringW(wSection.c_str(), wKey.c_str(), wValue.c_str(), config_file_name.c_str())) { + return false; + } + + return true; +} diff --git a/Simple/Simple64/SimpleConfig.h b/Simple/Simple64/SimpleConfig.h new file mode 100644 index 0000000..d75fb97 --- /dev/null +++ b/Simple/Simple64/SimpleConfig.h @@ -0,0 +1,19 @@ +#ifndef __SIMPLECONFIG_H__ +#define __SIMPLECONFIG_H__ + +class Config { +private: + std::wstring config_file_name; + bool SetConfigFile(std::wstring wFileName, HMODULE hModule); +public: + // EXẼfBNgQ + Config(std::wstring wFileName); + // DLL̃fBNgQ + Config(std::wstring wFileName, HMODULE hDll); + // ݒ̓ǂݎ + bool Read(std::wstring wSection, std::wstring wKey, std::wstring &wValue); + // ݒ̍XV + bool Update(std::wstring wSection, std::wstring wKey, std::wstring wValue); +}; + +#endif \ No newline at end of file diff --git a/Simple/Simple64/SimpleGUI.cpp b/Simple/Simple64/SimpleGUI.cpp new file mode 100644 index 0000000..899a983 --- /dev/null +++ b/Simple/Simple64/SimpleGUI.cpp @@ -0,0 +1,218 @@ +#include"Simple.h" + +#if defined _M_IX86 +# pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_IA64 +# pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +# pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +# pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif + +// global variables +std::vector Alice::window_list; +std::vector Alice::list; + +// public +Alice::Alice(std::wstring wClassName, std::wstring wWindowName, int nWidth, int nHeight, HINSTANCE hInstance) { + main_hwnd = NULL; + main_class_name = wClassName; + main_window_name = wWindowName; + main_width = nWidth; + main_height = nHeight; + main_instance = hInstance; + + SetOnCreate(NULL); + SetOnCommand(NULL); + SetOnNotify(NULL); + SetCallback(NULL, CT_UNDEFINED); +} + +Alice::~Alice() { + if (main_hwnd) { + UnRegister(); + } +} + +bool Alice::Run() { + if (!Register()) { + if (!UnRegister()) { + return false; + } + if (!Register()) { + return false; + } + } + + HWND hWnd = CreateWindowExW(NULL, main_class_name.c_str(), main_window_name.c_str(), (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME), CW_USEDEFAULT, CW_USEDEFAULT, main_width, main_height, NULL, NULL, main_instance, this); + if (!hWnd) { + return false; + } + + list.push_back(this); + window_list.push_back(hWnd); + return true; +} + +bool Alice::DetectInvalidWindow() { + for (size_t i = 0; i < window_list.size(); i++) { + if (!IsWindow(window_list[i])) { + list[i]->UnRegister(); + list.erase(list.begin() + i); + window_list.erase(window_list.begin() + i); + return true; + } + } + return false; +} + +bool Alice::Wait() { + MSG msg; + memset(&msg, 0, sizeof(msg)); + + do { + while (GetMessageW(&msg, NULL, NULL, NULL) > 0) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + DetectInvalidWindow(); + } while (window_list.size()); + + return true; +} + +// private +LRESULT CALLBACK Alice::AliceProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { + Alice *a = (Alice *)GetWindowLongPtrW(hWnd, GWLP_USERDATA); + + switch (Msg) { + case WM_CREATE: + { + if (!a) { + CREATESTRUCTW *cs = decltype(cs)(lParam); + a = (Alice *)cs->lpCreateParams; + Resize(hWnd, cs->cx, cs->cy); + a->main_hwnd = hWnd; + a->OnCreate(*a); + ShowWindow(hWnd, SW_SHOW); + SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)a); + } + break; + } + case WM_COMMAND: + { + if (a) { + a->OnCommand(*a, LOWORD(wParam)); + } + break; + } + case WM_NOTIFY: + { + NMHDR *nh = (NMHDR *)lParam; + if (a) { + if (nh->code == LVN_ITEMCHANGED) { + a->OnNotify(*a, LOWORD(wParam)); + } + } + break; + } + case WM_MOUSEMOVE: + { + static HCURSOR arrow = LoadCursorW(NULL, IDC_ARROW); + if (arrow) { + SetCursor(arrow); + } + break; + } + case WM_LBUTTONUP: + { + SetFocus(hWnd); + break; + } + case WM_CLOSE: + { + ShowWindow(hWnd, SW_HIDE); + break; + } + case WM_DESTROY: + { + PostQuitMessage(0); + break; + } + default: + break; + } + + if (a) { + switch (a->GetCallbackType()) { + case CT_CALL: + { + a->Callback(hWnd, Msg, wParam, lParam); + break; + } + case CT_INTERRUPTION: + { + return a->Callback(hWnd, Msg, wParam, lParam); + } + default: + break; + } + } + + return DefWindowProcW(hWnd, Msg, wParam, lParam); +} + +bool Alice::Resize(HWND hWnd, int cx, int cy) { + if (!hWnd) { + return false; + } + + RECT window_rect; + memset(&window_rect, 0, sizeof(window_rect)); + + if (!GetWindowRect(hWnd, &window_rect)) { + return false; + } + + RECT client_rect; + memset(&client_rect, 0, sizeof(client_rect)); + if (!GetClientRect(hWnd, &client_rect)) { + return false; + } + + if (!SetWindowPos(hWnd, HWND_TOP, NULL, NULL, (cx + (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left)), (cy + (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top)), SWP_NOMOVE)) { + return false; + } + + return true; +} + +bool Alice::Register() { + WNDCLASSEXW wc = { sizeof(WNDCLASSEXW) }; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + + wc.hInstance = main_instance; + if (callback_type == CT_MANUAL && manual_callback) { + wc.lpfnWndProc = manual_callback; + } + else { + wc.lpfnWndProc = AliceProc; + } + + wc.lpszClassName = main_class_name.c_str(); + wc.style = CS_HREDRAW | CS_VREDRAW; + + if (!RegisterClassExW(&wc)) { + return false; + } + + return true; +} +bool Alice::UnRegister() { + if (!UnregisterClassW(main_class_name.c_str(), main_instance)) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimpleGUI.h b/Simple/Simple64/SimpleGUI.h new file mode 100644 index 0000000..0afc176 --- /dev/null +++ b/Simple/Simple64/SimpleGUI.h @@ -0,0 +1,102 @@ +#ifndef __ALICE_H__ +#define __ALICE_H__ + +class Alice { + // global +public: + enum CallbackType { + CT_UNDEFINED, + CT_CALL, + CT_MANUAL, + CT_INTERRUPTION + }; + + static bool Wait(); + +private: + static std::vector window_list; + static std::vector list; + + static bool DetectInvalidWindow(); + + // main +private: + HWND main_hwnd; + std::wstring main_class_name; + std::wstring main_window_name; + int main_width; + int main_height; + HINSTANCE main_instance; + + static LRESULT CALLBACK AliceProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + static bool Resize(HWND hWnd, int cx, int cy); + bool Register(); + bool UnRegister(); + +public: + Alice(std::wstring wClassName, std::wstring wWindowName, int nWidth, int nHeight, HINSTANCE hInstance); + ~Alice(); + bool Run(); + + // External +private: + bool (*on_create)(Alice&); + bool (*on_command)(Alice&, int); + bool (*on_notify)(Alice&, int); + bool OnCreate(Alice &a); + bool OnCommand(Alice &a, int nIDDlgItem); + bool OnNotify(Alice &a, int nIDDlgItem); + + decltype(DefWindowProcW) *manual_callback; + CallbackType callback_type; + +public: + bool SetOnCreate(bool(*function)(Alice&)); + bool SetOnCommand(bool(*function)(Alice&, int)); + bool SetOnNotify(bool(*function)(Alice&, int)); + bool SetCallback(decltype(DefWindowProcW) *function, CallbackType ct); + CallbackType GetCallbackType(); + LRESULT CALLBACK Callback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + HWND GetMainHWND(); + + // Control +private: + std::vector control_id_list; + std::vector control_hwnd_list; + + bool SetFont(size_t nIDDlgItem); + int AutoWidth(std::wstring wText); +public: + // create + bool StaticText(size_t nIDDlgItem, std::wstring wText, int X, int Y); + bool Button(size_t nIDDlgItem, std::wstring wText, int X, int Y, int nWidth = 0); + bool CheckBox(size_t nIDDlgItem, std::wstring wText, int X, int Y, UINT uCheck = BST_UNCHECKED); + bool EditBox(size_t nIDDlgItem, int X, int Y, std::wstring wText = L"", int nWidth = 0); + bool TextArea(size_t nIDDlgItem, int X, int Y, int nWidth, int nHeight); + bool ListView(size_t nIDDlgItem, int X, int Y, int nWidth, int nHeight); + bool ComboBox(size_t nIDDlgItem, int X, int Y, int nWidth); + // do + bool ReadOnly(size_t nIDDlgItem, WPARAM wParam = true); + bool SetText(size_t nIDDlgItem, std::wstring wText); + bool AddText(size_t nIDDlgItem, std::wstring wText); + std::wstring GetText(size_t nIDDlgItem); + LRESULT CheckBoxStatus(size_t nIDDlgItem); + bool Embed(HWND hWnd, int nWidth, int nHeight); + + // ListView +private: + std::vector listview_id_list; + std::vector listview_previous_selected; + + LRESULT ListView_HeaderCount(size_t nIDDlgItem); + bool ListView_AutoScroll(size_t nIDDlgItem); + bool ListView_GetPreviousSelected(size_t nIDDlgItem, int &Selected); + bool ListView_SetPreviousSelected(size_t nIDDlgItem, int Selected); +public: + bool ListView_AddHeader(size_t nIDDlgItem, std::wstring wHeader, int Width); + bool ListView_AddItem(size_t nIDDlgItem, int index, std::wstring wText); + bool ListView_Clear(size_t nIDDlgItem); + bool ListView_Copy(size_t nIDDlgItem, int index, std::wstring &wText, bool block = false, size_t size = 256); +}; + +#endif \ No newline at end of file diff --git a/Simple/Simple64/SimpleGUICallback.cpp b/Simple/Simple64/SimpleGUICallback.cpp new file mode 100644 index 0000000..51541d3 --- /dev/null +++ b/Simple/Simple64/SimpleGUICallback.cpp @@ -0,0 +1,66 @@ +#include"Simple.h" + +// public +bool Alice::SetOnCreate(bool (*function)(Alice&)) { + on_create = function; + return true; +} + +bool Alice::SetOnCommand(bool (*function)(Alice&, int)) { + on_command = function; + return true; +} + +bool Alice::SetOnNotify(bool (*function)(Alice&, int)) { + on_notify = function; + return true; +} + +bool Alice::SetCallback(decltype(DefWindowProcW) *function , CallbackType ct) { + manual_callback = function; + callback_type = ct; + return true; +} + + +Alice::CallbackType Alice::GetCallbackType() { + return callback_type; +} + +LRESULT CALLBACK Alice::Callback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { + if (!manual_callback) { + return 0; + } + + return manual_callback(hWnd, Msg, wParam, lParam); +} + +// private +bool Alice::OnCreate(Alice &a) { + if (!on_create) { + return false; + } + + return on_create(a); +} + +bool Alice::OnCommand(Alice &a, int nIDDlgItem) { + if (!on_command) { + return false; + } + + return on_command(a, nIDDlgItem); +} + +bool Alice::OnNotify(Alice &a, int nIDDlgItem) { + if (!on_notify) { + return false; + } + + return on_notify(a, nIDDlgItem); +} + + +HWND Alice::GetMainHWND() { + return main_hwnd; +} \ No newline at end of file diff --git a/Simple/Simple64/SimpleGUIControl.cpp b/Simple/Simple64/SimpleGUIControl.cpp new file mode 100644 index 0000000..d90f375 --- /dev/null +++ b/Simple/Simple64/SimpleGUIControl.cpp @@ -0,0 +1,232 @@ +#include"Simple.h" + +// create +bool Alice::StaticText(size_t nIDDlgItem, std::wstring wText, int X, int Y) { + if (!main_hwnd) { + return false; + } + + HWND hWnd = CreateWindowExW(NULL, L"STATIC", wText.c_str(), WS_CHILD | WS_VISIBLE | ES_LEFT, X, (Y + 3), AutoWidth(wText), 13, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + + SetFont(nIDDlgItem); + return true; +} + +bool Alice::Button(size_t nIDDlgItem, std::wstring wText, int X, int Y, int nWidth) { + if (!main_hwnd) { + return false; + } + + int width = nWidth; + if (!width) { + width = AutoWidth(wText) + 12; + } + + HWND hWnd = CreateWindowExW(NULL, L"BUTTON", wText.c_str(), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, X, (Y + 1), width, 18, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + + SetFont(nIDDlgItem); + return true; +} + +bool Alice::CheckBox(size_t nIDDlgItem, std::wstring wText, int X, int Y, UINT uCheck) { + if (!main_hwnd) { + return false; + } + + HWND hWnd = CreateWindowExW(NULL, L"BUTTON", wText.c_str(), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, X, (Y + 3), AutoWidth(wText) + 15, 13, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + + SetFont(nIDDlgItem); + CheckDlgButton(main_hwnd, (int)nIDDlgItem, uCheck); + return true; +} + +bool Alice::EditBox(size_t nIDDlgItem, int X, int Y, std::wstring wText, int nWidth) { + if (!main_hwnd) { + return false; + } + + int width = nWidth; + if (!width) { + width = AutoWidth(wText) + 6; + } + + HWND hWnd = CreateWindowExW(NULL, L"EDIT", wText.c_str(), WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL | WS_BORDER, X, (Y + 2), width, 16, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + + SetFont(nIDDlgItem); + return true; +} + +bool Alice::TextArea(size_t nIDDlgItem, int X, int Y, int nWidth, int nHeight) { + if (!main_hwnd) { + return false; + } + + HWND hWnd = CreateWindowExW(NULL, L"EDIT", L"", WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | ES_MULTILINE | WS_VSCROLL, X, (Y + 2), nWidth, nHeight, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + + SetFont(nIDDlgItem); + return true; +} + +bool Alice::ListView(size_t nIDDlgItem, int X, int Y, int nWidth, int nHeight) { + static bool init = false; + if (!init) { + init = true; + INITCOMMONCONTROLSEX icex = { sizeof(icex) }; + icex.dwICC = ICC_LISTVIEW_CLASSES; + InitCommonControlsEx(&icex); + } + + if (!main_hwnd) { + return false; + } + + HWND hWnd = CreateWindowExW(NULL, L"SysListView32", NULL, LVS_REPORT | WS_CHILD | LVS_NOSORTHEADER | WS_BORDER | LVS_SINGLESEL | LVS_SHOWSELALWAYS, X, (Y + 1), nWidth, nHeight, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + LRESULT exstyle = SendMessageW(hWnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); + SendMessageW(hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, exstyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + listview_id_list.push_back(nIDDlgItem); + listview_previous_selected.push_back(-1); + + SetFont(nIDDlgItem); + ShowWindow(hWnd, SW_SHOW); + return true; +} + +bool Alice::ComboBox(size_t nIDDlgItem, int X, int Y, int nWidth) { + if (!main_hwnd) { + return false; + } + + HWND hWnd = CreateWindowExW(NULL, L"COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | CBS_SORT | CBS_SIMPLE | CBS_DROPDOWNLIST, X, (Y + 2), nWidth, 16, main_hwnd, (HMENU)nIDDlgItem, main_instance, NULL); + if (!hWnd) { + return false; + } + + SendMessageW(hWnd, CB_DIR, DDL_READWRITE, (LPARAM)L"C:\\Windows\\*.*"); + + control_hwnd_list.push_back(hWnd); + control_id_list.push_back(nIDDlgItem); + + SetFont(nIDDlgItem); + return true; +} + +// do something +bool Alice::ReadOnly(size_t nIDDlgItem, WPARAM wParam) { + if (!main_hwnd) { + return false; + } + + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, EM_SETREADONLY, wParam, NULL); + return true; +} + +bool Alice::SetText(size_t nIDDlgItem, std::wstring wText) { + if (!main_hwnd) { + return false; + } + + SetDlgItemTextW(main_hwnd, (int)nIDDlgItem, wText.c_str()); + return true; +} + +std::wstring Alice::GetText(size_t nIDDlgItem) { + if (!main_hwnd) { + return false; + } + + LRESULT length = SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, WM_GETTEXTLENGTH, NULL, NULL); + std::vector data; + data.resize(length + 1); + GetDlgItemTextW(main_hwnd, (int)nIDDlgItem, &data[0], (int)(length + 1)); + return std::wstring((wchar_t *)&data[0]); +} + +bool Alice::AddText(size_t nIDDlgItem, std::wstring wText) { + if (!main_hwnd) { + return false; + } + + LRESULT cursor = SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, WM_GETTEXTLENGTH, NULL, NULL); + std::wstring text = wText; + + if (cursor != 0) { + text = L"\r\n" + text; + } + + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, EM_SETSEL, cursor, cursor); + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, EM_REPLACESEL, NULL, (LPARAM)text.c_str()); + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, EM_SCROLL, SB_BOTTOM, NULL); + return true; +} + +LRESULT Alice::CheckBoxStatus(size_t nIDDlgItem) { + if (!main_hwnd) { + return false; + } + + return SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, BM_GETCHECK, 0, 0); +} + +// private +bool Alice::SetFont(size_t nIDDlgItem) { + static HFONT font = CreateFontW(12, NULL, NULL, NULL, FW_NORMAL, NULL, NULL, NULL, SHIFTJIS_CHARSET, NULL, NULL, NULL, NULL, L"lr SVbN"); + if (!font) { + return false; + } + + if (!main_hwnd) { + return false; + } + + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, WM_SETFONT, (WPARAM)font, NULL); + return true; +} + +int Alice::AutoWidth(std::wstring wText) { + return (int)(wText.length() * 6); +} + +bool Alice::Embed(HWND hWnd, int nWidth, int nHeight) { + SetWindowLongW(hWnd, GWL_STYLE, WS_CHILD | WS_POPUP); + ShowWindow(hWnd, SW_SHOW); + SetParent(hWnd, main_hwnd); + SetWindowPos(hWnd, HWND_TOP, 0, 0, nWidth, nHeight, NULL); + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimpleGUIListView.cpp b/Simple/Simple64/SimpleGUIListView.cpp new file mode 100644 index 0000000..38d28c8 --- /dev/null +++ b/Simple/Simple64/SimpleGUIListView.cpp @@ -0,0 +1,141 @@ +#include"Simple.h" + +// public +bool Alice::ListView_AddHeader(size_t nIDDlgItem, std::wstring wHeader, int Width) { + if (!main_hwnd) { + return false; + } + + LVCOLUMNW col; + memset(&col, 0, sizeof(col)); + col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + col.fmt = LVCFMT_LEFT; + col.iSubItem = (int)ListView_HeaderCount(nIDDlgItem); + + col.cx = Width; + col.pszText = (WCHAR *)wHeader.c_str(); + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_INSERTCOLUMNW, col.iSubItem, (LPARAM)&col); + return true; +} + +bool Alice::ListView_AddItem(size_t nIDDlgItem, int index, std::wstring wText) { + if (!main_hwnd) { + return false; + } + + LVITEMW item = { 0 }; + item.mask = LVIF_TEXT; + item.pszText = (WCHAR *)wText.c_str(); + item.iSubItem = index; + + LRESULT count = SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_GETITEMCOUNT, 0, 0); + + if (index) { + count--; + } + + item.iItem = (int)count; + + if (!index) { + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_INSERTITEM, 0, (LPARAM)&item); + } + else { + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_SETITEM, 0, (LPARAM)&item); + } + + if (index == ListView_HeaderCount(nIDDlgItem) - 1) { + ListView_AutoScroll(nIDDlgItem); + } + + return true; +} + +bool Alice::ListView_Clear(size_t nIDDlgItem) { + if (!main_hwnd) { + return false; + } + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_DELETEALLITEMS, 0, 0); + ListView_SetPreviousSelected(nIDDlgItem, -1); + return true; +} + +bool Alice::ListView_Copy(size_t nIDDlgItem, int index, std::wstring &wText, bool block, size_t size) { + if (!main_hwnd) { + return false; + } + + LRESULT res = SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_SELECTED, 0)); + if (res == -1) { + return false; + } + + int previous_res = 0; + if (!ListView_GetPreviousSelected(nIDDlgItem, previous_res)) { + return false; + } + + if (res == previous_res) { + return false; + } + + if (block) { + ListView_SetPreviousSelected(nIDDlgItem, (int)res); + } + + wText.clear(); + + std::vector temp_text(size); + + LVITEMW li; + memset(&li, 0, sizeof(li)); + li.iSubItem = index; + li.pszText = &temp_text[0]; + li.cchTextMax = (int)(temp_text.size() - 1); + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_GETITEMTEXT, res, (LPARAM)&li); + + wText = &temp_text[0]; + + return true; +} + +// private +LRESULT Alice::ListView_HeaderCount(size_t nIDDlgItem) { + if (!main_hwnd) { + return false; + } + + HWND header_hwnd = (HWND)SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_GETHEADER, 0, 0); + return SendMessageW(header_hwnd, HDM_GETITEMCOUNT, 0, 0); +} + +bool Alice::ListView_AutoScroll(size_t nIDDlgItem) { + if (!main_hwnd) { + return false; + } + + LRESULT count = SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_GETITEMCOUNT, 0, 0); + SendDlgItemMessageW(main_hwnd, (int)nIDDlgItem, LVM_ENSUREVISIBLE, (WPARAM)(count - 1), true); + return true; +} + +bool Alice::ListView_GetPreviousSelected(size_t nIDDlgItem, int &Selected) { + for (size_t i = 0; i < listview_id_list.size(); i++) { + if (listview_id_list[i] == nIDDlgItem) { + Selected = listview_previous_selected[i]; + return true; + } + } + + return false; +} + +bool Alice::ListView_SetPreviousSelected(size_t nIDDlgItem, int Selected) { + for (size_t i = 0; i < listview_id_list.size(); i++) { + if (listview_id_list[i] == nIDDlgItem) { + listview_previous_selected[i] = Selected; + return true; + } + } + + return false; +} \ No newline at end of file diff --git a/Simple/Simple64/SimpleInjector.cpp b/Simple/Simple64/SimpleInjector.cpp new file mode 100644 index 0000000..e00dcb5 --- /dev/null +++ b/Simple/Simple64/SimpleInjector.cpp @@ -0,0 +1,267 @@ +#include"Simple.h" + +Injector::Injector(std::wstring wTargetPath, std::wstring wDllPath) { + target_path = wTargetPath; + dll_path = wDllPath; + process_handle = NULL; + main_thread_handle = NULL; + is_successed = false; + memset(&target_pi, 0, sizeof(target_pi)); +}; + +Injector::Injector(PROCESS_INFORMATION &pi, std::wstring wDllPath) { + dll_path = wDllPath; + process_handle = NULL; + main_thread_handle = NULL; + is_successed = false; + target_pi = pi; +} + +Injector::~Injector() { + if (main_thread_handle) { + if (is_successed) { + ResumeThread(main_thread_handle); + } + CloseHandle(main_thread_handle); + } + if (process_handle) { + if (!is_successed) { + TerminateProcess(process_handle, 0xDEAD); + } + CloseHandle(process_handle); + } +} + +#ifdef _WIN64 +bool Injector::Run() { + STARTUPINFO si; + PROCESS_INFORMATION pi; + + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + si.cb = sizeof(si); + + std::wstring wDir = target_path; + size_t pos_last_backslash = wDir.rfind(L'\\'); + if (pos_last_backslash != std::wstring::npos) { + wDir.erase(wDir.begin() + pos_last_backslash + 1, wDir.end()); + if (!CreateProcessW(target_path.c_str(), 0, 0, 0, FALSE, CREATE_SUSPENDED, 0, wDir.c_str(), &si, &pi)) { + return false; + } + } + else { + if (!CreateProcessW(target_path.c_str(), 0, 0, 0, FALSE, CREATE_SUSPENDED, 0, 0, &si, &pi)) { + return false; + } + } + + process_handle = pi.hProcess; + main_thread_handle = pi.hThread; + + // Process + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); + if (!hProcess) { + return false; + } + + CloseHandle(process_handle); + process_handle = hProcess; + + // Thread + HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pi.dwThreadId); + if (!hThread) { + return false; + } + + CloseHandle(main_thread_handle); + main_thread_handle = hThread; + + // RIP + CONTEXT ct; + memset(&ct, 0, sizeof(ct)); + ct.ContextFlags = CONTEXT_ALL; + if (!GetThreadContext(main_thread_handle, &ct)) { + return false; + } + + void *vCode = VirtualAllocEx(process_handle, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (!vCode) { + return false; + } + +#pragma pack(push, 1) + typedef struct { + BYTE bCode[0x50]; + ULONG_PTR uLoadLibraryW; + ULONG_PTR uEntryPoint; + WCHAR wPath[MAX_PATH]; + } Loader64; +#pragma pack(pop) + + BYTE bLoader[sizeof(Loader64)] = { 0x48, 0x83, 0xEC, 0x30, 0x50, 0x53, 0x51, 0x52, 0x56, 0x57, 0x55, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x0D, 0x3E, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x28, 0x00, 0x00, 0x00, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5D, 0x5F, 0x5E, 0x5A, 0x59, 0x5B, 0x58, 0x48, 0x83, 0xC4, 0x30, 0xFF, 0x25, 0x0F, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; + ((Loader64 *)(&bLoader[0]))->uLoadLibraryW = (ULONG_PTR)LoadLibraryW; + ((Loader64 *)(&bLoader[0]))->uEntryPoint = (ULONG_PTR)ct.Rip; + memcpy_s(((Loader64 *)(&bLoader[0]))->wPath, dll_path.length() * sizeof(wchar_t), dll_path.c_str(), dll_path.length() * sizeof(wchar_t)); + + SIZE_T bw; + if (!WriteProcessMemory(process_handle, vCode, bLoader, sizeof(bLoader), &bw)) { + return false; + } + + CONTEXT ctInject = ct; + ctInject.Rip = (ULONG_PTR)vCode; + if (!SetThreadContext(main_thread_handle, &ctInject)) { + return false; + } + + is_successed = true; + return true; +} + +// Nς݂̃vZXInject +bool Injector::Inject() { + if (target_pi.dwProcessId == 0) { + return false; + } + + // Process + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, target_pi.dwProcessId); + if (!hProcess) { + return false; + } + process_handle = hProcess; + + // Thread + HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, target_pi.dwThreadId); + if (!hThread) { + return false; + } + main_thread_handle = hThread; + + // RIP + CONTEXT ct; + memset(&ct, 0, sizeof(ct)); + ct.ContextFlags = CONTEXT_ALL; + if (!GetThreadContext(main_thread_handle, &ct)) { + return false; + } + + void *vCode = VirtualAllocEx(process_handle, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (!vCode) { + return false; + } + +#pragma pack(push, 1) + typedef struct { + BYTE bCode[0x50]; + ULONG_PTR uLoadLibraryW; + ULONG_PTR uEntryPoint; + WCHAR wPath[MAX_PATH]; + } Loader64; +#pragma pack(pop) + + BYTE bLoader[sizeof(Loader64)] = { 0x48, 0x83, 0xEC, 0x30, 0x50, 0x53, 0x51, 0x52, 0x56, 0x57, 0x55, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x0D, 0x3E, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x28, 0x00, 0x00, 0x00, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5D, 0x5F, 0x5E, 0x5A, 0x59, 0x5B, 0x58, 0x48, 0x83, 0xC4, 0x30, 0xFF, 0x25, 0x0F, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; + ((Loader64 *)(&bLoader[0]))->uLoadLibraryW = (ULONG_PTR)LoadLibraryW; + ((Loader64 *)(&bLoader[0]))->uEntryPoint = (ULONG_PTR)ct.Rip; + memcpy_s(((Loader64 *)(&bLoader[0]))->wPath, dll_path.length() * sizeof(wchar_t), dll_path.c_str(), dll_path.length() * sizeof(wchar_t)); + + SIZE_T bw; + if (!WriteProcessMemory(process_handle, vCode, bLoader, sizeof(bLoader), &bw)) { + return false; + } + + CONTEXT ctInject = ct; + ctInject.Rip = (ULONG_PTR)vCode; + if (!SetThreadContext(main_thread_handle, &ctInject)) { + return false; + } + + is_successed = true; + return true; +} + +#else +bool Injector::Run() { + STARTUPINFO si; + PROCESS_INFORMATION pi; + + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + si.cb = sizeof(si); + + std::wstring wDir = target_path; + size_t pos_last_backslash = wDir.rfind(L'\\'); + if (pos_last_backslash != std::wstring::npos) { + wDir.erase(wDir.begin() + pos_last_backslash + 1, wDir.end()); + if (!CreateProcessW(target_path.c_str(), 0, 0, 0, FALSE, CREATE_SUSPENDED, 0, wDir.c_str(), &si, &pi)) { + return false; + } + } + else { + if (!CreateProcessW(target_path.c_str(), 0, 0, 0, FALSE, CREATE_SUSPENDED, 0, 0, &si, &pi)) { + return false; + } + } + + process_handle = pi.hProcess; + main_thread_handle = pi.hThread; + + // Process + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); + if (!hProcess) { + return false; + } + + CloseHandle(process_handle); + process_handle = hProcess; + + // Thread + HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pi.dwThreadId); + if (!hThread) { + return false; + } + + CloseHandle(main_thread_handle); + main_thread_handle = hThread; + + // EIP + CONTEXT ct; + memset(&ct, 0, sizeof(ct)); + ct.ContextFlags = CONTEXT_ALL; + if (!GetThreadContext(main_thread_handle, &ct)) { + return false; + } + + void *vPath = VirtualAllocEx(process_handle, NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); + if (!vPath) { + return false; + } + + SIZE_T bw; + if (!WriteProcessMemory(process_handle, vPath, dll_path.c_str(), (wcslen(dll_path.c_str()) + 1) * sizeof(wchar_t), &bw)) { + return false; + } + + void *vCode = VirtualAllocEx(process_handle, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (!vCode) { + return false; + } + + BYTE bLoader[] = { 0x50, 0x53, 0x68, 0xAB, 0xAB, 0xAB, 0xAB, 0xE8, 0x35, 0x02, 0x7C, 0x20, 0x5B, 0x58, 0xE9, 0x2E, 0x02, 0x7C, 0x20 }; + *(DWORD *)&bLoader[0x02 + 0x01] = (DWORD)vPath; + *(DWORD *)&bLoader[0x07 + 0x01] = (DWORD)LoadLibraryW - ((DWORD)vCode + 0x07) - 0x05; + *(DWORD *)&bLoader[0x0E + 0x01] = (DWORD)ct.Eip - ((DWORD)vCode + 0x0E) - 0x05; + if (!WriteProcessMemory(process_handle, vCode, bLoader, sizeof(bLoader), &bw)) { + return false; + } + + CONTEXT ctInject = ct; + ctInject.Eip = (DWORD)vCode; + if (!SetThreadContext(main_thread_handle, &ctInject)) { + return false; + } + + is_successed = true; + return true; +} +#endif \ No newline at end of file diff --git a/Simple/Simple64/SimpleInjector.h b/Simple/Simple64/SimpleInjector.h new file mode 100644 index 0000000..6c99d00 --- /dev/null +++ b/Simple/Simple64/SimpleInjector.h @@ -0,0 +1,21 @@ +#ifndef __INJECTOR_H__ +#define __INJECTOR_H__ + +class Injector { +private: + PROCESS_INFORMATION target_pi; + std::wstring target_path; + std::wstring dll_path; + HANDLE process_handle; + HANDLE main_thread_handle; + bool is_successed; + +public: + Injector(std::wstring wTargetPath, std::wstring wDllPath); + Injector(PROCESS_INFORMATION &pi, std::wstring wDllPath); + ~Injector(); + bool Run(); + bool Inject(); +}; + +#endif \ No newline at end of file diff --git a/Simple/Simple64/SimpleMemory.cpp b/Simple/Simple64/SimpleMemory.cpp new file mode 100644 index 0000000..0dfd520 --- /dev/null +++ b/Simple/Simple64/SimpleMemory.cpp @@ -0,0 +1,196 @@ +#include"Simple.h" + +Rosemary::Rosemary() { + init = GetSections(L"test", true); +} + +Rosemary::Rosemary(std::wstring wModuleName) { + init = GetSections(wModuleName); +} + +Rosemary::~Rosemary() { + +} + +bool Rosemary::GetSections(std::wstring wModuleName, bool bExe) { + DWORD pid = GetCurrentProcessId(); + + if (!pid) { + return false; + } + + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid); + + if (hSnapshot == INVALID_HANDLE_VALUE) { + return false; + } + + MODULEENTRY32W me; + memset(&me, 0, sizeof(me)); + me.dwSize = sizeof(me); + if (!Module32FirstW(hSnapshot, &me)) { + return false; + } + + std::vector module_list; + do { + module_list.push_back(me); + } while (Module32NextW(hSnapshot, &me)); + + CloseHandle(hSnapshot); + + for (size_t i = 0; i < module_list.size(); i++) { + if (bExe || _wcsicmp(module_list[i].szModule, wModuleName.c_str()) == 0) { + MEMORY_BASIC_INFORMATION mbi; + memset(&mbi, 0, sizeof(mbi)); + + ULONG_PTR section_base = (ULONG_PTR)module_list[i].modBaseAddr; + while (section_base < ((ULONG_PTR)module_list[i].modBaseAddr + module_list[i].modBaseSize) && (VirtualQuery((void *)section_base, &mbi, sizeof(mbi)) == sizeof(mbi))) { + if (mbi.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) { + section_list.push_back(mbi); + } + section_base += mbi.RegionSize; + } + + if (!section_list.size()) { + return false; + } + + return true; + } + } + + return false; +} + +ULONG_PTR Rosemary::Scan(std::wstring wAob, int res) { + if (!init) { + return 0; + } + + AobScan a(wAob); + + int count = 0; + for (size_t i = 0; i < section_list.size(); i++) { + for (ULONG_PTR uAddress = (ULONG_PTR)section_list[i].BaseAddress; uAddress < ((ULONG_PTR)section_list[i].BaseAddress + section_list[i].RegionSize); uAddress++) { + if (a.Compare(uAddress)) { + count++; + if (res) { + if (res != count) { + continue; + } + } + return uAddress; + } + } + } + + return 0; +} + +ULONG_PTR Rosemary::Scan(std::wstring wAob, bool(*Scanner)(ULONG_PTR)) { + if (!init) { + return 0; + } + + if (!Scanner) { + return 0; + } + + AobScan a(wAob); + + for (size_t i = 0; i < section_list.size(); i++) { + for (ULONG_PTR uAddress = (ULONG_PTR)section_list[i].BaseAddress; uAddress < ((ULONG_PTR)section_list[i].BaseAddress + section_list[i].RegionSize); uAddress++) { + if (a.Compare(uAddress)) { + if (Scanner(uAddress)) { + return uAddress; + } + } + } + } + + return 0; +} + +bool Rosemary::Patch(std::wstring wAob, std::wstring wCode) { + ULONG_PTR uAddress = Scan(wAob); + + if (!uAddress) { + return false; + } + + Code c(wCode); + return c.Write(uAddress); +} + +bool Rosemary::Patch(ULONG_PTR uAddress, std::wstring wCode) { + if (!uAddress) { + return false; + } + + Code c(wCode); + return c.Write(uAddress); +} + +bool Rosemary::Backup(std::vector &vSection, std::vector &vBackup) { + vSection.clear(); + vBackup.clear(); + + if (!init) { + return false; + } + + for (size_t i = 0; i < section_list.size(); i++) { + void *memory = VirtualAlloc(NULL, section_list[i].RegionSize, MEM_COMMIT, PAGE_READWRITE); + if (!memory) { + vBackup.clear(); + return false; + } + for (size_t j = 0; j < section_list[i].RegionSize; j++) { + ((BYTE *)memory)[j] = *(BYTE *)((ULONG_PTR)section_list[i].BaseAddress + j); + } + vBackup.push_back(memory); + } + + vSection = section_list; + return true; +} + +bool Rosemary::Hook(ULONG_PTR uAddress, void *HookFunction, ULONG_PTR uNop) { + DWORD old = 0; + if (!VirtualProtect((void *)uAddress, 5 + uNop, PAGE_EXECUTE_READWRITE, &old)) { + return false; + } + + *(BYTE *)uAddress = 0xE9; + *(DWORD *)(uAddress + 0x01) = (DWORD)((ULONG_PTR)HookFunction - uAddress) - 0x05; + + for (size_t i = 0; i < uNop; i++) { + ((BYTE *)uAddress)[5 + i] = 0x90; + } + + VirtualProtect((void *)uAddress, 5 + uNop, old, &old); + return true; +} + +bool Rosemary::JMP(ULONG_PTR uPrev, ULONG_PTR uNext, ULONG_PTR uNop) { + DWORD old = 0; + if (!VirtualProtect((void *)uPrev, 5 + uNop, PAGE_EXECUTE_READWRITE, &old)) { + return false; + } + + *(BYTE *)uPrev = 0xE9; + *(DWORD *)(uPrev + 0x01) = (DWORD)(uNext - uPrev) - 0x05; + + for (size_t i = 0; i < uNop; i++) { + ((BYTE *)uPrev)[5 + i] = 0x90; + } + + VirtualProtect((void *)uPrev, 5 + uNop, old, &old); + return true; +} + +bool Rosemary::GetSectionList(std::vector &vSection) { + vSection = section_list; + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimpleMemory.h b/Simple/Simple64/SimpleMemory.h new file mode 100644 index 0000000..4038e74 --- /dev/null +++ b/Simple/Simple64/SimpleMemory.h @@ -0,0 +1,55 @@ +#ifndef __ROSEMARY_H__ +#define __ROSEMARY_H__ + +class Code { +private: + bool init; + std::vector code; + + bool CreateCode(std::wstring wCode); + +public: + Code(std::wstring wCode); + bool Write(ULONG_PTR uAddress); +}; + + +class AobScan { +private: + bool init; + std::vector array_of_bytes; + std::vector mask; + + bool CreateAob(std::wstring wAob); + +public: + AobScan(std::wstring wAob); +#ifndef _WIN64 + bool Compare(unsigned long int uAddress); +#else + bool Compare(unsigned __int64 uAddress); +#endif +}; + + +class Rosemary { +private: + bool init; + std::vector section_list; + bool GetSections(std::wstring wModuleName, bool bExe = false); + +public: + Rosemary(); + Rosemary(std::wstring wModuleName); + ~Rosemary(); + ULONG_PTR Scan(std::wstring wAob, int res = 0); + ULONG_PTR Scan(std::wstring wAob, bool (*Scanner)(ULONG_PTR)); + bool Patch(std::wstring wAob, std::wstring wCode); + bool Patch(ULONG_PTR uAddress, std::wstring wCode); + bool Backup(std::vector &vSection, std::vector &vBackup); + bool JMP(ULONG_PTR uPrev, ULONG_PTR uNext, ULONG_PTR uNop = 0); + bool Hook(ULONG_PTR uAddress, void *HookFunction, ULONG_PTR uNop = 0); + bool GetSectionList(std::vector &vSection); +}; + +#endif \ No newline at end of file diff --git a/Simple/Simple64/SimpleMemoryAobScan.cpp b/Simple/Simple64/SimpleMemoryAobScan.cpp new file mode 100644 index 0000000..22b88d6 --- /dev/null +++ b/Simple/Simple64/SimpleMemoryAobScan.cpp @@ -0,0 +1,106 @@ +#include"Simple.h" + +AobScan::AobScan(std::wstring wAob) { + init = CreateAob(wAob); +} + +bool AobScan::CreateAob(std::wstring wAob) { + if (wAob.length() < 2) { + return false; + } + + std::wstring Aob; + + for (size_t i = 0; i < wAob.length(); i++) { + if (wAob[i] == L' ') { + continue; + } + if (L'0' <= wAob[i] && wAob[i] <= L'9') { + Aob.push_back(wAob[i]); + continue; + } + if (L'A' <= wAob[i] && wAob[i] <= L'F') { + Aob.push_back(wAob[i]); + continue; + } + if (L'a' <= wAob[i] && wAob[i] <= L'f') { + Aob.push_back((unsigned short)wAob[i] - 0x20); + continue; + } + if (wAob[i] == L'?' || wAob[i] == L'*') { + Aob.push_back(L'?'); + continue; + } + return false; + } + + if (Aob.length() % 2) { + return false; + } + + for (size_t i = 0; i < Aob.length(); i += 2) { + unsigned char t = 0x00; + int m = 0; + if (Aob[i] == L'?') { + m |= 1; + } + if (L'0' <= Aob[i] && Aob[i] <= L'9') { + t |= ((unsigned char)Aob[i] - 0x30) << 4; + } + else if (L'A' <= Aob[i] && Aob[i] <= L'F') { + t |= ((unsigned char)Aob[i] - 0x37) << 4; + } + if (Aob[i + 1] == L'?') { + m |= 2; + } + if (L'0' <= Aob[i + 1] && Aob[i + 1] <= L'9') { + t |= ((unsigned char)Aob[i + 1] - 0x30); + } + else if (L'A' <= Aob[i + 1] && Aob[i + 1] <= L'F') { + t |= ((unsigned char)Aob[i + 1] - 0x37); + } + + array_of_bytes.push_back(t); + mask.push_back(m); + } + + return true; +} + +#ifndef _WIN64 +bool AobScan::Compare(unsigned long int uAddress) { +#else +bool AobScan::Compare(unsigned __int64 uAddress) { +#endif + if (!init) { + return false; + } + + try { + for (size_t i = 0; i < array_of_bytes.size(); i++) { + // ignore + if (mask[i] == 3) { + continue; + } + // compare + if (mask[i] == 0 && ((unsigned char *)uAddress)[i] == array_of_bytes[i]) { + continue; + } + // ignore high + if (mask[i] == 1 && (((unsigned char *)uAddress)[i] & 0x0F) == (array_of_bytes[i] & 0x0F)) { + continue; + } + // ignore low + if (mask[i] == 2 && (((unsigned char *)uAddress)[i] & 0xF0) == (array_of_bytes[i] & 0xF0)) { + continue; + } + + return false; + } + } + catch (...) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimpleMemoryCode.cpp b/Simple/Simple64/SimpleMemoryCode.cpp new file mode 100644 index 0000000..549c2c6 --- /dev/null +++ b/Simple/Simple64/SimpleMemoryCode.cpp @@ -0,0 +1,78 @@ +#include"Simple.h" + +Code::Code(std::wstring wCode) { + init = CreateCode(wCode); +} + +bool Code::CreateCode(std::wstring wCode) { + if (wCode.length() < 2) { + return false; + } + + std::wstring Code; + + for (size_t i = 0; i < wCode.length(); i++) { + if (wCode[i] == L' ') { + continue; + } + if (L'0' <= wCode[i] && wCode[i] <= L'9') { + Code.push_back(wCode[i]); + continue; + } + if (L'A' <= wCode[i] && wCode[i] <= L'F') { + Code.push_back(wCode[i]); + continue; + } + if (L'a' <= wCode[i] && wCode[i] <= L'f') { + Code.push_back((unsigned short)wCode[i] - 0x20); + continue; + } + return false; + } + + if (Code.length() % 2) { + return false; + } + + for (size_t i = 0; i < Code.length(); i += 2) { + unsigned char t = 0x00; + if (L'0' <= Code[i] && Code[i] <= L'9') { + t |= ((unsigned char)Code[i] - 0x30) << 4; + } + else if (L'A' <= Code[i] && Code[i] <= L'F') { + t |= ((unsigned char)Code[i] - 0x37) << 4; + } + if (L'0' <= Code[i + 1] && Code[i + 1] <= L'9') { + t |= ((unsigned char)Code[i + 1] - 0x30); + } + else if (L'A' <= Code[i + 1] && Code[i + 1] <= L'F') { + t |= ((unsigned char)Code[i + 1] - 0x37); + } + + code.push_back(t); + } + + return true; +} + +bool Code::Write(ULONG_PTR uAddress) { + if (!init) { + return false; + } + + if (!code.size()) { + return false; + } + + DWORD old = 0; + if (!VirtualProtect((void *)uAddress, code.size(), PAGE_EXECUTE_READWRITE, &old)) { + return false; + } + + for (size_t i = 0; i < code.size(); i++) { + ((BYTE *)uAddress)[i] = code[i]; + } + + VirtualProtect((void *)uAddress, code.size(), old, &old); + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimplePipe.h b/Simple/Simple64/SimplePipe.h new file mode 100644 index 0000000..96b1e19 --- /dev/null +++ b/Simple/Simple64/SimplePipe.h @@ -0,0 +1,64 @@ +#ifndef __SIMPLEPIPE_H__ +#define __SIMPLEPIPE_H__ + +#define PIPE_MESSAGE_MAGIC 0xA11CE + +#pragma pack(push, 1) +typedef struct { + DWORD magic; + ULONG_PTR length; +#ifndef _WIN64 + DWORD padding; +#endif + BYTE data[1]; +} PipeMessage; +#pragma pack(pop) + + +class PipeServerThread { +private: + HANDLE server_pipe; + bool (*communicate)(PipeServerThread&); + +public: + PipeServerThread(HANDLE hPipe, bool (*function)(PipeServerThread&)); + ~PipeServerThread(); + + bool Run(); + bool Send(BYTE *bData, ULONG_PTR uLength); + bool Recv(std::vector &vData); + bool Send(std::wstring wText); + bool Recv(std::wstring &wText); +}; + +class PipeServer { +private: + std::wstring pipe_name; + static bool (*communicate)(PipeServerThread&); + + static bool Communicate(HANDLE server_pipe); + +public: + PipeServer(std::wstring wPipeName); + ~PipeServer(); + + bool SetCommunicate(bool (*function)(PipeServerThread&)); + bool Run(); +}; + +class PipeClient { +private: + std::wstring pipe_name; + HANDLE client_pipe; + +public: + PipeClient(std::wstring wPipeName); + ~PipeClient(); + + bool Run(); + bool Send(BYTE *bData, ULONG_PTR uLength); + bool Recv(std::vector &vData); + bool Send(std::wstring wText); + bool Recv(std::wstring &wText); +}; +#endif \ No newline at end of file diff --git a/Simple/Simple64/SimplePipeClient.cpp b/Simple/Simple64/SimplePipeClient.cpp new file mode 100644 index 0000000..bd6778c --- /dev/null +++ b/Simple/Simple64/SimplePipeClient.cpp @@ -0,0 +1,95 @@ +#include"Simple.h" + +PipeClient::PipeClient(std::wstring wPipeName) { + pipe_name = L"\\\\.\\pipe\\" + wPipeName; + client_pipe = INVALID_HANDLE_VALUE; +} + +PipeClient::~PipeClient() { + if (client_pipe != INVALID_HANDLE_VALUE) { + CloseHandle(client_pipe); + } +} + +bool PipeClient::Run() { + client_pipe = CreateFileW(pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (client_pipe == INVALID_HANDLE_VALUE) { + return false; + } + + return true; +} + +bool PipeClient::Send(BYTE *bData, ULONG_PTR uLength) { + if (client_pipe == INVALID_HANDLE_VALUE) { + return false; + } + + union { + BYTE *b; + PipeMessage *pm; + }; + + ULONG_PTR pm_length = sizeof(PipeMessage) - 1 + uLength; + + b = new BYTE[pm_length]; + + if (!b) { + return false; + } + + pm->magic = PIPE_MESSAGE_MAGIC; + pm->length = uLength; + memcpy_s(pm->data, uLength, bData, uLength); + + DWORD wb = 0; + BOOL ret = WriteFile(client_pipe, pm, (DWORD)pm_length, &wb, NULL); + FlushFileBuffers(client_pipe); + + delete[] b; + return ret; +} + +bool PipeClient::Recv(std::vector &vData) { + if (client_pipe == INVALID_HANDLE_VALUE) { + return false; + } + + PipeMessage header; + memset(&header, 0, sizeof(header)); + DWORD pm_length = sizeof(PipeMessage) - 1; + + DWORD rb = 0; + if (!ReadFile(client_pipe, &header, pm_length, &rb, NULL)) { + return false; + } + FlushFileBuffers(client_pipe); + + if (header.magic != PIPE_MESSAGE_MAGIC) { + return false; + } + + vData.resize(header.length); + if (!ReadFile(client_pipe, &vData[0], (DWORD)header.length, &rb, NULL)) { + return false; + } + FlushFileBuffers(client_pipe); + + return true; +} + +bool PipeClient::Send(std::wstring wText) { + return Send((BYTE *)wText.c_str(), (wText.length() + 1) * sizeof(wchar_t)); +} + +bool PipeClient::Recv(std::wstring &wText) { + std::vector data; + if (!Recv(data)) { + return false; + } + + wText = (wchar_t *)&data[0]; + + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimplePipeServer.cpp b/Simple/Simple64/SimplePipeServer.cpp new file mode 100644 index 0000000..20119e2 --- /dev/null +++ b/Simple/Simple64/SimplePipeServer.cpp @@ -0,0 +1,42 @@ +#include"Simple.h" + +bool(*PipeServer::communicate)(PipeServerThread&) = NULL; + +PipeServer::PipeServer(std::wstring wPipeName) { + pipe_name = L"\\\\.\\pipe\\" + wPipeName; +} + +PipeServer::~PipeServer() { + +} + +bool PipeServer::Run() { + HANDLE server_pipe = CreateNamedPipeW(pipe_name.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1, 0, 0, NULL); + + if (server_pipe == INVALID_HANDLE_VALUE) { + return false; + } + + if (!ConnectNamedPipe(server_pipe, NULL)) { + return false; + } + + HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Communicate, (void *)server_pipe, NULL, NULL); + if (!hThread) { + return false; + } + + CloseHandle(hThread); + return Run(); +} + +bool PipeServer::SetCommunicate(bool (*function)(PipeServerThread&)) { + communicate = function; + return true; +} + +bool PipeServer::Communicate(HANDLE server_pipe) { + PipeServerThread psh(server_pipe, communicate); + psh.Run(); + return true; +} \ No newline at end of file diff --git a/Simple/Simple64/SimplePipeServerThread.cpp b/Simple/Simple64/SimplePipeServerThread.cpp new file mode 100644 index 0000000..34f0773 --- /dev/null +++ b/Simple/Simple64/SimplePipeServerThread.cpp @@ -0,0 +1,91 @@ +#include"Simple.h" + +PipeServerThread::PipeServerThread(HANDLE hPipe, bool(*function)(PipeServerThread&)) { + server_pipe = hPipe; + communicate = function; +} + +PipeServerThread::~PipeServerThread() { + if (server_pipe != INVALID_HANDLE_VALUE) { + DisconnectNamedPipe(server_pipe); + CloseHandle(server_pipe); + } +} + +bool PipeServerThread::Run() { + if (communicate) { + communicate(*this); + } + return true; +} + +bool PipeServerThread::Send(BYTE *bData, ULONG_PTR uLength) { + if (server_pipe == INVALID_HANDLE_VALUE) { + return false; + } + + union { + BYTE *b; + PipeMessage *pm; + }; + + ULONG_PTR pm_length = sizeof(PipeMessage) - 1 + uLength; + + b = new BYTE[pm_length]; + + if (!b) { + return false; + } + + pm->magic = PIPE_MESSAGE_MAGIC; + pm->length = uLength; + memcpy_s(pm->data, uLength, bData, uLength); + + DWORD wb = 0; + BOOL ret = WriteFile(server_pipe, pm, (DWORD)pm_length, &wb, NULL); + FlushFileBuffers(server_pipe); + delete[] b; + return ret; +} + +bool PipeServerThread::Recv(std::vector &vData) { + if (server_pipe == INVALID_HANDLE_VALUE) { + return false; + } + + PipeMessage header; + memset(&header, 0, sizeof(header)); + DWORD pm_length = sizeof(PipeMessage) - 1; + + DWORD rb = 0; + if (!ReadFile(server_pipe, &header, pm_length, &rb, NULL)) { + return false; + } + FlushFileBuffers(server_pipe); + + if (header.magic != PIPE_MESSAGE_MAGIC) { + return false; + } + + vData.resize(header.length); + if (!ReadFile(server_pipe, &vData[0], (DWORD)header.length, &rb, NULL)) { + return false; + } + FlushFileBuffers(server_pipe); + return true; +} + +bool PipeServerThread::Send(std::wstring wText) { + return Send((BYTE *)wText.c_str(), (wText.length() + 1) * sizeof(wchar_t)); +} + +bool PipeServerThread::Recv(std::wstring &wText) { + std::vector data; + if (!Recv(data)) { + return false; + } + + wText = (wchar_t *)&data[0]; + + return true; +} \ No newline at end of file