Added function hooking
Cleaned up the injector a bit and added launch-time injection
This commit is contained in:
parent
ffbcc30427
commit
7cf3ab8580
11 changed files with 166 additions and 36 deletions
|
@ -169,7 +169,6 @@ void InjectDll(DWORD PID, bool do_resume = false)
|
||||||
cout << "[*] Injecting DLL " << dll_name << " into PID " << PID << endl;
|
cout << "[*] Injecting DLL " << dll_name << " into PID " << PID << endl;
|
||||||
cout << "[*] Opening Process Handle" << endl;
|
cout << "[*] Opening Process Handle" << endl;
|
||||||
hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
|
hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
|
||||||
PID = GetProcessId(hProc);
|
|
||||||
GetFullPathNameA(dll_name, MAX_PATH, dll_full_path, 0);
|
GetFullPathNameA(dll_name, MAX_PATH, dll_full_path, 0);
|
||||||
cout << "[*] Adjusting Privileges of Process" << endl;
|
cout << "[*] Adjusting Privileges of Process" << endl;
|
||||||
adjustPrivs(hProc);
|
adjustPrivs(hProc);
|
||||||
|
@ -216,11 +215,37 @@ void InjectDll(DWORD PID, bool do_resume = false)
|
||||||
CloseHandle(hProc);
|
CloseHandle(hProc);
|
||||||
return;
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
string prog;
|
string prog;
|
||||||
HANDLE hProc = INVALID_HANDLE_VALUE;
|
HANDLE hProc = INVALID_HANDLE_VALUE;
|
||||||
|
HANDLE hThread = INVALID_HANDLE_VALUE;
|
||||||
DWORD PID = 0;
|
DWORD PID = 0;
|
||||||
|
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);
|
GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID);
|
||||||
if (PID == 0)
|
if (PID == 0)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +257,11 @@ int main(int argc, char *argv[])
|
||||||
GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID);
|
GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID);
|
||||||
}
|
}
|
||||||
cout << "[+] Found PID: " << PID << endl;
|
cout << "[+] Found PID: " << PID << endl;
|
||||||
|
}
|
||||||
InjectDll(PID);
|
InjectDll(PID);
|
||||||
|
if (hThread != INVALID_HANDLE_VALUE) {
|
||||||
|
while (ResumeThread(hThread));
|
||||||
|
}
|
||||||
cout << "[*] Done!" << endl;
|
cout << "[*] Done!" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,5 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets" />
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
</Project>
|
50
ScrapHacks/ScrapHack/Hook.h
Normal file
50
ScrapHacks/ScrapHack/Hook.h
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -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));
|
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++)
|
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;
|
Py[mod.mod->name] = mod;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ void *get_py(const char *mod, const char *meth)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Py.at(mod).methods.at(meth).ml_meth;
|
return Py.at(mod).methods.at(meth)->ml_meth;
|
||||||
}
|
}
|
||||||
catch (out_of_range)
|
catch (out_of_range)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +51,7 @@ void inject(const char *mod, const char *meth, void *detour)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
void *orig = get_py(mod, meth);
|
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;
|
cout << mod << "." << meth << ": " << orig << " -> " << detour << endl;
|
||||||
}
|
}
|
||||||
catch (out_of_range)
|
catch (out_of_range)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -5,16 +6,19 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <functional>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <TlHelp32.h>
|
#include <TlHelp32.h>
|
||||||
//#include <D3d8.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include "Scrapland.h"
|
#include "Scrapland.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Structures.h"
|
#include "Structures.h"
|
||||||
#include "Py_Utils.h"
|
#include "Py_Utils.h"
|
||||||
|
#include "Hook.h"
|
||||||
|
|
||||||
|
#define SIZE 6
|
||||||
|
|
||||||
HMODULE hD3D8Dll = 0;
|
HMODULE hD3D8Dll = 0;
|
||||||
|
|
||||||
|
@ -22,7 +26,6 @@ bool initialized = false;
|
||||||
bool running = true;
|
bool running = true;
|
||||||
HMODULE mod = 0;
|
HMODULE mod = 0;
|
||||||
|
|
||||||
|
|
||||||
void MainLoop(HMODULE mod)
|
void MainLoop(HMODULE mod)
|
||||||
{
|
{
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
|
@ -67,7 +70,7 @@ void MainLoop(HMODULE mod)
|
||||||
{
|
{
|
||||||
for (auto meth : mod.second.methods)
|
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);
|
SetConsoleCtrlHandler(NULL, false);
|
||||||
|
hooks.clear();
|
||||||
|
scrap_log(0xff0000, "ScrapHacks unloaded!\n");
|
||||||
cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl;
|
cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl;
|
||||||
;
|
|
||||||
FreeConsole();
|
FreeConsole();
|
||||||
|
PostQuitMessage(0);
|
||||||
FreeLibraryAndExitThread(mod, 0);
|
FreeLibraryAndExitThread(mod, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,21 +95,53 @@ void InitConsole()
|
||||||
SetupConsole(me);
|
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)
|
void DllInit(HMODULE _mod)
|
||||||
{
|
{
|
||||||
initialized = true;
|
initialized = true;
|
||||||
mod = _mod;
|
mod = _mod;
|
||||||
char mfn[1024];
|
|
||||||
InitConsole();
|
|
||||||
GetModuleFileName(0, mfn, 1024);
|
|
||||||
cout << "[+] ScrapHacks v0.1 Loaded in " << mfn << endl;
|
|
||||||
Sleep(3000);
|
Sleep(3000);
|
||||||
Py = get_modules(P_PY_MODS);
|
cout << "[*] World: " << ptr<void>(P_WORLD, 0) << endl;
|
||||||
cout << "[*] Importing python dbg module" << endl;
|
cout << "[*] Importing python dbg module" << endl;
|
||||||
scrap_exec("import dbg");
|
scrap_exec("import dbg");
|
||||||
cout << "[*] World: " << ptr<void>(P_WORLD,0) << endl;
|
scrap_log(0xff0000, "ScrapHacks loaded!\n");
|
||||||
hD3D8Dll = GetModuleHandle("d3d8.dll");
|
|
||||||
cout << "[*] D3D8 DLL @0x"<< hD3D8Dll << endl;
|
|
||||||
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MainLoop, mod, 0, 0);
|
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MainLoop, mod, 0, 0);
|
||||||
cout << "[*] Starting message pump" << endl;
|
cout << "[*] Starting message pump" << endl;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
|
@ -150,6 +150,7 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Hook.h" />
|
||||||
<ClInclude Include="Py_Utils.h" />
|
<ClInclude Include="Py_Utils.h" />
|
||||||
<ClInclude Include="Structures.h" />
|
<ClInclude Include="Structures.h" />
|
||||||
<ClInclude Include="Scrapland.h" />
|
<ClInclude Include="Scrapland.h" />
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
<ClInclude Include="Py_Utils.h">
|
<ClInclude Include="Py_Utils.h">
|
||||||
<Filter>Headerdateien</Filter>
|
<Filter>Headerdateien</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Hook.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define P_WORLD 0x7FE944
|
//OFFSETS
|
||||||
#define P_PY_MODS 0x79C698
|
|
||||||
#define O_MONEY 0x2090
|
#define O_MONEY 0x2090
|
||||||
|
|
||||||
auto scrap_log = (int(_cdecl*)(int, const char*))0x4134C0;
|
//POINTERS
|
||||||
auto scrap_exec = (void(_cdecl*)(const char*))0x5a8390;
|
#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;
|
||||||
|
|
|
@ -30,5 +30,5 @@ struct PyMod
|
||||||
struct Module
|
struct Module
|
||||||
{
|
{
|
||||||
PyMod *mod;
|
PyMod *mod;
|
||||||
map<string, PyMethodDef> methods;
|
map<string, PyMethodDef*> methods;
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,7 +124,6 @@ void hexdump(void *addr, size_t count)
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* __ptr(uintptr_t addr)
|
T* __ptr(uintptr_t addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#define DLL_EXPORT extern "C" __declspec(dllexport)
|
#define DLL_EXPORT extern "C" __declspec(dllexport)
|
||||||
void DllInit(HMODULE);
|
void DllInit(HMODULE);
|
||||||
|
void DllPreInit(HMODULE);
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
DWORD ul_reason_for_call,
|
DWORD ul_reason_for_call,
|
||||||
|
@ -11,6 +12,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hModule);
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
DllPreInit(hModule);
|
||||||
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DllInit, hModule, 0, 0);
|
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DllInit, hModule, 0, 0);
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue