diff options
| author | boris <wzn@moneybot.cc> | 2019-01-01 14:35:30 +1300 |
|---|---|---|
| committer | boris <wzn@moneybot.cc> | 2019-01-01 14:35:30 +1300 |
| commit | b9702fe8541e61f27f5c788dc72feaefe5abfc0d (patch) | |
| tree | 292f12cc1cbf6088cd68fa81fd85cb44711c47ec | |
| parent | 009357a5f18ecf2ce8df42f5931c4c45181833c6 (diff) | |
eeeeeeeeeeeeeeek
| -rw-r--r-- | csgo-loader/ThemidaSettings._ini | 13 | ||||
| -rw-r--r-- | csgo-loader/ThemidaSettings.tmd | bin | 11215 -> 11302 bytes | |||
| -rw-r--r-- | csgo-loader/csgo-client/Client.cpp | 40 | ||||
| -rw-r--r-- | csgo-loader/csgo-client/Security/RuntimeSecurity.cpp | 169 | ||||
| -rw-r--r-- | csgo-loader/csgo-client/UserExperience/UserInterface.cpp | 2 | ||||
| -rw-r--r-- | csgo-loader/csgo-client/UserExperience/UserInterface.hpp | 3 | ||||
| -rw-r--r-- | csgo-loader/csgo-client/csgo-client.vcxproj | 12 | ||||
| -rw-r--r-- | csgo-loader/to-do list.txt | 10 |
8 files changed, 174 insertions, 75 deletions
diff --git a/csgo-loader/ThemidaSettings._ini b/csgo-loader/ThemidaSettings._ini index a03ee59..196b83a 100644 --- a/csgo-loader/ThemidaSettings._ini +++ b/csgo-loader/ThemidaSettings._ini @@ -20,7 +20,7 @@ cbBugCheck.Checked="False" cbChangeSectionName.Checked="True"
cbCompressApp.Checked="True"
cbCompressEngine.Checked="True"
-cbCompressResources.Checked="False"
+cbCompressResources.Checked="True"
cbControlMsgExports.Checked="False"
cbCustomEnv.Checked="False"
cbCustomFileStore.Checked="False"
@@ -111,7 +111,7 @@ cbRefixInitialThunk.Checked="False" cbRefixRuntimeTLS.Checked="False"
cbRegistryMonitorBlocker.Checked="False"
cbReHookingEnabled.Checked="False"
-cbResourceEncrypt.Checked="False"
+cbResourceEncrypt.Checked="True"
cbRestoreSectionAttributtes.Checked="False"
cbRsrcExtraSpace.Checked="False"
cbRunWithParams.Checked="False"
@@ -261,7 +261,7 @@ InternalMessages.Items=hex:04,44,61,74,61,0A,47,0A,00,00,0C,00,00,00,30,00,\ 79,70,65,72,76,69,73,6F,72,20,2F,20,76,69,72,74,75,61,6C,20,6D,61,63,68,69,\
6E,65,73,20,79,6F,75,20,6D,69,67,68,74,20,62,65,20,72,75,6E,6E,69,6E,67,2E,00
RzAntidebug.ItemIndex=1
-RzApiWrapping.ItemIndex=1
+RzApiWrapping.ItemIndex=2
SplashFile.AltBtnVisible="False"
SplashFile.ButtonVisible="True"
SplashMouse.Checked="False"
@@ -272,15 +272,18 @@ SplashTime.Checked="True" autoblocks=False
blocknumber=0
blockscrc32=
-crc32="$29A5CE28"
+crc32="$4525A0DA"
CustMsgDLLFunction0=
CustomVMCpus[0]="1"
CustomVMCpus[1]="1"
+CustomVMCpus[2]="1"
CustomVMId[0]="0xD4A7990A"
CustomVMId[1]="0xD4A79901"
+CustomVMId[2]="0x84581901"
CustomVMIntegrityCheck[0]="True"
CustomVMIntegrityCheck[1]="True"
-CustomVM_Number=2
+CustomVMIntegrityCheck[2]="True"
+CustomVM_Number=3
messages=hex:01,02,00,06,17,4D,73,67,49,44,30,20,3A,20,47,6C,6F,62,61,6C,20,\
43,61,70,74,69,6F,6E,02,02,02,02,02,00,02,01,06,01,20,02,FF,02,FF,02,00,02,\
00,06,17,4D,73,67,49,44,31,20,3A,20,44,65,62,75,67,67,65,72,20,66,6F,75,6E,\
diff --git a/csgo-loader/ThemidaSettings.tmd b/csgo-loader/ThemidaSettings.tmd Binary files differindex cedd442..d8dd596 100644 --- a/csgo-loader/ThemidaSettings.tmd +++ b/csgo-loader/ThemidaSettings.tmd diff --git a/csgo-loader/csgo-client/Client.cpp b/csgo-loader/csgo-client/Client.cpp index 8c90f66..c41856c 100644 --- a/csgo-loader/csgo-client/Client.cpp +++ b/csgo-loader/csgo-client/Client.cpp @@ -3,14 +3,10 @@ /*
TODO:
- Finish off security on client:
- - Hook OpenProcess, ExitProcess, WSARecv, WSASend and check if function is OOB. [DONE]
- - Use VM check that Nave gave me.
- Run a thread to check for blacklisted drivers periodically (also blacklist VBox)
- Run a thread to check if there is more than X threads running in the loader.
- Add dump protection (closes csgo.exe if a handle is detected, probably explorer shellcode)
- Add HWID generation
- - Hook DbgBreakPoint and DbgUiRemoteBreakin (instead of bytepatching, some debuggers will check that) [DONE]
- - Don't forget about the security callback; leave implementation up to Nave. [DONE]
- Apply Themida macros inside important functions:
- Apply mutation on Security hooks and main function.
@@ -25,7 +21,9 @@ - This will probably be the easiest thing to do.
- Finish off injection wrapper:
- - Allocate a 4KB page for trampoline imports (4096/6) { E8 ? ? ? ? C3 }
+ - Allocate a 4KB page for trampoline imports (4096/6) { E9 ? ? ? ? C3 }
+ - Actually, allocate every memory page as a bunch of consecutive 4kb sections
+ - Trampoline for imports
- Everything is already laid out, tbh.
- Have the loader inject a .DLL :^)
@@ -35,28 +33,31 @@ - Adapt the server to work with your backend.
*/
+
+#pragma optimize("", off)
+
int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow)
{
WRAP_IF_DEBUG(Utils::OpenConsole());
- // Autistic workaround for Hooked_OpenProcess crashing
- // when Device->CreateDevice is invoked...
- std::atomic<bool> UserInterfaceReady = false;
+ ///////////////////////////////////////////////////////////////
+
+ WRAP_IF_RELEASE(MUTATE_START);
+ WRAP_IF_RELEASE(STR_ENCRYPT_START);
+
+ ///////////////////////////////////////////////////////////////
// Create a thread to handle UI.
- std::thread WindowThread([&UserInterfaceReady]
+ std::thread WindowThread([]
{
// Create a window, initialise DirectX context.
if(!UserInterface->Start())
ERROR_ASSERT("[000F:00001C00] Failed to initialize. Please contact an administrator.");
-
- // Signal initialization.
- UserInterfaceReady = true;
-
+
UserInterface->RunUiFrame();
}); WindowThread.detach();
- while(!UserInterfaceReady) { Sleep(1); }
+ while(!UserInterface->m_Data.m_Ready) { Sleep(1); }
// Initialize the runtime protection system.
WRAP_IF_RELEASE(
@@ -83,4 +84,13 @@ int __stdcall WinMain(HINSTANCE inst, HINSTANCE prev, char* str, int cmdshow) // TODO: Add game selection.
while(1) { if(GetAsyncKeyState(VK_END) & 0x8000) break; Sleep(1); }
-}
\ No newline at end of file +
+ ///////////////////////////////////////////////////////////////
+
+ WRAP_IF_RELEASE(STR_ENCRYPT_END);
+ WRAP_IF_RELEASE(MUTATE_END);
+
+ ///////////////////////////////////////////////////////////////
+}
+
+#pragma optimize("", on)
\ No newline at end of file diff --git a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp index f9825c0..ab2ea87 100644 --- a/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp +++ b/csgo-loader/csgo-client/Security/RuntimeSecurity.cpp @@ -135,8 +135,12 @@ namespace Security #define CheckStatus() if(Status != MH_OK) { return false; }
#define SafeCallTo(Function) Status = Function; CheckStatus();
+#pragma optimize("", off)
+
bool RuntimeSecurity::ApplyApiHooks()
{
+ WRAP_IF_RELEASE(MUTATE_START);
+
// Make sure that MinHook is initialized properly.
CreateMinHook();
CheckStatus();
@@ -155,8 +159,12 @@ namespace Security SafeCallTo(MH_EnableHook(&send));
return true;
+
+ WRAP_IF_RELEASE(MUTATE_END);
}
+#pragma optimize("", on)
+
void RuntimeSecurity::PatchDebugFunctions()
{
WRAP_IF_RELEASE(VM_EAGLE_WHITE_START);
@@ -181,7 +189,7 @@ namespace Security uintptr_t Exports[] = {
Export_DbgUiRemoteBreakin,
Export_DbgBreakPoint,
- //Export_NtContinue // This causes a lot of crashes ATM while debugging, leave this out till release.
+ Export_NtContinue // This causes a lot of crashes ATM while debugging, leave this out till release.
};
for(auto &It : Exports)
@@ -224,20 +232,24 @@ namespace Security {
WRAP_IF_RELEASE(VM_EAGLE_BLACK_START);
- // Yeah, um, your code did absolutely fuck all in my analysis VM.
- int32_t VirtualMachineChecksum = 0x4000;
+ for(;;)
+ {
+ // Yeah, um, your code did absolutely fuck all in my analysis VM.
+ int32_t VirtualMachineChecksum = 0x4000;
- WRAP_IF_RELEASE(
- CHECK_VIRTUAL_PC(VirtualMachineChecksum, 0x2000);
+ WRAP_IF_RELEASE(
+ CHECK_VIRTUAL_PC(VirtualMachineChecksum, 0x2000);
- WRAP_IF_RELEASE(STR_ENCRYPT_START);
+ WRAP_IF_RELEASE(STR_ENCRYPT_START);
if(VirtualMachineChecksum != 0x2000)
SecurityCallback(__FUNCSIG__);
- WRAP_IF_RELEASE(STR_ENCRYPT_END);
- );
+ WRAP_IF_RELEASE(STR_ENCRYPT_END);
+ );
+
+ // Don't put too much stress on the CPU.
+ Sleep(VirtualMachineChecksum);
+ }
- // Don't put too much stress on the CPU.
- Sleep(VirtualMachineChecksum);
WRAP_IF_RELEASE(VM_EAGLE_BLACK_END);
}
@@ -245,21 +257,60 @@ namespace Security void RuntimeSecurity::CheckForDebugger()
{
WRAP_IF_RELEASE(VM_EAGLE_BLACK_START);
+ WRAP_IF_RELEASE(STR_ENCRYPT_START);
- // Read the PEB from the TIB.
- // Offset for x86 is 0x30 ; mov ..., dword ptr fs:[0x30]
- // Offset for x64 is 0x60 ; mov ..., qword ptr gs:[0x60]
- PEB *ProcessEnvBlock = (PEB *)__readgsqword(0x60);
-
- // if(ProcessEnvBlock->BeingDebugged)
- // SecurityCallback();
-
- // TODO: Check for x64dbg window?
+ for(;;)
+ {
+ // Read the PEB from the TIB.
+ // Offset for x86 is 0x30 ; mov ..., dword ptr fs:[0x30]
+ // Offset for x64 is 0x60 ; mov ..., qword ptr gs:[0x60]
+ PEB *ProcessEnvBlock = (PEB *)__readgsqword(0x60);
+
+ //if(ProcessEnvBlock->BeingDebugged)
+ // SecurityCallback(__FUNCSIG__);
+
+ // TODO: Check for x64dbg window?
+ /*
+ ------------------------------
+ HWND: 000305A4
+ HWND->m_Class = "ID"
+ HWND->m_Text = "Immunity
+ ------------------------------
+ HWND: 00060574
+ HWND->m_Class = || NON CONSTANT ||
+ HWND->m_Text = "x64dbg"
+ ------------------------------
+ HWND: 002C0680
+ HWND->m_Class = || NON CONSTANT ||
+ HWND->m_Text = "Progress Telerik Fiddler Web Debugger"
+ ------------------------------
+ HWND: 000406E4
+ HWND->m_Class = "OLLYDBG"
+ HWND->m_Text = "OllyDbg"
+ ------------------------------
+ */
+ using WindowParams = std::pair<const char *, const char *>;
+ static std::vector<WindowParams> BlackListedWindows = {
+ {"ID", "Immunity"}, // Immunity Debugger
+ {"Qt5QWindowIcon", "x64dbg"}, // x64dbg
+ {"Qt5QWindowIcon", "x32dbg"}, // x32dbg
+ {"OLLYDBG", "OllyDbg"}, // OllyDbg
+ {nullptr, "Progress Telerik Fiddler Web Debugger"}, // Telerik Fiddler
+ };
+
+ for(auto &It : BlackListedWindows)
+ {
+ // size_t Index = std::distance(...);
+ if(FindWindowA(It.first, It.second))
+ SecurityCallback(__FUNCSIG__);
+ }
- // Don't put too much stress on the CPU.
- Sleep(150);
+ // Don't put too much stress on the CPU.
+ Sleep(150);
+ }
+ WRAP_IF_RELEASE(STR_ENCRYPT_END);
WRAP_IF_RELEASE(VM_EAGLE_BLACK_END);
}
@@ -267,10 +318,16 @@ namespace Security {
WRAP_IF_RELEASE(VM_EAGLE_BLACK_START);
- // TODO:
+ // TODO: Check if test-signing mode is on
+ // TODO: Check if safe-mode is on
- // Don't put too much stress on the CPU.
- Sleep(150);
+ // TODO: Check for disallowed drivers
+ for(;;)
+ {
+
+ // Don't put too much stress on the CPU.
+ Sleep(150);
+ }
WRAP_IF_RELEASE(VM_EAGLE_BLACK_END);
}
@@ -279,28 +336,32 @@ namespace Security {
WRAP_IF_RELEASE(VM_EAGLE_BLACK_START);
- int32_t CodeIntegrityChecksum = 0x2000;
+ for(;;)
+ {
+ int32_t CodeIntegrityChecksum = 0x2000;
- WRAP_IF_RELEASE(
- CHECK_CODE_INTEGRITY(CodeIntegrityChecksum, 0x4000);
+ WRAP_IF_RELEASE(
+ CHECK_CODE_INTEGRITY(CodeIntegrityChecksum, 0x4000);
- WRAP_IF_RELEASE(STR_ENCRYPT_START);
+ WRAP_IF_RELEASE(STR_ENCRYPT_START);
if(CodeIntegrityChecksum != 0x4000)
SecurityCallback(__FUNCSIG__);
- WRAP_IF_RELEASE(STR_ENCRYPT_END);
- );
+ WRAP_IF_RELEASE(STR_ENCRYPT_END);
+ );
- WRAP_IF_RELEASE(
- CHECK_PROTECTION(CodeIntegrityChecksum, 0x4000);
+ WRAP_IF_RELEASE(
+ CHECK_PROTECTION(CodeIntegrityChecksum, 0x4000);
- WRAP_IF_RELEASE(STR_ENCRYPT_START);
- if(CodeIntegrityChecksum != 0x4000)
- SecurityCallback(__FUNCSIG__);
- WRAP_IF_RELEASE(STR_ENCRYPT_END);
- );
+ WRAP_IF_RELEASE(STR_ENCRYPT_START);
+ if(CodeIntegrityChecksum != 0x4000)
+ SecurityCallback(__FUNCSIG__);
+ WRAP_IF_RELEASE(STR_ENCRYPT_END);
+ );
+
+ // Don't put too much stress on the CPU.
+ Sleep(CodeIntegrityChecksum);
+ }
- // Don't put too much stress on the CPU.
- Sleep(CodeIntegrityChecksum);
WRAP_IF_RELEASE(VM_EAGLE_BLACK_END);
}
@@ -331,21 +392,24 @@ namespace Security return HardwareIdentifier{};
}
+#pragma optimize("", off)
+
MEMORY_BASIC_INFORMATION RuntimeSecurity::QueryMemory(void *Address)
{
static auto ZwQueryVirtualMemory = Syscalls->Find<long(__stdcall *)(HANDLE, void *, int, void *, uint32_t, uint32_t *)>(FNV("ZwQueryVirtualMemory"));
- MEMORY_BASIC_INFORMATION Result;
-
- NTSTATUS Status = ZwQueryVirtualMemory(GetCurrentProcess(), Address, 0, &Result, sizeof Result, nullptr);
+ MEMORY_BASIC_INFORMATION Result{};
+ NTSTATUS Status = ZwQueryVirtualMemory((HANDLE)-1, Address, 0, &Result, sizeof Result, nullptr);
if(NT_ERROR(Status))
{
-
char ReasonParameter[64];
WRAP_IF_DEBUG(sprintf_s(ReasonParameter, "[QueryMemory] NTSTATUS: %08x", Status));
- WRAP_IF_RELEASE(sprintf_s(ReasonParameter, "[00DF:%08x] There was an error with accessing a process.", Status));
+ WRAP_IF_RELEASE(
+ sprintf_s(ReasonParameter, "[00DF:%08x] There was an error with accessing a process.", Status);
+ ERROR_ASSERT(ReasonParameter);
+ );
// yeet
SecurityCallback(ReasonParameter);
@@ -358,21 +422,32 @@ namespace Security {
WRAP_IF_RELEASE(VM_FISH_WHITE_START);
- // TODO: Implement something that bans the user or notifies
- // you if someone tampers with the loader.
static bool TriggeredCallback = false;
if(!TriggeredCallback)
{
WRAP_IF_RELEASE(STR_ENCRYPT_START);
+
+ // You can use the reason parameters to debug the security in case
+ // something weird starts going on with it.
char Buffer[2048];
sprintf_s(Buffer, "Security callback was called. Reason parameter: \"%s\"\n", Reason);
-
+
MessageBoxA(0, Buffer, "Information", MB_ICONINFORMATION | MB_OK);
+
+
+ // The process will straight up die on Release mode.
+ // Compile with FuckMSVC to debug this.
+ WRAP_IF_RELEASE(
+ ExitProcess(rand() % RAND_MAX);
+ );
+
TriggeredCallback = true;
WRAP_IF_RELEASE(STR_ENCRYPT_END);
}
WRAP_IF_RELEASE(VM_FISH_WHITE_END);
}
+
+#pragma optimize("", on)
}
\ No newline at end of file diff --git a/csgo-loader/csgo-client/UserExperience/UserInterface.cpp b/csgo-loader/csgo-client/UserExperience/UserInterface.cpp index 75b79b2..24f92c4 100644 --- a/csgo-loader/csgo-client/UserExperience/UserInterface.cpp +++ b/csgo-loader/csgo-client/UserExperience/UserInterface.cpp @@ -65,6 +65,8 @@ namespace UserExperience g_window.add_on_frame(&OnDirectXFrame);
}
+ m_Data.m_Ready = result;
+
return result;
}
diff --git a/csgo-loader/csgo-client/UserExperience/UserInterface.hpp b/csgo-loader/csgo-client/UserExperience/UserInterface.hpp index d4a3dc4..aaa4b10 100644 --- a/csgo-loader/csgo-client/UserExperience/UserInterface.hpp +++ b/csgo-loader/csgo-client/UserExperience/UserInterface.hpp @@ -35,6 +35,9 @@ namespace UserExperience // Structure that holds global data that will be used by the UI.
struct UserExperienceData
{
+ // Is the user interface initialised?
+ bool m_Ready = false;
+
// Holds the current execution state of the loader.
ExecutionState m_ExecutionState = EXECUTION_WAITING;
diff --git a/csgo-loader/csgo-client/csgo-client.vcxproj b/csgo-loader/csgo-client/csgo-client.vcxproj index f6f1787..40af0a8 100644 --- a/csgo-loader/csgo-client/csgo-client.vcxproj +++ b/csgo-loader/csgo-client/csgo-client.vcxproj @@ -172,6 +172,8 @@ <ExecutablePath>$(ExecutablePath)</ExecutablePath>
<IncludePath>$(SolutionDir)shared\include;$(DXSDK_DIR)\Include;$(ProjectDir);$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
<LibraryPath>$(SolutionDir)shared\lib;$(DXSDK_DIR)\Lib\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
+ <CustomBuildAfterTargets>
+ </CustomBuildAfterTargets>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='FuckMSVC|x64'">
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
@@ -242,7 +244,7 @@ <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4100;4189;4244;4267;4522;4714;4838;4307;4706;4702</DisableSpecificWarnings>
</ClCompile>
@@ -253,6 +255,12 @@ <SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
+ <CustomBuildStep>
+ <Command>B:\Themida 2.4.6.0\Themida64.exe $(SolutionDir)ThemidaSettings.tmd</Command>
+ </CustomBuildStep>
+ <CustomBuildStep>
+ <Message>Protecting file with Themida...</Message>
+ </CustomBuildStep>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='FuckMSVC|x64'">
<ClCompile>
@@ -263,7 +271,7 @@ <SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>DEBUG;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32_LEAN_AND_MEAN;NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeTypeInfo>true</RuntimeTypeInfo>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4100;4189;4244;4267;4522;4714;4838;4307;4706;4702</DisableSpecificWarnings>
</ClCompile>
diff --git a/csgo-loader/to-do list.txt b/csgo-loader/to-do list.txt index d6470b5..e93062e 100644 --- a/csgo-loader/to-do list.txt +++ b/csgo-loader/to-do list.txt @@ -104,11 +104,9 @@ If the problem persists, please download the latest version from here. [0005:xxxxxxxx]
The server does not recognize your subscription as valid.
-This could be due to numerous factors including:
- - You do not have a subscription.
- - You have attempted to tamper with the loader.
- - Your machine is infected with malware that triggered a loader integrity check.
- - You have another account on the same IP address/hardware ID.
+This could be due to numerous factors including but not limited to:
+ - not having a subscription.
+ - tampering with the loader.
To trouble-shoot this issue, try changing your password on the forums to force a database update.
@@ -119,6 +117,6 @@ The server does not recognize your credentials as valid. To trouble-shoot this issue, please take note of the following:
- CAPS LOCK is not parsed as valid input by the loader.
- - Pressing TAB will insert a character into the text input field.
+ - Pressing TAB will insert an invalid character into the text input field.
If the issue persists, contact an administrator.
\ No newline at end of file |
