Created
January 27, 2022 03:24
-
-
Save BenjaminUrquhart/aa17b4a1370d4e3126a127af00df8ff2 to your computer and use it in GitHub Desktop.
Source to the GMInvoke GMS extension to comply with GPL3
This file contains hidden or 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
#include <Windows.h> | |
#include <iostream> | |
#include <string> | |
#define func extern "C" __declspec(dllexport) | |
// Some boilerplate code | |
// Taken from https://github.com/Archie-osu/YYToolkit | |
#define TRoutine void* | |
#define GMI_ERROR -3 | |
#define GMI_NOT_FOUND -4 | |
#define ENSURE_INITIALIZED if (!EnsureInitialized()) { return GMI_ERROR; } | |
typedef void (*FNCodeFunctionGetTheFunction)(int id, char** bufName, void** bufRoutine, int* bufArgs, void* unused); | |
static FNCodeFunctionGetTheFunction GetFuncAddr = nullptr; | |
struct ModuleInfo_t | |
{ | |
unsigned long Base; | |
unsigned long Size; | |
unsigned long EntryPoint; | |
}; | |
struct FunctionInfo_t | |
{ | |
int Index; | |
char* Name; | |
TRoutine Function; | |
int Argc; | |
}; | |
ModuleInfo_t GetModuleInfo() | |
{ | |
using Fn = int(__stdcall*)(HANDLE, HMODULE, ModuleInfo_t*, DWORD); | |
static HMODULE Module = GetModuleHandleA("kernel32.dll"); | |
static Fn K32GetModuleInformation = (Fn)GetProcAddress(Module, "K32GetModuleInformation"); | |
ModuleInfo_t modinfo = { 0 }; | |
HMODULE hModule = GetModuleHandleA(NULL); | |
if (hModule == 0) | |
return modinfo; | |
K32GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(ModuleInfo_t)); | |
return modinfo; | |
} | |
unsigned long FindPattern(const char* Pattern, const char* Mask, long base, unsigned size) | |
{ | |
size_t PatternSize = strlen(Mask); | |
for (unsigned i = 0; i < size - PatternSize; i++) | |
{ | |
int found = 1; | |
for (unsigned j = 0; j < PatternSize; j++) | |
{ | |
found &= Mask[j] == '?' || Pattern[j] == *(char*)(base + i + j); | |
} | |
if (found) | |
return (base + i); | |
} | |
return (unsigned long)NULL; | |
} | |
bool GetFunctionByIndex(int index, FunctionInfo_t& outInfo) | |
{ | |
if (index < 0) | |
return false; | |
void* pUnknown = nullptr; | |
GetFuncAddr(index, &outInfo.Name, (PVOID*)&outInfo.Function, &outInfo.Argc, &pUnknown); | |
if (!outInfo.Name) | |
return false; | |
if (!*outInfo.Name) | |
return false; | |
outInfo.Index = index; | |
return true; | |
} | |
bool GetFunctionByName(const char* Name, FunctionInfo_t& outInfo) | |
{ | |
int Index = 0; | |
if (!Name) | |
return false; | |
while (GetFunctionByIndex(Index, outInfo)) | |
{ | |
if (outInfo.Name != nullptr && _strnicmp(Name, outInfo.Name, 64) == 0) | |
{ | |
return true; | |
} | |
Index++; | |
} | |
return false; | |
} | |
bool GetCodeFunctionAddr(FNCodeFunctionGetTheFunction& outAddress) | |
{ | |
ModuleInfo_t CurInfo = GetModuleInfo(); | |
if ((outAddress = (FNCodeFunctionGetTheFunction)FindPattern("\x8B\x44\x24\x04\x3B\x05\x00\x00\x00\x00\x7F", "xxxxxx????x", CurInfo.Base, CurInfo.Size))) | |
return true; | |
return false; | |
} | |
func double EnsureInitialized() { | |
if (!GetFuncAddr) { | |
if (!GetCodeFunctionAddr(GetFuncAddr)) { | |
printf("[!] Failed to find GetFuncAddr\n"); | |
std::cout.flush(); | |
return false; | |
} | |
printf("[.] Found GetFuncAddr at %p\n", GetFuncAddr); | |
std::cout.flush(); | |
} | |
return true; | |
} | |
func char* method_get_name(double index) { | |
static std::string out; | |
out = ""; | |
if (EnsureInitialized()) { | |
FunctionInfo_t result = { 0 }; | |
if (GetFunctionByIndex((int)index, result)) { | |
out = result.Name ? result.Name : "func_" + std::to_string(index); | |
} | |
} | |
return (char*)out.c_str(); | |
} | |
func double method_get_arg_count(double index) { | |
ENSURE_INITIALIZED | |
FunctionInfo_t result = { 0 }; | |
if (GetFunctionByIndex((int)index, result)) { | |
return result.Argc; | |
} | |
return GMI_NOT_FOUND; | |
} | |
func double method_by_name(char* name) { | |
ENSURE_INITIALIZED | |
FunctionInfo_t result = { 0 }; | |
if (GetFunctionByName(name, result)) { | |
printf("[.] Found %s at index %d\n", name, result.Index); | |
std::cout.flush(); | |
return result.Index; | |
} | |
printf("[!] Failed to find function %s\n", name); | |
std::cout.flush(); | |
return GMI_NOT_FOUND; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment