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) | ||||
| SET(CMAKE_BUILD_TYPE "Release") | ||||
| SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}") | ||||
| set(CMAKE_BUILD_TYPE "Release") | ||||
| set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}") | ||||
| if(WIN32) | ||||
|   if(MSVC) | ||||
|     # 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 \"NOMINMAX\"") | ||||
|     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"WIN32_LEAN_AND_MEAN\"") | ||||
|     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"NOMINMAX\"") | ||||
|     # disable SAFESEH - to avoid "LNK2026: module unsafe" | ||||
|     SET(CMAKE_CXX_FLAGS           "${CMAKE_CXX_FLAGS} /D \"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_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /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_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") | ||||
|     set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO") | ||||
|   endif(MSVC) | ||||
| endif(WIN32) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| #include "stdafx.h" | ||||
| #include <iostream> | ||||
| #include <windows.h> | ||||
| #include <TlHelp32.h> | ||||
|  | @ -27,8 +26,9 @@ string GetLastErrorAsString() | |||
|     return message; | ||||
| } | ||||
| 
 | ||||
| void fail(char* msg) { | ||||
| 	cerr << "[!] "<<msg<<": "<<GetLastErrorAsString()<<endl; | ||||
| void fail(char *msg) | ||||
| { | ||||
|     cerr << "[!] " << msg << ": " << GetLastErrorAsString() << endl; | ||||
|     exit(1); | ||||
| } | ||||
| 
 | ||||
|  | @ -164,7 +164,7 @@ void InjectDll(DWORD PID) | |||
|     const char *dll_name = DLL_NAME; | ||||
|     char dll_full_path[MAX_PATH]; | ||||
|     char executable_dir[MAX_PATH]; | ||||
| 	GetModuleFileNameA(NULL,executable_dir,MAX_PATH); | ||||
|     GetModuleFileNameA(NULL, executable_dir, MAX_PATH); | ||||
|     if (!fexists(dll_name)) | ||||
|     { | ||||
|         fail("DLL not found"); | ||||
|  | @ -211,16 +211,18 @@ void InjectDll(DWORD PID) | |||
|     return; | ||||
| } | ||||
| 
 | ||||
| vector<HANDLE> spawn(char* binary) { | ||||
| 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)) { | ||||
|     if (!CreateProcessA(NULL, binary, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupinfo, &processinfo)) | ||||
|     { | ||||
|         return {}; | ||||
|     } | ||||
| 	return { processinfo.hProcess,processinfo.hThread }; | ||||
|     return {processinfo.hProcess, processinfo.hThread}; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
|  | @ -232,23 +234,29 @@ int main(int argc, char *argv[]) | |||
|     char s_PID[MAX_PATH]; | ||||
|     snprintf(s_PID, MAX_PATH, "%d", GetCurrentProcessId()); | ||||
|     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; | ||||
|         vector<HANDLE> handles = spawn(argv[1]); | ||||
| 		if (handles.empty()) { | ||||
|         if (handles.empty()) | ||||
|         { | ||||
|             fail("Failed to spawn process"); | ||||
|         } | ||||
|         hProc = handles[0]; | ||||
|         hThread = handles[1]; | ||||
|         PID = GetProcessId(hProc); | ||||
| 	} else { | ||||
| 		cerr<<"Usage: " << argv[0] << " <Path to Scrap.exe>"<<endl; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         cerr << "Usage: " << argv[0] << " <Path to Scrap.exe>" << endl; | ||||
|         return 1; | ||||
|     } | ||||
|     InjectDll(PID); | ||||
| 	if (hThread != INVALID_HANDLE_VALUE) { | ||||
| 		while (ResumeThread(hThread)); | ||||
|     if (hThread != INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         while (ResumeThread(hThread)) | ||||
|             ; | ||||
|     } | ||||
|     SetEnvironmentVariableA("Inj_PID", NULL); | ||||
|     cout << "[*] Done!" << endl; | ||||
|  |  | |||
|  | @ -1,17 +1,21 @@ | |||
| include(ExternalProject) | ||||
| ExternalProject_Add(DirectX | ||||
| ExternalProject_Add( | ||||
|   DirectX | ||||
|   PREFIX ${CMAKE_CURRENT_BINARY_DIR} | ||||
|   CONFIGURE_COMMAND "" | ||||
|   BUILD_COMMAND "" | ||||
|   INSTALL_COMMAND "" | ||||
|     URL https://archive.org/download/DirectX.8.0a.SDK_includes_libs_only/DirectX.8.0a.SDK.zip | ||||
|     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) | ||||
| include_directories(AFTER ${SOURCE_DIR}/8.0/include/) | ||||
| link_directories(AFTER ${SOURCE_DIR}/8.0/lib/) | ||||
| add_compile_definitions(_CRT_SECURE_NO_WARNINGS) | ||||
| add_compile_definitions(POINTER_64=__ptr64) | ||||
| 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) | ||||
|  |  | |||
|  | @ -2,35 +2,40 @@ | |||
| #include <d3d8.h> | ||||
| #include <d3dx8.h> | ||||
| uintmax_t frame = 0; | ||||
| DWORD* GetVTable(void* addr) { | ||||
| 	return (DWORD*)(*(DWORD*)addr); | ||||
| DWORD *GetVTable(void *addr) | ||||
| { | ||||
|     return (DWORD *)(*(DWORD *)addr); | ||||
| } | ||||
| bool overlay = false; | ||||
| LPD3DXFONT m_pFont; | ||||
| HFONT hFont; | ||||
| HBRUSH hBrush; | ||||
| D3DCOLOR color = D3DCOLOR_ARGB(255,255, 0, 0); | ||||
| RECT Rect = { 0,0,0,0 }; | ||||
| D3DCOLOR color = D3DCOLOR_ARGB(255, 255, 0, 0); | ||||
| RECT Rect = {0, 0, 0, 0}; | ||||
| D3DRECT panel; | ||||
| 
 | ||||
| size_t size_ht(HashTable<EntityList>* ht); | ||||
| size_t size_ht(HashTable<Entity>* ht); | ||||
| size_t size_ht(HashTable<EntityList> *ht); | ||||
| size_t size_ht(HashTable<Entity> *ht); | ||||
| 
 | ||||
| LPDIRECT3DDEVICE8 Render(LPDIRECT3DDEVICE8 dev) { | ||||
| 	if (!overlay) { | ||||
| LPDIRECT3DDEVICE8 Render(LPDIRECT3DDEVICE8 dev) | ||||
| { | ||||
|     if (!overlay) | ||||
|     { | ||||
|         return dev; | ||||
|     } | ||||
|     char text[4096]; | ||||
|     int32_t money = 0; | ||||
|     size_t num_ents = 0; | ||||
|     size_t num_ent_lst = 0; | ||||
| 	if (ptr<void>(P_WORLD, 0)!=nullptr) { | ||||
|     if (ptr<void>(P_WORLD, 0) != nullptr) | ||||
|     { | ||||
|         money = ptr<int32_t>(P_WORLD, O_MONEY)[0]; | ||||
| 		num_ents= size_ht(ptr<HashTable<Entity>>(P_WORLD, O_ENTS)); | ||||
|         num_ents = size_ht(ptr<HashTable<Entity>>(P_WORLD, O_ENTS)); | ||||
|         num_ent_lst = size_ht(ptr<HashTable<EntityList>>(P_WORLD, O_ENTLISTS)); | ||||
|     } | ||||
| 	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) { | ||||
|     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) | ||||
|     { | ||||
|         D3DXCreateFont(dev, hFont, &m_pFont); | ||||
|         CloseHandle(hFont); | ||||
|     } | ||||
|  | @ -41,34 +46,37 @@ LPDIRECT3DDEVICE8 Render(LPDIRECT3DDEVICE8 dev) { | |||
|     return dev; | ||||
| } | ||||
| 
 | ||||
| HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) { | ||||
| 	typedef HRESULT(WINAPI *t_func)(LPDIRECT3DDEVICE8); | ||||
| HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) | ||||
| { | ||||
|     typedef HRESULT(WINAPI * t_func)(LPDIRECT3DDEVICE8); | ||||
|     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, | ||||
| 	unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, | ||||
| 	LPDIRECT3DDEVICE8* ppReturnedDeviceInterface) { | ||||
| 	typedef HRESULT(WINAPI *t_func)(void*, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*); | ||||
| HRESULT WINAPI H_CreateDevice(void *pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow, | ||||
|                               unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, | ||||
|                               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); | ||||
|     HRESULT ret = hook->func<t_func>(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); | ||||
|     cout << "CreateDevice -> " << ret << endl; | ||||
| 	void* EndScene = reinterpret_cast<void*>(GetVTable(ppReturnedDeviceInterface[0])[35]); | ||||
|     void *EndScene = reinterpret_cast<void *>(GetVTable(ppReturnedDeviceInterface[0])[35]); | ||||
|     cout << "EndScene @ " << EndScene << endl; // EndScene
 | ||||
|     Hook::addr(EndScene, H_EndScene); | ||||
|     Hook::drop(H_CreateDevice); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) { | ||||
| 	typedef LPDIRECT3D8(_stdcall *t_func)(unsigned int); | ||||
| LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) | ||||
| { | ||||
|     typedef LPDIRECT3D8(_stdcall * t_func)(unsigned int); | ||||
|     shared_ptr<Hook> hook = Hook::get(H_Direct3DCreate8); | ||||
| 
 | ||||
|     LPDIRECT3D8 ret = hook->func<t_func>(SDKVersion); | ||||
|     cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl; | ||||
| 	void *CreateDevice = reinterpret_cast<void*>(GetVTable(ret)[15]); | ||||
| 	void *Release = reinterpret_cast<void*>(GetVTable(ret)[2]); | ||||
|     void *CreateDevice = reinterpret_cast<void *>(GetVTable(ret)[15]); | ||||
|     void *Release = reinterpret_cast<void *>(GetVTable(ret)[2]); | ||||
|     cout << "CreateDevice @ " << CreateDevice << endl; // CreateDevice
 | ||||
|     Hook::addr(CreateDevice, H_CreateDevice); | ||||
|     Hook::drop(H_Direct3DCreate8); | ||||
|  | @ -76,18 +84,22 @@ LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) { | |||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void unhook_d3d8() { | ||||
| 	if (hFont != INVALID_HANDLE_VALUE) { | ||||
| void unhook_d3d8() | ||||
| { | ||||
|     if (hFont != INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         CloseHandle(hFont); | ||||
|     } | ||||
| 	if (m_pFont != nullptr) { | ||||
|     if (m_pFont != nullptr) | ||||
|     { | ||||
|         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)); | ||||
| 	Hook::module("d3d8.dll","Direct3DCreate8", H_Direct3DCreate8); | ||||
|     Hook::module("d3d8.dll", "Direct3DCreate8", H_Direct3DCreate8); | ||||
| } | ||||
|  | @ -4,16 +4,16 @@ class Hook | |||
| { | ||||
| private: | ||||
| 	MEMORY_BASIC_INFORMATION mbi; | ||||
| 	void* orig; | ||||
| 	void* detour; | ||||
| 	void *orig; | ||||
| 	void *detour; | ||||
| 	bool enabled; | ||||
| 	uint8_t orig_bytes[6]; | ||||
| 	uint8_t jmp_bytes[6]; | ||||
| 	static map<uintptr_t, shared_ptr<Hook>> hooks; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
| 	Hook(void* func, void* detour) { | ||||
| 	Hook(void *func, void *detour) | ||||
| 	{ | ||||
| 		uintptr_t dest = reinterpret_cast<uintptr_t>(detour); | ||||
| 		uintptr_t src = reinterpret_cast<uintptr_t>(func); | ||||
| 		this->orig = func; | ||||
|  | @ -31,57 +31,70 @@ public: | |||
| 		this->enabled = false; | ||||
| 	} | ||||
| 
 | ||||
| 	~Hook() { | ||||
| 	~Hook() | ||||
| 	{ | ||||
| 		cout << "Unhooking: [" << this->orig << " <- " << this->detour << "]" << endl; | ||||
| 		this->disable(); | ||||
| 	} | ||||
| 
 | ||||
| 	static void addr(void* addr, void* detour) { | ||||
| 		cout << "Hooking: [" << addr << " -> " << detour <<"]" << endl; | ||||
| 	static void addr(void *addr, void *detour) | ||||
| 	{ | ||||
| 		cout << "Hooking: [" << addr << " -> " << detour << "]" << endl; | ||||
| 		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(); | ||||
| 	} | ||||
| 
 | ||||
| 	static void module(const char* mod, const char* func, void* detour) { | ||||
| 		cout << "Hooking: [" << mod<<"]."<<func << " -> " << detour << endl; | ||||
| 		void* addr = GetProcAddress(GetModuleHandle(mod), func); | ||||
| 		if (addr != NULL) { | ||||
| 	static void module(const char *mod, const char *func, void *detour) | ||||
| 	{ | ||||
| 		cout << "Hooking: [" << mod << "]." << func << " -> " << detour << endl; | ||||
| 		void *addr = GetProcAddress(GetModuleHandle(mod), func); | ||||
| 		if (addr != NULL) | ||||
| 		{ | ||||
| 			Hook::addr(addr, detour); | ||||
| 		} | ||||
| 		else { | ||||
| 		else | ||||
| 		{ | ||||
| 			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); | ||||
| 		return Hook::get(addr); | ||||
| 	} | ||||
| 
 | ||||
| 	static shared_ptr<Hook> get(uintptr_t addr) { | ||||
| 	static shared_ptr<Hook> get(uintptr_t 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); | ||||
| 		return Hook::drop(addr); | ||||
| 	} | ||||
| 
 | ||||
| 	static size_t drop(uintptr_t addr) { | ||||
| 	static size_t drop(uintptr_t addr) | ||||
| 	{ | ||||
| 		return hooks.erase(addr); | ||||
| 	} | ||||
| 
 | ||||
| 	static void clear() { | ||||
| 	static void clear() | ||||
| 	{ | ||||
| 		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(); | ||||
| 		} | ||||
| 		return hooks.clear(); | ||||
| 	} | ||||
| 
 | ||||
| 	void disable() { | ||||
| 		if (enabled) { | ||||
| 	void disable() | ||||
| 	{ | ||||
| 		if (enabled) | ||||
| 		{ | ||||
| 			//cout << "Disabling: [" << this->orig << " <- " << this->detour << "]" << endl;
 | ||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||
| 			memcpy(this->orig, this->orig_bytes, 1 + 4 + 1); | ||||
|  | @ -89,8 +102,10 @@ public: | |||
| 			enabled = false; | ||||
| 		} | ||||
| 	} | ||||
| 	void enable() { | ||||
| 		if (!enabled) { | ||||
| 	void enable() | ||||
| 	{ | ||||
| 		if (!enabled) | ||||
| 		{ | ||||
| 			//cout << "Enabling: [" << this->orig << " -> " << this->detour << "]" << endl;
 | ||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||
| 			memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1); | ||||
|  | @ -99,14 +114,16 @@ public: | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	void* get_orig() { | ||||
| 	void *get_orig() | ||||
| 	{ | ||||
| 		return this->orig; | ||||
| 	} | ||||
| 
 | ||||
| 	template<typename F,typename ...Args> | ||||
| 	decltype(auto) func(Args... args) { | ||||
| 	template <typename F, typename... Args> | ||||
| 	decltype(auto) func(Args... args) | ||||
| 	{ | ||||
| 		disable(); | ||||
| 		auto ret=reinterpret_cast<F>(this->orig)(args...); | ||||
| 		auto ret = reinterpret_cast<F>(this->orig)(args...); | ||||
| 		enable(); | ||||
| 		return ret; | ||||
| 	} | ||||
|  |  | |||
|  | @ -8,12 +8,13 @@ PyMethodDef *find_method_table(uintptr_t base, uintptr_t needle) | |||
| 	for (ptrdiff_t offset = 0; offset < 64; ++offset) | ||||
| 	{ | ||||
| 		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]; | ||||
| 			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) | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| #include "stdafx.h" | ||||
| #include <string> | ||||
| #include <sstream> | ||||
| #include <vector> | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ | |||
| #define P_SCRAP_EXIT 0x4010c0 | ||||
| 
 | ||||
| //FUNCTION TYPES
 | ||||
| #define T_SCRAP_LOG int(_cdecl*)(unsigned int, const char*) | ||||
| #define T_SCRAP_EXEC int(_cdecl*)(const char*) | ||||
| #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; | ||||
|  |  | |||
|  | @ -1,19 +1,20 @@ | |||
| #pragma once | ||||
| template<typename T> | ||||
| template <typename T> | ||||
| struct HashTableEntry; | ||||
| struct Vector3 { | ||||
| struct Vector3 | ||||
| { | ||||
| 	float x; | ||||
| 	float y; | ||||
| 	float z; | ||||
| }; | ||||
| 
 | ||||
| struct Matrix3x3 { | ||||
| struct Matrix3x3 | ||||
| { | ||||
| 	Vector3 a; | ||||
| 	Vector3 b; | ||||
| 	Vector3 c; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| struct PyMethodDef | ||||
| { | ||||
| 	char *ml_name; | ||||
|  | @ -31,31 +32,35 @@ struct PyMod | |||
| struct Module | ||||
| { | ||||
| 	PyMod *mod; | ||||
| 	map<string, PyMethodDef*> methods; | ||||
| 	map<string, PyMethodDef *> methods; | ||||
| }; | ||||
| 
 | ||||
| struct Entity { | ||||
| 	void* vmt; | ||||
| 	const char* name; | ||||
| struct Entity | ||||
| { | ||||
| 	void *vmt; | ||||
| 	const char *name; | ||||
| }; | ||||
| 
 | ||||
| struct EntityList { | ||||
| 	const char* name; | ||||
| 	void* unk_1; | ||||
| 	void* unk_2; | ||||
| 	const char* mod; | ||||
| 	const char* func; | ||||
| struct EntityList | ||||
| { | ||||
| 	const char *name; | ||||
| 	void *unk_1; | ||||
| 	void *unk_2; | ||||
| 	const char *mod; | ||||
| 	const char *func; | ||||
| }; | ||||
| 
 | ||||
| template<typename T> | ||||
| struct HashTable { | ||||
| template <typename T> | ||||
| struct HashTable | ||||
| { | ||||
| 	uint32_t size; | ||||
| 	HashTableEntry<T>** chains; | ||||
| 	HashTableEntry<T> **chains; | ||||
| }; | ||||
| 
 | ||||
| template<typename T> | ||||
| struct HashTableEntry { | ||||
| 	T* data; | ||||
| 	const char* name; | ||||
| 	HashTableEntry* next; | ||||
| template <typename T> | ||||
| struct HashTableEntry | ||||
| { | ||||
| 	T *data; | ||||
| 	const char *name; | ||||
| 	HashTableEntry *next; | ||||
| }; | ||||
|  | @ -62,7 +62,6 @@ void FreeConsole(bool wait) | |||
| 	FreeConsole(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| bool in_foreground = false; | ||||
| BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam) | ||||
| { | ||||
|  | @ -109,7 +108,6 @@ bool key_down_norepeat(int keycode, int delay = 100) | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void hexdump(void *addr, size_t count) | ||||
| { | ||||
| 	for (size_t i = 0; i < count; ++i) | ||||
|  | @ -124,35 +122,35 @@ void hexdump(void *addr, size_t count) | |||
| 	cout << endl; | ||||
| } | ||||
| 
 | ||||
| template<typename T> | ||||
| T* __ptr(uintptr_t addr) | ||||
| template <typename T> | ||||
| T *__ptr(uintptr_t addr) | ||||
| { | ||||
| 	return reinterpret_cast<T*>(addr); | ||||
| 	return reinterpret_cast<T *>(addr); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| template<typename T> | ||||
| T* __ptr(uintptr_t addr, ptrdiff_t offset) | ||||
| template <typename T> | ||||
| T *__ptr(uintptr_t addr, ptrdiff_t 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;;
 | ||||
| 	auto ret = __ptr<T>(addr); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| template<typename T, typename... Offsets> | ||||
| T* __ptr(uintptr_t addr, ptrdiff_t offset, Offsets... offsets) { | ||||
| template <typename T, typename... Offsets> | ||||
| T *__ptr(uintptr_t addr, ptrdiff_t offset, Offsets... offsets) | ||||
| { | ||||
| 	//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;;
 | ||||
| 	auto ret = __ptr<T>(addr, offsets...); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| template<typename T, typename... Offsets> | ||||
| T* ptr(uintptr_t addr, Offsets... offsets) { | ||||
| template <typename T, typename... Offsets> | ||||
| T *ptr(uintptr_t addr, Offsets... offsets) | ||||
| { | ||||
| 	auto ret = __ptr<T>(addr, offsets...); | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
|  | @ -4,23 +4,23 @@ class VMT_Hook | |||
| { | ||||
| private: | ||||
| 	MEMORY_BASIC_INFORMATION mbi; | ||||
| 	void* orig; | ||||
| 	void* detour; | ||||
| 	DWORD* vtable; | ||||
| 	void *orig; | ||||
| 	void *detour; | ||||
| 	DWORD *vtable; | ||||
| 	size_t ord; | ||||
| 	bool enabled; | ||||
| 	static map<uintptr_t, shared_ptr<VMT_Hook>> hooks; | ||||
| 	static DWORD* GetVTable(void* addr) { | ||||
| 	static DWORD *GetVTable(void *addr) | ||||
| 	{ | ||||
| 		return (DWORD *)*(DWORD *)addr; | ||||
| 	}; | ||||
| 
 | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
| 	VMT_Hook(void* obj, size_t ord, void* detour) { | ||||
| 	VMT_Hook(void *obj, size_t ord, void *detour) | ||||
| 	{ | ||||
| 		this->vtable = GetVTable(obj); | ||||
| 		this->detour = detour; | ||||
| 		this->orig = reinterpret_cast<void*>(vtable[ord]); | ||||
| 		this->orig = reinterpret_cast<void *>(vtable[ord]); | ||||
| 		this->ord = ord; | ||||
| 		this->enabled = false; | ||||
| 
 | ||||
|  | @ -28,51 +28,62 @@ public: | |||
| 		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; | ||||
| 		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); | ||||
| 		hooks[key] = make_shared<VMT_Hook>(obj,ord, detour); | ||||
| 		hooks[key] = make_shared<VMT_Hook>(obj, ord, detour); | ||||
| 		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); | ||||
| 		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); | ||||
| 	} | ||||
| 
 | ||||
| 	static size_t drop(void* func) { | ||||
| 	static size_t drop(void *func) | ||||
| 	{ | ||||
| 		uintptr_t addr = reinterpret_cast<uintptr_t>(func); | ||||
| 		return VMT_Hook::drop(addr); | ||||
| 	} | ||||
| 
 | ||||
| 	static size_t drop(uintptr_t addr) { | ||||
| 	static size_t drop(uintptr_t addr) | ||||
| 	{ | ||||
| 		return hooks.erase(addr); | ||||
| 	} | ||||
| 
 | ||||
| 	static void clear() { | ||||
| 	static void clear() | ||||
| 	{ | ||||
| 		return hooks.clear(); | ||||
| 	} | ||||
| 
 | ||||
| 	void disable() { | ||||
| 		if (enabled) { | ||||
| 			cout << "Disabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour<<")" << endl; | ||||
| 	void disable() | ||||
| 	{ | ||||
| 		if (enabled) | ||||
| 		{ | ||||
| 			cout << "Disabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | ||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||
| 			this->vtable[ord] = reinterpret_cast<DWORD>(this->orig); | ||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); | ||||
| 			enabled = false; | ||||
| 		} | ||||
| 	} | ||||
| 	void enable() { | ||||
| 		if (!enabled) { | ||||
| 			cout << "Enabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour <<")" << endl; | ||||
| 	void enable() | ||||
| 	{ | ||||
| 		if (!enabled) | ||||
| 		{ | ||||
| 			cout << "Enabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; | ||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); | ||||
| 			this->vtable[ord] = reinterpret_cast<DWORD>(this->detour); | ||||
| 			VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); | ||||
|  | @ -80,12 +91,11 @@ public: | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	template<typename T> | ||||
| 	T func() { | ||||
| 	template <typename T> | ||||
| 	T func() | ||||
| 	{ | ||||
| 		return reinterpret_cast<T>(this->orig); | ||||
| 	} | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| 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) | ||||
| void DllInit(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 pprint import pprint | ||||
| 
 | ||||
| ScrapSaveVar = Struct( | ||||
|     'name'/PascalString(Int32ul,encoding='utf-8'), | ||||
|     'data'/PascalString(Int32ul,encoding='utf-8'), | ||||
|     "name" / PascalString(Int32ul, encoding="utf-8"), | ||||
|     "data" / PascalString(Int32ul, encoding="utf-8"), | ||||
| ) | ||||
| ScrapSave = 'ScarpSaveGame'/Struct( | ||||
|                    'title'/PascalString(Int32ul,encoding='utf-8'), | ||||
|                    'id'/PascalString(Int32ul,encoding='utf-8'), | ||||
|                    'data'/PrefixedArray(Int32ul,ScrapSaveVar), | ||||
|                    Terminated | ||||
|                    ) | ||||
| with open("Save0.sav", 'rb') as sav_file: | ||||
| ScrapSave = "ScarpSaveGame" / Struct( | ||||
|     "title" / PascalString(Int32ul, encoding="utf-8"), | ||||
|     "id" / PascalString(Int32ul, encoding="utf-8"), | ||||
|     "data" / PrefixedArray(Int32ul, ScrapSaveVar), | ||||
|     Terminated, | ||||
| ) | ||||
| with open("Save0.sav", "rb") as sav_file: | ||||
|     save = ScrapSave.parse_stream(sav_file) | ||||
|     print("ID:",save.id) | ||||
|     print("Title:",save.title) | ||||
|     print("ID:", save.id) | ||||
|     print("Title:", save.title) | ||||
|     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 | ||||
| from construct import * | ||||
| from tqdm import tqdm | ||||
| 
 | ||||
| setglobalstringencoding(None) | ||||
| 
 | ||||
| ScrapFile = Struct( | ||||
|                'path'/PascalString(Int32ul), | ||||
|                'size'/Int32ul, | ||||
|                'offset'/Int32ul, | ||||
|                'data'/OnDemandPointer(this.offset,Bytes(this.size)), | ||||
|                ) | ||||
| DummyFile = Struct( | ||||
|                'path'/PascalString(Int32ul), | ||||
|                'size'/Int32ul, | ||||
|                'offset'/Int32ul, | ||||
|                ) | ||||
|     "path" / PascalString(Int32ul), | ||||
|     "size" / Int32ul, | ||||
|     "offset" / Int32ul, | ||||
|     "data" / OnDemandPointer(this.offset, Bytes(this.size)), | ||||
| ) | ||||
| DummyFile = Struct("path" / PascalString(Int32ul), "size" / Int32ul, "offset" / Int32ul) | ||||
| 
 | ||||
| PackedHeader = Struct( | ||||
|                       Const(b'BFPK'), | ||||
|                       Const(b'\0\0\0\0'), | ||||
|                       'files'/PrefixedArray(Int32ul,ScrapFile), | ||||
|                     ) | ||||
|     Const(b"BFPK"), Const(b"\0\0\0\0"), "files" / PrefixedArray(Int32ul, ScrapFile) | ||||
| ) | ||||
| DummyHeader = Struct( | ||||
|                       Const(b'BFPK'), | ||||
|                       Const(b'\0\0\0\0'), | ||||
|                       'files'/PrefixedArray(Int32ul,DummyFile), | ||||
|                     ) | ||||
| parser = argparse.ArgumentParser(description='Unpack and Repack .packed files') | ||||
| parser.add_argument('-u', '--unpack', action='store_true', | ||||
|                     help='unpack file to \'extracted\' directory') | ||||
| parser.add_argument('-r', '--repack', action='store_true', | ||||
|                     help='repack file from \'extracted\' directory') | ||||
|     Const(b"BFPK"), Const(b"\0\0\0\0"), "files" / PrefixedArray(Int32ul, DummyFile) | ||||
| ) | ||||
| parser = argparse.ArgumentParser(description="Unpack and Repack .packed files") | ||||
| parser.add_argument( | ||||
|     "-u", "--unpack", action="store_true", help="unpack file to 'extracted' directory" | ||||
| ) | ||||
| parser.add_argument( | ||||
|     "-r", "--repack", action="store_true", help="repack file from 'extracted' directory" | ||||
| ) | ||||
| 
 | ||||
| parser.add_argument( | ||||
|     '--reset', | ||||
|     action='store_true', | ||||
|     default=False, | ||||
|     help='restore backup') | ||||
|     "--reset", action="store_true", default=False, help="restore backup" | ||||
| ) | ||||
| 
 | ||||
| parser.add_argument( | ||||
|     'scrap_dir', | ||||
|     metavar='Scrapland Directory', | ||||
|     "scrap_dir", | ||||
|     metavar="Scrapland Directory", | ||||
|     type=str, | ||||
|     default=".", | ||||
|     help='Scrapland installation directory') | ||||
|     help="Scrapland installation directory", | ||||
| ) | ||||
| options = parser.parse_args() | ||||
| scrap_dir = os.path.abspath(options.scrap_dir) | ||||
| 
 | ||||
| if options.reset: | ||||
|     print('Restoring Backups and removing extracted folder...') | ||||
|     for packed_file in glob.glob(os.path.join(scrap_dir, '*.packed.bak')): | ||||
|     print("Restoring Backups and removing extracted folder...") | ||||
|     for packed_file in glob.glob(os.path.join(scrap_dir, "*.packed.bak")): | ||||
|         outfile = os.path.basename(packed_file) | ||||
|         orig_filename = outfile[:-4] | ||||
|         if os.path.isfile(outfile): | ||||
|             print('deleting', orig_filename) | ||||
|             print("deleting", orig_filename) | ||||
|             os.remove(orig_filename) | ||||
|             print('moving', outfile, '->', orig_filename) | ||||
|             print("moving", outfile, "->", orig_filename) | ||||
|             shutil.move(outfile, orig_filename) | ||||
|         target_folder = os.path.join( | ||||
|             'extracted', os.path.basename(orig_filename)) | ||||
|         print('deleting', target_folder) | ||||
|         target_folder = os.path.join("extracted", os.path.basename(orig_filename)) | ||||
|         print("deleting", target_folder) | ||||
|         shutil.rmtree(target_folder) | ||||
|     if os.path.isdir('extracted'): | ||||
|         input('Press enter to remove rest of extracted folder') | ||||
|         shutil.rmtree('extracted') | ||||
|     exit('Done!') | ||||
|     if os.path.isdir("extracted"): | ||||
|         input("Press enter to remove rest of extracted folder") | ||||
|         shutil.rmtree("extracted") | ||||
|     exit("Done!") | ||||
| 
 | ||||
| if not (options.unpack or options.repack): | ||||
|     parser.print_help() | ||||
|     exit() | ||||
| pstatus = '' | ||||
| pstatus = "" | ||||
| if options.unpack: | ||||
|     if os.path.isdir('extracted'): | ||||
|     if os.path.isdir("extracted"): | ||||
|         print("Removing extracted folder") | ||||
|         shutil.rmtree('extracted') | ||||
|     for packed_file in glob.glob(os.path.join(scrap_dir, '*.packed')): | ||||
|         shutil.rmtree("extracted") | ||||
|     for packed_file in glob.glob(os.path.join(scrap_dir, "*.packed")): | ||||
|         os.chdir(scrap_dir) | ||||
|         BN=os.path.basename(packed_file) | ||||
|         target_folder = os.path.join( | ||||
|             'extracted', os.path.basename(packed_file)) | ||||
|         BN = os.path.basename(packed_file) | ||||
|         target_folder = os.path.join("extracted", os.path.basename(packed_file)) | ||||
|         os.makedirs(target_folder, exist_ok=True) | ||||
|         os.chdir(target_folder) | ||||
|         print('Unpacking {}'.format(os.path.basename(packed_file))) | ||||
|         with open(packed_file, 'rb') as pkfile: | ||||
|         print("Unpacking {}".format(os.path.basename(packed_file))) | ||||
|         with open(packed_file, "rb") as pkfile: | ||||
|             data = PackedHeader.parse_stream(pkfile) | ||||
|             print("Offset:",hex(pkfile.tell())) | ||||
|             for file in tqdm(data.files,ascii=True): | ||||
|             print("Offset:", hex(pkfile.tell())) | ||||
|             for file in tqdm(data.files, ascii=True): | ||||
|                 folder, filename = os.path.split(file.path) | ||||
|                 if folder: | ||||
|                     os.makedirs(folder, exist_ok=True) | ||||
|                 with open(file.path, 'wb') as outfile: | ||||
|                 with open(file.path, "wb") as outfile: | ||||
|                     outfile.write(file.data()) | ||||
|         print('\r' + ' ' * len(pstatus) + '\r', end='', flush=True) | ||||
|         print("\r" + " " * len(pstatus) + "\r", end="", flush=True) | ||||
|         os.chdir(scrap_dir) | ||||
| 
 | ||||
| if (options.unpack and options.repack): | ||||
|     input('Press enter to rebuild *.packed files from folders in \'extracted\' dir...')  # noqa | ||||
| if options.unpack and options.repack: | ||||
|     input( | ||||
|         "Press enter to rebuild *.packed files from folders in 'extracted' dir..." | ||||
|     )  # noqa | ||||
|     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): | ||||
|     files_list=list(file_gen(files,offset)) | ||||
| 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): | ||||
|     files_list = list(file_gen(files, offset)) | ||||
|     return DummyHeader.build(dict(files=files_list)) | ||||
| 
 | ||||
| 
 | ||||
| if options.repack: | ||||
|     for folder in glob.glob(os.path.join(scrap_dir, 'extracted', '*.packed')): | ||||
|         data=[] | ||||
|         filename=os.path.join(scrap_dir,os.path.basename(folder)) | ||||
|         for root,folders,files in os.walk(folder): | ||||
|     for folder in glob.glob(os.path.join(scrap_dir, "extracted", "*.packed")): | ||||
|         data = [] | ||||
|         filename = os.path.join(scrap_dir, os.path.basename(folder)) | ||||
|         for root, folders, files in os.walk(folder): | ||||
|             for file in sorted(files): | ||||
|                 file=os.path.join(root,file) | ||||
|                 rel_path=bytes(file.replace(folder, '').replace('\\', '/').lstrip('/'), 'windows-1252') | ||||
|                 size=os.stat(file).st_size | ||||
|                 data.append((file,size,rel_path)) | ||||
|         print("Found {} files for {}".format(len(data),filename)) | ||||
|         offset=len(make_header(data)) | ||||
|         print("Writing",filename) | ||||
|         header=make_header(data,offset) | ||||
|         with open(filename,"wb") as outfile: | ||||
|                 file = os.path.join(root, file) | ||||
|                 rel_path = bytes( | ||||
|                     file.replace(folder, "").replace("\\", "/").lstrip("/"), | ||||
|                     "windows-1252", | ||||
|                 ) | ||||
|                 size = os.stat(file).st_size | ||||
|                 data.append((file, size, rel_path)) | ||||
|         print("Found {} files for {}".format(len(data), filename)) | ||||
|         offset = len(make_header(data)) | ||||
|         print("Writing", filename) | ||||
|         header = make_header(data, offset) | ||||
|         with open(filename, "wb") as outfile: | ||||
|             outfile.write(header) | ||||
|             for file,size,rel_path in tqdm(data,ascii=True): | ||||
|                 outfile.write(open(file,"rb").read()) | ||||
| print('Done!') | ||||
|             for file, size, rel_path in tqdm(data, ascii=True): | ||||
|                 outfile.write(open(file, "rb").read()) | ||||
| print("Done!") | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue