From cfd7881fed1537abbbc9900edcf9893459d95cf6 Mon Sep 17 00:00:00 2001
From: iivillian <56281742+iivillian@users.noreply.github.com>
Date: Sat, 11 Jun 2022 19:47:34 -0700
Subject: [PATCH] Kind Push
---
RACBW.sln | 31 ++++++++
RACBW/RACBW.vcxproj | 143 ++++++++++++++++++++++++++++++++++++
RACBW/RACBW.vcxproj.filters | 39 ++++++++++
RACBW/main.cpp | 96 ++++++++++++++++++++++++
RACBW/structs/structs.hpp | 16 ++++
RACBW/utilities/hook.hpp | 37 ++++++++++
RACBW/utilities/io.hpp | 53 +++++++++++++
RACBW/utilities/scan.hpp | 54 ++++++++++++++
RACBW/utilities/trust.hpp | 38 ++++++++++
9 files changed, 507 insertions(+)
create mode 100644 RACBW.sln
create mode 100644 RACBW/RACBW.vcxproj
create mode 100644 RACBW/RACBW.vcxproj.filters
create mode 100644 RACBW/main.cpp
create mode 100644 RACBW/structs/structs.hpp
create mode 100644 RACBW/utilities/hook.hpp
create mode 100644 RACBW/utilities/io.hpp
create mode 100644 RACBW/utilities/scan.hpp
create mode 100644 RACBW/utilities/trust.hpp
diff --git a/RACBW.sln b/RACBW.sln
new file mode 100644
index 0000000..eef6775
--- /dev/null
+++ b/RACBW.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32526.322
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RACBW", "RACBW\RACBW.vcxproj", "{403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Debug|x64.ActiveCfg = Debug|x64
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Debug|x64.Build.0 = Debug|x64
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Debug|x86.ActiveCfg = Debug|Win32
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Debug|x86.Build.0 = Debug|Win32
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Release|x64.ActiveCfg = Release|x64
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Release|x64.Build.0 = Release|x64
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Release|x86.ActiveCfg = Release|Win32
+ {403CAC8D-686C-428C-8B6B-A8F7FF8D2DC4}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A0190D4F-5605-449F-8293-B4A0F077DA29}
+ EndGlobalSection
+EndGlobal
diff --git a/RACBW/RACBW.vcxproj b/RACBW/RACBW.vcxproj
new file mode 100644
index 0000000..0160391
--- /dev/null
+++ b/RACBW/RACBW.vcxproj
@@ -0,0 +1,143 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {403cac8d-686c-428c-8b6b-a8f7ff8d2dc4}
+ RACBW
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ MultiByte
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpplatest
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RACBW/RACBW.vcxproj.filters b/RACBW/RACBW.vcxproj.filters
new file mode 100644
index 0000000..81d876f
--- /dev/null
+++ b/RACBW/RACBW.vcxproj.filters
@@ -0,0 +1,39 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/RACBW/main.cpp b/RACBW/main.cpp
new file mode 100644
index 0000000..8163f6e
--- /dev/null
+++ b/RACBW/main.cpp
@@ -0,0 +1,96 @@
+#include
+#include
+#include
+
+#include
+#pragma comment(lib, "DbgHelp.lib")
+
+#include "structs/structs.hpp"
+#include "utilities/scan.hpp"
+#include "utilities/io.hpp"
+#include "utilities/hook.hpp"
+#include "utilities/trust.hpp"
+
+void __stdcall detect(std::uintptr_t mod)
+{
+ const auto get_roblox_handle = [ ] ( ) -> HANDLE
+ {
+ DWORD proc_id;
+ GetWindowThreadProcessId( FindWindowA( nullptr, "Roblox" ), &proc_id );
+
+ return OpenProcess( PROCESS_ALL_ACCESS, FALSE, proc_id );
+
+ }; static auto roblox_handle = get_roblox_handle( );
+
+ const auto scan = reinterpret_cast< scan_container_t* >( mod );
+
+ if ( scan->status == scan_container_t::status_t::queued )
+ {
+ const auto to_copy_sz = min( 0x1000, scan->size );
+
+ std::uint8_t* buff = new std::uint8_t [ to_copy_sz ];
+ ReadProcessMemory( roblox_handle, reinterpret_cast< void* >( scan->address ), buff, to_copy_sz, nullptr );
+
+ if ( const auto nt_header = ImageNtHeader( buff ) )
+ {
+ if ( nt_header->Signature == 0x4550 )
+ {
+ if ( !is_signed( roblox_handle, scan->address ) )
+ {
+ utilities::io::log( "[RACBW] -> Setting unsigned module status to whitelisted\n\n" );
+
+ scan->status = scan_container_t::status_t::whitelisted;
+ }
+ }
+ }
+
+ delete [ ] buff;
+ }
+
+ utilities::io::log(
+ "[RACBW] -> status: %i | address: 0x%X | size: 0x%X\n\n",
+ scan->status,
+ scan->address,
+ scan->size
+ );
+}
+
+std::uintptr_t old = 0;
+__declspec( naked ) void stub( )
+{
+ std::uintptr_t mf_edi;
+
+ __asm
+ {
+ mov mf_edi, edi
+ pushad
+ }
+
+ detect( mf_edi );
+
+ __asm
+ {
+ popad
+ jmp old
+ }
+}
+
+void entry( )
+{
+ utilities::io::initiate( "RACBW - gogo1000, 0x90, iivillian, ozzy" );
+
+ if ( const auto ac = find_ac( ) )
+ {
+ utilities::io::log( "[RACBW] -> add_to_map: 0x%X\n\n", ac );
+
+ old = tramp_hook( ac, reinterpret_cast< std::uintptr_t >( &stub ), 6 );
+ }
+}
+
+bool __stdcall DllMain( void*, DWORD reason, void* )
+{
+ if ( reason == DLL_PROCESS_ATTACH )
+ std::thread{ entry }.detach( );
+
+ return true;
+}
\ No newline at end of file
diff --git a/RACBW/structs/structs.hpp b/RACBW/structs/structs.hpp
new file mode 100644
index 0000000..9b8d31f
--- /dev/null
+++ b/RACBW/structs/structs.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+
+struct scan_container_t
+{
+ enum class status_t : std::int32_t
+ {
+ queued = -1,
+ scanning,
+ whitelisted,
+ finished
+ } status;
+
+ std::uint32_t address, size;
+};
\ No newline at end of file
diff --git a/RACBW/utilities/hook.hpp b/RACBW/utilities/hook.hpp
new file mode 100644
index 0000000..f885fdf
--- /dev/null
+++ b/RACBW/utilities/hook.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+inline std::uintptr_t tramp_hook( std::uintptr_t func, std::uintptr_t new_func, std::size_t inst_size )
+{
+ constexpr auto extra_size = 5;
+
+ auto clone = reinterpret_cast< std::uintptr_t >( VirtualAlloc( nullptr, inst_size + extra_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ) );
+
+ if ( !clone )
+ return 0;
+
+ std::memmove( reinterpret_cast< void* >( clone ), reinterpret_cast< void* >( func ), inst_size );
+
+ const auto jmp_pos = ( func - clone - extra_size );
+
+ *reinterpret_cast< std::uint8_t* >( clone + inst_size ) = 0xE9;
+ *reinterpret_cast< std::uintptr_t* >( clone + inst_size + 1 ) = jmp_pos;
+
+ DWORD old_protect;
+
+ VirtualProtect( reinterpret_cast< void* >( func ), inst_size, 0x40, &old_protect );
+
+ std::memset( reinterpret_cast< void* >( func ), 0x90, inst_size );
+
+ const auto rel_location = ( new_func - func - extra_size );
+ *reinterpret_cast< std::uint8_t* >( func ) = 0xE9;
+ *reinterpret_cast< std::uintptr_t* >( func + 1 ) = rel_location;
+
+ VirtualProtect( reinterpret_cast< void* >( func ), inst_size, old_protect, &old_protect );
+
+ return clone;
+}
diff --git a/RACBW/utilities/io.hpp b/RACBW/utilities/io.hpp
new file mode 100644
index 0000000..578501b
--- /dev/null
+++ b/RACBW/utilities/io.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include
+#include
+#include
+
+#pragma section(".text")
+__declspec( allocate( ".text" ) ) const std::uint8_t ret_stub [ ] = { 0x90,0xC3 };
+
+namespace utilities::io
+{
+ constexpr auto debug = true;
+
+ inline void initiate( const char* const console_name )
+ {
+ static auto global_stub_pointer = reinterpret_cast< std::uintptr_t >( ret_stub );
+
+ if constexpr ( debug )
+ {
+ if ( const auto lib = LoadLibraryA( "KERNEL32.dll" ) )
+ {
+ if ( const auto free_console_address = reinterpret_cast< std::uintptr_t >( &FreeConsole ) )
+ {
+ DWORD old_protection;
+
+ constexpr const auto size = sizeof( std::uintptr_t ) + sizeof( std::uint8_t ) * 2;
+
+ VirtualProtect( reinterpret_cast< void* >( &FreeConsole ), size, PAGE_EXECUTE_READWRITE, &old_protection );
+
+ *reinterpret_cast< void** >( free_console_address + sizeof( std::uint8_t ) * 2 ) = &global_stub_pointer;
+
+ VirtualProtect( reinterpret_cast< void* >( &FreeConsole ), size, old_protection, &old_protection );
+ }
+
+ AllocConsole( );
+
+ FILE* file_stream;
+
+ freopen_s( &file_stream, "CONIN$", "r", stdin );
+ freopen_s( &file_stream, "CONOUT$", "w", stdout );
+ freopen_s( &file_stream, "CONOUT$", "w", stderr );
+
+ SetConsoleTitleA( console_name );
+ }
+ }
+ }
+
+ inline void log( const char* const format, const auto&... args )
+ {
+ if constexpr ( debug )
+ std::printf( format, args... );
+ }
+}
\ No newline at end of file
diff --git a/RACBW/utilities/scan.hpp b/RACBW/utilities/scan.hpp
new file mode 100644
index 0000000..27c20ff
--- /dev/null
+++ b/RACBW/utilities/scan.hpp
@@ -0,0 +1,54 @@
+#pragma once
+#include
+
+inline std::uintptr_t scan( const char* const pattern, const char* const mask, std::uintptr_t start, std::uintptr_t end )
+{
+ for ( auto at = start; at < end; ++at )
+ {
+ const auto is_same = [ & ] ( ) -> bool
+ {
+ for ( auto i = 0u; i < std::strlen( mask ); ++i )
+ {
+ if ( *reinterpret_cast< std::uint8_t* >( at + i ) != static_cast< std::uint8_t >( pattern [ i ] ) && mask [ i ] != '?' )
+ return false;
+ }
+
+ return true;
+ };
+
+ if ( is_same( ) )
+ return at;
+ }
+
+ return 0;
+}
+
+std::vector< MEMORY_BASIC_INFORMATION > get_allocations( )
+{
+ std::vector< MEMORY_BASIC_INFORMATION > allocations;
+
+ std::uintptr_t addr = 0;
+
+ MEMORY_BASIC_INFORMATION mbi;
+
+ while ( VirtualQuery( reinterpret_cast< std::uintptr_t* >( addr), &mbi, sizeof( mbi ) ) )
+ {
+ if ( mbi.State == MEM_COMMIT && mbi.Protect == PAGE_EXECUTE_READ )
+ allocations.push_back( mbi );
+
+ addr += mbi.RegionSize;
+ }
+
+ return allocations;
+}
+
+inline std::uintptr_t find_ac( )
+{
+ for ( const auto& alloc : get_allocations( ) )
+ {
+ if ( const auto result = scan( "\x8B\x0F\x8B\xD8", "xxxx", reinterpret_cast< std::uintptr_t >( alloc.BaseAddress ), reinterpret_cast< std::uintptr_t >( alloc.BaseAddress ) + alloc.RegionSize ) )
+ return result;
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/RACBW/utilities/trust.hpp b/RACBW/utilities/trust.hpp
new file mode 100644
index 0000000..e25e90c
--- /dev/null
+++ b/RACBW/utilities/trust.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#pragma comment (lib, "wintrust")
+
+inline bool is_signed( HANDLE roblox_handle, std::uintptr_t address )
+{
+ wchar_t name [ MAX_PATH ];
+ GetModuleFileNameExW( roblox_handle, reinterpret_cast< HMODULE >( address ), name, MAX_PATH );
+
+ GUID policy_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+ WINTRUST_DATA wintrustdata { };
+
+ WINTRUST_FILE_INFO file_info { };
+ file_info.cbStruct = sizeof( WINTRUST_FILE_INFO );
+ file_info.pcwszFilePath = name;
+
+ wintrustdata.cbStruct = sizeof( WINTRUST_DATA );
+ wintrustdata.dwUIChoice = WTD_UI_NONE;
+ wintrustdata.fdwRevocationChecks = WTD_REVOKE_NONE;
+ wintrustdata.dwUnionChoice = WTD_CHOICE_FILE;
+ wintrustdata.dwStateAction = WTD_STATEACTION_VERIFY;
+ wintrustdata.pFile = &file_info;
+
+ const auto valid = WinVerifyTrust( nullptr, &policy_guid, &wintrustdata ) == ERROR_SUCCESS;
+
+ wintrustdata.dwStateAction = WTD_STATEACTION_CLOSE;
+ WinVerifyTrust( nullptr, &policy_guid, &wintrustdata );
+
+ return valid;
+
+}
\ No newline at end of file