forked from ReScrap/ScrapHacks
		
	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 << "[*] 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,11 +215,37 @@ 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; | ||||
| 	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) | ||||
| 		{ | ||||
|  | @ -232,7 +257,11 @@ int main(int argc, char *argv[]) | |||
| 			GetWindowThreadProcessId(FindWindowA("ScrapClass", NULL), &PID); | ||||
| 		} | ||||
| 		cout << "[+] Found PID: " << PID << endl; | ||||
| 	} | ||||
| 	InjectDll(PID); | ||||
| 	if (hThread != INVALID_HANDLE_VALUE) { | ||||
| 		while (ResumeThread(hThread)); | ||||
| 	} | ||||
| 	cout << "[*] Done!" << endl; | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -160,6 +160,5 @@ | |||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="ExtensionTargets" /> | ||||
| </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)); | ||||
| 		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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -150,6 +150,7 @@ | |||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="Hook.h" /> | ||||
|     <ClInclude Include="Py_Utils.h" /> | ||||
|     <ClInclude Include="Structures.h" /> | ||||
|     <ClInclude Include="Scrapland.h" /> | ||||
|  |  | |||
|  | @ -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"> | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -30,5 +30,5 @@ struct PyMod | |||
| struct Module | ||||
| { | ||||
| 	PyMod *mod; | ||||
| 	map<string, PyMethodDef> methods; | ||||
| 	map<string, PyMethodDef*> methods; | ||||
| }; | ||||
|  |  | |||
|  | @ -124,7 +124,6 @@ void hexdump(void *addr, size_t count) | |||
| 	cout << endl; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| template<typename T> | ||||
| T* __ptr(uintptr_t addr) | ||||
| { | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue