diff --git a/saco/buildinfo.h b/saco/buildinfo.h new file mode 100644 index 0000000..291a817 --- /dev/null +++ b/saco/buildinfo.h @@ -0,0 +1 @@ +#define SAMP_VERSION "0.3.7-R5" \ No newline at end of file diff --git a/saco/exceptions.cpp b/saco/exceptions.cpp new file mode 100644 index 0000000..cc45862 --- /dev/null +++ b/saco/exceptions.cpp @@ -0,0 +1,217 @@ + +#include "main.h" +#include "resource.h" +#include "httpclient.h" +#include "runutil.h" +#include "buildinfo.h" + +#include + +PCONTEXT pContextRecord; +extern HANDLE hInstance; +extern CGame *pGame; +extern DWORD dwScmOpcodeDebug; +extern BOOL bScmLocalDebug; +extern WORD wLastRendObj; + +CHAR szErrorString[16384]; + +//---------------------------------------------------- + +void DumpNetworkStateInformation(PCHAR sz) +{ + // TODO: DumpNetworkStateInformation 10060160 +} + +//---------------------------------------------------- + +void DumpMemory(BYTE *pData, DWORD dwCount, PCHAR sz, BOOL bAsDWords = FALSE) +{ + char s[16384]; + + if (bAsDWords) + { + for(int i=0; i<(int)dwCount; i += 16) + { + sprintf(s, "+%04X: 0x%08X 0x%08X 0x%08X 0x%08X\r\n", i, + *(DWORD*)(pData+i+0), *(DWORD*)(pData+i+4), + *(DWORD*)(pData+i+8), *(DWORD*)(pData+i+12) + ); + strcat(sz,s); + } + } + else + { + for(int i=0; i<(int)dwCount; i += 16) + { + sprintf(s, "+%04X: %02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X\r\n", i, + pData[i+0], pData[i+1], pData[i+2], pData[i+3], + pData[i+4], pData[i+5], pData[i+6], pData[i+7], + pData[i+8], pData[i+9], pData[i+10], pData[i+11], + pData[i+12], pData[i+13], pData[i+14], pData[i+15] + ); + strcat(sz,s); + } + } +} + +//---------------------------------------------------- + +void DumpLoadedModules(PCHAR sz) +{ + HANDLE hModuleSnap = NULL; + MODULEENTRY32 me32; + char s[16384]; + + hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); + + strcpy(sz, "\r\nLoaded Modules:\r\n"); + + if(hModuleSnap == INVALID_HANDLE_VALUE) + { + strcat(sz, "-FailedCreate-\r\n"); + return; + } + + me32.dwSize = sizeof( MODULEENTRY32 ); + + if( !Module32First( hModuleSnap, &me32 ) ) + { + strcat(sz, "-FailedFirst-"); // Show cause of failure + CloseHandle( hModuleSnap ); // Must clean up the snapshot object! + return; + } + + do + { + if (me32.szModule[0] != 'f' && me32.szModule[1] != 'l' && me32.szModule[2] != 'a') + { + sprintf(s, "%s\tB: 0x%08X\tS: 0x%08X\t(%s)\r\n", + me32.szModule, me32.modBaseAddr, me32.modBaseSize, me32.szExePath); + strcat(sz, s); + } + } while( Module32Next( hModuleSnap, &me32 ) ); + + CloseHandle( hModuleSnap ); + + return; +} + +//---------------------------------------------------- + +void DumpMain(BOOL bIncModules) +{ + CHAR s[16384]; + DWORD *pdwStack; + + sprintf(szErrorString, + "SA-MP %s\r\n" + "Exception At Address: 0x%08X\r\n" + "Base: 0x%08X\r\n\r\n" + "Registers:\r\n" + "EAX: 0x%08X\tEBX: 0x%08X\tECX: 0x%08X\tEDX: 0x%08X\r\n" + "ESI: 0x%08X\tEDI: 0x%08X\tEBP: 0x%08X\tESP: 0x%08X\r\n" + "EFLAGS: 0x%08X\r\n\r\nStack:\r\n", + SAMP_VERSION, + pContextRecord->Eip, + hInstance, + pContextRecord->Eax, + pContextRecord->Ebx, + pContextRecord->Ecx, + pContextRecord->Edx, + pContextRecord->Esi, + pContextRecord->Edi, + pContextRecord->Ebp, + pContextRecord->Esp, + pContextRecord->EFlags); + + pdwStack = (DWORD *)pContextRecord->Esp; + DumpMemory(reinterpret_cast(pdwStack), 640, szErrorString, TRUE); + + sprintf(s,"\r\nSCM Op: 0x%X, lDbg: %d LastRendObj: %u\r\n", dwScmOpcodeDebug, bScmLocalDebug, wLastRendObj); + strcat(szErrorString,s); + + // TODO: DumpMain 100605B0 + + if (bIncModules) + { + DumpLoadedModules(s); + strcat(szErrorString,s); + } +} + +//---------------------------------------------------- + +void DoCrashReportingStuff() +{ + CHttpClient pHttp; + char szURL[256]; + char szBase64[16384]; + + DumpMain(TRUE); + + strcpy(szBase64,"data="); + + Util_Base64Encode(szErrorString,&szBase64[5]); + + sprintf(szURL,"team.sa-mp.com/report_037.php?addr=0x%X>a=sa",pContextRecord->Eip); + pHttp.ProcessURL(HTTP_POST,szURL,szBase64,"www.sa-mp.com"); + + return; +} + +//---------------------------------------------------- + +BOOL CALLBACK GuiDlgProcMain(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: + + DumpMain(FALSE); + + SetDlgItemText(hDlg,IDC_EDIT1,szErrorString); + SetForegroundWindow(GetDlgItem(hDlg,IDD_DIALOG1)); + SetFocus(GetDlgItem(hDlg,IDC_BUTTON1)); + SetCursor(LoadCursor(NULL,IDC_ARROW)); + ShowCursor(TRUE); + break; + + case WM_DESTROY: + EndDialog(hDlg,TRUE); + ShowWindow(pGame->GetMainWindowHwnd(),SW_HIDE); + DestroyWindow(pGame->GetMainWindowHwnd()); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_BUTTON1: + EndDialog(hDlg,TRUE); + break; + case IDC_BUTTON2: + DoCrashReportingStuff(); + EnableWindow(GetDlgItem(hDlg,IDC_BUTTON2),FALSE); + SetDlgItemTextA(hDlg,IDC_EDIT1,"Thanks for reporting this problem."); + break; + } + break; + } + + return FALSE; +} + +//---------------------------------------------------- + +LONG WINAPI exc_handler(_EXCEPTION_POINTERS* exc_inf) +{ + pContextRecord = exc_inf->ContextRecord; + + ShowWindow(pGame->GetMainWindowHwnd(),SW_MINIMIZE); + DialogBox((HINSTANCE)hInstance,MAKEINTRESOURCE(IDD_DIALOG1),pGame->GetMainWindowHwnd(),(DLGPROC)GuiDlgProcMain); + + return EXCEPTION_EXECUTE_HANDLER; +} + +//---------------------------------------------------- \ No newline at end of file diff --git a/saco/game/address.h b/saco/game/address.h index d64ecbd..9f35c63 100644 --- a/saco/game/address.h +++ b/saco/game/address.h @@ -1,4 +1,6 @@ #pragma once +#define ADDR_HWND 0xC97C1C + #define ADDR_KEYSTATES 0xB73458 diff --git a/saco/game/game.h b/saco/game/game.h index 2864d07..326d22e 100644 --- a/saco/game/game.h +++ b/saco/game/game.h @@ -31,6 +31,8 @@ private: public: + HWND GetMainWindowHwnd() { return *(HWND *)ADDR_HWND; }; + void InitGame(); CGame(); diff --git a/saco/game/hooks.cpp b/saco/game/hooks.cpp index bceefec..e05e32c 100644 --- a/saco/game/hooks.cpp +++ b/saco/game/hooks.cpp @@ -3,3 +3,4 @@ BYTE *pbyteCameraMode = (BYTE *)0xB6F1A8; +WORD wLastRendObj=0; diff --git a/saco/game/scripting.cpp b/saco/game/scripting.cpp new file mode 100644 index 0000000..da57d12 --- /dev/null +++ b/saco/game/scripting.cpp @@ -0,0 +1,5 @@ + +#include "../main.h" + +DWORD dwScmOpcodeDebug=0; +BOOL bScmLocalDebug=FALSE; diff --git a/saco/game/scripting.h b/saco/game/scripting.h new file mode 100644 index 0000000..e69de29 diff --git a/saco/main.cpp b/saco/main.cpp index 0314689..8e1bf52 100644 --- a/saco/main.cpp +++ b/saco/main.cpp @@ -6,6 +6,10 @@ HANDLE hInstance=0; CGame *pGame=0; +// forwards + +LONG WINAPI exc_handler(_EXCEPTION_POINTERS* exc_inf); + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(DLL_PROCESS_ATTACH==fdwReason) @@ -15,9 +19,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) if(tSettings.bDebug || tSettings.bPlayOnline) { + SetUnhandledExceptionFilter(exc_handler); + // TODO: DllMain /* - SetUnhandledExceptionFilter(TopLevelExceptionFilter); dword_1026EB3C = (int)sub_100C4FF0; GetModuleFileNameA((HMODULE)hInstance, &Filename, 0x104u); v3 = strlen(&Filename); diff --git a/saco/main.h b/saco/main.h index e9de6c7..fb5d315 100644 --- a/saco/main.h +++ b/saco/main.h @@ -1,7 +1,9 @@ #pragma once +#include #include +#include #define MAX_SETTINGS_STRING 256 diff --git a/saco/saco.vcproj b/saco/saco.vcproj index 483fe41..d1aed5c 100644 --- a/saco/saco.vcproj +++ b/saco/saco.vcproj @@ -156,6 +156,12 @@ + + + + @@ -169,6 +175,9 @@ + + @@ -178,6 +187,9 @@ + +