forked from ReScrap/ScrapHacks
		
	Auto format everything
This commit is contained in:
		
							parent
							
								
									e21faa76a1
								
							
						
					
					
						commit
						a920c63d41
					
				
					 16 changed files with 1165 additions and 5336 deletions
				
			
		|  | @ -1,17 +1,17 @@ | ||||||
| cmake_minimum_required (VERSION 2.6) | cmake_minimum_required(VERSION 2.6) | ||||||
| project(ScrapHacks) | project(ScrapHacks) | ||||||
| SET(CMAKE_BUILD_TYPE "Release") | set(CMAKE_BUILD_TYPE "Release") | ||||||
| SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}") | set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}") | ||||||
| if(WIN32) | if(WIN32) | ||||||
|   if(MSVC) |   if(MSVC) | ||||||
|     # ensure we use minimal "windows.h" lib without the crazy min max macros |     # ensure we use minimal "windows.h" lib without the crazy min max macros | ||||||
|     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"WIN32_LEAN_AND_MEAN\"") |     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"WIN32_LEAN_AND_MEAN\"") | ||||||
|     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"NOMINMAX\"") |     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"NOMINMAX\"") | ||||||
|     # disable SAFESEH - to avoid "LNK2026: module unsafe" |     # disable SAFESEH - to avoid "LNK2026: module unsafe" | ||||||
|     SET(CMAKE_CXX_FLAGS           "${CMAKE_CXX_FLAGS} /D \"SAFESEH:NO\"") |     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"SAFESEH:NO\"") | ||||||
|     SET(CMAKE_EXE_LINKER_FLAGS    "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") |     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") | ||||||
|     SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") |     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") | ||||||
|     SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO") |     set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO") | ||||||
|   endif(MSVC) |   endif(MSVC) | ||||||
| endif(WIN32) | endif(WIN32) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| #include "stdafx.h" |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <windows.h> | #include <windows.h> | ||||||
| #include <TlHelp32.h> | #include <TlHelp32.h> | ||||||
|  | @ -12,245 +11,254 @@ using namespace std; | ||||||
| 
 | 
 | ||||||
| string GetLastErrorAsString() | string GetLastErrorAsString() | ||||||
| { | { | ||||||
| 	DWORD errorMessageID = GetLastError(); |     DWORD errorMessageID = GetLastError(); | ||||||
| 	if (errorMessageID == 0) |     if (errorMessageID == 0) | ||||||
| 		return "No error"; |         return "No error"; | ||||||
| 	LPSTR messageBuffer = NULL; |     LPSTR messageBuffer = NULL; | ||||||
| 	size_t m_size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, |     size_t m_size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | ||||||
| 								   NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); |                                    NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); | ||||||
| 	string message(messageBuffer, m_size); |     string message(messageBuffer, m_size); | ||||||
| 	LocalFree(messageBuffer); |     LocalFree(messageBuffer); | ||||||
| 	if (!message.empty() && message[message.length() - 1] == '\n') |     if (!message.empty() && message[message.length() - 1] == '\n') | ||||||
| 	{ |     { | ||||||
| 		message.erase(message.length() - 1); |         message.erase(message.length() - 1); | ||||||
| 	} |     } | ||||||
| 	return message; |     return message; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void fail(char* msg) { | void fail(char *msg) | ||||||
| 	cerr << "[!] "<<msg<<": "<<GetLastErrorAsString()<<endl; | { | ||||||
| 	exit(1); |     cerr << "[!] " << msg << ": " << GetLastErrorAsString() << endl; | ||||||
|  |     exit(1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| string fromhex(string input) | string fromhex(string input) | ||||||
| { | { | ||||||
| 	transform(input.begin(), input.end(), input.begin(), ::toupper); |     transform(input.begin(), input.end(), input.begin(), ::toupper); | ||||||
| 	string hc = "0123456789ABCDEF"; |     string hc = "0123456789ABCDEF"; | ||||||
| 	string o = ""; |     string o = ""; | ||||||
| 	int n = 0; |     int n = 0; | ||||||
| 	int v = 0; |     int v = 0; | ||||||
| 	for (unsigned char c : input) |     for (unsigned char c : input) | ||||||
| 	{ |     { | ||||||
| 		if (hc.find(c) != size_t(-1)) |         if (hc.find(c) != size_t(-1)) | ||||||
| 		{ |         { | ||||||
| 			if ((n++) % 2 == 0) |             if ((n++) % 2 == 0) | ||||||
| 			{ |             { | ||||||
| 				v = hc.find(c) << 4; |                 v = hc.find(c) << 4; | ||||||
| 			} |             } | ||||||
| 			else |             else | ||||||
| 			{ |             { | ||||||
| 				o += char(v + hc.find(c)); |                 o += char(v + hc.find(c)); | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 		else |         else | ||||||
| 		{ |         { | ||||||
| 			cout << "Invalid Character in hex string" << endl; |             cout << "Invalid Character in hex string" << endl; | ||||||
| 			return ""; |             return ""; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 	return o; |     return o; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| vector<string> split(string str, char sep) | vector<string> split(string str, char sep) | ||||||
| { | { | ||||||
| 	vector<string> ret; |     vector<string> ret; | ||||||
| 	string part; |     string part; | ||||||
| 	for (auto n : str) |     for (auto n : str) | ||||||
| 	{ |     { | ||||||
| 		if (n == sep) |         if (n == sep) | ||||||
| 		{ |         { | ||||||
| 			ret.push_back(part); |             ret.push_back(part); | ||||||
| 			part.clear(); |             part.clear(); | ||||||
| 		} |         } | ||||||
| 		else |         else | ||||||
| 		{ |         { | ||||||
| 			part = part + n; |             part = part + n; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 	if (part != "") |     if (part != "") | ||||||
| 		ret.push_back(part); |         ret.push_back(part); | ||||||
| 	return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool fexists(const char *filename) | bool fexists(const char *filename) | ||||||
| { | { | ||||||
| 	ifstream ifile(filename); |     ifstream ifile(filename); | ||||||
| 	bool ret = ifile.good(); |     bool ret = ifile.good(); | ||||||
| 	ifile.close(); |     ifile.close(); | ||||||
| 	return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool HasModule(int PID, const char *modname) | bool HasModule(int PID, const char *modname) | ||||||
| { | { | ||||||
| 	HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID); |     HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID); | ||||||
| 	MODULEENTRY32 me; |     MODULEENTRY32 me; | ||||||
| 	me.dwSize = sizeof(MODULEENTRY32); |     me.dwSize = sizeof(MODULEENTRY32); | ||||||
| 	if (hModuleSnap == INVALID_HANDLE_VALUE) |     if (hModuleSnap == INVALID_HANDLE_VALUE) | ||||||
| 	{ |     { | ||||||
| 		return false; |         return false; | ||||||
| 	} |     } | ||||||
| 	if (!Module32First(hModuleSnap, &me)) |     if (!Module32First(hModuleSnap, &me)) | ||||||
| 	{ |     { | ||||||
| 		CloseHandle(hModuleSnap); |         CloseHandle(hModuleSnap); | ||||||
| 		cout << "Error reading Module Snapshot" << endl; |         cout << "Error reading Module Snapshot" << endl; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		do |         do | ||||||
| 		{ |         { | ||||||
| 			if (strstr((const char *)me.szModule, modname) != NULL) |             if (strstr((const char *)me.szModule, modname) != NULL) | ||||||
| 				return true; |                 return true; | ||||||
| 		} while (Module32Next(hModuleSnap, &me)); |         } while (Module32Next(hModuleSnap, &me)); | ||||||
| 		CloseHandle(hModuleSnap); |         CloseHandle(hModuleSnap); | ||||||
| 	} |     } | ||||||
| 	return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ProcRunning(DWORD PID) | bool ProcRunning(DWORD PID) | ||||||
| { | { | ||||||
| 	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID); |     HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID); | ||||||
| 	if (hSnap == INVALID_HANDLE_VALUE) |     if (hSnap == INVALID_HANDLE_VALUE) | ||||||
| 	{ |     { | ||||||
| 		return false; |         return false; | ||||||
| 	} |     } | ||||||
| 	CloseHandle(hSnap); |     CloseHandle(hSnap); | ||||||
| 	return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool adjustPrivs(HANDLE hProc) | bool adjustPrivs(HANDLE hProc) | ||||||
| { | { | ||||||
| 	HANDLE hToken; |     HANDLE hToken; | ||||||
| 	LUID luid; |     LUID luid; | ||||||
| 	TOKEN_PRIVILEGES tkprivs; |     TOKEN_PRIVILEGES tkprivs; | ||||||
| 	if (!OpenProcessToken(hProc, (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY), &hToken)) |     if (!OpenProcessToken(hProc, (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY), &hToken)) | ||||||
| 	{ |     { | ||||||
| 		fail("Could not open process token:"); |         fail("Could not open process token:"); | ||||||
| 	} |     } | ||||||
| 	if (!LookupPrivilegeValue(0, SE_DEBUG_NAME, &luid)) |     if (!LookupPrivilegeValue(0, SE_DEBUG_NAME, &luid)) | ||||||
| 	{ |     { | ||||||
| 		CloseHandle(hToken); |         CloseHandle(hToken); | ||||||
| 		fail("Error looking up privilege value for SE_DEBUG_NAME"); |         fail("Error looking up privilege value for SE_DEBUG_NAME"); | ||||||
| 	} |     } | ||||||
| 	tkprivs.PrivilegeCount = 1; |     tkprivs.PrivilegeCount = 1; | ||||||
| 	tkprivs.Privileges[0].Luid = luid; |     tkprivs.Privileges[0].Luid = luid; | ||||||
| 	tkprivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |     tkprivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; | ||||||
| 	bool bRet = AdjustTokenPrivileges(hToken, 0, &tkprivs, sizeof(tkprivs), NULL, NULL); |     bool bRet = AdjustTokenPrivileges(hToken, 0, &tkprivs, sizeof(tkprivs), NULL, NULL); | ||||||
| 	CloseHandle(hToken); |     CloseHandle(hToken); | ||||||
| 	if (!bRet) |     if (!bRet) | ||||||
| 	{ |     { | ||||||
| 		fail("Could not adjust privileges"); |         fail("Could not adjust privileges"); | ||||||
| 	} |     } | ||||||
| 	return bRet; |     return bRet; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Injected(DWORD PID) | bool Injected(DWORD PID) | ||||||
| { | { | ||||||
| 	return HasModule(PID, DLL_NAME); |     return HasModule(PID, DLL_NAME); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void InjectDll(DWORD PID) | void InjectDll(DWORD PID) | ||||||
| { | { | ||||||
| 	HANDLE hRemThread, hProc; |     HANDLE hRemThread, hProc; | ||||||
| 	const char *dll_name = DLL_NAME; |     const char *dll_name = DLL_NAME; | ||||||
| 	char dll_full_path[MAX_PATH]; |     char dll_full_path[MAX_PATH]; | ||||||
| 	char executable_dir[MAX_PATH]; |     char executable_dir[MAX_PATH]; | ||||||
| 	GetModuleFileNameA(NULL,executable_dir,MAX_PATH); |     GetModuleFileNameA(NULL, executable_dir, MAX_PATH); | ||||||
| 	if (!fexists(dll_name)) |     if (!fexists(dll_name)) | ||||||
| 	{ |     { | ||||||
| 		fail("DLL not found"); |         fail("DLL not found"); | ||||||
| 		return; |         return; | ||||||
| 	} |     } | ||||||
| 	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); | ||||||
| 	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); | ||||||
| 	if (HasModule(PID, dll_name)) |     if (HasModule(PID, dll_name)) | ||||||
| 	{ |     { | ||||||
| 		cout << "[*] DLL already loaded" << endl; |         cout << "[*] DLL already loaded" << endl; | ||||||
| 		CloseHandle(hProc); |         CloseHandle(hProc); | ||||||
| 		return; |         return; | ||||||
| 	}; |     }; | ||||||
| 	if (!fexists(dll_full_path)) |     if (!fexists(dll_full_path)) | ||||||
| 	{ |     { | ||||||
| 		CloseHandle(hProc); |         CloseHandle(hProc); | ||||||
| 		fail("DLL file not found"); |         fail("DLL file not found"); | ||||||
| 	} |     } | ||||||
| 	HINSTANCE hK32 = LoadLibraryA("kernel32"); |     HINSTANCE hK32 = LoadLibraryA("kernel32"); | ||||||
| 	cout << "[*] Getting address of LoadLibrary" << endl; |     cout << "[*] Getting address of LoadLibrary" << endl; | ||||||
| 	LPVOID LoadLibrary_Address = (LPVOID)GetProcAddress(hK32, "LoadLibraryA"); |     LPVOID LoadLibrary_Address = (LPVOID)GetProcAddress(hK32, "LoadLibraryA"); | ||||||
| 	FreeLibrary(hK32); |     FreeLibrary(hK32); | ||||||
| 	cout << "[+] LoadLibrary is at " << LoadLibrary_Address << endl; |     cout << "[+] LoadLibrary is at " << LoadLibrary_Address << endl; | ||||||
| 	cout << "[*] Allocating " << strlen(dll_full_path) << " Bytes of Memory" << endl; |     cout << "[*] Allocating " << strlen(dll_full_path) << " Bytes of Memory" << endl; | ||||||
| 	LPVOID mem = VirtualAllocEx(hProc, NULL, strlen(dll_full_path), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); |     LPVOID mem = VirtualAllocEx(hProc, NULL, strlen(dll_full_path), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); | ||||||
| 	if (mem == NULL) |     if (mem == NULL) | ||||||
| 	{ |     { | ||||||
| 		fail("Could not allocate memory"); |         fail("Could not allocate memory"); | ||||||
| 		return; |         return; | ||||||
| 	} |     } | ||||||
| 	cout << "[*] Writing DLL Name to Process Memory at " << mem << endl; |     cout << "[*] Writing DLL Name to Process Memory at " << mem << endl; | ||||||
| 	WriteProcessMemory(hProc, mem, dll_full_path, strlen(dll_full_path), 0); |     WriteProcessMemory(hProc, mem, dll_full_path, strlen(dll_full_path), 0); | ||||||
| 	cout << "[*] Creating Thread to Load DLL" << endl; |     cout << "[*] Creating Thread to Load DLL" << endl; | ||||||
| 	hRemThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibrary_Address, mem, 0, 0); |     hRemThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibrary_Address, mem, 0, 0); | ||||||
| 	cout << "[*] Waiting for DLL to load" << endl; |     cout << "[*] Waiting for DLL to load" << endl; | ||||||
| 	WaitForSingleObject(hRemThread, INFINITE); |     WaitForSingleObject(hRemThread, INFINITE); | ||||||
| 	CloseHandle(hRemThread); |     CloseHandle(hRemThread); | ||||||
| 	cout << "[*] Closing Process Handle" << endl; |     cout << "[*] Closing Process Handle" << endl; | ||||||
| 	CloseHandle(hProc); |     CloseHandle(hProc); | ||||||
| 	return; |     return; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| vector<HANDLE> spawn(char* binary) { | vector<HANDLE> spawn(char *binary) | ||||||
| 	STARTUPINFO startupinfo; | { | ||||||
| 	PROCESS_INFORMATION processinfo; |     STARTUPINFO startupinfo; | ||||||
| 	ZeroMemory(&startupinfo, sizeof(startupinfo)); |     PROCESS_INFORMATION processinfo; | ||||||
| 	ZeroMemory(&processinfo, sizeof(processinfo)); |     ZeroMemory(&startupinfo, sizeof(startupinfo)); | ||||||
| 	startupinfo.cb = sizeof(startupinfo); |     ZeroMemory(&processinfo, sizeof(processinfo)); | ||||||
| 	if (!CreateProcessA(NULL, binary, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupinfo, &processinfo)) { |     startupinfo.cb = sizeof(startupinfo); | ||||||
| 		return {}; |     if (!CreateProcessA(NULL, binary, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupinfo, &processinfo)) | ||||||
| 	} |     { | ||||||
| 	return { processinfo.hProcess,processinfo.hThread }; |         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; |     HANDLE hThread = INVALID_HANDLE_VALUE; | ||||||
| 	DWORD PID = 0; |     DWORD PID = 0; | ||||||
| 	char s_PID[MAX_PATH]; |     char s_PID[MAX_PATH]; | ||||||
| 	snprintf(s_PID, MAX_PATH, "%d", GetCurrentProcessId()); |     snprintf(s_PID, MAX_PATH, "%d", GetCurrentProcessId()); | ||||||
| 	SetEnvironmentVariableA("Inj_PID", s_PID); |     SetEnvironmentVariableA("Inj_PID", s_PID); | ||||||
| 	if ((argc>1)&&fexists(argv[1])) { |     if ((argc > 1) && fexists(argv[1])) | ||||||
| 		cout << "[*] Injector PID: " << GetCurrentProcessId() << endl; |     { | ||||||
| 		cout << "[*] Spawning process for \"" << argv[1] << "\"" << endl; |         cout << "[*] Injector PID: " << GetCurrentProcessId() << endl; | ||||||
| 		vector<HANDLE> handles = spawn(argv[1]); |         cout << "[*] Spawning process for \"" << argv[1] << "\"" << endl; | ||||||
| 		if (handles.empty()) { |         vector<HANDLE> handles = spawn(argv[1]); | ||||||
| 			fail("Failed to spawn process"); |         if (handles.empty()) | ||||||
| 		} |         { | ||||||
| 		hProc = handles[0]; |             fail("Failed to spawn process"); | ||||||
| 		hThread = handles[1]; |         } | ||||||
| 		PID = GetProcessId(hProc); |         hProc = handles[0]; | ||||||
| 	} else { |         hThread = handles[1]; | ||||||
| 		cerr<<"Usage: " << argv[0] << " <Path to Scrap.exe>"<<endl; |         PID = GetProcessId(hProc); | ||||||
| 		return 1; |     } | ||||||
| 	} |     else | ||||||
| 	InjectDll(PID); |     { | ||||||
| 	if (hThread != INVALID_HANDLE_VALUE) { |         cerr << "Usage: " << argv[0] << " <Path to Scrap.exe>" << endl; | ||||||
| 		while (ResumeThread(hThread)); |         return 1; | ||||||
| 	} |     } | ||||||
| 	SetEnvironmentVariableA("Inj_PID", NULL); |     InjectDll(PID); | ||||||
| 	cout << "[*] Done!" << endl; |     if (hThread != INVALID_HANDLE_VALUE) | ||||||
| 	return 0; |     { | ||||||
|  |         while (ResumeThread(hThread)) | ||||||
|  |             ; | ||||||
|  |     } | ||||||
|  |     SetEnvironmentVariableA("Inj_PID", NULL); | ||||||
|  |     cout << "[*] Done!" << endl; | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,17 +1,21 @@ | ||||||
| include(ExternalProject) | include(ExternalProject) | ||||||
| ExternalProject_Add(DirectX | ExternalProject_Add( | ||||||
|     PREFIX ${CMAKE_CURRENT_BINARY_DIR} |   DirectX | ||||||
|     CONFIGURE_COMMAND "" |   PREFIX ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|     BUILD_COMMAND "" |   CONFIGURE_COMMAND "" | ||||||
|     INSTALL_COMMAND "" |   BUILD_COMMAND "" | ||||||
|     URL https://archive.org/download/DirectX.8.0a.SDK_includes_libs_only/DirectX.8.0a.SDK.zip |   INSTALL_COMMAND "" | ||||||
|     URL_HASH SHA1=39f168336d0df92ff14d62d5e3aef1b9e3191312 |   URL | ||||||
| ) |     https://archive.org/download/DirectX.8.0a.SDK_includes_libs_only/DirectX.8.0a.SDK.zip | ||||||
|  |   URL_HASH SHA1=39f168336d0df92ff14d62d5e3aef1b9e3191312) | ||||||
| ExternalProject_Get_Property(DirectX SOURCE_DIR) | ExternalProject_Get_Property(DirectX SOURCE_DIR) | ||||||
| include_directories(AFTER ${SOURCE_DIR}/8.0/include/) | include_directories(AFTER ${SOURCE_DIR}/8.0/include/) | ||||||
| link_directories(AFTER ${SOURCE_DIR}/8.0/lib/) | link_directories(AFTER ${SOURCE_DIR}/8.0/lib/) | ||||||
| add_compile_definitions(_CRT_SECURE_NO_WARNINGS) | add_compile_definitions(_CRT_SECURE_NO_WARNINGS) | ||||||
| add_compile_definitions(POINTER_64=__ptr64) | add_compile_definitions(POINTER_64=__ptr64) | ||||||
| add_library(ScrapHack SHARED ScrapHack.cpp dllmain.cpp) | add_library(ScrapHack SHARED ScrapHack.cpp dllmain.cpp) | ||||||
| target_link_libraries(ScrapHack d3d8 d3dx8 legacy_stdio_definitions) | target_link_libraries(ScrapHack | ||||||
|  |                       d3d8 | ||||||
|  |                       d3dx8 | ||||||
|  |                       legacy_stdio_definitions) | ||||||
| install(TARGETS ScrapHack DESTINATION bin) | install(TARGETS ScrapHack DESTINATION bin) | ||||||
|  |  | ||||||
|  | @ -2,92 +2,104 @@ | ||||||
| #include <d3d8.h> | #include <d3d8.h> | ||||||
| #include <d3dx8.h> | #include <d3dx8.h> | ||||||
| uintmax_t frame = 0; | uintmax_t frame = 0; | ||||||
| DWORD* GetVTable(void* addr) { | DWORD *GetVTable(void *addr) | ||||||
| 	return (DWORD*)(*(DWORD*)addr); | { | ||||||
|  |     return (DWORD *)(*(DWORD *)addr); | ||||||
| } | } | ||||||
| bool overlay = false; | bool overlay = false; | ||||||
| LPD3DXFONT m_pFont; | LPD3DXFONT m_pFont; | ||||||
| HFONT hFont; | HFONT hFont; | ||||||
| HBRUSH hBrush; | HBRUSH hBrush; | ||||||
| D3DCOLOR color = D3DCOLOR_ARGB(255,255, 0, 0); | D3DCOLOR color = D3DCOLOR_ARGB(255, 255, 0, 0); | ||||||
| RECT Rect = { 0,0,0,0 }; | RECT Rect = {0, 0, 0, 0}; | ||||||
| D3DRECT panel; | D3DRECT panel; | ||||||
| 
 | 
 | ||||||
| size_t size_ht(HashTable<EntityList>* ht); | size_t size_ht(HashTable<EntityList> *ht); | ||||||
| size_t size_ht(HashTable<Entity>* ht); | size_t size_ht(HashTable<Entity> *ht); | ||||||
| 
 | 
 | ||||||
| LPDIRECT3DDEVICE8 Render(LPDIRECT3DDEVICE8 dev) { | LPDIRECT3DDEVICE8 Render(LPDIRECT3DDEVICE8 dev) | ||||||
| 	if (!overlay) { | { | ||||||
| 		return dev; |     if (!overlay) | ||||||
| 	} |     { | ||||||
| 	char text[4096]; |         return dev; | ||||||
| 	int32_t money = 0; |     } | ||||||
| 	size_t num_ents = 0; |     char text[4096]; | ||||||
| 	size_t num_ent_lst = 0; |     int32_t money = 0; | ||||||
| 	if (ptr<void>(P_WORLD, 0)!=nullptr) { |     size_t num_ents = 0; | ||||||
| 		money = ptr<int32_t>(P_WORLD, O_MONEY)[0]; |     size_t num_ent_lst = 0; | ||||||
| 		num_ents= size_ht(ptr<HashTable<Entity>>(P_WORLD, O_ENTS)); |     if (ptr<void>(P_WORLD, 0) != nullptr) | ||||||
| 		num_ent_lst = size_ht(ptr<HashTable<EntityList>>(P_WORLD, O_ENTLISTS)); |     { | ||||||
| 	} |         money = ptr<int32_t>(P_WORLD, O_MONEY)[0]; | ||||||
| 	snprintf(text, 4096, "ScrapHack v0.1\nFrame: [%lld]\nMoney: [%d]\nEntities: [%ld]\nEntity Lists: [%ld]", ++frame, money, num_ents,num_ent_lst); |         num_ents = size_ht(ptr<HashTable<Entity>>(P_WORLD, O_ENTS)); | ||||||
| 	if (m_pFont == nullptr) { |         num_ent_lst = size_ht(ptr<HashTable<EntityList>>(P_WORLD, O_ENTLISTS)); | ||||||
| 		D3DXCreateFont(dev, hFont, &m_pFont); |     } | ||||||
| 		CloseHandle(hFont); |     snprintf(text, 4096, "ScrapHack v0.1\nFrame: [%lld]\nMoney: [%d]\nEntities: [%ld]\nEntity Lists: [%ld]", ++frame, money, num_ents, num_ent_lst); | ||||||
| 	} |     if (m_pFont == nullptr) | ||||||
| 	m_pFont->Begin(); |     { | ||||||
| 	m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0); |         D3DXCreateFont(dev, hFont, &m_pFont); | ||||||
| 	m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color); |         CloseHandle(hFont); | ||||||
| 	m_pFont->End(); |     } | ||||||
| 	return dev; |     m_pFont->Begin(); | ||||||
|  |     m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0); | ||||||
|  |     m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color); | ||||||
|  |     m_pFont->End(); | ||||||
|  |     return dev; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) { | HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) | ||||||
| 	typedef HRESULT(WINAPI *t_func)(LPDIRECT3DDEVICE8); | { | ||||||
| 	shared_ptr<Hook> hook = Hook::get(H_EndScene); |     typedef HRESULT(WINAPI * t_func)(LPDIRECT3DDEVICE8); | ||||||
| 	return hook->func<t_func>(Render(dev)); |     shared_ptr<Hook> hook = Hook::get(H_EndScene); | ||||||
|  |     return hook->func<t_func>(Render(dev)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT WINAPI H_CreateDevice(void* pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow, | HRESULT WINAPI H_CreateDevice(void *pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow, | ||||||
| 	unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, |                               unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, | ||||||
| 	LPDIRECT3DDEVICE8* ppReturnedDeviceInterface) { |                               LPDIRECT3DDEVICE8 *ppReturnedDeviceInterface) | ||||||
| 	typedef HRESULT(WINAPI *t_func)(void*, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*); | { | ||||||
| 	shared_ptr<Hook> hook = Hook::get(H_CreateDevice); |     typedef HRESULT(WINAPI * t_func)(void *, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS *, LPDIRECT3DDEVICE8 *); | ||||||
| 	HRESULT ret = hook->func<t_func>(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); |     shared_ptr<Hook> hook = Hook::get(H_CreateDevice); | ||||||
| 	cout << "CreateDevice -> " << ret << endl; |     HRESULT ret = hook->func<t_func>(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); | ||||||
| 	void* EndScene = reinterpret_cast<void*>(GetVTable(ppReturnedDeviceInterface[0])[35]); |     cout << "CreateDevice -> " << ret << endl; | ||||||
| 	cout << "EndScene @ " << EndScene << endl; // EndScene
 |     void *EndScene = reinterpret_cast<void *>(GetVTable(ppReturnedDeviceInterface[0])[35]); | ||||||
| 	Hook::addr(EndScene, H_EndScene); |     cout << "EndScene @ " << EndScene << endl; // EndScene
 | ||||||
| 	Hook::drop(H_CreateDevice); |     Hook::addr(EndScene, H_EndScene); | ||||||
| 	return ret; |     Hook::drop(H_CreateDevice); | ||||||
|  |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) { | LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) | ||||||
| 	typedef LPDIRECT3D8(_stdcall *t_func)(unsigned int); | { | ||||||
| 	shared_ptr<Hook> hook = Hook::get(H_Direct3DCreate8); |     typedef LPDIRECT3D8(_stdcall * t_func)(unsigned int); | ||||||
|  |     shared_ptr<Hook> hook = Hook::get(H_Direct3DCreate8); | ||||||
| 
 | 
 | ||||||
| 	LPDIRECT3D8 ret = hook->func<t_func>(SDKVersion); |     LPDIRECT3D8 ret = hook->func<t_func>(SDKVersion); | ||||||
| 	cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl; |     cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl; | ||||||
| 	void *CreateDevice = reinterpret_cast<void*>(GetVTable(ret)[15]); |     void *CreateDevice = reinterpret_cast<void *>(GetVTable(ret)[15]); | ||||||
| 	void *Release = reinterpret_cast<void*>(GetVTable(ret)[2]); |     void *Release = reinterpret_cast<void *>(GetVTable(ret)[2]); | ||||||
| 	cout << "CreateDevice @ " << CreateDevice << endl; // CreateDevice
 |     cout << "CreateDevice @ " << CreateDevice << endl; // CreateDevice
 | ||||||
| 	Hook::addr(CreateDevice, H_CreateDevice); |     Hook::addr(CreateDevice, H_CreateDevice); | ||||||
| 	Hook::drop(H_Direct3DCreate8); |     Hook::drop(H_Direct3DCreate8); | ||||||
| 
 | 
 | ||||||
| 	return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void unhook_d3d8() { | void unhook_d3d8() | ||||||
| 	if (hFont != INVALID_HANDLE_VALUE) { | { | ||||||
| 		CloseHandle(hFont); |     if (hFont != INVALID_HANDLE_VALUE) | ||||||
| 	} |     { | ||||||
| 	if (m_pFont != nullptr) { |         CloseHandle(hFont); | ||||||
| 		m_pFont->Release(); |     } | ||||||
| 	} |     if (m_pFont != nullptr) | ||||||
| 	Hook::drop(H_EndScene); |     { | ||||||
|  |         m_pFont->Release(); | ||||||
|  |     } | ||||||
|  |     Hook::drop(H_EndScene); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void hook_d3d8() { | void hook_d3d8() | ||||||
| 	hFont = CreateFont(20, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana"); | { | ||||||
| 	hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0)); |     hFont = CreateFont(20, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana"); | ||||||
| 	Hook::module("d3d8.dll","Direct3DCreate8", H_Direct3DCreate8); |     hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0)); | ||||||
|  |     Hook::module("d3d8.dll", "Direct3DCreate8", H_Direct3DCreate8); | ||||||
| } | } | ||||||
|  | @ -4,16 +4,16 @@ class Hook | ||||||
| { | { | ||||||
| private: | private: | ||||||
| 	MEMORY_BASIC_INFORMATION mbi; | 	MEMORY_BASIC_INFORMATION mbi; | ||||||
| 	void* orig; | 	void *orig; | ||||||
| 	void* detour; | 	void *detour; | ||||||
| 	bool enabled; | 	bool enabled; | ||||||
| 	uint8_t orig_bytes[6]; | 	uint8_t orig_bytes[6]; | ||||||
| 	uint8_t jmp_bytes[6]; | 	uint8_t jmp_bytes[6]; | ||||||
| 	static map<uintptr_t, shared_ptr<Hook>> hooks; | 	static map<uintptr_t, shared_ptr<Hook>> hooks; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 
 | 	Hook(void *func, void *detour) | ||||||
| 	Hook(void* func, void* detour) { | 	{ | ||||||
| 		uintptr_t dest = reinterpret_cast<uintptr_t>(detour); | 		uintptr_t dest = reinterpret_cast<uintptr_t>(detour); | ||||||
| 		uintptr_t src = reinterpret_cast<uintptr_t>(func); | 		uintptr_t src = reinterpret_cast<uintptr_t>(func); | ||||||
| 		this->orig = func; | 		this->orig = func; | ||||||
|  | @ -31,57 +31,70 @@ public: | ||||||
| 		this->enabled = false; | 		this->enabled = false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	~Hook() { | 	~Hook() | ||||||
|  | 	{ | ||||||
| 		cout << "Unhooking: [" << this->orig << " <- " << this->detour << "]" << endl; | 		cout << "Unhooking: [" << this->orig << " <- " << this->detour << "]" << endl; | ||||||
| 		this->disable(); | 		this->disable(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static void addr(void* addr, void* detour) { | 	static void addr(void *addr, void *detour) | ||||||
| 		cout << "Hooking: [" << addr << " -> " << detour <<"]" << endl; | 	{ | ||||||
|  | 		cout << "Hooking: [" << addr << " -> " << detour << "]" << endl; | ||||||
| 		uintptr_t key = reinterpret_cast<uintptr_t>(detour); | 		uintptr_t key = reinterpret_cast<uintptr_t>(detour); | ||||||
| 		hooks[key] = make_shared<Hook>(addr,detour); | 		hooks[key] = make_shared<Hook>(addr, detour); | ||||||
| 		hooks[key]->enable(); | 		hooks[key]->enable(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static void module(const char* mod, const char* func, void* detour) { | 	static void module(const char *mod, const char *func, void *detour) | ||||||
| 		cout << "Hooking: [" << mod<<"]."<<func << " -> " << detour << endl; | 	{ | ||||||
| 		void* addr = GetProcAddress(GetModuleHandle(mod), func); | 		cout << "Hooking: [" << mod << "]." << func << " -> " << detour << endl; | ||||||
| 		if (addr != NULL) { | 		void *addr = GetProcAddress(GetModuleHandle(mod), func); | ||||||
|  | 		if (addr != NULL) | ||||||
|  | 		{ | ||||||
| 			Hook::addr(addr, detour); | 			Hook::addr(addr, detour); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else | ||||||
|  | 		{ | ||||||
| 			cerr << "[" << mod << "]." << func << " not found!" << endl; | 			cerr << "[" << mod << "]." << func << " not found!" << endl; | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static shared_ptr<Hook> get(void* func) { | 	static shared_ptr<Hook> get(void *func) | ||||||
|  | 	{ | ||||||
| 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | ||||||
| 		return Hook::get(addr); | 		return Hook::get(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static shared_ptr<Hook> get(uintptr_t addr) { | 	static shared_ptr<Hook> get(uintptr_t addr) | ||||||
|  | 	{ | ||||||
| 		return hooks.at(addr); | 		return hooks.at(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static size_t drop(void* func) { | 	static size_t drop(void *func) | ||||||
|  | 	{ | ||||||
| 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | ||||||
| 		return Hook::drop(addr); | 		return Hook::drop(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static size_t drop(uintptr_t addr) { | 	static size_t drop(uintptr_t addr) | ||||||
|  | 	{ | ||||||
| 		return hooks.erase(addr); | 		return hooks.erase(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static void clear() { | 	static void clear() | ||||||
|  | 	{ | ||||||
| 		cout << "Clearing Hooks" << endl; | 		cout << "Clearing Hooks" << endl; | ||||||
| 		for (pair<uintptr_t,shared_ptr<Hook>> h : hooks) { | 		for (pair<uintptr_t, shared_ptr<Hook>> h : hooks) | ||||||
|  | 		{ | ||||||
| 			h.second->disable(); | 			h.second->disable(); | ||||||
| 		} | 		} | ||||||
| 		return hooks.clear(); | 		return hooks.clear(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void disable() { | 	void disable() | ||||||
| 		if (enabled) { | 	{ | ||||||
|  | 		if (enabled) | ||||||
|  | 		{ | ||||||
| 			//cout << "Disabling: [" << this->orig << " <- " << this->detour << "]" << endl;
 | 			//cout << "Disabling: [" << this->orig << " <- " << this->detour << "]" << endl;
 | ||||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||||
| 			memcpy(this->orig, this->orig_bytes, 1 + 4 + 1); | 			memcpy(this->orig, this->orig_bytes, 1 + 4 + 1); | ||||||
|  | @ -89,8 +102,10 @@ public: | ||||||
| 			enabled = false; | 			enabled = false; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	void enable() { | 	void enable() | ||||||
| 		if (!enabled) { | 	{ | ||||||
|  | 		if (!enabled) | ||||||
|  | 		{ | ||||||
| 			//cout << "Enabling: [" << this->orig << " -> " << this->detour << "]" << endl;
 | 			//cout << "Enabling: [" << this->orig << " -> " << this->detour << "]" << endl;
 | ||||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||||
| 			memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1); | 			memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1); | ||||||
|  | @ -99,14 +114,16 @@ public: | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void* get_orig() { | 	void *get_orig() | ||||||
|  | 	{ | ||||||
| 		return this->orig; | 		return this->orig; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	template<typename F,typename ...Args> | 	template <typename F, typename... Args> | ||||||
| 	decltype(auto) func(Args... args) { | 	decltype(auto) func(Args... args) | ||||||
|  | 	{ | ||||||
| 		disable(); | 		disable(); | ||||||
| 		auto ret=reinterpret_cast<F>(this->orig)(args...); | 		auto ret = reinterpret_cast<F>(this->orig)(args...); | ||||||
| 		enable(); | 		enable(); | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -8,12 +8,13 @@ PyMethodDef *find_method_table(uintptr_t base, uintptr_t needle) | ||||||
| 	for (ptrdiff_t offset = 0; offset < 64; ++offset) | 	for (ptrdiff_t offset = 0; offset < 64; ++offset) | ||||||
| 	{ | 	{ | ||||||
| 		uintptr_t instr = reinterpret_cast<uintptr_t *>(base + offset)[0]; | 		uintptr_t instr = reinterpret_cast<uintptr_t *>(base + offset)[0]; | ||||||
| 		if (instr == needle) { | 		if (instr == needle) | ||||||
|  | 		{ | ||||||
| 			uintptr_t mod_addr = reinterpret_cast<uintptr_t *>(base + offset - (1 + 4))[0]; | 			uintptr_t mod_addr = reinterpret_cast<uintptr_t *>(base + offset - (1 + 4))[0]; | ||||||
| 			return reinterpret_cast<PyMethodDef*>(mod_addr); | 			return reinterpret_cast<PyMethodDef *>(mod_addr); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return reinterpret_cast<PyMethodDef*>(0); | 	return reinterpret_cast<PyMethodDef *>(0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| map<string, Module> get_modules(uintptr_t base) | map<string, Module> get_modules(uintptr_t base) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| #include "stdafx.h" |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
|  | @ -16,8 +16,8 @@ | ||||||
| #define P_SCRAP_EXIT 0x4010c0 | #define P_SCRAP_EXIT 0x4010c0 | ||||||
| 
 | 
 | ||||||
| //FUNCTION TYPES
 | //FUNCTION TYPES
 | ||||||
| #define T_SCRAP_LOG int(_cdecl*)(unsigned int, const char*) | #define T_SCRAP_LOG int(_cdecl *)(unsigned int, const char *) | ||||||
| #define T_SCRAP_EXEC int(_cdecl*)(const char*) | #define T_SCRAP_EXEC int(_cdecl *)(const char *) | ||||||
| 
 | 
 | ||||||
| auto scrap_log = (T_SCRAP_LOG)P_SCRAP_LOG; | auto scrap_log = (T_SCRAP_LOG)P_SCRAP_LOG; | ||||||
| auto scrap_exec = (T_SCRAP_EXEC)P_SCRAP_EXEC; | auto scrap_exec = (T_SCRAP_EXEC)P_SCRAP_EXEC; | ||||||
|  |  | ||||||
|  | @ -1,19 +1,20 @@ | ||||||
| #pragma once | #pragma once | ||||||
| template<typename T> | template <typename T> | ||||||
| struct HashTableEntry; | struct HashTableEntry; | ||||||
| struct Vector3 { | struct Vector3 | ||||||
|  | { | ||||||
| 	float x; | 	float x; | ||||||
| 	float y; | 	float y; | ||||||
| 	float z; | 	float z; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Matrix3x3 { | struct Matrix3x3 | ||||||
|  | { | ||||||
| 	Vector3 a; | 	Vector3 a; | ||||||
| 	Vector3 b; | 	Vector3 b; | ||||||
| 	Vector3 c; | 	Vector3 c; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| struct PyMethodDef | struct PyMethodDef | ||||||
| { | { | ||||||
| 	char *ml_name; | 	char *ml_name; | ||||||
|  | @ -31,31 +32,35 @@ struct PyMod | ||||||
| struct Module | struct Module | ||||||
| { | { | ||||||
| 	PyMod *mod; | 	PyMod *mod; | ||||||
| 	map<string, PyMethodDef*> methods; | 	map<string, PyMethodDef *> methods; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Entity { | struct Entity | ||||||
| 	void* vmt; | { | ||||||
| 	const char* name; | 	void *vmt; | ||||||
|  | 	const char *name; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct EntityList { | struct EntityList | ||||||
| 	const char* name; | { | ||||||
| 	void* unk_1; | 	const char *name; | ||||||
| 	void* unk_2; | 	void *unk_1; | ||||||
| 	const char* mod; | 	void *unk_2; | ||||||
| 	const char* func; | 	const char *mod; | ||||||
|  | 	const char *func; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<typename T> | template <typename T> | ||||||
| struct HashTable { | struct HashTable | ||||||
|  | { | ||||||
| 	uint32_t size; | 	uint32_t size; | ||||||
| 	HashTableEntry<T>** chains; | 	HashTableEntry<T> **chains; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<typename T> | template <typename T> | ||||||
| struct HashTableEntry { | struct HashTableEntry | ||||||
| 	T* data; | { | ||||||
| 	const char* name; | 	T *data; | ||||||
| 	HashTableEntry* next; | 	const char *name; | ||||||
|  | 	HashTableEntry *next; | ||||||
| }; | }; | ||||||
|  | @ -9,7 +9,7 @@ string GetLastErrorAsString() | ||||||
| 		return "No error"; | 		return "No error"; | ||||||
| 	LPSTR messageBuffer = NULL; | 	LPSTR messageBuffer = NULL; | ||||||
| 	size_t m_size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | 	size_t m_size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | ||||||
| 		NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); | 								   NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); | ||||||
| 	string message(messageBuffer, m_size); | 	string message(messageBuffer, m_size); | ||||||
| 	LocalFree(messageBuffer); | 	LocalFree(messageBuffer); | ||||||
| 	if (!message.empty() && message[message.length() - 1] == '\n') | 	if (!message.empty() && message[message.length() - 1] == '\n') | ||||||
|  | @ -62,7 +62,6 @@ void FreeConsole(bool wait) | ||||||
| 	FreeConsole(); | 	FreeConsole(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| bool in_foreground = false; | bool in_foreground = false; | ||||||
| BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) | BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) | ||||||
| { | { | ||||||
|  | @ -109,7 +108,6 @@ bool key_down_norepeat(int keycode, int delay = 100) | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| void hexdump(void *addr, size_t count) | void hexdump(void *addr, size_t count) | ||||||
| { | { | ||||||
| 	for (size_t i = 0; i < count; ++i) | 	for (size_t i = 0; i < count; ++i) | ||||||
|  | @ -124,35 +122,35 @@ 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) | ||||||
| { | { | ||||||
| 	return reinterpret_cast<T*>(addr); | 	return reinterpret_cast<T *>(addr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | template <typename T> | ||||||
| template<typename T> | T *__ptr(uintptr_t addr, ptrdiff_t offset) | ||||||
| T* __ptr(uintptr_t addr, ptrdiff_t offset) |  | ||||||
| { | { | ||||||
| 	//cout << "[" << (void*)addr << "] + " << (void*)offset << " = ";
 | 	//cout << "[" << (void*)addr << "] + " << (void*)offset << " = ";
 | ||||||
| 	addr = reinterpret_cast<uintptr_t*>(addr)[0] + offset; | 	addr = reinterpret_cast<uintptr_t *>(addr)[0] + offset; | ||||||
| 	//cout << (void*)addr << endl;;
 | 	//cout << (void*)addr << endl;;
 | ||||||
| 	auto ret = __ptr<T>(addr); | 	auto ret = __ptr<T>(addr); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | template <typename T, typename... Offsets> | ||||||
| template<typename T, typename... Offsets> | T *__ptr(uintptr_t addr, ptrdiff_t offset, Offsets... offsets) | ||||||
| T* __ptr(uintptr_t addr, ptrdiff_t offset, Offsets... offsets) { | { | ||||||
| 	//cout << "[" << (void*)addr << "] + " << (void*)offset << " = ";
 | 	//cout << "[" << (void*)addr << "] + " << (void*)offset << " = ";
 | ||||||
| 	addr = reinterpret_cast<uintptr_t*>(addr)[0] + offset; | 	addr = reinterpret_cast<uintptr_t *>(addr)[0] + offset; | ||||||
| 	//cout << (void*)addr << endl;;
 | 	//cout << (void*)addr << endl;;
 | ||||||
| 	auto ret = __ptr<T>(addr, offsets...); | 	auto ret = __ptr<T>(addr, offsets...); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename T, typename... Offsets> | template <typename T, typename... Offsets> | ||||||
| T* ptr(uintptr_t addr, Offsets... offsets) { | T *ptr(uintptr_t addr, Offsets... offsets) | ||||||
|  | { | ||||||
| 	auto ret = __ptr<T>(addr, offsets...); | 	auto ret = __ptr<T>(addr, offsets...); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,23 +4,23 @@ class VMT_Hook | ||||||
| { | { | ||||||
| private: | private: | ||||||
| 	MEMORY_BASIC_INFORMATION mbi; | 	MEMORY_BASIC_INFORMATION mbi; | ||||||
| 	void* orig; | 	void *orig; | ||||||
| 	void* detour; | 	void *detour; | ||||||
| 	DWORD* vtable; | 	DWORD *vtable; | ||||||
| 	size_t ord; | 	size_t ord; | ||||||
| 	bool enabled; | 	bool enabled; | ||||||
| 	static map<uintptr_t, shared_ptr<VMT_Hook>> hooks; | 	static map<uintptr_t, shared_ptr<VMT_Hook>> hooks; | ||||||
| 	static DWORD* GetVTable(void* addr) { | 	static DWORD *GetVTable(void *addr) | ||||||
|  | 	{ | ||||||
| 		return (DWORD *)*(DWORD *)addr; | 		return (DWORD *)*(DWORD *)addr; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| public: | public: | ||||||
| 
 | 	VMT_Hook(void *obj, size_t ord, void *detour) | ||||||
| 	VMT_Hook(void* obj, size_t ord, void* detour) { | 	{ | ||||||
| 		this->vtable = GetVTable(obj); | 		this->vtable = GetVTable(obj); | ||||||
| 		this->detour = detour; | 		this->detour = detour; | ||||||
| 		this->orig = reinterpret_cast<void*>(vtable[ord]); | 		this->orig = reinterpret_cast<void *>(vtable[ord]); | ||||||
| 		this->ord = ord; | 		this->ord = ord; | ||||||
| 		this->enabled = false; | 		this->enabled = false; | ||||||
| 
 | 
 | ||||||
|  | @ -28,51 +28,62 @@ public: | ||||||
| 		cout << "Hooking: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | 		cout << "Hooking: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	~VMT_Hook() { | 	~VMT_Hook() | ||||||
|  | 	{ | ||||||
| 		cout << "Unhooking: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | 		cout << "Unhooking: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | ||||||
| 		this->disable(); | 		this->disable(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static void create(void* obj, size_t ord, void* detour) { | 	static void create(void *obj, size_t ord, void *detour) | ||||||
|  | 	{ | ||||||
| 		uintptr_t key = reinterpret_cast<uintptr_t>(detour); | 		uintptr_t key = reinterpret_cast<uintptr_t>(detour); | ||||||
| 		hooks[key] = make_shared<VMT_Hook>(obj,ord, detour); | 		hooks[key] = make_shared<VMT_Hook>(obj, ord, detour); | ||||||
| 		hooks[key]->enable(); | 		hooks[key]->enable(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static shared_ptr<VMT_Hook> get(void* func) { | 	static shared_ptr<VMT_Hook> get(void *func) | ||||||
|  | 	{ | ||||||
| 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | ||||||
| 		return VMT_Hook::get(addr); | 		return VMT_Hook::get(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static shared_ptr<VMT_Hook> get(uintptr_t addr) { | 	static shared_ptr<VMT_Hook> get(uintptr_t addr) | ||||||
|  | 	{ | ||||||
| 		return hooks.at(addr); | 		return hooks.at(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static size_t drop(void* func) { | 	static size_t drop(void *func) | ||||||
|  | 	{ | ||||||
| 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | ||||||
| 		return VMT_Hook::drop(addr); | 		return VMT_Hook::drop(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static size_t drop(uintptr_t addr) { | 	static size_t drop(uintptr_t addr) | ||||||
|  | 	{ | ||||||
| 		return hooks.erase(addr); | 		return hooks.erase(addr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	static void clear() { | 	static void clear() | ||||||
|  | 	{ | ||||||
| 		return hooks.clear(); | 		return hooks.clear(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void disable() { | 	void disable() | ||||||
| 		if (enabled) { | 	{ | ||||||
| 			cout << "Disabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour<<")" << endl; | 		if (enabled) | ||||||
|  | 		{ | ||||||
|  | 			cout << "Disabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | ||||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||||
| 			this->vtable[ord] = reinterpret_cast<DWORD>(this->orig); | 			this->vtable[ord] = reinterpret_cast<DWORD>(this->orig); | ||||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); | 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); | ||||||
| 			enabled = false; | 			enabled = false; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	void enable() { | 	void enable() | ||||||
| 		if (!enabled) { | 	{ | ||||||
| 			cout << "Enabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour <<")" << endl; | 		if (!enabled) | ||||||
|  | 		{ | ||||||
|  | 			cout << "Enabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | ||||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||||
| 			this->vtable[ord] = reinterpret_cast<DWORD>(this->detour); | 			this->vtable[ord] = reinterpret_cast<DWORD>(this->detour); | ||||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); | 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); | ||||||
|  | @ -80,12 +91,11 @@ public: | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	template<typename T> | 	template <typename T> | ||||||
| 	T func() { | 	T func() | ||||||
|  | 	{ | ||||||
| 		return reinterpret_cast<T>(this->orig); | 		return reinterpret_cast<T>(this->orig); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| map<uintptr_t, shared_ptr<VMT_Hook>> VMT_Hook::hooks; | map<uintptr_t, shared_ptr<VMT_Hook>> VMT_Hook::hooks; | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| #include "stdafx.h" | #include <Windows.h> | ||||||
| #define DLL_EXPORT extern "C" __declspec(dllexport) | #define DLL_EXPORT extern "C" __declspec(dllexport) | ||||||
| void DllInit(HMODULE); | void DllInit(HMODULE); | ||||||
| void DllPreInit(HMODULE); | void DllPreInit(HMODULE); | ||||||
|  |  | ||||||
							
								
								
									
										5470
									
								
								helplib.txt
									
										
									
									
									
								
							
							
						
						
									
										5470
									
								
								helplib.txt
									
										
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -1,18 +1,20 @@ | ||||||
| from construct import * | from construct import * | ||||||
| from pprint import pprint | from pprint import pprint | ||||||
|  | 
 | ||||||
| ScrapSaveVar = Struct( | ScrapSaveVar = Struct( | ||||||
|     'name'/PascalString(Int32ul,encoding='utf-8'), |     "name" / PascalString(Int32ul, encoding="utf-8"), | ||||||
|     'data'/PascalString(Int32ul,encoding='utf-8'), |     "data" / PascalString(Int32ul, encoding="utf-8"), | ||||||
| ) | ) | ||||||
| ScrapSave = 'ScarpSaveGame'/Struct( | ScrapSave = "ScarpSaveGame" / Struct( | ||||||
|                    'title'/PascalString(Int32ul,encoding='utf-8'), |     "title" / PascalString(Int32ul, encoding="utf-8"), | ||||||
|                    'id'/PascalString(Int32ul,encoding='utf-8'), |     "id" / PascalString(Int32ul, encoding="utf-8"), | ||||||
|                    'data'/PrefixedArray(Int32ul,ScrapSaveVar), |     "data" / PrefixedArray(Int32ul, ScrapSaveVar), | ||||||
|                    Terminated |     Terminated, | ||||||
|                    ) | ) | ||||||
| with open("Save0.sav", 'rb') as sav_file: | with open("Save0.sav", "rb") as sav_file: | ||||||
|     save = ScrapSave.parse_stream(sav_file) |     save = ScrapSave.parse_stream(sav_file) | ||||||
|     print("ID:",save.id) |     print("ID:", save.id) | ||||||
|     print("Title:",save.title) |     print("Title:", save.title) | ||||||
|     for var in save.data: |     for var in save.data: | ||||||
|         print(" - {}: {}".format(var.name,var.data)) |         print(" - {}: {}".format(var.name, var.data)) | ||||||
|  | 
 | ||||||
|  |  | ||||||
							
								
								
									
										161
									
								
								scrapper.py
									
										
									
									
									
								
							
							
						
						
									
										161
									
								
								scrapper.py
									
										
									
									
									
								
							|  | @ -5,131 +5,128 @@ import os | ||||||
| import shutil | import shutil | ||||||
| from construct import * | from construct import * | ||||||
| from tqdm import tqdm | from tqdm import tqdm | ||||||
|  | 
 | ||||||
| setglobalstringencoding(None) | setglobalstringencoding(None) | ||||||
| 
 | 
 | ||||||
| ScrapFile = Struct( | ScrapFile = Struct( | ||||||
|                'path'/PascalString(Int32ul), |     "path" / PascalString(Int32ul), | ||||||
|                'size'/Int32ul, |     "size" / Int32ul, | ||||||
|                'offset'/Int32ul, |     "offset" / Int32ul, | ||||||
|                'data'/OnDemandPointer(this.offset,Bytes(this.size)), |     "data" / OnDemandPointer(this.offset, Bytes(this.size)), | ||||||
|                ) | ) | ||||||
| DummyFile = Struct( | DummyFile = Struct("path" / PascalString(Int32ul), "size" / Int32ul, "offset" / Int32ul) | ||||||
|                'path'/PascalString(Int32ul), |  | ||||||
|                'size'/Int32ul, |  | ||||||
|                'offset'/Int32ul, |  | ||||||
|                ) |  | ||||||
| 
 | 
 | ||||||
| PackedHeader = Struct( | PackedHeader = Struct( | ||||||
|                       Const(b'BFPK'), |     Const(b"BFPK"), Const(b"\0\0\0\0"), "files" / PrefixedArray(Int32ul, ScrapFile) | ||||||
|                       Const(b'\0\0\0\0'), | ) | ||||||
|                       'files'/PrefixedArray(Int32ul,ScrapFile), |  | ||||||
|                     ) |  | ||||||
| DummyHeader = Struct( | DummyHeader = Struct( | ||||||
|                       Const(b'BFPK'), |     Const(b"BFPK"), Const(b"\0\0\0\0"), "files" / PrefixedArray(Int32ul, DummyFile) | ||||||
|                       Const(b'\0\0\0\0'), | ) | ||||||
|                       'files'/PrefixedArray(Int32ul,DummyFile), | parser = argparse.ArgumentParser(description="Unpack and Repack .packed files") | ||||||
|                     ) | parser.add_argument( | ||||||
| parser = argparse.ArgumentParser(description='Unpack and Repack .packed files') |     "-u", "--unpack", action="store_true", help="unpack file to 'extracted' directory" | ||||||
| parser.add_argument('-u', '--unpack', action='store_true', | ) | ||||||
|                     help='unpack file to \'extracted\' directory') | parser.add_argument( | ||||||
| parser.add_argument('-r', '--repack', action='store_true', |     "-r", "--repack", action="store_true", help="repack file from 'extracted' directory" | ||||||
|                     help='repack file from \'extracted\' directory') | ) | ||||||
| 
 | 
 | ||||||
| parser.add_argument( | parser.add_argument( | ||||||
|     '--reset', |     "--reset", action="store_true", default=False, help="restore backup" | ||||||
|     action='store_true', | ) | ||||||
|     default=False, |  | ||||||
|     help='restore backup') |  | ||||||
| 
 | 
 | ||||||
| parser.add_argument( | parser.add_argument( | ||||||
|     'scrap_dir', |     "scrap_dir", | ||||||
|     metavar='Scrapland Directory', |     metavar="Scrapland Directory", | ||||||
|     type=str, |     type=str, | ||||||
|     default=".", |     default=".", | ||||||
|     help='Scrapland installation directory') |     help="Scrapland installation directory", | ||||||
|  | ) | ||||||
| options = parser.parse_args() | options = parser.parse_args() | ||||||
| scrap_dir = os.path.abspath(options.scrap_dir) | scrap_dir = os.path.abspath(options.scrap_dir) | ||||||
| 
 | 
 | ||||||
| if options.reset: | if options.reset: | ||||||
|     print('Restoring Backups and removing extracted folder...') |     print("Restoring Backups and removing extracted folder...") | ||||||
|     for packed_file in glob.glob(os.path.join(scrap_dir, '*.packed.bak')): |     for packed_file in glob.glob(os.path.join(scrap_dir, "*.packed.bak")): | ||||||
|         outfile = os.path.basename(packed_file) |         outfile = os.path.basename(packed_file) | ||||||
|         orig_filename = outfile[:-4] |         orig_filename = outfile[:-4] | ||||||
|         if os.path.isfile(outfile): |         if os.path.isfile(outfile): | ||||||
|             print('deleting', orig_filename) |             print("deleting", orig_filename) | ||||||
|             os.remove(orig_filename) |             os.remove(orig_filename) | ||||||
|             print('moving', outfile, '->', orig_filename) |             print("moving", outfile, "->", orig_filename) | ||||||
|             shutil.move(outfile, orig_filename) |             shutil.move(outfile, orig_filename) | ||||||
|         target_folder = os.path.join( |         target_folder = os.path.join("extracted", os.path.basename(orig_filename)) | ||||||
|             'extracted', os.path.basename(orig_filename)) |         print("deleting", target_folder) | ||||||
|         print('deleting', target_folder) |  | ||||||
|         shutil.rmtree(target_folder) |         shutil.rmtree(target_folder) | ||||||
|     if os.path.isdir('extracted'): |     if os.path.isdir("extracted"): | ||||||
|         input('Press enter to remove rest of extracted folder') |         input("Press enter to remove rest of extracted folder") | ||||||
|         shutil.rmtree('extracted') |         shutil.rmtree("extracted") | ||||||
|     exit('Done!') |     exit("Done!") | ||||||
| 
 | 
 | ||||||
| if not (options.unpack or options.repack): | if not (options.unpack or options.repack): | ||||||
|     parser.print_help() |     parser.print_help() | ||||||
|     exit() |     exit() | ||||||
| pstatus = '' | pstatus = "" | ||||||
| if options.unpack: | if options.unpack: | ||||||
|     if os.path.isdir('extracted'): |     if os.path.isdir("extracted"): | ||||||
|         print("Removing extracted folder") |         print("Removing extracted folder") | ||||||
|         shutil.rmtree('extracted') |         shutil.rmtree("extracted") | ||||||
|     for packed_file in glob.glob(os.path.join(scrap_dir, '*.packed')): |     for packed_file in glob.glob(os.path.join(scrap_dir, "*.packed")): | ||||||
|         os.chdir(scrap_dir) |         os.chdir(scrap_dir) | ||||||
|         BN=os.path.basename(packed_file) |         BN = os.path.basename(packed_file) | ||||||
|         target_folder = os.path.join( |         target_folder = os.path.join("extracted", os.path.basename(packed_file)) | ||||||
|             'extracted', os.path.basename(packed_file)) |  | ||||||
|         os.makedirs(target_folder, exist_ok=True) |         os.makedirs(target_folder, exist_ok=True) | ||||||
|         os.chdir(target_folder) |         os.chdir(target_folder) | ||||||
|         print('Unpacking {}'.format(os.path.basename(packed_file))) |         print("Unpacking {}".format(os.path.basename(packed_file))) | ||||||
|         with open(packed_file, 'rb') as pkfile: |         with open(packed_file, "rb") as pkfile: | ||||||
|             data = PackedHeader.parse_stream(pkfile) |             data = PackedHeader.parse_stream(pkfile) | ||||||
|             print("Offset:",hex(pkfile.tell())) |             print("Offset:", hex(pkfile.tell())) | ||||||
|             for file in tqdm(data.files,ascii=True): |             for file in tqdm(data.files, ascii=True): | ||||||
|                 folder, filename = os.path.split(file.path) |                 folder, filename = os.path.split(file.path) | ||||||
|                 if folder: |                 if folder: | ||||||
|                     os.makedirs(folder, exist_ok=True) |                     os.makedirs(folder, exist_ok=True) | ||||||
|                 with open(file.path, 'wb') as outfile: |                 with open(file.path, "wb") as outfile: | ||||||
|                     outfile.write(file.data()) |                     outfile.write(file.data()) | ||||||
|         print('\r' + ' ' * len(pstatus) + '\r', end='', flush=True) |         print("\r" + " " * len(pstatus) + "\r", end="", flush=True) | ||||||
|         os.chdir(scrap_dir) |         os.chdir(scrap_dir) | ||||||
| 
 | 
 | ||||||
| if (options.unpack and options.repack): | if options.unpack and options.repack: | ||||||
|     input('Press enter to rebuild *.packed files from folders in \'extracted\' dir...')  # noqa |     input( | ||||||
|  |         "Press enter to rebuild *.packed files from folders in 'extracted' dir..." | ||||||
|  |     )  # noqa | ||||||
|     pass |     pass | ||||||
| 
 | 
 | ||||||
| def file_gen(files,offset=0): |  | ||||||
|     for real_path,size,path in files: |  | ||||||
|         file=dict( |  | ||||||
|             path=path, |  | ||||||
|             offset=offset, |  | ||||||
|             size=size) |  | ||||||
|         yield file |  | ||||||
|         offset+=file['size'] |  | ||||||
| 
 | 
 | ||||||
| def make_header(files,offset=0): | def file_gen(files, offset=0): | ||||||
|     files_list=list(file_gen(files,offset)) |     for real_path, size, path in files: | ||||||
|  |         file = dict(path=path, offset=offset, size=size) | ||||||
|  |         yield file | ||||||
|  |         offset += file["size"] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def make_header(files, offset=0): | ||||||
|  |     files_list = list(file_gen(files, offset)) | ||||||
|     return DummyHeader.build(dict(files=files_list)) |     return DummyHeader.build(dict(files=files_list)) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| if options.repack: | if options.repack: | ||||||
|     for folder in glob.glob(os.path.join(scrap_dir, 'extracted', '*.packed')): |     for folder in glob.glob(os.path.join(scrap_dir, "extracted", "*.packed")): | ||||||
|         data=[] |         data = [] | ||||||
|         filename=os.path.join(scrap_dir,os.path.basename(folder)) |         filename = os.path.join(scrap_dir, os.path.basename(folder)) | ||||||
|         for root,folders,files in os.walk(folder): |         for root, folders, files in os.walk(folder): | ||||||
|             for file in sorted(files): |             for file in sorted(files): | ||||||
|                 file=os.path.join(root,file) |                 file = os.path.join(root, file) | ||||||
|                 rel_path=bytes(file.replace(folder, '').replace('\\', '/').lstrip('/'), 'windows-1252') |                 rel_path = bytes( | ||||||
|                 size=os.stat(file).st_size |                     file.replace(folder, "").replace("\\", "/").lstrip("/"), | ||||||
|                 data.append((file,size,rel_path)) |                     "windows-1252", | ||||||
|         print("Found {} files for {}".format(len(data),filename)) |                 ) | ||||||
|         offset=len(make_header(data)) |                 size = os.stat(file).st_size | ||||||
|         print("Writing",filename) |                 data.append((file, size, rel_path)) | ||||||
|         header=make_header(data,offset) |         print("Found {} files for {}".format(len(data), filename)) | ||||||
|         with open(filename,"wb") as outfile: |         offset = len(make_header(data)) | ||||||
|  |         print("Writing", filename) | ||||||
|  |         header = make_header(data, offset) | ||||||
|  |         with open(filename, "wb") as outfile: | ||||||
|             outfile.write(header) |             outfile.write(header) | ||||||
|             for file,size,rel_path in tqdm(data,ascii=True): |             for file, size, rel_path in tqdm(data, ascii=True): | ||||||
|                 outfile.write(open(file,"rb").read()) |                 outfile.write(open(file, "rb").read()) | ||||||
| print('Done!') | print("Done!") | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue