Skip to content

Commit

Permalink
Updated the code to allow unicode names
Browse files Browse the repository at this point in the history
  • Loading branch information
Kariaro committed May 11, 2021
1 parent 1dce138 commit e320b53
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 78 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -339,4 +339,5 @@ ASALocalRun/
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb
healthchecksdb
/PluginDevFolder/PlaygroundPlugin
32 changes: 32 additions & 0 deletions SMInjector/SMInjector.sln
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,58 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SMLuaReaderPlugin", "..\Plu
{81368E09-9FA2-4F28-9915-22FE758BFD48} = {81368E09-9FA2-4F28-9915-22FE758BFD48}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlaygroundPlugin", "..\PluginDevFolder\PlaygroundPlugin\PlaygroundPlugin.vcxproj", "{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}"
ProjectSection(ProjectDependencies) = postProject
{81368E09-9FA2-4F28-9915-22FE758BFD48} = {81368E09-9FA2-4F28-9915-22FE758BFD48}
EndProjectSection
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
{E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Debug|x64.ActiveCfg = Debug|x64
{E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Debug|x86.ActiveCfg = Debug|x64
{E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Release|x64.ActiveCfg = Release|x64
{E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Release|x64.Build.0 = Release|x64
{E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Release|x86.ActiveCfg = Release|x64
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Debug|x64.ActiveCfg = Debug|x64
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Debug|x86.ActiveCfg = Debug|Win32
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Debug|x86.Build.0 = Debug|Win32
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x64.ActiveCfg = Release|x64
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x64.Build.0 = Release|x64
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x86.ActiveCfg = Release|Win32
{81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x86.Build.0 = Release|Win32
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Debug|x64.ActiveCfg = Debug|x64
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Debug|x86.ActiveCfg = Debug|Win32
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Debug|x86.Build.0 = Debug|Win32
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x64.ActiveCfg = Release|x64
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x64.Build.0 = Release|x64
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x86.ActiveCfg = Release|Win32
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x86.Build.0 = Release|Win32
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Debug|x64.ActiveCfg = Debug|x64
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Debug|x86.ActiveCfg = Debug|Win32
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Debug|x86.Build.0 = Debug|Win32
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x64.ActiveCfg = Release|x64
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x64.Build.0 = Release|x64
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x86.ActiveCfg = Release|Win32
{16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x86.Build.0 = Release|Win32
{13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Debug|x64.ActiveCfg = Debug|x64
{13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Debug|x86.ActiveCfg = Debug|x64
{13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x64.ActiveCfg = Release|x64
{13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x64.Build.0 = Release|x64
{13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x86.ActiveCfg = Release|x64
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x64.ActiveCfg = Debug|x64
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x64.Build.0 = Debug|x64
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x86.ActiveCfg = Debug|Win32
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x86.Build.0 = Debug|Win32
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x64.ActiveCfg = Release|x64
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x64.Build.0 = Release|x64
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x86.ActiveCfg = Release|Win32
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -53,6 +84,7 @@ Global
{F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7}
{16BDCA26-D20C-4AC4-8DB3-9C108719B752} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7}
{13E88C11-DEB6-47D5-9382-4E5D484A58C2} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7}
{53AE29AD-5DEB-4557-A65E-6E68D2E5336A} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D7E2F6B1-96AC-4FB5-B8AA-FDB43C7F169E}
Expand Down
50 changes: 20 additions & 30 deletions SMInjector/src/find_steam.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,28 @@ namespace SteamFinder {
using std::vector;
using std::filesystem::directory_iterator;

LONG get_registry_string(HKEY hKey, const char* key_name, string& strValue) {
CHAR szBuffer[512] = { 0 };
LONG get_registry_string(HKEY hKey, const wchar_t* key_name, std::wstring& strValue) {
wchar_t szBuffer[512] = { 0 };
DWORD dwBufferSize = sizeof(szBuffer);
ULONG nError = RegQueryValueExA(hKey, key_name, 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
ULONG nError = RegQueryValueExW(hKey, key_name, 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
if(nError == ERROR_SUCCESS) strValue = szBuffer;
return nError;
}

string get_game_path() {
std::wstring get_game_path() {
HKEY hKey;
LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\WOW6432Node\\Valve\\Steam", 0, KEY_READ, &hKey);
string install_path;
get_registry_string(hKey, "InstallPath", install_path);
std::wstring install_path;
get_registry_string(hKey, L"InstallPath", install_path);
RegCloseKey(hKey);
return install_path;
}

/*
inline bool does_file_exist(const string& name) {
struct stat buffer;
return (stat(name.c_str(), &buffer) == 0);
}
*/

vector<string> get_steam_libraries(string install_path, string vdf_file) {
vector<string> vec;
vector<std::wstring> get_steam_libraries(std::wstring install_path, std::wstring vdf_file) {
vector<std::wstring> vec;
vec.reserve(10);

vec.push_back(install_path.append("\\steamapps\\common"));
vec.push_back(install_path.append(L"\\steamapps\\common"));
if(vdf_file.empty()) {
return vec;
}
Expand All @@ -50,7 +43,7 @@ namespace SteamFinder {
std::string buffer(std::istreambuf_iterator<char>{infile}, {});

if(!buffer.empty()) {
char temp[2048] = { 0 };
wchar_t temp[2048] = { 0 };
int idx = 0;
int len = 0;

Expand All @@ -64,7 +57,7 @@ namespace SteamFinder {
if(i > 16 && quote) {
len++;
if(len > 4 && ((len & 1) == 0)) {
vec.push_back(string(temp).append("\\steamapps\\common"));
vec.push_back(std::wstring(temp).append(L"\\steamapps\\common"));
}

temp[0] = 0;
Expand All @@ -83,29 +76,26 @@ namespace SteamFinder {
return vec;
}

string find_game_from_libs(vector<string> list, const char* game) {
std::wstring name(game, game + strlen(game));
std::wstring find_game_from_libs(vector<std::wstring> list, const wchar_t* game) {
std::wstring name(game);

for(int i = 0; i < list.size(); i++) {
for(const auto& file : directory_iterator(list[i])) {
if(file.path().filename().compare(name) == 0) {
char szBuffer[512] = { 0 };
size_t num;
wcstombs_s(&num, szBuffer, file.path().c_str(), 512);
return string(szBuffer);
return std::wstring(file.path());
}
}
}

return "";
return L"";
}

string FindGame(const char* game) {
string install_path = get_game_path();
if(install_path.empty()) return "";
std::wstring FindGame(const wchar_t* game) {
std::wstring install_path = get_game_path();
if(install_path.empty()) return L"";

string vdf_test = string(install_path).append("\\steamapps\\libraryfolders.vdf");
vector<string> libs = get_steam_libraries(install_path, vdf_test);
std::wstring vdf_test = std::wstring(install_path).append(L"\\steamapps\\libraryfolders.vdf");
vector<std::wstring> libs = get_steam_libraries(install_path, vdf_test);
return find_game_from_libs(libs, game);
}
}
84 changes: 39 additions & 45 deletions SMInjector/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,50 @@

#include "find_steam.h"

bool Inject(HANDLE, const char*);
bool Inject(HANDLE, const wchar_t*);

inline bool does_file_exist(const char* name) {
struct stat buffer;
return (stat(name, &buffer) == 0);
inline bool does_file_exist(const wchar_t* name) {
struct _stat buffer;
return (_wstat(name, &buffer) == 0);
}

std::string get_dir_path() {
CHAR buffer[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL, buffer, MAX_PATH);
std::string::size_type pos = std::string(buffer).find_last_of("\\/");
return std::string(buffer).substr(0, pos);
std::wstring get_dir_path() {
wchar_t buffer[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, buffer, MAX_PATH);
std::wstring::size_type pos = std::wstring(buffer).find_last_of(L"\\/");
return std::wstring(buffer).substr(0, pos);
}

std::string get_dll_path(const char* dll_name) {
CHAR buffer[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL, buffer, MAX_PATH);
std::string::size_type pos = std::string(buffer).find_last_of("\\/");
return std::string(buffer).substr(0, pos).append("\\").append(dll_name);
std::wstring get_dll_path(const wchar_t* dll_name) {
wchar_t buffer[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, buffer, MAX_PATH);
std::wstring::size_type pos = std::wstring(buffer).find_last_of(L"\\/");
return std::wstring(buffer).substr(0, pos).append(L"\\").append(dll_name);
}

BOOL startup(std::string in_exe, std::string in_dir, std::string in_cmd, HANDLE &hProcess, HANDLE &hThread) {
STARTUPINFOA si;
BOOL startup(std::wstring in_exe, std::wstring in_dir, std::wstring in_cmd, HANDLE &hProcess, HANDLE &hThread) {
STARTUPINFO si;
PROCESS_INFORMATION pi;

CHAR exe[MAX_PATH + 1] = { 0 };
CHAR dir[MAX_PATH + 1] = { 0 };
CHAR cmd[4097] = { 0 };
wchar_t exe[MAX_PATH + 1] = { 0 };
wchar_t dir[MAX_PATH + 1] = { 0 };
wchar_t cmd[4097] = { 0 };
ZeroMemory(cmd, 4097);

memcpy(exe, in_exe.c_str(), min(in_exe.size(), MAX_PATH + 1));
memcpy(dir, in_dir.c_str(), min(in_dir.size(), MAX_PATH + 1));
sprintf_s(cmd, 4097, "\"%s\" %s", exe, in_cmd.c_str());
memcpy(exe, in_exe.c_str(), min(in_exe.size() * 2, MAX_PATH + 1));
memcpy(dir, in_dir.c_str(), min(in_dir.size() * 2, MAX_PATH + 1));
swprintf_s(cmd, 4097, L"\"%s\" %s", exe, in_cmd.c_str());

// printf("EXE: [%s]\n", exe);
// printf("DIR: [%s]\n", dir);
// printf("CMD: [%s]\n", cmd);
//wprintf(L"EXE: [%s]\n", exe);
//wprintf(L"DIR: [%s]\n", dir);
//wprintf(L"CMD: [%s]\n", cmd);

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
si.wShowWindow = true;

if(!CreateProcessA(
if(!CreateProcessW(
exe,
cmd,
NULL, NULL,
Expand All @@ -78,11 +78,11 @@ BOOL startup(std::string in_exe, std::string in_dir, std::string in_cmd, HANDLE
int main(int argc, char** argv) {
printf("SMInjector: startup\n");

std::string game_path = SteamFinder::FindGame("Scrap Mechanic");
std::string dll_path = get_dll_path("SMLibrary.dll");
std::wstring game_path = SteamFinder::FindGame(L"Scrap Mechanic");
std::wstring dll_path = get_dll_path(L"SMLibrary.dll");

printf("GAME: [%s]\n", game_path.c_str());
printf("DLL : [%s]\n", dll_path.c_str());
wprintf(L"GAME: [%s]\n", game_path.c_str());
wprintf(L"DLL : [%s]\n", dll_path.c_str());

if(game_path.empty()) {
printf("SMInjector: Failed to find the game \"ScrapMechanic\"\n");
Expand All @@ -91,9 +91,9 @@ int main(int argc, char** argv) {

HANDLE hProcess;
HANDLE hThread;
std::string exe_exe = std::string(game_path).append("\\Release\\ScrapMechanic.exe");
std::string exe_dir = std::string(game_path).append("\\Release");
if(startup(exe_exe, exe_dir, "-dev", hProcess, hThread)) {
std::wstring exe_exe = std::wstring(game_path).append(L"\\Release\\ScrapMechanic.exe");
std::wstring exe_dir = std::wstring(game_path).append(L"\\Release");
if(startup(exe_exe, exe_dir, L"-dev", hProcess, hThread)) {
if(!Inject(hProcess, dll_path.c_str())) {
printf("SMInjector: failed to inject dll file\n");
TerminateProcess(hProcess, 0);
Expand All @@ -102,47 +102,41 @@ int main(int argc, char** argv) {
}

printf("\nSMInjector: Adding plugins.\n");
for(const auto& file : std::filesystem::directory_iterator(get_dir_path().append("\\plugins"))) {
char dll_plugin[512] = { 0 };
size_t num;
wcstombs_s(&num, dll_plugin, file.path().c_str(), 512);

if(!Inject(hProcess, dll_plugin)) {
for(const auto& file : std::filesystem::directory_iterator(get_dir_path().append(L"\\plugins"))) {
if(!Inject(hProcess, file.path().c_str())) {
wprintf(L" Failed to inject '%s'\n", file.path().filename().c_str());
return 0;
} else {
wprintf(L" Injected '%s'\n", file.path().filename().c_str());
}
}

Sleep(500);

ResumeThread(hThread);
}

return 0;
}

bool Inject(HANDLE hProc, const char* path) {
bool Inject(HANDLE hProc, const wchar_t* path) {
if(!does_file_exist(path)) {
return false;
}

const size_t path_length = strlen(path);
const size_t path_length = wcslen(path) * 2;

LPVOID lpvoid = VirtualAllocEx(hProc, NULL, path_length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(!lpvoid) {
return false;
}

WriteProcessMemory(hProc, lpvoid, path, path_length, NULL);

HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
if(!kernel32) {
return false;
}

LPVOID LoadLibAddr = (LPVOID)GetProcAddress(kernel32, "LoadLibraryA");
LPVOID LoadLibAddr = (LPVOID)GetProcAddress(kernel32, "LoadLibraryW");
HANDLE threadID = CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, lpvoid, NULL, NULL);
if(!threadID) {
return false;
Expand Down
10 changes: 10 additions & 0 deletions SMLibrary/include/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
#ifndef _SM_LIBRARY_BUILD_PLUGIN
#include <windows.h>
#include <iostream>

#ifdef _SM_OUTPUT_LOGS
#include <fcntl.h>
#include <io.h>
#endif

#endif

#include <cstdarg>
Expand Down Expand Up @@ -46,7 +52,11 @@ namespace Console {

void log_open() {
log_close();
#ifdef _SM_OUTPUT_LOGS
freopen_s(&console_handle, "CONOUT$", "w", stdout);
#else
freopen_s(&console_handle, "CONOUT$", "w", stdout);
#endif
}

_LIB_EXPORT
Expand Down
1 change: 1 addition & 0 deletions SMLibrary/src/hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Hook *hck_init_console;

namespace Hooks {
void hook_init_console(void* a, void* b) {
FreeConsole();
((pinit_console)hck_init_console->Gate())(a, b);
PostConsoleInjections();
return;
Expand Down
5 changes: 3 additions & 2 deletions SMLibrary/src/sm_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>

#define _SM_PLUGIN_NAME SMLibrary
#define _SM_OUTPUT_LOGS

#include "../include/sm_lib.h"
#include "../include/hook.h"
Expand Down Expand Up @@ -34,9 +35,9 @@ HookUtility *util;
BOOL Startup(HMODULE hModule) {
HMODULE sm_handle = GetModuleHandleA("ScrapMechanic.exe");
if(!sm_handle) return false;

hck_init_console = new Hook();
hck_init_console->Inject((void*)((longlong)sm_handle + offset_InitConsole), &Hooks::hook_init_console, 15);
hck_init_console->Inject((void*)((longlong)sm_handle + offset_InitConsole), &Hooks::hook_init_console, 0, 15);
return true;
}

Expand Down

0 comments on commit e320b53

Please sign in to comment.