Some experiments

This commit is contained in:
momo5502 2016-07-31 20:46:22 +02:00
parent a343c5ac5b
commit 3c448f173f
9 changed files with 350 additions and 206 deletions

View File

@ -9,6 +9,26 @@
namespace Components namespace Components
{ {
void Exception::UploadMinidump(std::string filename)
{
// Utils::WebIO webio("Firefucks", UPLOAD_URL);
//
// if (Utils::IO::FileExists(filename))
// {
// std::string buffer = Utils::IO::ReadFile(filename);
// std::string result = webio.PostFile(buffer);
//
// MessageBoxA(0, result.data(), "Minidump", 0);
// }
// mg_mgr mgr;
// mg_mgr_init(&mgr, NULL);
//
// mg_connect_http
//
// mg_mgr_free(&mgr);
}
LONG WINAPI Exception::ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo) LONG WINAPI Exception::ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo)
{ {
char filename[MAX_PATH]; char filename[MAX_PATH];
@ -23,11 +43,13 @@ namespace Components
if (hFile && hFile != INVALID_HANDLE_VALUE) if (hFile && hFile != INVALID_HANDLE_VALUE)
{ {
MINIDUMP_EXCEPTION_INFORMATION ex = { GetCurrentThreadId(),ExceptionInfo, FALSE }; MINIDUMP_EXCEPTION_INFORMATION ex = { GetCurrentThreadId(), ExceptionInfo, FALSE };
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ex, NULL, NULL); MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ex, NULL, NULL);
CloseHandle(hFile); CloseHandle(hFile);
} }
Exception::UploadMinidump(filename);
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW)
{ {
Logger::Error("Termination because of a stack overflow.\n"); Logger::Error("Termination because of a stack overflow.\n");
@ -35,7 +57,7 @@ namespace Components
} }
else else
{ {
Logger::Error("Fatal error (0x%08x) at 0x%08x.", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress); Logger::Error("Fatal error (0x%08X) at 0x%08X.", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
} }
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;

View File

@ -1,13 +1,17 @@
namespace Components #define UPLOAD_URL "https://momo5502.com/test/upload.php"
{
class Exception : public Component namespace Components
{ {
public: class Exception : public Component
Exception(); {
const char* GetName() { return "Exception"; }; public:
Exception();
private: const char* GetName() { return "Exception"; };
static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo);
static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter); private:
}; static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo);
} static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
static void UploadMinidump(std::string filename);
};
}

View File

@ -331,6 +331,11 @@ namespace Components
QuickPatch::UnlockStats(); QuickPatch::UnlockStats();
}); });
Command::Add("crash", [] (Command::Params params)
{
throw new std::exception();
});
// Debug patches // Debug patches
#ifdef DEBUG #ifdef DEBUG

View File

