mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add RewriteRemoteEntryPointW and deprecate RewriteRemoteEntryPoint
This commit is contained in:
parent
1a9e3fd80b
commit
d0680bf1f7
1 changed files with 35 additions and 14 deletions
|
|
@ -226,6 +226,18 @@ void write_process_memory_or_throw(HANDLE hProcess, void* pAddress, const T& dat
|
||||||
return write_process_memory_or_throw(hProcess, pAddress, &data, sizeof data);
|
return write_process_memory_or_throw(hProcess, pAddress, &data, sizeof data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string from_utf16(const std::wstring& wstr, UINT codePage = CP_UTF8) {
|
||||||
|
std::string str(WideCharToMultiByte(codePage, 0, &wstr[0], static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr), 0);
|
||||||
|
WideCharToMultiByte(codePage, 0, &wstr[0], static_cast<int>(wstr.size()), &str[0], static_cast<int>(str.size()), nullptr, nullptr);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring to_utf16(const std::string& str, UINT codePage = CP_UTF8, bool errorOnInvalidChars = false) {
|
||||||
|
std::wstring wstr(MultiByteToWideChar(codePage, 0, &str[0], static_cast<int>(str.size()), nullptr, 0), 0);
|
||||||
|
MultiByteToWideChar(codePage, errorOnInvalidChars ? MB_ERR_INVALID_CHARS : 0, &str[0], static_cast<int>(str.size()), &wstr[0], static_cast<int>(wstr.size()));
|
||||||
|
return wstr;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Rewrite target process' entry point so that this DLL can be loaded and executed first.
|
/// @brief Rewrite target process' entry point so that this DLL can be loaded and executed first.
|
||||||
/// @param hProcess Process handle.
|
/// @param hProcess Process handle.
|
||||||
/// @param pcwzPath Path to target process.
|
/// @param pcwzPath Path to target process.
|
||||||
|
|
@ -236,7 +248,7 @@ void write_process_memory_or_throw(HANDLE hProcess, void* pAddress, const T& dat
|
||||||
/// Instead, we have to enumerate through all the files mapped into target process' virtual address space and find the base address
|
/// Instead, we have to enumerate through all the files mapped into target process' virtual address space and find the base address
|
||||||
/// of memory region corresponding to the path given.
|
/// of memory region corresponding to the path given.
|
||||||
///
|
///
|
||||||
DllExport DWORD WINAPI RewriteRemoteEntryPoint(HANDLE hProcess, const wchar_t* pcwzPath, const char* pcszLoadInfo) {
|
DllExport DWORD WINAPI RewriteRemoteEntryPointW(HANDLE hProcess, const wchar_t* pcwzPath, const wchar_t* pcwzLoadInfo) {
|
||||||
try {
|
try {
|
||||||
const auto base_address = reinterpret_cast<char*>(get_mapped_image_base_address(hProcess, pcwzPath));
|
const auto base_address = reinterpret_cast<char*>(get_mapped_image_base_address(hProcess, pcwzPath));
|
||||||
|
|
||||||
|
|
@ -260,17 +272,18 @@ DllExport DWORD WINAPI RewriteRemoteEntryPoint(HANDLE hProcess, const wchar_t* p
|
||||||
nethost_path.resize(nethost_path.size() + 1); // ensure null termination
|
nethost_path.resize(nethost_path.size() + 1); // ensure null termination
|
||||||
auto nethost_path_bytes = std::span(reinterpret_cast<const char*>(&nethost_path[0]), std::span(nethost_path).size_bytes());
|
auto nethost_path_bytes = std::span(reinterpret_cast<const char*>(&nethost_path[0]), std::span(nethost_path).size_bytes());
|
||||||
|
|
||||||
const auto load_info_size = strlen(pcszLoadInfo) + 1;
|
auto load_info = from_utf16(pcwzLoadInfo);
|
||||||
|
load_info.resize(load_info.size() + 1); //ensure null termination
|
||||||
|
|
||||||
// Allocate full buffer in advance to keep reference to trampoline valid.
|
// Allocate full buffer in advance to keep reference to trampoline valid.
|
||||||
std::vector<uint8_t> buffer(sizeof TrampolineTemplate + load_info_size + nethost_path_bytes.size() + path_bytes.size());
|
std::vector<uint8_t> buffer(sizeof TrampolineTemplate + load_info.size() + nethost_path_bytes.size() + path_bytes.size());
|
||||||
auto& trampoline = *reinterpret_cast<TrampolineTemplate*>(&buffer[0]);
|
auto& trampoline = *reinterpret_cast<TrampolineTemplate*>(&buffer[0]);
|
||||||
const auto load_info_buffer = std::span(buffer).subspan(sizeof trampoline, load_info_size);
|
const auto load_info_buffer = std::span(buffer).subspan(sizeof trampoline, load_info.size());
|
||||||
const auto nethost_path_buffer = std::span(buffer).subspan(sizeof trampoline + load_info_size, nethost_path_bytes.size());
|
const auto nethost_path_buffer = std::span(buffer).subspan(sizeof trampoline + load_info.size(), nethost_path_bytes.size());
|
||||||
const auto dalamud_path_buffer = std::span(buffer).subspan(sizeof trampoline + load_info_size + nethost_path_bytes.size(), path_bytes.size());
|
const auto dalamud_path_buffer = std::span(buffer).subspan(sizeof trampoline + load_info.size() + nethost_path_bytes.size(), path_bytes.size());
|
||||||
|
|
||||||
new(&trampoline)TrampolineTemplate(); // this line initializes given buffer instead of allocating memory
|
new(&trampoline)TrampolineTemplate(); // this line initializes given buffer instead of allocating memory
|
||||||
memcpy(&load_info_buffer[0], pcszLoadInfo, load_info_buffer.size());
|
memcpy(&load_info_buffer[0], &load_info[0], load_info_buffer.size());
|
||||||
memcpy(&nethost_path_buffer[0], &nethost_path_bytes[0], nethost_path_buffer.size());
|
memcpy(&nethost_path_buffer[0], &nethost_path_bytes[0], nethost_path_buffer.size());
|
||||||
memcpy(&dalamud_path_buffer[0], &path_bytes[0], dalamud_path_buffer.size());
|
memcpy(&dalamud_path_buffer[0], &path_bytes[0], dalamud_path_buffer.size());
|
||||||
|
|
||||||
|
|
@ -313,6 +326,20 @@ DllExport DWORD WINAPI RewriteRemoteEntryPoint(HANDLE hProcess, const wchar_t* p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @deprecated
|
||||||
|
DllExport DWORD WINAPI RewriteRemoteEntryPoint(HANDLE hProcess, const wchar_t* pcwzPath, const char* pcszLoadInfo) {
|
||||||
|
return RewriteRemoteEntryPointW(hProcess, pcwzPath, to_utf16(pcszLoadInfo).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_for_game_window() {
|
||||||
|
HWND game_window;
|
||||||
|
while (!(game_window = try_find_game_window())) {
|
||||||
|
WaitForInputIdle(GetCurrentProcess(), INFINITE);
|
||||||
|
Sleep(100);
|
||||||
|
};
|
||||||
|
SendMessageW(game_window, WM_NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Entry point function "called" instead of game's original main entry point.
|
/// @brief Entry point function "called" instead of game's original main entry point.
|
||||||
/// @param params Parameters set up from RewriteRemoteEntryPoint.
|
/// @param params Parameters set up from RewriteRemoteEntryPoint.
|
||||||
DllExport void WINAPI RewrittenEntryPoint(RewrittenEntryPointParameters& params) {
|
DllExport void WINAPI RewrittenEntryPoint(RewrittenEntryPointParameters& params) {
|
||||||
|
|
@ -339,13 +366,7 @@ DllExport void WINAPI RewrittenEntryPoint(RewrittenEntryPointParameters& params)
|
||||||
SetEvent(params.hMainThreadContinue);
|
SetEvent(params.hMainThreadContinue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until game main window shows up and becomes responsive.
|
wait_for_game_window();
|
||||||
HWND game_window;
|
|
||||||
while (!(game_window = try_find_game_window())) {
|
|
||||||
WaitForInputIdle(GetCurrentProcess(), INFINITE);
|
|
||||||
Sleep(100);
|
|
||||||
};
|
|
||||||
SendMessageW(game_window, WM_NULL, 0, 0);
|
|
||||||
|
|
||||||
Initialize(&loadInfo[0]);
|
Initialize(&loadInfo[0]);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue