Destroy unused code
Well since i have been working on CSS i have been looking for ways to cover up code when [myg0t]wav eluded to a method that is pretty effective.
Problem: You have code that is only called once and then never called again, It's just sitting there waiting to be scanned.
What do you do?
Well this is my solution however it isn't the only solution. There is others and in fact there is others better than this. This is just an example.
You can see the call to "Core::VAC::DestroyAndMorphSection"
Here is my Header file and CPP file for my "VAC" code, but can also be used as a general unused code destroyer and will help with much more than just hiding unused code from VAC2.
VAC.h
VAC.cpp
The function "MD5_PseudoRandom" is a source engine function and can be replaced.
The "Core::VAC::UseThisAndThenMorphIt" function i call in DllMain and then proceed to overwrite it as well. There is no purpose for this besides changing the hash of your module in memory.
This does not effect the code in the file so if your module isn't hidden this will hardly matter, also you must call
"Core::VAC::RunFrame" in a thread or, like i prefer, in a hooked function which is called each frame.
Problem: You have code that is only called once and then never called again, It's just sitting there waiting to be scanned.
What do you do?
Well this is my solution however it isn't the only solution. There is others and in fact there is others better than this. This is just an example.
PHP Code:
#pragma code_seg(".init")
CreateInterfaceFn CaptureFactory( char *pszFactoryModule )
{
CreateInterfaceFn fn = NULL;
while( fn == NULL )
{
HMODULE hFactoryModule = GetModuleHandleA( pszFactoryModule );
if( hFactoryModule )
{
fn = reinterpret_cast< CreateInterfaceFn >( GetProcAddress( hFactoryModule, "CreateInterface" ) );
}
Sleep( 10 );
}
return fn;
}
void *CaptureInterface( CreateInterfaceFn fn, char *pszInterfaceName )
{
unsigned long *ptr = NULL;
while( ptr == NULL )
{
ptr = reinterpret_cast< unsigned long* >( fn( pszInterfaceName, NULL ) );
Sleep( 10 );
}
if( ptr )
{
GApp.AddToLogFileA( "hook.log", "(%s) 0x%X", pszInterfaceName, ptr );
}
return ptr;
}
DWORD WINAPI HookThread( LPVOID lpParams )
{
while( FindWindowA( "Valve001", NULL ) == NULL )
Sleep( 100 );
GApp.AddToLogFileA( "hook.log", "Window Found" );
while( GetModuleHandleA( "engine.dll" ) == NULL || GetModuleHandleA( "client.dll" ) == NULL )
Sleep( 100 );
CreateInterfaceFn fnClient = CaptureFactory( "client.dll" );
CreateInterfaceFn fnEngine = CaptureFactory( "engine.dll" );
CreateInterfaceFn fnVPhysics = CaptureFactory( "vphysics.dll" );
CreateInterfaceFn fnVStd = CaptureFactory( "vstdlib.dll" );
CreateInterfaceFn fnFileSystem = CaptureFactory( "FileSystem_Steam.dll" );
CreateInterfaceFn fnMatSystem = CaptureFactory( "MaterialSystem.dll" );
GClient = reinterpret_cast< IBaseClientDLL* >( CaptureInterface( fnClient, CLIENT_DLL_INTERFACE_VERSION ) );
GRenderView = reinterpret_cast< IVRenderView* >( CaptureInterface( fnEngine, VENGINE_RENDERVIEW_INTERFACE_VERSION ) );
GFileSystem = reinterpret_cast< IFileSystem* >( CaptureInterface( fnFileSystem, FILESYSTEM_INTERFACE_VERSION ) );
GPrediction = reinterpret_cast< IPrediction* >( CaptureInterface( fnClient, VCLIENT_PREDICTION_INTERFACE_VERSION ) );
GModelRender = reinterpret_cast< IVModelRender* >( CaptureInterface( fnEngine, VENGINE_HUDMODEL_INTERFACE_VERSION ) );
GEntList = reinterpret_cast< IClientEntityList* >( CaptureInterface( fnClient, VCLIENTENTITYLIST_INTERFACE_VERSION ) );
GEffects = reinterpret_cast< IVEfx* >( CaptureInterface( fnEngine, VENGINE_EFFECTS_INTERFACE_VERSION ) );
GCvarInterface = reinterpret_cast< ICvar* >( CaptureInterface( fnVStd, CVAR_INTERFACE_VERSION ) );
GEngine = reinterpret_cast< IVEngineClient* >( CaptureInterface( fnEngine, VENGINE_CLIENT_INTERFACE_VERSION ) );
GEnginetrace = reinterpret_cast< IEngineTrace* >( CaptureInterface( fnEngine, INTERFACEVERSION_ENGINETRACE_CLIENT ) );
GModelinfo = reinterpret_cast< IVModelInfo* >( CaptureInterface( fnEngine, VMODELINFO_CLIENT_INTERFACE_VERSION ) );
GEnginevgui = reinterpret_cast< IEngineVGui* >( CaptureInterface( fnEngine, VENGINE_VGUI_VERSION ) );
GDebugOverlay = reinterpret_cast< IVDebugOverlay* >( CaptureInterface( fnEngine, VDEBUG_OVERLAY_INTERFACE_VERSION ) );
GGameEventManager = reinterpret_cast< IGameEventManager2* >( CaptureInterface( fnEngine, INTERFACEVERSION_GAMEEVENTSMANAGER2 ) );
GMatSystem = reinterpret_cast< IMaterialSystem* >( CaptureInterface( fnMatSystem, "VMaterialSystem079" ) );
GPhysicAPI = reinterpret_cast< IPhysicsSurfaceProps* >( CaptureInterface( fnVPhysics, VPHYSICS_SURFACEPROPS_INTERFACE_VERSION ) );
GRandom = reinterpret_cast< IUniformRandomStream* >( CaptureInterface( fnEngine, VENGINE_CLIENT_RANDOM_INTERFACE_VERSION ) );
GShadowMgr = reinterpret_cast< IShadowMgr* >( CaptureInterface( fnEngine, ENGINE_SHADOWMGR_INTERFACE_VERSION ) );
GGameUIFuncs = reinterpret_cast< IGameUIFuncs* >( CaptureInterface( fnEngine, VENGINE_GAMEUIFUNCS_VERSION ) );
GEngineSound = reinterpret_cast< IEngineSound* >( CaptureInterface( fnEngine, IENGINESOUND_CLIENT_INTERFACE_VERSION ) );
DWORD *pdwLevel = reinterpret_cast< DWORD* >( reinterpret_cast< DWORD >( GClient_VTable.LevelInitPreEntity ) + 0xF );
while( *pdwLevel == NULL )
Sleep( 100 );
while( *(DWORD *)*pdwLevel == NULL )
Sleep( 100 );
GInput = reinterpret_cast< CInput* >( *(DWORD *) *pdwLevel );
Core::VAC::DestroyAndMorphSection( GApp.m_LocalModule, ".init" ); //m_LocalModule is the "Tool" module, look at "code_seg" above
return 0;
}
#pragma code_seg()
Here is my Header file and CPP file for my "VAC" code, but can also be used as a general unused code destroyer and will help with much more than just hiding unused code from VAC2.
VAC.h
PHP Code:
#ifndef __VAC_HEADER__
#define __VAC_HEADER__
namespace Core{
namespace VAC
{
typedef struct
{
unsigned long start;
unsigned long end;
} SectionInformation_t;
extern SectionInformation_t GetSectionInformation( HMODULE hModule, const char *pszName );
extern void DestroyAndMorphSection( HMODULE hModule, const char *pszName );
extern void UseThisAndThenMorphIt( void );
extern void RunFrame( void );
};
};
#endif
PHP Code:
#include "stdafx.h"
#include "VAC.h"
namespace Core{
namespace VAC
{
std::vector< SectionInformation_t > m_vMorphTheseSections;
SectionInformation_t GetSectionInformation( HMODULE hModule, const char *pszName )
{
SectionInformation_t si;
si.start = 0;
si.end = 0;
if( hModule )
{
IMAGE_DOS_HEADER *pDosHeader = reinterpret_cast<IMAGE_DOS_HEADER *>( hModule );
if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
return si;
IMAGE_NT_HEADERS *pNTHeaders = reinterpret_cast<IMAGE_NT_HEADERS *>( ( DWORD )hModule + pDosHeader->e_lfanew );
if( pNTHeaders->Signature != IMAGE_NT_SIGNATURE )
return si;
IMAGE_SECTION_HEADER *pSectionHeader = reinterpret_cast<IMAGE_SECTION_HEADER *>( ( DWORD )pNTHeaders +
sizeof( IMAGE_FILE_HEADER ) + sizeof( DWORD ) + pNTHeaders->FileHeader.SizeOfOptionalHeader );
for( unsigned int i = 0; i < pNTHeaders->FileHeader.NumberOfSections; i++ )
{
IMAGE_SECTION_HEADER *pSection = &pSectionHeader[ i ];
if( pSection == NULL )
continue;
if( memcmp( pszName, ( CHAR* )pSection->Name, strlen( pszName ) ) == 0 )
{
si.start = ( ( DWORD )hModule + ( DWORD )pSection->VirtualAddress );
si.end = si.start + ( DWORD ) pSection->SizeOfRawData;
break;
}
}
}
return si;
}
void DestroyAndMorphSection( HMODULE hModule, const char *pszName )
{
SectionInformation_t si = GetSectionInformation( hModule, pszName );
if( si.start && si.end )
{
m_vMorphTheseSections.push_back( si );
}
}
void UseThisAndThenMorphIt( void )
{
_asm nop; //0000
_asm nop; //0001
_asm nop; //0002
_asm nop; //0003
_asm nop; //0004
_asm nop; //0005
_asm nop; //0006
_asm nop; //0007
_asm nop; //0008
_asm nop; //0009
_asm nop; //0010
_asm nop; //0011
_asm nop; //0012
_asm nop; //0013
_asm nop; //0014
_asm nop; //0015
_asm nop; //0016
_asm nop; //0017
_asm nop; //0018
_asm nop; //0019
_asm nop; //0020
_asm nop; //0021
_asm nop; //0022
_asm nop; //0023
_asm nop; //0024
_asm nop; //0025
_asm nop; //0026
_asm nop; //0027
_asm nop; //0028
_asm nop; //0029
_asm nop; //0030
_asm nop; //0031
_asm nop; //0032
_asm retn; //0033
}
void RandomizeCodeAtPlace( unsigned long begin, unsigned long end )
{
BYTE *ArrayOfCode = reinterpret_cast< BYTE* >( begin );
int seed = MD5_PseudoRandom( ( rand() % 9999 ) ^ 0xFFFFFFFF );
srand( GetTickCount() ^ seed );
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery( ( LPCVOID ) begin, &mbi, sizeof( mbi ) );
VirtualProtect( mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect );
for( size_t i = 0; i < ( end - begin ); i++ )
{
int CurrentRandomSeed = ( GetTickCount() ^ seed * ( ArrayOfCode[ i + 1 ] & 0xFFFF ) );
srand( CurrentRandomSeed );
ArrayOfCode[ i ] = rand() % 0xFF;
}
VirtualProtect( mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL );
FlushInstructionCache( GetCurrentProcess(), ( LPCVOID ) begin, ( end - begin ) );
}
void RunFrame( void )
{
RandomizeCodeAtPlace(
( unsigned long ) UseThisAndThenMorphIt,
( unsigned long ) UseThisAndThenMorphIt + 32 );
for( size_t i = 0; i < m_vMorphTheseSections.size(); i++ )
{
SectionInformation_t si = m_vMorphTheseSections[ i ];
if( si.start == 0 || si.end == 0 ) continue;
RandomizeCodeAtPlace( si.start, si.end );
}
}
};
};
The "Core::VAC::UseThisAndThenMorphIt" function i call in DllMain and then proceed to overwrite it as well. There is no purpose for this besides changing the hash of your module in memory.
This does not effect the code in the file so if your module isn't hidden this will hardly matter, also you must call
"Core::VAC::RunFrame" in a thread or, like i prefer, in a hooked function which is called each frame.
0 comentarios:
Publicar un comentario