@ -1,57 +1,118 @@
#include "STDInclude.hpp" #include "STDInclude.hpp"
namespace Components namespace Components
{ {
Utils::Hook Renderer::DrawFrameHook; Utils::Hook Renderer::DrawFrameHook;
wink::signal<wink::slot<Renderer::Callback>> Renderer::FrameSignal; wink::signal<wink::slot<Renderer::Callback>> Renderer::FrameSignal;
wink::signal<wink::slot<Renderer::Callback>> Renderer::FrameOnceSignal; wink::signal<wink::slot<Renderer::Callback>> Renderer::FrameOnceSignal;
wink::signal<wink::slot<Renderer::BackendCallback>> Renderer::BackendFrameSignal;
void __declspec(naked) Renderer::FrameHook()
{ void __declspec(naked) Renderer::FrameStub()
__asm {
{ __asm
call Renderer::FrameHandler {
jmp Renderer::DrawFrameHook.Original call Renderer::FrameHandler
} jmp Renderer::DrawFrameHook.Original
} }
}
void Renderer::FrameHandler()
{ void Renderer::FrameHandler()
Renderer::FrameSignal(); {
Renderer::FrameOnceSignal(); Renderer::FrameSignal();
Renderer::FrameOnceSignal.clear(); Renderer::FrameOnceSignal();
} Renderer::FrameOnceSignal.clear();
}
void Renderer::Once(Renderer::Callback* callback)
{ void __declspec(naked) Renderer::BackendFrameStub()
Renderer::FrameOnceSignal.connect(callback); {
} __asm
{
void Renderer::OnFrame(Renderer::Callback* callback) call Renderer::BackendFrameHandler
{
Renderer::FrameSignal.connect(callback); mov eax, ds:66E1BF0h
} mov ecx, 536A85h
jmp ecx
int Renderer::Width() }
{ }
return Utils::Hook::Get<int>(0x66E1C68);
} void Renderer::BackendFrameHandler()
{
int Renderer::Height() IDirect3DDevice9* device = *Game::dx_ptr;
{
return Utils::Hook::Get<int>(0x66E1C6C); if (device)
} {
device->AddRef();
Renderer::Renderer() Renderer::BackendFrameSignal(device);
{ device->Release();
// Frame hook }
Renderer::DrawFrameHook.Initialize(0x5ACB99, Renderer::FrameHook, HOOK_CALL)->Install(); }
}
void Renderer::Once(Renderer::Callback* callback)
Renderer::~Renderer() {
{ Renderer::FrameOnceSignal.connect(callback);
Renderer::DrawFrameHook.Uninstall(); }
Renderer::FrameOnceSignal.clear();
Renderer::FrameSignal.clear(); void Renderer::OnFrame(Renderer::Callback* callback)
} {
} Renderer::FrameSignal.connect(callback);
}
void Renderer::OnBackendFrame(Renderer::BackendCallback* callback)
{
Renderer::BackendFrameSignal.connect(callback);
}
int Renderer::Width()
{
return Utils::Hook::Get<int>(0x66E1C68);
}
int Renderer::Height()
{
return Utils::Hook::Get<int>(0x66E1C6C);
}
Renderer::Renderer()
{
// Renderer::OnBackendFrame([] (IDirect3DDevice9* device)
// {
// if (Game::Sys_Milliseconds() % 2)
// {
// device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, 0, 0);
// }
//
// return;
//
// IDirect3DSurface9* buffer = nullptr;
//
// device->CreateOffscreenPlainSurface(Renderer::Width(), Renderer::Height(), D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &buffer, nullptr);
// device->GetFrontBufferData(0, buffer);
//
// if (buffer)
// {
// D3DSURFACE_DESC desc;
// D3DLOCKED_RECT lockedRect;
//
// buffer->GetDesc(&desc);
//
// HRESULT res = buffer->LockRect(&lockedRect, NULL, D3DLOCK_READONLY);
//
//
// buffer->UnlockRect();
// }
// });
// Frame hook
Renderer::DrawFrameHook.Initialize(0x5ACB99, Renderer::FrameStub, HOOK_CALL)->Install();
Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).Install()->Quick();
}
Renderer::~Renderer()
{
Renderer::DrawFrameHook.Uninstall();
Renderer::BackendFrameSignal.clear();
Renderer::FrameOnceSignal.clear();
Renderer::FrameSignal.clear();
}
}

View File

@ -1,26 +1,32 @@
namespace Components namespace Components
{ {
class Renderer : public Component class Renderer : public Component
{ {
public: public:
typedef void(Callback)(); typedef void(Callback)();
typedef void(BackendCallback)(IDirect3DDevice9*);
Renderer();
~Renderer(); Renderer();
const char* GetName() { return "Renderer"; }; ~Renderer();
const char* GetName() { return "Renderer"; };
static int Width();
static int Height(); static int Width();
static int Height();
static void Once(Callback* callback);
static void OnFrame(Callback* callback); static void Once(Callback* callback);
static void OnFrame(Callback* callback);
private: static void OnBackendFrame(BackendCallback* callback);
static void FrameHook();
static void FrameHandler(); private:
static void FrameStub();
static wink::signal<wink::slot<Callback>> FrameSignal; static void FrameHandler();
static wink::signal<wink::slot<Callback>> FrameOnceSignal;
static Utils::Hook DrawFrameHook; static void BackendFrameStub();
}; static void BackendFrameHandler();
}
static wink::signal<wink::slot<Callback>> FrameSignal;
static wink::signal<wink::slot<Callback>> FrameOnceSignal;
static wink::signal<wink::slot<BackendCallback>> BackendFrameSignal;
static Utils::Hook DrawFrameHook;
};
}

View File

@ -230,6 +230,9 @@ namespace Game
SpawnVar* spawnVars = (SpawnVar*)0x1A83DE8; SpawnVar* spawnVars = (SpawnVar*)0x1A83DE8;
MapEnts** marMapEntsPtr = (MapEnts**)0x112AD34; MapEnts** marMapEntsPtr = (MapEnts**)0x112AD34;
IDirect3D9** d3d9 = (IDirect3D9**)0x66DEF84;
IDirect3DDevice9** dx_ptr = (IDirect3DDevice9**)0x66DEF88;
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize) XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
{ {
int elSize = DB_GetXAssetSizeHandlers[type](); int elSize = DB_GetXAssetSizeHandlers[type]();

View File

@ -459,6 +459,9 @@ namespace Game
extern SpawnVar* spawnVars; extern SpawnVar* spawnVars;
extern MapEnts** marMapEntsPtr; extern MapEnts** marMapEntsPtr;
extern IDirect3D9** d3d9;
extern IDirect3DDevice9** dx_ptr;
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize); XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_t* item); void Menu_FreeItemMemory(Game::itemDef_t* item);
const char* TableLookup(StringTable* stringtable, int row, int column); const char* TableLookup(StringTable* stringtable, int row, int column);

View File

@ -134,6 +134,29 @@ namespace Utils
return body; return body;
} }
std::string WebIO::PostFile(std::string url, std::string data)
{
WebIO::SetURL(url);
return WebIO::PostFile(data);
}
std::string WebIO::PostFile(std::string data)
{
WebIO::Params headers;
std::string boundary = "xxxxxxxxx";
headers["Content-Type"] = "multipart/form-data, boundary=" + boundary;
headers["Content-Length"] = fmt::sprintf("%u", data.size());
std::string body = "--" + boundary + "\r\n";
body += "Content-Disposition: form-data; name=\"contents\"; filename=\"minidump.dmp\"\r\n";
body += "Content-Type: application/octet-stream\r\n\r\n";
body += data + "\r\n";
body += "--" + boundary + "--";
return WebIO::Execute("POST", body, headers);
}
std::string WebIO::Post(std::string url, std::string body) std::string WebIO::Post(std::string url, std::string body)
{ {
WebIO::SetURL(url); WebIO::SetURL(url);
@ -203,7 +226,7 @@ namespace Utils
return this; return this;
} }
std::string WebIO::Execute(const char* command, std::string body) std::string WebIO::Execute(const char* command, std::string body, WebIO::Params headers)
{ {
if (!WebIO::OpenConnection()) return ""; if (!WebIO::OpenConnection()) return "";
@ -225,8 +248,22 @@ namespace Utils
return ""; return "";
} }
const char* headers = "Content-type: application/x-www-form-urlencoded"; if (headers.find("Content-type") == headers.end())
HttpSendRequestA(WebIO::m_hFile, headers, strlen(headers), const_cast<char*>(body.data()), body.size() + 1); {
headers["Content-type"] = "application/x-www-form-urlencoded";
}
std::string finalHeaders;
for (auto i = headers.begin(); i != headers.end(); ++i)
{
finalHeaders.append(i->first);
finalHeaders.append(": ");
finalHeaders.append(i->second);
finalHeaders.append("\r\n");
}
HttpSendRequestA(WebIO::m_hFile, finalHeaders.data(), finalHeaders.size(), const_cast<char*>(body.data()), body.size() + 1);
std::string returnBuffer; std::string returnBuffer;

View File

@ -1,105 +1,108 @@
/* /*
This project is released under the GPL 2.0 license. This project is released under the GPL 2.0 license.
Some parts are based on research by Bas Timmer and the OpenSteamworks project. Some parts are based on research by Bas Timmer and the OpenSteamworks project.
Please do no evil. Please do no evil.
Initial author: (https://github.com/)momo5502 Initial author: (https://github.com/)momo5502
Started: 2015-03-01 Started: 2015-03-01
Notes: Notes:
Small FTP and HTTP utility class using WinAPI Small FTP and HTTP utility class using WinAPI
*/ */
namespace Utils namespace Utils
{ {
class WebIO class WebIO
{ {
public: public:
typedef std::map<std::string, std::string> Params; typedef std::map<std::string, std::string> Params;
WebIO(); WebIO();
WebIO(std::string useragent); WebIO(std::string useragent);
WebIO(std::string useragent, std::string url); WebIO(std::string useragent, std::string url);
~WebIO(); ~WebIO();
void SetURL(std::string url); void SetURL(std::string url);
void SetCredentials(std::string username, std::string password); void SetCredentials(std::string username, std::string password);
std::string Post(std::string url, WebIO::Params params); std::string PostFile(std::string url, std::string data);
std::string Post(std::string url, std::string body); std::string PostFile(std::string data);
std::string Post(WebIO::Params params);
std::string Post(std::string body); std::string Post(std::string url, WebIO::Params params);
std::string Post(std::string url, std::string body);
std::string Get(std::string url); std::string Post(WebIO::Params params);
std::string Get(); std::string Post(std::string body);
WebIO* SetTimeout(DWORD mseconds); std::string Get(std::string url);
std::string Get();
// FTP
bool Connect(); WebIO* SetTimeout(DWORD mseconds);
void Disconnect(); // Not necessary
// FTP
bool SetDirectory(std::string directory); bool Connect();
bool SetRelativeDirectory(std::string directory); void Disconnect(); // Not necessary
bool GetDirectory(std::string &directory);
bool CreateDirectory(std::string directory); bool SetDirectory(std::string directory);
bool DeleteDirectory(std::string directory); bool SetRelativeDirectory(std::string directory);
bool RenameDirectory(std::string directory, std::string newDir); bool GetDirectory(std::string &directory);
bool CreateDirectory(std::string directory);
bool ListDirectories(std::string directory, std::vector<std::string> &list); bool DeleteDirectory(std::string directory);
bool ListFiles(std::string directory, std::vector<std::string> &list); bool RenameDirectory(std::string directory, std::string newDir);
bool DeleteFile(std::string file); bool ListDirectories(std::string directory, std::vector<std::string> &list);
bool RenameFile(std::string file, std::string newFile); bool ListFiles(std::string directory, std::vector<std::string> &list);
bool UploadFile(std::string file, std::string localfile);
bool DownloadFile(std::string file, std::string localfile); bool DeleteFile(std::string file);
bool RenameFile(std::string file, std::string newFile);
bool UploadFileData(std::string file, std::string data); bool UploadFile(std::string file, std::string localfile);
bool DownloadFileData(std::string file, std::string &data); bool DownloadFile(std::string file, std::string localfile);
private: bool UploadFileData(std::string file, std::string data);
bool DownloadFileData(std::string file, std::string &data);
enum Command
{ private:
COMMAND_POST,
COMMAND_GET, enum Command
}; {
COMMAND_POST,
struct WebURL COMMAND_GET,
{ };
std::string protocol;
std::string server; struct WebURL
std::string document; {
std::string raw; std::string protocol;
}; std::string server;
std::string document;
bool m_isFTP; std::string raw;
std::string m_username; };
std::string m_password;
bool m_isFTP;
WebURL m_sUrl; std::string m_username;
std::string m_password;
HINTERNET m_hSession;
HINTERNET m_hConnect; WebURL m_sUrl;
HINTERNET m_hFile;
HINTERNET m_hSession;
DWORD m_timeout; HINTERNET m_hConnect;
HINTERNET m_hFile;
std::string BuildPostBody(WebIO::Params params);
DWORD m_timeout;
bool IsSecuredConnection();
std::string BuildPostBody(WebIO::Params params);
std::string Execute(const char* command, std::string body);
bool IsSecuredConnection();
bool ListElements(std::string directory, std::vector<std::string> &list, bool files);
std::string Execute(const char* command, std::string body, WebIO::Params headers = WebIO::Params());
void OpenSession(std::string useragent);
void CloseSession(); bool ListElements(std::string directory, std::vector<std::string> &list, bool files);
bool OpenConnection(); void OpenSession(std::string useragent);
void CloseConnection(); void CloseSession();
void FormatPath(std::string &path, bool win); /* if (win == true): / -> \\ */ bool OpenConnection();
}; void CloseConnection();
}
void FormatPath(std::string &path, bool win); /* if (win == true): / -> \\ */
};
}