-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
1,244 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,157 @@ | ||
#include <windows.h> | ||
#include <detours.h> | ||
#include <Shlwapi.h> | ||
#pragma comment(lib, "shlwapi.lib") | ||
|
||
#include "path.h" | ||
#include "util.h" | ||
#include "directory.h" | ||
#include "encoding.h" | ||
#include "resource.h" | ||
|
||
#pragma comment(linker, "/MERGE:\".detourd=.data\"") | ||
#pragma comment(linker, "/MERGE:\".detourc=.rdata\"") | ||
|
||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) | ||
{ | ||
UNREFERENCED_PARAMETER(hPrevInstance); | ||
constexpr size_t MaxPath = 1024u; | ||
#ifdef _UNICODE | ||
#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_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 | ||
#endif | ||
|
||
wchar_t appFullPathW[MaxPath]; | ||
wchar_t gameFullPathW[MaxPath]; | ||
GetModuleFileNameW(hInstance, appFullPathW, MaxPath); | ||
|
||
int argc = 0; | ||
LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc); | ||
if (argc) | ||
{ | ||
wchar_t* arg = argv[0]; | ||
memcpy(gameFullPathW, arg, (lstrlenW(arg) + 1) * 2); | ||
static std::wstring g_LoaderFullPath; //加载器全路径 | ||
static std::wstring g_LoaderCurrentDirectory; //加载器目录 | ||
static std::wstring g_KrkrExeFullPath; //Krkr游戏主程序全路径 | ||
static std::wstring g_KrkrExeDirectory; //Krkr游戏目录 | ||
|
||
if (lstrcmpW(appFullPathW, gameFullPathW)) | ||
/// <summary> | ||
/// 主窗体消息循环 | ||
/// </summary> | ||
/// <param name="hwnd">窗口句柄</param> | ||
/// <param name="msg">消息</param> | ||
/// <param name="wParam"></param> | ||
/// <param name="lParam"></param> | ||
INT_PTR CALLBACK LoaderDialogWindProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (msg) | ||
{ | ||
case WM_COMMAND: | ||
{ | ||
wchar_t gameCurrentDirectory[MaxPath]; | ||
char injectDllFullPathA[MaxPath]; | ||
|
||
std::wstring injectDllFileName = std::wstring(); | ||
switch (LOWORD(wParam)) | ||
{ | ||
memcpy(gameCurrentDirectory, gameFullPathW, MaxPath); | ||
*(PathFindFileNameW(gameCurrentDirectory) - 1u) = L'\0'; | ||
case IDC_Extractor: | ||
{ | ||
injectDllFileName = L"CxdecExtractorUI.dll"; | ||
break; | ||
} | ||
case IDC_StringDumper: | ||
{ | ||
injectDllFileName = L"CxdecStringDumper.dll"; | ||
break; | ||
} | ||
case IDC_KeyDumper: | ||
{ | ||
//NotImpl | ||
::MessageBoxW(nullptr, L"此功能暂未实现", L"错误", MB_OK); | ||
break; | ||
} | ||
} | ||
|
||
if (!injectDllFileName.empty()) | ||
{ | ||
constexpr const char InjectDllNameA[] = "CxdecExtractorUI.dll"; | ||
GetModuleFileNameA(hInstance, injectDllFullPathA, MaxPath); | ||
char* dllName = PathFindFileNameA(injectDllFullPathA); | ||
memcpy(dllName, InjectDllNameA, sizeof(InjectDllNameA)); | ||
} | ||
std::wstring injectDllFullPath = Path::Combine(g_LoaderCurrentDirectory, injectDllFileName); | ||
std::string injectDllFullPathA = Encoding::UnicodeToAnsi(injectDllFullPath, Encoding::CodePage::ACP); | ||
|
||
STARTUPINFO si{ 0 }; | ||
si.cb = sizeof(si); | ||
PROCESS_INFORMATION pi{ 0 }; | ||
STARTUPINFOW si{ }; | ||
si.cb = sizeof(si); | ||
PROCESS_INFORMATION pi{ }; | ||
|
||
if (DetourCreateProcessWithDllW(gameFullPathW, NULL, NULL, NULL, FALSE, 0, NULL, gameCurrentDirectory, &si, &pi, injectDllFullPathA, NULL)) | ||
{ | ||
CloseHandle(pi.hThread); | ||
CloseHandle(pi.hProcess); | ||
if (DetourCreateProcessWithDllW(g_KrkrExeFullPath.c_str(), NULL, NULL, NULL, FALSE, 0u, NULL, g_KrkrExeDirectory.c_str(), &si, &pi, injectDllFullPathA.c_str(), NULL)) | ||
{ | ||
::CloseHandle(pi.hThread); | ||
::CloseHandle(pi.hProcess); | ||
|
||
//运行成功 关闭窗口 | ||
::PostMessageW(hwnd, WM_CLOSE, 0u, 0u); | ||
} | ||
else | ||
{ | ||
::MessageBoxW(nullptr, L"创建进程错误", L"错误", MB_OK); | ||
} | ||
} | ||
else | ||
return TRUE; | ||
} | ||
case WM_CLOSE: | ||
{ | ||
::DestroyWindow(hwnd); | ||
return TRUE; | ||
} | ||
case WM_DESTROY: | ||
{ | ||
::PostQuitMessage(0); | ||
return TRUE; | ||
} | ||
} | ||
return FALSE; | ||
} | ||
|
||
|
||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) | ||
{ | ||
UNREFERENCED_PARAMETER(hPrevInstance); | ||
|
||
std::wstring loaderFullPath = Util::GetAppPathW(); | ||
std::wstring loaderCurrentDirectory = Path::GetDirectoryName(loaderFullPath); | ||
std::wstring krkrExeFullPath = std::wstring(); | ||
std::wstring krkrExeDirectory = std::wstring(); | ||
|
||
//获取启动参数 | ||
{ | ||
int argc = 0; | ||
LPWSTR* argv = ::CommandLineToArgvW(lpCmdLine, &argc); | ||
if (argc) | ||
{ | ||
wchar_t* arg = argv[0]; | ||
|
||
krkrExeFullPath = std::wstring(arg); | ||
krkrExeDirectory = Path::GetDirectoryName(krkrExeFullPath); | ||
} | ||
::LocalFree(argv); | ||
} | ||
|
||
g_LoaderFullPath = loaderFullPath; | ||
g_LoaderCurrentDirectory = loaderCurrentDirectory; | ||
g_KrkrExeFullPath = krkrExeFullPath; | ||
g_KrkrExeDirectory = krkrExeDirectory; | ||
|
||
//启动加载器 | ||
{ | ||
if (!krkrExeFullPath.empty() && krkrExeFullPath != loaderFullPath) | ||
{ | ||
HWND hwnd = ::CreateDialogParamW((HINSTANCE)hInstance, MAKEINTRESOURCEW(IDD_MainForm), NULL, LoaderDialogWindProc, 0u); | ||
::ShowWindow(hwnd, SW_NORMAL); | ||
|
||
MSG msg{ }; | ||
while (BOOL ret = ::GetMessageW(&msg, NULL, 0u, 0u)) | ||
{ | ||
MessageBoxW(nullptr, L"创建进程错误", L"错误", MB_OK); | ||
if (ret == -1) | ||
{ | ||
return -1; | ||
} | ||
else | ||
{ | ||
::TranslateMessage(&msg); | ||
::DispatchMessageW(&msg); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
MessageBoxW(nullptr, L"请拖拽游戏主程序到启动器", L"错误", MB_OK); | ||
::MessageBoxW(nullptr, L"请拖拽游戏主程序到启动器", L"错误", MB_OK); | ||
} | ||
} | ||
LocalFree(argv); | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.