* safety check for archives with incorrect comment lengths

* 1.5.5.0
This commit is contained in:
DubbleClick
2023-11-18 15:55:25 +01:00
committed by GitHub
parent ab2d8cdb0a
commit 13b7df3ae3
9 changed files with 51 additions and 116 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.16)
cmake_minimum_required(VERSION 3.16)
set(CMAKE_GENERATOR_PLATFORM win32)
@@ -17,7 +17,7 @@ endif()
set(VERSION_MAJOR 1)
set(VERSION_MINOR 5)
set(VERSION_PATCH 4)
set(VERSION_PATCH 5)
set(VERSION_TWEAK 0)
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
+8
View File
@@ -30,6 +30,14 @@ public:
data[i] = XOR(data[i], i);
}
for (int i = data.size() - 1; i > 0 && data[i] != 0; i--) {
data[i] = 0;
}
// in the other zip libraries, these had to be cut off, with libzip we need to zero them out
// cutting them off makes the archive invalid
//data.resize(last_zero);
return data;
}
+1 -4
View File
@@ -23,16 +23,13 @@ class gMod_FileLoader {
0x77, 0x6E, 0x46, 0x47, 0x77, 0x49, 0x0C, 0x4B,
0x46, 0x6F
};
std::vector<TpfEntry> entry_cache{};
bool loaded = false;
public:
gMod_FileLoader(const std::string& fileName);
std::vector<TpfEntry> Load();
std::vector<TpfEntry> GetContents();
private:
std::vector<TpfEntry> GetContents();
std::vector<TpfEntry> GetTpfContents();
-1
View File
@@ -9,7 +9,6 @@ bool FindLoadedDll();
bool IsDesiredModule(HMODULE hModule, HANDLE hProcess);
bool HasDesiredMethods(HMODULE hModule, HANDLE hProcess);
bool HookThisProgram(char* ret);
DWORD WINAPI ServerThread(LPVOID lpParam);
void* DetourFunc(BYTE* src, const BYTE* dst, int len);
bool RetourFunc(BYTE* src, BYTE* restore, int len);
+1 -7
View File
@@ -22,8 +22,6 @@ public:
~uMod_TextureServer();
int AddClient(uMod_TextureClient* client, TextureFileStruct** update, int* number); // called from a Client
int RemoveClient(uMod_TextureClient* client); // called from a Client
int Initialize(); // is executed in a server thread
@@ -33,7 +31,6 @@ public:
int AddFile(char* buffer, unsigned int size, MyTypeHash hash, bool force); // called from Mainloop(), if the content of the texture is sent
private:
wchar_t SavePath[MAX_PATH];
wchar_t GameName[MAX_PATH];
char UModName[MAX_PATH];
@@ -44,10 +41,7 @@ private:
// the file content of the textures are not copied, the clients get the pointer to the file content
// but the arrays allocate by this function, must be deleted by the client
uMod_TextureClient** Clients;
int NumberOfClients;
int LenghtOfClients;
uMod_TextureClient* Client;
uMod_FileHandler CurrentMod; // hold the file content of texture
uMod_FileHandler OldMod; // hold the file content of texture which were added previously but are not needed any more
// this is needed, because a texture clients might not have merged the last update and thus hold pointers to the file content of old textures
+26 -36
View File
@@ -8,40 +8,35 @@ gMod_FileLoader::gMod_FileLoader(const std::string& fileName)
file_name = std::filesystem::absolute(fileName).string();
}
std::vector<TpfEntry> gMod_FileLoader::Load()
{
if (!loaded) {
entry_cache = GetContents();
loaded = true;
}
return entry_cache;
}
std::vector<TpfEntry> gMod_FileLoader::GetContents()
{
return file_name.ends_with(".tpf") ? GetTpfContents() : GetFileContents();
try {
return file_name.ends_with(".tpf") ? GetTpfContents() : GetFileContents();
}
catch (const std::exception&) {
Message("Failed to open mod file: %s\n", file_name.c_str());
}
return {};
}
std::vector<TpfEntry> gMod_FileLoader::GetTpfContents()
{
std::vector<TpfEntry> entries;
try {
auto xorreader = XorStreamReader(file_name);
const auto buffer = xorreader.ReadToEnd();
const auto zip_archive = libzippp::ZipArchive::fromBuffer(buffer.data(), buffer.size(), false, TPF_PASSWORD);
zip_archive->setErrorHandlerCallback(
[](const std::string& message, const std::string& strerror, int zip_error_code, int system_error_code) -> void {
Message("GetTpfContents: %s %s %d %d\n", message.c_str(), strerror.c_str(), zip_error_code, system_error_code);
});
zip_archive->open();
LoadEntries(*zip_archive, entries);
zip_archive->close();
libzippp::ZipArchive::free(zip_archive);
}
catch (const std::exception& e) {
throw std::runtime_error("Failed to open zip file: " + file_name + "\n" + e.what());
auto xorreader = XorStreamReader(file_name);
const auto buffer = xorreader.ReadToEnd();
const auto zip_archive = libzippp::ZipArchive::fromBuffer(buffer.data(), buffer.size(), false, TPF_PASSWORD);
if (!zip_archive) {
Message("Failed to open tpf file: %s - %u bytes!", file_name.c_str(), buffer.size());
return {};
}
zip_archive->setErrorHandlerCallback(
[](const std::string& message, const std::string& strerror, int zip_error_code, int system_error_code) -> void {
Message("GetTpfContents: %s %s %d %d\n", message.c_str(), strerror.c_str(), zip_error_code, system_error_code);
});
zip_archive->open();
LoadEntries(*zip_archive, entries);
zip_archive->close();
libzippp::ZipArchive::free(zip_archive);
return entries;
}
@@ -50,15 +45,10 @@ std::vector<TpfEntry> gMod_FileLoader::GetFileContents()
{
std::vector<TpfEntry> entries;
try {
libzippp::ZipArchive zip_archive(file_name);
zip_archive.open();
LoadEntries(zip_archive, entries);
zip_archive.close();
}
catch (const std::exception& e) {
throw std::runtime_error("Failed to open zip file: " + file_name);
}
libzippp::ZipArchive zip_archive(file_name);
zip_archive.open();
LoadEntries(zip_archive, entries);
zip_archive.close();
return entries;
}
@@ -151,7 +141,7 @@ void ParseTexmodArchive(std::vector<std::string>& lines, libzippp::ZipArchive& a
continue;
}
const auto data_ptr= entry.readAsBinary();
const auto data_ptr = entry.readAsBinary();
const auto size = entry.getSize();
uint32_t crcHash;
try {
-11
View File
@@ -8,7 +8,6 @@
HINSTANCE gl_hOriginalDll = nullptr;
HINSTANCE gl_hThisInstance = nullptr;
std::unique_ptr<uMod_TextureServer> gl_TextureServer = nullptr;
HANDLE gl_ServerThread = nullptr;
using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT);
using Direct3DCreate9Ex_type = HRESULT(APIENTRY*)(UINT SDKVersion, IDirect3D9Ex** ppD3D);
@@ -61,16 +60,6 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
return true;
}
DWORD WINAPI ServerThread(LPVOID lpParam)
{
UNREFERENCED_PARAMETER(lpParam);
if (gl_TextureServer != nullptr) {
gl_TextureServer->Initialize(); //This is and endless mainloop, it sleep till something is written into the pipe.
}
return 0;
}
void InitInstance(HINSTANCE hModule)
{
DisableThreadLibraryCalls(hModule); //reduce overhead
-4
View File
@@ -32,10 +32,6 @@ uMod_TextureClient::uMod_TextureClient(uMod_TextureServer* server, IDirect3DDevi
uMod_TextureClient::~uMod_TextureClient()
{
Message("uMod_TextureClient::~uMod_TextureClient(): %p\n", this);
if (Server != nullptr) {
Server->RemoveClient(this);
}
if (Mutex != nullptr) {
CloseHandle(Mutex);
}
+13 -51
View File
@@ -5,16 +5,13 @@
#include "uMod_Main.h"
#include "gMod_FileLoader.h"
long long loadedSize = 0;
unsigned long loadedSize = 0;
uMod_TextureServer::uMod_TextureServer(char* game, char* uModName)
{
Message("uMod_TextureServer(): %p\n", this);
Clients = nullptr;
NumberOfClients = 0;
LenghtOfClients = 0;
SavePath[0] = 0;
Client = nullptr;
int len = 0;
int path_pos = 0;
@@ -75,39 +72,8 @@ int uMod_TextureServer::AddClient(uMod_TextureClient* client, TextureFileStruct*
return ret; // get a copy of all texture to be modded
}
Client = client;
if (NumberOfClients == LenghtOfClients) //allocate more memory
{
uMod_TextureClient** temp = nullptr;
try { temp = new uMod_TextureClient*[LenghtOfClients + 10]; }
catch (...) {
gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER;
return RETURN_NO_MEMORY;
}
for (int i = 0; i < LenghtOfClients; i++) {
temp[i] = Clients[i];
}
delete[] Clients;
Clients = temp;
LenghtOfClients += 10;
}
Clients[NumberOfClients++] = client;
return RETURN_OK;
}
int uMod_TextureServer::RemoveClient(uMod_TextureClient* client) // called from a client
{
Message("RemoveClient(): %p\n", client);
for (int i = 0; i < NumberOfClients; i++) {
if (client == Clients[i]) {
NumberOfClients--;
Clients[i] = Clients[NumberOfClients];
break;
}
}
return RETURN_OK;
}
@@ -152,7 +118,8 @@ int uMod_TextureServer::AddFile(char* dataPtr, unsigned int size, MyTypeHash has
{
new_file = false;
delete[] temp->pData;
delete[] temp->pData; // todo: this tries deleting memory out of a vector of tpfentries, which won't do anything
// todo: therefore we don't get out memory back here
temp->pData = nullptr;
}
@@ -191,16 +158,6 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr
}
client->AddUpdate(update, number);
}
else {
for (int i = 0; i < NumberOfClients; i++) {
TextureFileStruct* update;
int number;
if (const int ret = PrepareUpdate(&update, &number)) {
return ret;
}
Clients[i]->AddUpdate(update, number);
}
}
return RETURN_OK;
}
@@ -242,7 +199,7 @@ int uMod_TextureServer::PrepareUpdate(TextureFileStruct** update, int* number) /
return RETURN_NO_MEMORY;
}
for (int i = 0; i < num; i++) cpy_file_struct(temp[i], (*(CurrentMod[i])));
for (int i = 0; i < num; i++) cpy_file_struct(temp[i], *CurrentMod[i]);
qsort(temp, num, sizeof(TextureFileStruct), TextureFileStruct_Compare);
}
@@ -266,7 +223,11 @@ void uMod_TextureServer::LoadModsFromFile(const char* source)
line.erase(std::ranges::remove(line, '\n').begin(), line.end());
auto file_loader = gMod_FileLoader(line);
const auto entries = file_loader.Load();
const auto entries = file_loader.GetContents();
if (loadedSize > 1'500'000'000) {
Message("LoadModsFromFile: Loaded %d bytes, aborting!!!", loadedSize);
return;
}
if (!entries.empty()) {
Message("Initialize: Texture count %zu %s\n", entries.size(), line.c_str());
for (const auto& tpf_entry : entries) {
@@ -279,12 +240,13 @@ void uMod_TextureServer::LoadModsFromFile(const char* source)
Message("LoadModsFromFile: Loaded %d bytes", loadedSize);
}
PropagateUpdate(nullptr);
PropagateUpdate(Client);
}
else {
Message("Initialize: Failed to load any textures for %s\n", line.c_str());
}
}
Message("Finished loading mods: Loaded %u bytes (%u mb)", loadedSize, loadedSize / 1024 / 1024);
}
}