Added function hooking

Cleaned up the injector a bit and added launch-time injection
This commit is contained in:
Daniel S. 2019-03-01 01:00:50 +01:00
parent ffbcc30427
commit 7cf3ab8580
11 changed files with 166 additions and 36 deletions

View File

@ -169,7 +169,6 @@ void InjectDll(DWORD PID, bool do_resume = false)
cout << "[*] Injecting DLL " << dll_name << " into PID " << PID << endl;
cout << "[*] Opening Process Handle" << endl;
hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
PID = GetProcessId(hProc);
GetFullPathNameA(dll_name, MAX_PATH, dll_full_path, 0);
cout << "[*] Adjusting Privileges of Process" << endl;
adjustPrivs(hProc);
@ -216,23 +215,53 @@ void InjectDll(DWORD PID, bool do_resume = false)
CloseHandle(hProc);
return;
}
vector<HANDLE> spawn(char* binary) {
STARTUPINFO startupinfo;
PROCESS_INFORMATION processinfo;
ZeroMemory(&startupinfo, sizeof(startupinfo));
ZeroMemory(&processinfo, sizeof(processinfo));
startupinfo.cb = sizeof(startupinfo);
if (!CreateProcessA(NULL, binary, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupinfo, &processinfo)) {
return {};
}
return { processinfo.hProcess,processinfo.hThread };
}
int main(int argc, char *argv[])
{
string prog;
HANDLE hProc = INVALID_HANDLE_VALUE;
HANDLE hThread = INVALID_HANDLE_VALUE;
DWORD PID = 0;
GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID);
if (PID == 0)
{
cout << "[*] Waiting for Scrapland to Launch..." << endl;
}
while (PID == 0)
{
Sleep(100);
if ((argc>1)&&fexists(argv[1])) {
cout << "[*] Spawning process for \"" << argv[1] << "\"" << endl;
vector<HANDLE> handles = spawn(argv[1]);
if (handles.empty()) {
cout << "[!] Error: " << GetLastErrorAsString() << endl;
return -1;
}
hProc = handles[0];
hThread = handles[1];
PID = GetProcessId(hProc);
cout << "[+] Got PID: " << PID << endl;
} else {
GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID);
if (PID == 0)
{
cout << "[*] Waiting for Scrapland to Launch..." << endl;
}
while (PID == 0)
{
Sleep(100);
GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID);
}
cout << "[+] Found PID: " << PID << endl;
}
cout << "[+] Found PID: " << PID << endl;
InjectDll(PID);
if (hThread != INVALID_HANDLE_VALUE) {
while (ResumeThread(hThread));
}
cout << "[*] Done!" << endl;
return 0;
}

View File

@ -160,6 +160,5 @@
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -0,0 +1,50 @@
#pragma once
#include <functional>
class Hook;
map<uintptr_t, shared_ptr<Hook>> hooks;
class Hook {
private:
DWORD protect;
void* orig;
void* detour;
uint8_t orig_bytes[6];
uint8_t jmp_bytes[6];
public:
Hook(void* func, void* detour) {
cout << "Hooking: " << func << " -> " << detour << endl;
uintptr_t dest = reinterpret_cast<uintptr_t>(detour);
uintptr_t src = reinterpret_cast<uintptr_t>(func);
this->orig = func;
this->detour = detour;
this->jmp_bytes[0] = 0x68; // push
this->jmp_bytes[1] = (dest >> 0) & 0xff;
this->jmp_bytes[2] = (dest >> 8) & 0xff;
this->jmp_bytes[3] = (dest >> 16) & 0xff;
this->jmp_bytes[4] = (dest >> 24) & 0xff;
this->jmp_bytes[5] = 0xC3; // ret
VirtualProtect(func, 16, PAGE_EXECUTE_READWRITE, &(this->protect));
memcpy(this->orig_bytes, this->orig, 1 + 4 + 1);
memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1);
hooks[src]=shared_ptr<Hook>(this);
}
~Hook() {
cout << "Unhooking: " << this->detour << " -> " << this->orig << endl;
uintptr_t src = reinterpret_cast<uintptr_t>(this->orig);
memcpy(this->orig, this->orig_bytes, 1 + 4 + 1);
}
void disable() {
memcpy(this->orig, this->orig_bytes, 1 + 4 + 1);
}
void enable() {
memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1);
}
void* func() {
return this->orig;
}
};

View File

@ -13,7 +13,7 @@ PyMethodDef *find_method_table(uintptr_t base, uintptr_t needle)
return reinterpret_cast<PyMethodDef*>(mod_addr);
}
}
return reinterpret_cast<PyMethodDef *>(0);
return reinterpret_cast<PyMethodDef*>(0);
}
map<string, Module> get_modules(uintptr_t base)
@ -27,7 +27,7 @@ map<string, Module> get_modules(uintptr_t base)
PyMethodDef *method_table = find_method_table((size_t)modules[i].init_func, reinterpret_cast<uintptr_t>(modules[i].name));
for (size_t j = 0; method_table != NULL && method_table[j].ml_name != NULL; j++)
{
mod.methods[method_table[j].ml_name] = method_table[j];
mod.methods[method_table[j].ml_name] = &method_table[j];
}
Py[mod.mod->name] = mod;
}
@ -38,7 +38,7 @@ void *get_py(const char *mod, const char *meth)
{
try
{
return Py.at(mod).methods.at(meth).ml_meth;
return Py.at(mod).methods.at(meth)->ml_meth;
}
catch (out_of_range)
{
@ -51,7 +51,7 @@ void inject(const char *mod, const char *meth, void *detour)
try
{
void *orig = get_py(mod, meth);
Py.at(mod).methods.at(meth).ml_meth = detour;
Py.at(mod).methods.at(meth)->ml_meth = detour;
cout << mod << "." << meth << ": " << orig << " -> " << detour << endl;
}
catch (out_of_range)

View File

@ -1,3 +1,4 @@
#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <string>
#include <sstream>
@ -5,16 +6,19 @@
#include <map>
#include <iomanip>
#include <iostream>
#include <typeinfo>
#include <functional>
#include <Windows.h>
#include <TlHelp32.h>
//#include <D3d8.h>
using namespace std;
#include "Scrapland.h"
#include "Util.h"
#include "Structures.h"
#include "Py_Utils.h"
#include "Hook.h"
#define SIZE 6
HMODULE hD3D8Dll = 0;
@ -22,7 +26,6 @@ bool initialized = false;
bool running = true;
HMODULE mod = 0;
void MainLoop(HMODULE mod)
{
Sleep(100);
@ -67,7 +70,7 @@ void MainLoop(HMODULE mod)
{
for (auto meth : mod.second.methods)
{
cout << mod.first << "." << meth.first << " @ " << meth.second.ml_meth << endl;
cout << mod.first << "." << meth.first << " @ " << meth.second->ml_meth << endl;
}
}
}
@ -77,9 +80,11 @@ void MainLoop(HMODULE mod)
}
}
SetConsoleCtrlHandler(NULL, false);
hooks.clear();
scrap_log(0xff0000, "ScrapHacks unloaded!\n");
cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl;
;
FreeConsole();
PostQuitMessage(0);
FreeLibraryAndExitThread(mod, 0);
}
@ -90,21 +95,53 @@ void InitConsole()
SetupConsole(me);
}
void handle_command(const char* cmd) {
cout << "CMD: " << cmd << endl;
scrap_log(0x00ff00, "HAXX: ");
scrap_log(0x00ff00,cmd);
scrap_log(0x00ff00,"\n");
return;
}
int my_console(const char* cmd) {
typedef int(_cdecl *t_func)(const char*);
shared_ptr<Hook> hook = hooks[P_CON_HANDLER];
t_func func= reinterpret_cast<t_func>(hook->func());
if (cmd[0] == '$') {
handle_command(++cmd);
return 0;
}
hook->disable();
int ret=func(cmd);
hook->enable();
return ret;
}
void hook_console() {
new Hook(reinterpret_cast<void*>(P_CON_HANDLER) , my_console);
}
void DllPreInit(HMODULE _mod) {
char mfn[1024];
InitConsole();
GetModuleFileName(0, mfn, 1024);
Py = get_modules(P_PY_MODS);
hD3D8Dll = GetModuleHandle("d3d8.dll");
cout << "[+] ScrapHacks v0.1 Loaded in " << mfn << endl;
cout << "[*] D3D8 DLL @0x" << hD3D8Dll << endl;
hook_console();
}
void DllInit(HMODULE _mod)
{
initialized = true;
mod = _mod;
char mfn[1024];
InitConsole();
GetModuleFileName(0, mfn, 1024);
cout << "[+] ScrapHacks v0.1 Loaded in " << mfn << endl;
Sleep(3000);
Py = get_modules(P_PY_MODS);
cout << "[*] World: " << ptr<void>(P_WORLD, 0) << endl;
cout << "[*] Importing python dbg module" << endl;
scrap_exec("import dbg");
cout << "[*] World: " << ptr<void>(P_WORLD,0) << endl;
hD3D8Dll = GetModuleHandle("d3d8.dll");
cout << "[*] D3D8 DLL @0x"<< hD3D8Dll << endl;
scrap_log(0xff0000, "ScrapHacks loaded!\n");
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MainLoop, mod, 0, 0);
cout << "[*] Starting message pump" << endl;
MSG msg;

View File

@ -150,6 +150,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Hook.h" />
<ClInclude Include="Py_Utils.h" />
<ClInclude Include="Structures.h" />
<ClInclude Include="Scrapland.h" />

View File

@ -33,6 +33,9 @@
<ClInclude Include="Py_Utils.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="Hook.h">
<Filter>Headerdateien</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">

View File

@ -1,7 +1,17 @@
#pragma once
#define P_WORLD 0x7FE944
#define P_PY_MODS 0x79C698
//OFFSETS
#define O_MONEY 0x2090
auto scrap_log = (int(_cdecl*)(int, const char*))0x4134C0;
auto scrap_exec = (void(_cdecl*)(const char*))0x5a8390;
//POINTERS
#define P_WORLD 0x7FE944
#define P_PY_MODS 0x79C698
#define P_CON_HANDLER 0x402190
#define P_SCRAP_LOG 0x4134C0
#define P_SCRAP_EXEC 0x5a8390
//FUNCTION TYPES
#define T_SCRAP_LOG int(_cdecl*)(unsigned int, const char*)
#define T_SCRAP_EXEC int(_cdecl*)(const char*)
auto scrap_log = (T_SCRAP_LOG)P_SCRAP_LOG;
auto scrap_exec = (T_SCRAP_EXEC)P_SCRAP_EXEC;

View File

@ -30,5 +30,5 @@ struct PyMod
struct Module
{
PyMod *mod;
map<string, PyMethodDef> methods;
map<string, PyMethodDef*> methods;
};

View File

@ -124,7 +124,6 @@ void hexdump(void *addr, size_t count)
cout << endl;
}
template<typename T>
T* __ptr(uintptr_t addr)
{
@ -156,4 +155,4 @@ template<typename T, typename... Offsets>
T* ptr(uintptr_t addr, Offsets... offsets) {
auto ret = __ptr<T>(addr, offsets...);
return ret;
}
}

View File

@ -1,6 +1,7 @@
#include "stdafx.h"
#define DLL_EXPORT extern "C" __declspec(dllexport)
void DllInit(HMODULE);
void DllPreInit(HMODULE);
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
@ -11,6 +12,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
DllPreInit(hModule);
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DllInit, hModule, 0, 0);
break;
case DLL_PROCESS_DETACH: