Last active
January 26, 2021 02:32
-
-
Save twilight-sparkle-irl/0836cf8736653b4f133270c6bf26a4a6 to your computer and use it in GitHub Desktop.
example of what an extremely barebones among us hook looks like (no graphics)
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
// use il2cppinspector to create a c++ scaffolding project | |
// import minhook | |
// replace user/main.cpp with this | |
// play around! this basically shows you how to hook any function you'd like | |
// it's obviously not at all what you'd call "complete", but it contains enough stuff i had to figure out through trial and error | |
#include "pch-il2cpp.h" | |
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <iostream> | |
#include "il2cpp-appdata.h" | |
#include "helpers.h" | |
#include "MinHook.h" | |
using namespace app; | |
#include <string> | |
#include <locale> | |
#include <codecvt> | |
// this is stuff for setting up the addchat hook. paste from the il2cpp functions definitions | |
typedef void addchat(ChatController * __this, PlayerControl * sourcePlayer, String * chatText, MethodInfo * method); | |
addchat* orig_addchat = nullptr; | |
std::string utf16_to_utf8(std::u16string utf16_string) | |
{ | |
std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert; | |
auto p = reinterpret_cast<const int16_t *>(utf16_string.data()); | |
return convert.to_bytes(p, p + utf16_string.size()); | |
} | |
// pasted from https://github.com/ExtraConcentratedJuice/ChristWareAmongUs, StringUtility.cpp | |
// you don't need to change this. | |
std::string stringify(String* netString) | |
{ | |
if (netString == NULL) | |
return NULL; | |
uint16_t* buffer = new uint16_t[netString->fields.m_stringLength + 1]; | |
memcpy(buffer, &netString->fields.m_firstChar, netString->fields.m_stringLength * sizeof(uint16_t)); | |
buffer[netString->fields.m_stringLength] = L'\0'; | |
std::string newString = utf16_to_utf8((const char16_t*)buffer); | |
delete[] buffer; | |
return newString; | |
} | |
// an example hooked plugin | |
void hook_addchat(ChatController * __this, PlayerControl * sourcePlayer, String * chatText, MethodInfo * method) { | |
GameData_PlayerInfo* player = PlayerControl_get_Data(sourcePlayer, NULL); | |
// stringify()ing the text is important, you're starting out with this nebulous String object that if you try to put into cout will just return a pointer | |
std::cout << stringify(player->fields.PlayerName) << (player->fields.IsDead ? " (DEAD)" : "") << ": " << stringify(chatText) << '\n'; | |
return orig_addchat(__this, sourcePlayer, chatText, method); // make sure to return flow back to the normal function! ...if you want | |
} | |
// Custom injected code entry point | |
void Run() | |
{ | |
NewConsole(); // create a console | |
// start setup bullshit | |
auto domain = il2cpp_domain_get(); printf("[0] Domain gotten.\n"); | |
il2cpp_thread_attach(domain); // i'm not sure if this is necessary | |
auto assembly = il2cpp_domain_assembly_open(domain, "Assembly-CSharp"); printf("[0] Assembly gotten.\n"); | |
auto image = il2cpp_assembly_get_image(assembly); printf("[0] Image gotten.\n"); | |
// end setup bullshit | |
// start what should be in a function if you ever expand upon this | |
auto chatcontroller = il2cpp_class_from_name(image, "", "ChatController"); printf("[0] Class gotten.\n"); // get the class you want | |
auto addchat = il2cpp_class_get_method_from_name(chatcontroller, "AddChat", 2); printf("[0] AddChat: %x\n",&addchat); // get method from name (2 is the number of arguments, this is important) | |
printf("[0] If this is not AddChat, there's a bug in the code: %s\n", il2cpp_method_get_name(addchat)); // ensure that you grabbed the right function | |
uintptr_t pointer = (uintptr_t)addchat->methodPointer; printf("[0] Pointer gotten\n"); // get the pointer to the function! | |
// Initialize MinHook. | |
if (MH_Initialize() != MH_OK) | |
{ | |
printf("[0] minhook is not ok!\n"); | |
} | |
printf("[0] CreateHook return code: %x\n",MH_CreateHook((void*)pointer, &hook_addchat, | |
reinterpret_cast<LPVOID*>(&orig_addchat))); // hook the pointer you just got | |
printf("[0] EnableHook return code: %x\n", MH_EnableHook((void*)pointer)); // enable the hook | |
printf("[0] Chat logger loaded. Have a very safe day.\n__________________\n\n"); // :thumbsup: | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment