Skip to content

Commit

Permalink
Finishing things up.
Browse files Browse the repository at this point in the history
  • Loading branch information
b1scoito committed Apr 1, 2021
1 parent c001c54 commit caefc6d
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 157 deletions.
3 changes: 2 additions & 1 deletion cozinha_loader/cozinha_loader.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="singleton.hpp" />
<ClInclude Include="vac3_bypass_data.hpp" />
<ClInclude Include="injection.hpp" />
<ClInclude Include="logger.hpp" />
<ClInclude Include="memory.hpp" />
<ClInclude Include="pch.hpp" />
<ClInclude Include="util.hpp" />
<ClInclude Include="utils.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
8 changes: 7 additions & 1 deletion cozinha_loader/cozinha_loader.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
<Filter Include="helpers\vac3_bypass">
<UniqueIdentifier>{1771c7ca-3cf1-4f5a-8fb0-c784c17f5d96}</UniqueIdentifier>
</Filter>
<Filter Include="helpers\singleton">
<UniqueIdentifier>{526d0e79-9eb5-4faa-8937-dab1afdc9273}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
Expand All @@ -42,7 +45,7 @@
<ClInclude Include="memory.hpp">
<Filter>helpers\memory</Filter>
</ClInclude>
<ClInclude Include="util.hpp">
<ClInclude Include="utils.hpp">
<Filter>helpers\utils</Filter>
</ClInclude>
<ClInclude Include="injection.hpp">
Expand All @@ -51,5 +54,8 @@
<ClInclude Include="vac3_bypass_data.hpp">
<Filter>helpers\vac3_bypass</Filter>
</ClInclude>
<ClInclude Include="singleton.hpp">
<Filter>helpers\singleton</Filter>
</ClInclude>
</ItemGroup>
</Project>
120 changes: 70 additions & 50 deletions cozinha_loader/injection.cpp
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
#include "pch.hpp"
#include "injection.hpp"

bool injector::map( std::string process, std::wstring module_name, std::vector<std::uint8_t> binary_bytes ) {
log_debug( "Waiting for [ %s ] to be opened!", process.c_str() );
bool injector::map( std::string process, std::wstring module_name, std::vector<std::uint8_t> binary_bytes )
{
log_debug( "Waiting for [ %s ] to be opened...", process.c_str() );

// Wait for process to be opened
auto process_list = memory::get_process_list();
while (true) {
while (true)
{
std::this_thread::sleep_for( 500ms );

process_list = memory::get_process_list();
if (memory::is_process_open( process_list, process ))
break;
}

if (process.find( "csgo" ) != std::string::npos) {
if (process.find( "csgo" ) != std::string::npos)
{
// Bypassing injection block by csgo (-allow_third_party_software) the easiest way.
const auto bypass_nt_open_file = []( DWORD pid ) {
const auto bypass_nt_open_file = []( DWORD pid )
{
const auto h_process = OpenProcess( PROCESS_ALL_ACCESS, false, pid );
LPVOID nt_open_file = GetProcAddress( LoadLibrary( "ntdll" ), "NtOpenFile" );

LPVOID nt_open_file_address {};
if (nt_open_file_address) {
// Get NtOpenFile memory address
nt_open_file_address = GetProcAddress( LoadLibrary( "ntdll" ), "NtOpenFile" );
char bytes[5];
if (nt_open_file)
{
char original_bytes[5];
// Copy 5 bytes to NtOpenFile procedure address
std::memcpy( bytes, nt_open_file_address, 5 );
std::memcpy( original_bytes, nt_open_file, 5 );
// Write it to memory.
WriteProcessMemory( h_process, nt_open_file_address, bytes, 5, nullptr );
WriteProcessMemory( h_process, nt_open_file, original_bytes, 5, nullptr );
}

CloseHandle( h_process );
Expand All @@ -35,20 +39,22 @@ bool injector::map( std::string process, std::wstring module_name, std::vector<s
bypass_nt_open_file( memory::get_process_id_by_name( process_list, process ) );
}

// Spawning blackbone process variable
blackbone::Process bb_process {};

// Attaching blackbone to the process
bb_process.Attach( memory::get_process_id_by_name( process_list, process ), PROCESS_ALL_ACCESS );
log_debug( "Injecting into [ %s ] waiting for [ %ls ]", process.c_str(), module_name.c_str() );

log_debug( "Injecting into [ %s ] waiting for [ %ls ]...", process.c_str(), module_name.c_str() );

// Wait for a process module so we can continue with injection.
auto mod_ready = false;
while (!mod_ready) {
while (!mod_ready)
{
std::this_thread::sleep_for( 500ms );

for (const auto &mod : bb_process.modules().GetAllModules()) {
if (mod.first.first == module_name) {
for (const auto &mod : bb_process.modules().GetAllModules())
{
if (mod.first.first == module_name)
{
mod_ready = true;
break;
}
Expand All @@ -59,87 +65,101 @@ bool injector::map( std::string process, std::wstring module_name, std::vector<s
}

// Resolve PE imports
const auto mod_callback = []( blackbone::CallbackType type, void *, blackbone::Process &, const blackbone::ModuleData &modInfo ) {
const auto mod_callback = []( blackbone::CallbackType type, void *, blackbone::Process &, const blackbone::ModuleData &modInfo )
{
std::string user32 = "user32.dll";
if (type == blackbone::PreCallback) {
if (type == blackbone::PreCallback)
{
if (modInfo.name == std::wstring( user32.begin(), user32.end() ))
return blackbone::LoadData( blackbone::MT_Native, blackbone::Ldr_Ignore );
}
return blackbone::LoadData( blackbone::MT_Default, blackbone::Ldr_Ignore );
};

// Mapping dll bytes to the process
if (!bb_process.mmap().MapImage( binary_bytes.size(), binary_bytes.data(), false, blackbone::WipeHeader, mod_callback, nullptr, nullptr ).success()) {
if (!bb_process.mmap().MapImage( binary_bytes.size(), binary_bytes.data(), false, blackbone::WipeHeader, mod_callback, nullptr, nullptr ).success())
{
log_err( "Failed to inject into [ %s ]! [ blackbone_mapping_failed ]", process.c_str() );
bb_process.Detach();

return EXIT_FAILURE;
return false;
}

// Detach blackbone from the target process.
// Free memory and detach from process
bb_process.Detach();

log_ok( "Injected into [ %s ] successfully!", process.c_str() );
return EXIT_SUCCESS;
return true;
}

bool injector::run() {
if (!std::filesystem::exists( cheat_filename )) {
bool injector::call()
{
if (!std::filesystem::exists( cheat_filename ))
{
log_err( "[ %s ] not found! Try dragging and dropping the dll into the loader or putting a cheat dll called cheat.dll in the same folder as the loader.", cheat_filename.c_str() );
return EXIT_FAILURE;
return false;
}

// Closing processes
close_processes( { "csgo.exe", "steam.exe" } );

const auto steam_path = utils::other::get_steam_path();
if (steam_path.empty()) {
if (steam_path.empty())
{
log_err( "Failed to retrieve steam path!" );
return EXIT_FAILURE;
return false;
}

log_info( "Steam path [ %s ]", steam_path.c_str() );
log_info( "Steam path [ %s ], Opening steam...", steam_path.c_str() );

// Open steam with console and game opened.
PROCESS_INFORMATION pi {};
if (!memory::open_process( steam_path, { "-console", "-applaunch 730" }, pi )) {
if (!memory::open_process( steam_path, { "-console", "-applaunch 730" }, pi ))
{
log_err( "Failed to open steam! [ open_process_failed ]" );

if (pi.hProcess && pi.hThread) {
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
utils::other::safe_close_handle( pi.hProcess );
utils::other::safe_close_handle( pi.hThread );

return EXIT_FAILURE;
return false;
}

if (pi.hProcess && pi.hThread) {
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
utils::other::safe_close_handle( pi.hProcess );
utils::other::safe_close_handle( pi.hThread );

std::vector<std::uint8_t> cheat {};

// Reading file and writing it to a variable
if (!utils::other::read_file_to_memory( std::filesystem::absolute( cheat_filename ).string(), &cheat )) {
if (!utils::other::read_file_to_memory( std::filesystem::absolute( cheat_filename ).string(), &cheat ))
{
log_err( "Failed to write dll to memory! [ read_file_to_memory ]" );
return EXIT_FAILURE;
return false;
}

// Inject vac bypass to steam
map( "steam.exe", L"tier0_s.dll", vac3_data );
if (!map( "steam.exe", L"tier0_s.dll", vac3_data ))
{
log_err( "Steam memory mapping failure!" );
return false;
}

// Then inject cheat to csgo
map( "csgo.exe", L"serverbrowser.dll", cheat );
if (!map( "csgo.exe", L"serverbrowser.dll", cheat ))
{
log_err( "Cheat memory mapping failure!" );
return false;
}

log_ok( "All done!" );
return EXIT_SUCCESS;
return true;
}

void injector::close_processes( std::vector<std::string> processes ) {
void injector::close_processes( std::vector<std::string> processes )
{
auto process_list = memory::get_process_list();
for (const auto &process : processes) {
log_debug( "Trying to close [ %s ]", process.c_str() );
while (true) {
for (const auto &process : processes)
{
while (true)
{
std::this_thread::sleep_for( 500ms );

memory::kill_process( process_list, process );
Expand Down
8 changes: 4 additions & 4 deletions cozinha_loader/injection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

using namespace std::chrono_literals;

class injector {
class injector: public singleton<injector>
{
private:
bool map( std::string process, std::wstring module_name, std::vector<std::uint8_t> binary_bytes );
void close_processes( std::vector<std::string> processes );
Expand All @@ -12,7 +13,6 @@ class injector {

injector() = default;
~injector() = default;
bool run();
};

inline auto injection = std::make_unique<injector>();
bool call();
};
24 changes: 16 additions & 8 deletions cozinha_loader/logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

#include <shared_mutex>

enum class msg_type_t: std::uint32_t {
enum class msg_type_t: std::uint32_t
{
LNONE = 0,
LSUCCESS = 10, /* green */
LDEBUG = 9, /* blue */
Expand All @@ -11,8 +12,10 @@ enum class msg_type_t: std::uint32_t {
LINFO = 8 /* gray */
};

inline std::ostream &operator<< ( std::ostream &os, const msg_type_t type ) {
switch (type) {
inline std::ostream &operator<< ( std::ostream &os, const msg_type_t type )
{
switch (type)
{
case msg_type_t::LSUCCESS:
return os << ">>";
case msg_type_t::LDEBUG:
Expand All @@ -27,12 +30,14 @@ inline std::ostream &operator<< ( std::ostream &os, const msg_type_t type ) {
};
}

class logger {
class logger
{
private:
std::shared_timed_mutex m {};

public:
logger() {
logger()
{
FILE *conin {}, *conout {};

AllocConsole();
Expand All @@ -44,14 +49,16 @@ class logger {
freopen_s( &conout, "conout$", "w", stdout );
freopen_s( &conout, "conout$", "w", stderr );
}
~logger() {
~logger()
{
const auto handle = FindWindow( "ConsoleWindowClass", nullptr );
ShowWindow( handle, SW_HIDE );
FreeConsole();
}

template< typename ... arg >
void print( const msg_type_t type, const std::string &func, const std::string &format, arg ... a ) {
void print( const msg_type_t type, const std::string &func, const std::string &format, arg ... a )
{
static auto *h_console = GetStdHandle( STD_OUTPUT_HANDLE );
std::unique_lock<decltype(m)> lock( m );

Expand All @@ -62,7 +69,8 @@ class logger {
const auto formated = std::string( buf.get(), buf.get() + size - 1 );

// print msg
if (type != msg_type_t::LNONE) {
if (type != msg_type_t::LNONE)
{
SetConsoleTextAttribute( h_console, static_cast<WORD>(type) );
std::cout << "[";
std::cout << type;
Expand Down
16 changes: 9 additions & 7 deletions cozinha_loader/main.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
#include "pch.hpp"

// WinMain definition as-is.
int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd ) {
int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd )
{
// Sleep for 5 seconds before exiting.
std::atexit( [] { std::this_thread::sleep_for( std::chrono::seconds( 5 ) ); } );

// Get arguments
int argc {}; LPWSTR *argv = CommandLineToArgvW( GetCommandLineW(), &argc );

// if an argument is passed inject the target dll, so we can drag and drop the dll to the exe.
if (argv[1] != nullptr)
injection->cheat_filename = utils::string::wstring_to_string( argv[1] );
// If an argument is passed inject the target dll, so we can drag and drop the dll to the exe.
if (argv[1]) injector::get().cheat_filename = utils::string::wstring_to_string( argv[1] );

if (!injection->run()) {
log_err( "Injection run failed!" );
if (!injector::get().call())
{
log_err( "Injection failed!" );
return EXIT_FAILURE;
}

Expand Down
Loading

0 comments on commit caefc6d

Please sign in to comment.