CS Source кратко о создании чита All in One

    Добрый день.

    Решил поделиться, с Вами, своим небольшим опытом создании чита для Counter-Strike Source v34. Данное приложение было написано исключительно ради спортивного интереса(служит, исключительно, для ознакомления), так как в годы своей юности (изрядно убил времени за этой игрой :() всегда интересовало как же устроены эти программы, хотя теоретически знал как они работают. И вот спустя пол десятка лет (в 2010 году), после игры с коллегами в канун одного из праздников я опять вспомнил о своем давнем *интересе*…

    Думаю с прелюдиями стоит закончить, скучно это, переходим к практике.
    Будет много кода.
    Полных исходников выкладывать не буду, а отдам только абстрактные куски кода, но это рабочие фрагменты.
    Для раззадоривания скажу, что в данном чите реализована функция, позволяющая стрелять в любое место и убивать противников которые могут находиться где угодно, главное, чтобы был прострел (можно бежать и убивать всех за спиной), ее я назвал AssShot — для настоящих читеров, не привыкших скрываться (что наглядно продемонстрировано в видео). VAC его не обнаруживает, но это пока кто-то не выложит его в свободный доступ.

    Видео записалось с низким фпс, извиняюсь — камтазия, а так никаких фризов модуль не вызывает.


    И так, для начала нам понадобится:
    Microsoft DirectX — менюшки, есп, имя, хелсы, кросхайр рисовать.
    Microsoft Detours — как нетрудно догадаться для подмены вызовов, как собрать и работать с данной либой есть на хабре , я на этом останавливаться не буду.
    Source SDK — SDK CSS оно облегчит нам процесс.

    Приступим. Создаем новый проект из Source SDK. Удаляем весь хлам в нем — все *.cpp, они нам не нужны.
    И так в точке входа создаем свой виток, в котором запускаем бесконечный цикл (для хоткеев) и подменяем вызовы DX:

    DllMain.cpp

    DWORD MainThread ( LPVOID lpArgs )
    {
        HMODULE hClient = NULL;
        for ( ; hClient == NULL ; Sleep(100) )
            hClient = GetModuleHandle("client.dll");
    
    	CreateInterfaceFn IGCCreateInterface = (CreateInterfaceFn)GetProcAddress(GetModuleHandle("gameui.dll"), "CreateInterface");
    
        IGameConsole *m_pIGameConsole = (IGameConsole *)IGCCreateInterface(GAMECONSOLE_INTERFACE_VERSION, NULL);
    	if (m_pIGameConsole->IsConsoleShown() == false)
            m_pIGameConsole->Show();
    	
    	ConMsg(0, "workeDDD!!!\n");
    
    	//===========================================================================
    	//===========================================================================
    
    	SetupVariables();
    
    	DWORD* VTable;
        DWORD D3D9ModuleBase;
    
        do {
        D3D9ModuleBase = (DWORD)GetModuleHandle(_T("d3d9.dll"));
    	Sleep(100);
        } while(!D3D9ModuleBase);
    
        DWORD DevicePTR = FindPattern(D3D9ModuleBase,0x128000,(PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86","xx????xx????xx");
        memcpy(&VTable,(void*)(DevicePTR+2),4); 
    
    	VoidCSS.res = GetGameResources( );
    	if (VoidCSS.res != NULL)
    	{
    		const char *p0 =  VoidCSS.res->GetPlayerName(3);
    		const char *p1 =  VoidCSS.res->GetPlayerName(4);
    		const char *p2 =  VoidCSS.res->GetPlayerName(5);
    	}
    
    	pDrawIndexedPrimitive = (DrawIndexedPrimitive_)DetourFunction((PBYTE)VTable[82],(PBYTE)nDrawIndexedPrimitive);
    	cPresent = (iPresent) DetourFunction((PBYTE)VTable[17], (PBYTE)fPresent);
    	cEndScene = (iEndScene) DetourFunction((PBYTE)VTable[42], (PBYTE)fEndScene);
    
    	for (;;Sleep (500))
    	{
    		if (GetAsyncKeyState (VK_F12) != 0) 
    		{
    			Beep (2000,200);
    			VoidCSS.s_wallhack = !VoidCSS.s_wallhack;
    		}
    
    		if (GetAsyncKeyState (VK_INSERT)!= 0) 
    		{
    			Beep (3000,200);
    			VoidCSS.s_espbox = !VoidCSS.s_espbox;
    		}
    		
    		if (GetAsyncKeyState (VK_DELETE)!= 0) 
    		{
    			Beep (4000,200);
    			VoidCSS.s_aimbot = !VoidCSS.s_aimbot;
    		}
    	}
    
    	return 1;
    }
    
    
    BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
    {
        if( dwReason == 1 )
        {
            DLLModule = hinstDLL;
            DWORD dwThreadID;
    
    		CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)MainThread, NULL, NULL, &dwThreadID);
    	}
    
        return TRUE;
    }
    


    А вот и самая грязная функция, она то и подменяет вызовы CSS:

    void SetupVariables()
    {
    	HMODULE hModuleClient		= NULL;
    	HMODULE hModuleEngine		= NULL;
    	HMODULE hModuleVGUIFactory	= NULL;
    	HMODULE hMaterialSysFactory = NULL;
    
    	while(!hModuleClient)
    	{
    		hModuleClient		= GetModuleHandle("client.dll");
    		hModuleEngine		= GetModuleHandle("engine.dll");
    		hModuleVGUIFactory	= GetModuleHandle("vguimatsurface.dll");
    		hMaterialSysFactory	= GetModuleHandle("materialsystem.dll");
    		Sleep(100);
    	}
    
    	VoidCSS.ClientFactory	= (CreateInterfaceFn)GetProcAddress(hModuleClient, "CreateInterface");
    	VoidCSS.EngineFactory	= (CreateInterfaceFn)GetProcAddress(hModuleEngine, "CreateInterface");
    	VoidCSS.VGUIFactory		= (CreateInterfaceFn)GetProcAddress(hModuleVGUIFactory, "CreateInterface");
    	VoidCSS.MaterialSys		= (CreateInterfaceFn)GetProcAddress(hMaterialSysFactory, "CreateInterface");
    	
    
    	VoidCSS.g_pdwEngine		= (DWORD*)				VoidCSS.EngineFactory( VENGINE_CLIENT_INTERFACE_VERSION , NULL );
    	VoidCSS.g_pdwClient		= (DWORD*)				VoidCSS.ClientFactory( CLIENT_DLL_INTERFACE_VERSION , NULL );
    	VoidCSS.g_pdwModelRender = (DWORD*)				VoidCSS.EngineFactory( VENGINE_HUDMODEL_INTERFACE_VERSION, NULL );
    
    	VoidCSS.g_pEntList		= (IClientEntityList*)	VoidCSS.ClientFactory( VCLIENTENTITYLIST_INTERFACE_VERSION , NULL );
    
    	VoidCSS.g_pEngClient	= (IVEngineClient*)		VoidCSS.EngineFactory("VEngineClient012", NULL);
    	VoidCSS.g_pSurface		= (vgui::ISurface *)	VoidCSS.VGUIFactory	( "VGUI_Surface028", NULL ); 
    	VoidCSS.g_pMatSystemSurface = ( IMatSystemSurface* )VoidCSS.g_pSurface->QueryInterface( "MatSystemSurface005" ); 
    	VoidCSS.g_pDraw			= (IMatSystemSurface*)	VoidCSS.g_pSurface->QueryInterface(MAT_SYSTEM_SURFACE_INTERFACE_VERSION);
    
    	VoidCSS.g_pEffects		= (IVEfx*)				VoidCSS.EngineFactory( VENGINE_EFFECTS_INTERFACE_VERSION, NULL );
    	VoidCSS.g_pCvar			= (ICvar*)				VoidCSS.EngineFactory( VENGINE_CVAR_INTERFACE_VERSION, NULL );
    	VoidCSS.g_pEnginetrace	= (IEngineTrace*)		VoidCSS.EngineFactory( INTERFACEVERSION_ENGINETRACE_CLIENT, NULL );
    	VoidCSS.g_pDebugoverlay	= (IVDebugOverlay*)		VoidCSS.EngineFactory( VDEBUG_OVERLAY_INTERFACE_VERSION, NULL );
    	VoidCSS.g_pEngineCache	= (IVEngineCache*)		VoidCSS.EngineFactory( VENGINE_CACHE_INTERFACE_VERSION, NULL );
    	VoidCSS.g_pModelinfo	= (IVModelInfoClient*)	VoidCSS.EngineFactory( VMODELINFO_CLIENT_INTERFACE_VERSION, NULL );
    	VoidCSS.g_pEnginevgui	= (IEngineVGui*)		VoidCSS.EngineFactory( VENGINE_VGUI_VERSION, NULL );
    	VoidCSS.g_pModelRender	= (IVModelRender*)		VoidCSS.EngineFactory( VENGINE_HUDMODEL_INTERFACE_VERSION, NULL );
    	VoidCSS.g_pRender		= (IVRenderView*)       VoidCSS.EngineFactory( VENGINE_RENDERVIEW_INTERFACE_VERSION, NULL);
    
    	VoidCSS.g_pMaterialSystem = (IMaterialSystem *) VoidCSS.MaterialSys( MATERIAL_SYSTEM_INTERFACE_VERSION, NULL );
    
    	VoidCSS.g_pBaseCDll		= (IBaseClientDLL*)		VoidCSS.ClientFactory(CLIENT_DLL_INTERFACE_VERSION, NULL);
    	VoidCSS.g_pMRender		= (IVModelRender*)		VoidCSS.EngineFactory(VENGINE_HUDMODEL_INTERFACE_VERSION, NULL);
    
    	VoidCSS.g_pdwBaseCDll = (PDWORD*)VoidCSS.g_pBaseCDll;
    	VoidCSS.g_pdwMRender  = (PDWORD*)VoidCSS.g_pMRender;
    
    	DWORD dwOld;
    	
    	memcpy( (void*) &VoidCSS.g_oldClient,(void*)*VoidCSS.g_pdwBaseCDll , sizeof(CClient) );
    	VoidCSS.gClientFuncs2 = (CClient*)*VoidCSS.g_pdwBaseCDll;
    
    	VirtualProtect( (LPVOID)&((CClient*)*VoidCSS.g_pdwBaseCDll)->Init, 4, PAGE_EXECUTE_READWRITE, &dwOld );
    	VoidCSS.gClientFuncs2->Init = &new_Init;
    
    	VirtualProtect( (LPVOID)&((CClient*)*VoidCSS.g_pdwBaseCDll)->CreateMove, 4, PAGE_EXECUTE_READWRITE, &dwOld );
    	VoidCSS.gClientFuncs2->CreateMove = &new_CreateMove;
    
    	VirtualProtect( (LPVOID)&((CClient*)*VoidCSS.g_pdwBaseCDll)->HudUpdate, 4, PAGE_EXECUTE_READWRITE, &dwOld );
    	VoidCSS.gClientFuncs2->HudUpdate = &new_HudUpdate;
    
    	if ( VoidCSS.g_pInput == NULL )
    	{
    		PDWORD pdwAddress = ( PDWORD ) ((( DWORD ) VoidCSS.g_oldClient.CreateMove ) + 0x20 );
    		PDWORD pdwTable = ( PDWORD ) *pdwAddress;
    		VoidCSS.g_pInput = ( CInput* ) *pdwTable;
    	}
    
    	VoidCSS.g_pGlobals = ( CGlobalVarsBase* )0x200D01A4;
    }
    


    Как вы помните мы переопредилили вызов iEndScene, которым и воспользуемся для отрисовки menu, esp, wallHack и Anti flash/smoke/fog:

    HRESULT WINAPI fEndScene ( LPDIRECT3DDEVICE9 nDevice )
    {
    	_asm pushad
    
    	try
    	{
    		if (VoidCSS.s_espbox)
    		{
    			if (VoidCSS.pLine == NULL)
    				D3DXCreateLine(nDevice, &VoidCSS.pLine);
    			else
    			{
    				VoidCSS.g_pEsp->DrawEsp();
    				VoidCSS.g_pEsp->DrawMap();
    			}
    		}
    
    		if (Red == NULL)
    		{
    			GenerateTexture(nDevice, &Red, D3DCOLOR_ARGB (255 , 255 , 0 , 0 ));
    			GenerateTexture(nDevice, &Yellow, D3DCOLOR_ARGB (255 , 255 , 255 , 0 ));
    			GenerateTexture(nDevice, &Green, D3DCOLOR_ARGB (255 , 0 , 255 , 0 ));
    			GenerateTexture(nDevice, &Blue, D3DCOLOR_ARGB (255 , 0 , 0 , 255 ));
    			GenerateTexture(nDevice, &Purple, D3DCOLOR_ARGB (255 , 102 , 0 , 153 ));
    			GenerateTexture(nDevice, &Pink, D3DCOLOR_ARGB (255 , 255 , 20 , 147 ));
    			GenerateTexture(nDevice, &Orange, D3DCOLOR_ARGB (255 , 255 , 165 , 0 ));
    		}
    
    		D3DVIEWPORT9 viewP;
    		nDevice->GetViewport( &viewP );
    		DWORD ScreenCenterX = viewP.Width / 2;
    		DWORD ScreenCenterY = viewP.Height / 2;
    		D3DRECT rec16 = {ScreenCenterX-20, ScreenCenterY, ScreenCenterX+ 20, ScreenCenterY+1};
    		D3DRECT rec17 = {ScreenCenterX, ScreenCenterY-20, ScreenCenterX+ 1,ScreenCenterY+20};  
    		nDevice->Clear( 1, &rec16, D3DCLEAR_TARGET, D3DXCOLOR(1.0, 1.0, 1.0, 1.0), 0,  0 );//white
    		nDevice->Clear( 1, &rec17, D3DCLEAR_TARGET, D3DXCOLOR(1.0, 1.0, 1.0, 1.0), 0,  0 );
    
    		if(menu_setup == false)
    		{
    			g_pCMenu = new CDXMenu( nDevice, 10, 160 ); 
    
    			g_pCMenu->addHackBool( "WallHack", &VoidCSS.s_wallhack );
    			g_pCMenu->addHackBool( "Aimbot", &VoidCSS.s_aimbot );
    			g_pCMenu->addHackInt( "AimBotFOV", &VoidCSS.s_aimfov );
    			g_pCMenu->addHackBool( "AssShot", &VoidCSS.s_assshot );
    			g_pCMenu->addHackBool( "ESPBox", &VoidCSS.s_espbox );
    
    			menu_setup = true; 
    		}
    
    		if(GetAsyncKeyState( VK_END ) &1)
    		{
    			VoidCSS.s_ShowMenu = !VoidCSS.s_ShowMenu;
    		}
    
    		g_pCMenu->showMenu( VoidCSS.s_ShowMenu );
    		g_pCMenu->updateMenu();
    	}
    	catch(...){}
    
    	_asm popad
    	return cEndScene ( nDevice );
    }
    


    Для wallHack и Anti то/се нам требуется получит материалы:

    	IMaterial* TTeam1 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\t_arctic\\t_arctic", "Model textures");
    	IMaterial* TTeam2 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\t_guerilla\\t_guerilla", "Model textures");
    	IMaterial* TTeam3 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\t_leet\\t_leet", "Model textures");
    	IMaterial* TTeam4 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\t_phoenix\\t_phoenix", "Model textures");
    	IMaterial* CTeam1 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\ct_gign\\ct_gign", "Model textures");
    	IMaterial* CTeam2 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\ct_gsg9\\ct_gsg9", "Model textures");
    	IMaterial* CTeam3 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\ct_sas\\ct_sas", "Model textures");
    	IMaterial* CTeam4 = VoidCSS.g_pMaterialSystem->FindMaterial("models\\player\\ct_urban\\ct_urban", "Model textures");
    
    	IMaterial* SmokeStack		=	VoidCSS.g_pMaterialSystem->FindMaterial( "SmokeStack", "ClientEffect textures" );
    	IMaterial* FlashEffect		=	VoidCSS.g_pMaterialSystem->FindMaterial( "effects/flashbang", "ClientEffect textures" );
    	IMaterial* FlashOverlay		=	VoidCSS.g_pMaterialSystem->FindMaterial( "effects/flashbang_white", "ClientEffect textures" );
    	IMaterial* SmokeParticle	=	VoidCSS.g_pMaterialSystem->FindMaterial( "particle/particle_smokegrenade", "ClientEffect textures" );
    	IMaterial* SmokeParticle1	=	VoidCSS.g_pMaterialSystem->FindMaterial( "particle/particle_smokegrenade1", "ClientEffect textures" );
    	IMaterial* ScreenSpaceFog	=	VoidCSS.g_pMaterialSystem->FindMaterial( "particle/screenspace_fog", "ClientEffect textures" );
    


    И говорим рисуем/игнорируем их или нет:

    	if(VoidCSS.s_wallhack)
    	{
    		TTeam1->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );		
    		TTeam2->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );		
    		CTeam1->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );		
    		CTeam2->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );		
    		TTeam3->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );		
    		TTeam4->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );	
    		CTeam3->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );
    		CTeam4->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, true );
    
    		FlashEffect->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,	  true );
    		FlashOverlay->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,	  true );
    		SmokeStack->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,	  true );
    		SmokeParticle->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,  true );
    		SmokeParticle1->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW, true );
    		ScreenSpaceFog->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW, true );
    	}
    	else
    	{
    		TTeam1->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		TTeam2->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		CTeam1->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		CTeam2->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		TTeam3->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		TTeam4->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		CTeam3->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    		CTeam4->SetMaterialVarFlag( MATERIAL_VAR_IGNOREZ, false );
    
    		FlashEffect->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,	  false );
    		FlashOverlay->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,	  false );
    		SmokeStack->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,	  false );
    		SmokeParticle->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW,  false );
    		SmokeParticle1->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW, false );
    		ScreenSpaceFog->SetMaterialVarFlag( MATERIAL_VAR_NO_DRAW, false );
    		
    	}
    


    Переопределенной функцией new_CreateMove воспользуемся для aimBot и, совсем забыл, bunnyHop:

    void __stdcall new_CreateMove ( int sequence_number, float input_sample_frametime, bool active ) 
    {
    	
    	VoidCSS.g_oldClient.CreateMove( sequence_number , input_sample_frametime , active );
    	ModelHack();
    
    	if ( VoidCSS.g_pInput )
    	{
    		CUserCmd* cmd = VoidCSS.g_pInput->GetUserCmd( sequence_number );		
    
    		if ( VoidCSS.g_pEngClient->IsInGame() )
    		{
    			//Aimbot Norecoil Nospread
    			if( cmd->buttons & IN_ATTACK && VoidCSS.s_aimbot)
    				VoidCSS.g_pAimbot->AimAtTarget( cmd );
    			
    			//BunnyHop
    			if ( cmd->buttons & IN_JUMP )
    			{
    				int *iMyFlAgs = (int*) ( (DWORD)VoidCSS.g_pMyPlayer->BaseEnt() + (DWORD)0x2B4 );
    				int iFlags = *iMyFlAgs;
    
    				if( !(iFlags &FL_ONGROUND) )
    					cmd->buttons &= ~IN_JUMP;
    			}
    		}
    	}
    }
    


    В классе аимбота отслеживаем жертву (удостоверившись, что это игрок противоположной команды), перебирая кости находи нужную часть тела (в нашем случае голова) и перемещаем центр экрана в эту точку, делаем выстрел, попутно гася отдачу (antiRecoil). Да забыл сказать, что если включен assShot то возвращаем нашего персонажа в положение до стрельбы (так вот он работает).

    void cCAimbot::AimAtTarget( CUserCmd* c )
    { 
    	if( VoidCSS.g_pEngClient->IsInGame() == false 
    	||	VoidCSS.g_pEngClient->IsHLTV() == true  
    	||	VoidCSS.g_pMyPlayer->BaseEnt() == NULL )
    		return;
    
    	DropTarget();
    	//----------------------------------//
    	player_info_t pinfo;
    	QAngle* pPunchAngle = ( QAngle* )( (DWORD)VoidCSS.g_pMyPlayer->BaseEnt() + 0xBB0 );
    	//----------------------------------//
    	//----------------------------------//
    	for( int index = 1; index <= VoidCSS.g_pEntList->NumberOfEntities( false ); ++index )
    	{
    		if ( index == VoidCSS.g_pEngClient->GetLocalPlayer() )
    			continue;
    
    		IClientEntity* ClientEntity = VoidCSS.g_pEntList->GetClientEntity( index );
    
    		if (	ClientEntity == NULL
    			||	ClientEntity->IsDormant() )
    				continue;
    
    		CBaseEntity* pBaseEntity = ClientEntity->GetBaseEntity();
    		//Get Life State
    		int *lifestate = (int*) ( ( DWORD )pBaseEntity + ( DWORD )0x87 );
    		float fov = (float)VoidCSS.s_aimfov;
    		if (VoidCSS.s_assshot)
    			fov = 360.0f;
    
    		if(		pBaseEntity == NULL/* nothing */
    			||	pBaseEntity->IsDormant()/* not active */
    			||	!(*lifestate  == LIFE_ALIVE)/* not alive */
    			||	VoidCSS.g_pEngClient->GetPlayerInfo( index, &pinfo ) == false/* not a player!*/
    			||	pBaseEntity->GetTeamNumber() == VoidCSS.g_pMyPlayer->BaseEnt()->GetTeamNumber()/*enemy*/
    			||	!GetBonePosition( 14/*Head*/, vPlayer, c->viewangles, index )
    			||	GetFov( VoidCSS.g_pMyPlayer->BaseEnt()->GetAbsAngles(), VoidCSS.g_pMyPlayer->BaseEnt()->EyePosition(), vPlayer ) > fov /*4.0f*/
    			||	!GetVisible( VoidCSS.g_pMyPlayer->BaseEnt()->EyePosition(), vPlayer, pBaseEntity )/* not visible */
    			||	flBestDist < GetFov( VoidCSS.g_pMyPlayer->BaseEnt()->GetAbsAngles(), VoidCSS.g_pMyPlayer->BaseEnt()->EyePosition(), vPlayer ))
    				continue;
    
    		flBestDist = GetFov( VoidCSS.g_pMyPlayer->BaseEnt()->GetAbsAngles(), VoidCSS.g_pMyPlayer->BaseEnt()->EyePosition(), vPlayer );
    
    		m_nTarget = index;
    		// Calculate the delta origin
    		Vector vDeltaOrigin = vPlayer - vPlayer;
    		// Calculate the Latency
    		float fLatency = VoidCSS.g_pEngClient->GetNetChannelInfo()->GetLatency( FLOW_OUTGOING );
    		// Compensate the latency
    		vDeltaOrigin[0] *= fLatency;
    		vDeltaOrigin[1] *= fLatency;
    		vDeltaOrigin[2] *= fLatency;
    		//Apply the prediction
    		PredictedTargetPosition = vPlayer + vDeltaOrigin;
    	}
    	if( m_nTarget == -1 )	
    		return;
    
    	CalcAngle( VoidCSS.g_pMyPlayer->BaseEnt()->EyePosition(), PredictedTargetPosition, c->viewangles );
    	//recoil
    	c->viewangles.x -= (	pPunchAngle->x *2.0f	);
    	c->viewangles.y -= (	pPunchAngle->y *2.0f	);
    	//aimbot
    	VoidCSS.g_pEngClient->SetViewAngles( c->viewangles );//aim
    	//nospread
    	float flNew[3],flOld[3];
    	flOld[0] = c->viewangles[0];
    	flOld[1] = c->viewangles[1];
    	flOld[2] = c->viewangles[2];
    	//VoidCSS.g_pNoSpread->GetSpreadFix( c->random_seed, flOld, flNew );
    	c->viewangles[0] += flNew[0];
    	c->viewangles[1] += flNew[1];
    	c->viewangles[2] += flNew[2];
    
    	if (VoidCSS.s_assshot)
    		VoidCSS.g_pEngClient->SetViewAngles( m_angle );
    
    	DropTarget();
    }
    


    Вот в принципе самые главные части кода. Конечно есть небольшой пучек вспомогательных функций, а также классы для отрисовки меню, чтения файла настроек (у меня это setings.ini) и рисования esp, но в них вроде и так все понятно. На SpeedHack энтузиазма у меня уже не хватило, но подскажу — нужно баловаться с таймингами (правда чревато подвисаниями при плохом пинге).

    И так перейдем к инъекции нашей сборки в процесс игры, 2 варианта c++ по хендлу окна или c# по процессу

    с++


    #include "stdafx.h"
    
    #include <stdio.h>
    #include <windows.h>
    
    #define MAXINJECTSIZE 4096
    
    typedef HINSTANCE (*LoadLibrary_Ptr)(LPCTSTR);
    typedef FARPROC (*GetProcAddress_Ptr)(HMODULE, LPCSTR lpProcName);
    
    typedef struct _injectionRoutineParam
    {
            LoadLibrary_Ptr _call_LoadLibrary;
            GetProcAddress_Ptr _call_GetProcAddress;
            HINSTANCE _ret;
            FARPROC _proc;
            char _dll_name[1024];
            char _proc_name[256];
    }InjectionRoutineParam;
    
    DWORD __stdcall injectionThreadRoutine(InjectionRoutineParam* param)
    {
          HINSTANCE hinstance = param->_call_LoadLibrary((LPCTSTR)param->_dll_name);
          param->_ret = hinstance;
          FARPROC proc= param->_call_GetProcAddress(hinstance, param->_proc_name);
          param->_proc = proc;
          return 0;
    }
    
    void inject(HANDLE process, char *dllName)
    {
         char * procName ="HelloWorld";
         InjectionRoutineParam param;
         DWORD threadId;
         void *p = VirtualAllocEx(process, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
         void *data = VirtualAllocEx(process, 0, sizeof(InjectionRoutineParam), MEM_COMMIT, PAGE_EXECUTE_READWRITE );
         
         HINSTANCE kernel32=LoadLibrary(_T("KERNEL32.DLL"));
         param._call_LoadLibrary = (LoadLibrary_Ptr)GetProcAddress( kernel32, "LoadLibraryA" );
         param._call_GetProcAddress = (GetProcAddress_Ptr)GetProcAddress( kernel32, "GetProcAddress" );
         memcpy(param._dll_name,dllName,strlen(dllName));
         memcpy(param._proc_name, procName, strlen(procName));
         
         WriteProcessMemory(process, p, (void*)&injectionThreadRoutine, MAXINJECTSIZE, 0 );
         WriteProcessMemory(process, data, (void*)¶m, sizeof(InjectionRoutineParam), 0 );
         
         HANDLE remoteThread = CreateRemoteThread(process, NULL,0,(DWORD (__stdcall *)(LPVOID))p, data, 0, &threadId);
         WaitForSingleObject(remoteThread, INFINITE);
         DWORD read;
         ReadProcessMemory(process, data, ¶m, sizeof(InjectionRoutineParam), &read);
         VirtualFreeEx(process, p, 0, MEM_RELEASE );
         VirtualFreeEx(process, data, 0, MEM_RELEASE );
    	 FreeLibrary( kernel32 );
    }
    
    
    void die(char *msg)
    {
         fprintf(stderr, msg);
         exit(-1);
    }
    
    
    #include <string>
    #include <windows.h>
    
    #define MAXWAIT 10000
    
    bool insertDll(DWORD procID, std::string dll)
    {
        //Находим адрес LoadLibraryA, к счастью для нас, она загружается в один адрес для каждого процесса
        HMODULE hLocKernel32 = GetModuleHandle(_T("Kernel32"));
        FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryA");
        
        //Получаем привилегии на системный процесс
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp;
        if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        {
            LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
        }
    
        //открываем процесс на полный доступ
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
    
        //Выделите память для хранения пути к Dll файла в памяти процесса
        dll += '\0';
        LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, dll.size(), MEM_COMMIT, PAGE_READWRITE);
    
        //записываем
        DWORD numBytesWritten;
        WriteProcessMemory(hProc, hRemoteMem, dll.c_str(), dll.size(), &numBytesWritten);
    
        //Создаем удаленный поток
        HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL);
    
       // cout << hRemoteThread << endl;
    
        //Подождем, пока нить закончится
        bool res = false;
        if (hRemoteThread)
            res = (bool)WaitForSingleObject(hRemoteThread, MAXWAIT) != WAIT_TIMEOUT;
    
        //Подчищаем за собой
        VirtualFreeEx(hProc, hRemoteMem, dll.size(), MEM_RELEASE);
    
        //И отпускаем процесс :)
        CloseHandle(hProc);
    
        return res;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HWND WindowHandle;
    	DWORD processId;
    
    	WindowHandle = FindWindow(NULL, _T("Counter-Strike Source"));
        if (WindowHandle)
    	{
    		GetWindowThreadProcessId(WindowHandle, &processId);
    		insertDll(processId, "..\\..\\client.dll");
        }
    	
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    


    с#


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace voidLoader
    {
        public static class Inject
        {
            private static class WINAPI
            {
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern IntPtr OpenProcess(
                    UInt32 dwDesiredAccess,
                    Int32 bInheritHandle,
                    UInt32 dwProcessId);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern Int32 CloseHandle(
                    IntPtr hObject);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern IntPtr GetProcAddress(
                    IntPtr hModule,
                    string lpProcName);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern IntPtr GetModuleHandle(
                    string lpModuleName);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern IntPtr VirtualAllocEx(
                    IntPtr hProcess,
                    IntPtr lpAddress,
                    IntPtr dwSize,
                    uint flAllocationType,
                    uint flProtect);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern Int32 WriteProcessMemory(
                    IntPtr hProcess,
                    IntPtr lpBaseAddress,
                    byte[] buffer,
                    uint size,
                    out IntPtr lpNumberOfBytesWritten);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern IntPtr CreateRemoteThread(
                    IntPtr hProcess,
                    IntPtr lpThreadAttribute,
                    IntPtr dwStackSize,
                    IntPtr lpStartAddress,
                    IntPtr lpParameter,
                    uint dwCreationFlags,
                    IntPtr lpThreadId);
    
                public static class VAE_Enums
                {
                    public enum AllocationType
                    {
                        MEM_COMMIT = 0x1000,
                        MEM_RESERVE = 0x2000,
                        MEM_RESET = 0x80000,
                    }
    
                    public enum ProtectionConstants
                    {
                        PAGE_EXECUTE = 0X10,
                        PAGE_EXECUTE_READ = 0X20,
                        PAGE_EXECUTE_READWRITE = 0X40,
                        PAGE_EXECUTE_WRITECOPY = 0X80,
                        PAGE_NOACCESS = 0X01
                    }
                }
            }
    
            public static bool DoInject(
                Process pToBeInjected,
                string sDllPath,
                out string sError)
            {
                IntPtr hwnd = IntPtr.Zero;
                if (!CRT(pToBeInjected, sDllPath, out sError, out hwnd))
                {
                    if (hwnd != (IntPtr)0)
                        WINAPI.CloseHandle(hwnd);
                    return false;
                }
                int wee = Marshal.GetLastWin32Error();
                return true;
            }
    
            private static bool CRT(
                Process pToBeInjected,
                string sDllPath,
                out string sError,
                out IntPtr hwnd)
            {
                sError = String.Empty;
    
                IntPtr hndProc = WINAPI.OpenProcess(
                    (0x2 | 0x8 | 0x10 | 0x20 | 0x400), 
                    1,
                    (uint)pToBeInjected.Id);
    
                hwnd = hndProc;
    
                if (hndProc == (IntPtr)0)
                {
                    sError = "Unable to attatch to process.\n";
                    sError += "Error code: " + Marshal.GetLastWin32Error();
                    return false;
                }
    
                IntPtr lpLLAddress = WINAPI.GetProcAddress(
                    WINAPI.GetModuleHandle("kernel32.dll"),
                    "LoadLibraryA");
    
                if (lpLLAddress == (IntPtr)0)
                {
                    sError = "Unable to find address of \"LoadLibraryA\".\n";
                    sError += "Error code: " + Marshal.GetLastWin32Error();
                    return false;
                }
    
                IntPtr lpAddress = WINAPI.VirtualAllocEx(
                    hndProc,
                    (IntPtr)null,
                    (IntPtr)sDllPath.Length,
                    (uint)WINAPI.VAE_Enums.AllocationType.MEM_COMMIT |
                    (uint)WINAPI.VAE_Enums.AllocationType.MEM_RESERVE,
                    (uint)WINAPI.VAE_Enums.ProtectionConstants.PAGE_EXECUTE_READWRITE);
    
                if (lpAddress == (IntPtr)0)
                {
                    if (lpAddress == (IntPtr)0)
                    {
                        sError = "Unable to allocate memory to target process.\n";
                        sError += "Error code: " + Marshal.GetLastWin32Error();
                        return false;
                    }
                }
    
                byte[] bytes = CalcBytes(sDllPath);
                IntPtr ipTmp = IntPtr.Zero;
    
                WINAPI.WriteProcessMemory(
                    hndProc,
                    lpAddress,
                    bytes,
                    (uint)bytes.Length,
                    out ipTmp);
    
                if (Marshal.GetLastWin32Error() != 0)
                {
                    sError = "Unable to write memory to process.";
                    sError += "Error code: " + Marshal.GetLastWin32Error();
                    return false;
                }
    
                IntPtr ipThread = WINAPI.CreateRemoteThread(
                    hndProc,
                    (IntPtr)null,
                    (IntPtr)0,
                    lpLLAddress,
                    lpAddress,
                    0,
                    (IntPtr)null);
    
                if (ipThread == (IntPtr)0)
                {
                    sError = "Unable to load dll into memory.";
                    sError += "Error code: " + Marshal.GetLastWin32Error();
                    return false;
                }
    
                return true;
            }
    
            private static byte[] CalcBytes(string sToConvert)
            {
                byte[] bRet = System.Text.Encoding.ASCII.GetBytes(sToConvert);
                return bRet;
            }
        } 
    }
    
    


    Ну собственно и сами файлики. (перезалиты на github)
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 78

      +1
      Впечатляет!
        0
        Интересный опыт, спасибо.
          +12
          You have been banned. Reason — AIM + WH :)
            +3
            Permanent ban!
            +25
            Я бы вам посоветовал использовать для исходников, например, github, а не постить их в статью. Потому что статья в которой 10 строчек текста и тонна кода, мало кому интересна для прочтения, а те кто захочет поковыряться в коде с удовольствием сделают это там, к тому же там удобнее читать его.
              +2
              Пора сделать свой habrahub с блекджеком и шлюхами.
                +2
                посоны дайте скачать! :))
                  0
                  Спасибо за совет, так и сделал.
                  +4
                  ага, очень кратко =) добавьте комменты, простыня невнятного кода и чуть-чуть текста — не есть полезно
                    +6
                    Отправьте, пожалуйста, копию этого письма в steamcommunity. Пусть это будет баловство для NONSTEAM контрстрайкеров. Неприятно будет, если это останется безнаказанным при игре на серверах STEAM.
                      0
                      Как я понял из опыта игры в CS, NOSTEAM сервера как раз и предназначены для игроков, которые с читами.
                      Иначе смысл играть на таких серверах?
                        +7
                        Совсме даже не для этого. А, наоборот, для того чтобы играть на халяву.
                          0
                          Хм, я думаю таких меньшинство, а большинство просто с читами играет.

                          Любить играть в определенную игру и не иметь 3 баксов на нее(постоянные распродажи)? При этом заплатить можно даже со счета мобилы. Имхо это что-то из разряда фантастики.
                            –1
                            Linux, не?
                              0
                              Купил и играл в свое время в hl2 через стим на бубунте. Нормально и купилось и игралось. Сомневаюсь что для CS нужно что-то принципиально иное.
                                0
                                Почему вы считаете, что люди, которые используют СПО, не признают платный софт?
                                Или думаете, что wine не умеет steam?
                                  +1
                                  У самого есть CS1.6 в стиме, но чья-то кастомная сборка Cedega+CS1.6 работает в разы лучше той, что я пытался сделать из wine+либы+steam+cs1.6. Так что я играю на non-steam сервере и отстреливаю читеров, чтобы не мешали. Иначе никак. Их, кстати, не так много заходит.
                                    +1
                                    (баню в смысле)
                                0
                                По моим последним подсчетам в России где-то 50/50
                                Выборка из месячной посещаемости 15 серверов с разными модами.
                                  0
                                  в CS 1.6 подавляющее количество серверов dproto с мультипротоколом. На крайняк дпроту настраивают чтобы пускал как минимум эмуляторы.
                                  –1
                                  Ну вот я, например, не люблю эту игру. Но пару раз в год часа по 4 играю. Но покупать игру, которую, вероятно, больше никогда не открою, мне не хочется.
                                0
                                Не обязательно. Еще такой сервер может быть близко к тебе расположен и иметь низкий пинг. Плюс наличие адекватных людей и администрации на сервере — и тогда nosteam не особо и влияет на выбор.
                                  0
                                  Если честно, то я не играю на одном и том же сервере а выбираю их по 2 параметрам: пинг и карта.
                                  Ну и еще третий параметр есть: я слово nosteam загнал в блок, т.к. по моему опыту игры там всегда есть читеры.
                                  0
                                  Я вам объясню смысл.
                                  У меня, например, провайдер предоставляет быстрый, но не полноценный инет. Не поддерживаются входящие соединения (судя по медленной скачке torrent'ов) — видимо NAT без мэппинга портов, насколько я разбираюсь. А входящие соединения необходимы для работы Steam-клиента. В итоге, я, купивший себе CS:S, не могу авторизоваться, и поэтому не могу играть на Steam-серваках.
                                  Приходится играть только на NOSTEAM :(

                                  Вот нафига Valve сделала такой заумный Steam-клиент, который не работает там, где у меня отлично работает сам Counter-Strike:Source и все остальные инет-требующие программы/игры (кроме торрентов). Сам CS:S работает абсолютно нормально, но блин, зачем чтоб подрубить Steam-клиент ему требуется что-то ещё! Я не знаю даже кто больше виноват Valve или провайдер.

                                  Часто производители софта не заморачиваются с поддержкой Прокси, либо, в данном случае, с поддержкой подрезанного инета.
                                    0
                                    Вы что-то путаете, стиму не нужны входящие соединения, спокойно запускается за любым натом(с мобильника и т.д.).
                                    Что сказала техподдержка стима на это?
                                    Скорее всего ваш провайдер просто посчитал действия стима вредоносными и заблокировал.
                                      0
                                      С мобильника? Вы про вход на сайт через браузер? Или вы про Steam-клиент для iOS или Android?
                                      Через браузер то работает. Я не об этом. Мне нужно игру запустить.

                                      Для запуска CS:S, требуется предварительное подключение Steam-клиента (программы), через который происходит установка/обновление игр, общение с другими игроками и т.д и т.п. И без авторизации которого (подключения его к Steam-серверу) не запускаются игры, в моём случае CS:S.

                                      Требуемые порты для Стима
                                      Required Ports for Steam
                                      https#support.steampowered.com#kb_article.php?ref=8571-GLVN-8711

                                      Много разных портов, и TCP и UDP, видимо не все открыты у провайдера.

                                      «Что сказала техподдержка стима на это?»
                                      шлют на статьи «Troubleshooting Network Connectivity»
                                        0
                                        Перечисленные порты(Steam Client) не исходящие. Так что стим тут не причем: тут однозначно виноват провайдер, который их целенаправленно фильтрует.

                                        В техподдержке провайдера что говорят? Я практически уверен, что по глупости они посчитали, что данная активность от malware.
                                          0
                                          Да не, не malware, сослались на не прозрачность сети.
                                          Ну судите сами: если у меня torrent еле качает файлы, в то время как на другом компе через другого провайдера эти же файлы качаются раз в 30-40 быстрее, при том что КС без Стима работает и там и там одинаково. То и проблемы Steam видимо оттуда же.

                                          Ситуация осложняется тем, что провайдер — монополист. И с поддержкой у него достаточно не просто.
                                  +1
                                  Отправил :-)
                                  Кто знает может и прочитают ;-)
                                  +23
                                  В книжных магазинах сейчас сметут все книги по С
                                  В гугле топ-1 запрос: как выучить С за 7 дней
                                  На всех форумах страны: памагите зопустидь чит
                                    +1
                                    ах, C++
                                      –1
                                      Вы сделали мой вечер.
                                        +4
                                        Ну, как выучить C++ за 21 день, знают почти все
                                        +12
                                        ее я назвал Ашот…
                                          +6
                                          А как античиты работают? Как такие штуки отлавливают?
                                            +2
                                            Хотя бы проверка на хуки в ключевых функциях (iEndScene в данном случае).
                                              0
                                                0
                                                VAC просто сканирует память на сигнатуру чита. Если нашел — через 2-3 недели банит. Минус только один — если о чите он не знает то и бан не последует.
                                                  +2
                                                  а полиморфные читы уже были?
                                                +3
                                                меня всегда удивляло почему не пишут умных читов, что не палится совсем. к примеру, в хед не всегда попадать, а только когда прицел в разумной окрестности цели, тогда тебя на видео не запалят никогда
                                                  +1
                                                  В раннем юношестве часто смотрел записи всяких чемпионатов и лично я всегда недоумевал, стреляют иногда вообще не особо даже рядом, а тем не менее хедшот.
                                                    +5
                                                    представьте себе, но люди пишут и такие «умные» читы. Но как подсказывает опыт, рано или поздно все читеры палятся, или античитом или когда горят в аду.
                                                      0
                                                      Обычно их сдаёт статистика. А если и статистика не выделяется, то пусть себе читерят сколько влезет, раз никому не мешают.
                                                      0
                                                      Почему вы думаете, что не пишут? Читеры палятся чаще всего на WH. AIM сложнее распознать, если он тонко настроен и если это не откровенное самонаведение, как в этом топике. Если читер умелый, то его вряд ли когда-то заметят. Я уверен, что определенный процент таких игроков существует.
                                                        +1
                                                        Да, только вот что бы тонко настроить чит (а в особенности aim) нужно потратить туеву хучу времени и иметь определенный опыт игры.
                                                        И получается, что бы играть с читами безпалева нужно уметь играть, а умея играть читы становятся не нужны.
                                                          0
                                                          поправлю. что бы хорошо играть с читами безпалева нужно уметь играть
                                                            +1
                                                            Несомненно. Если ты не умеешь играть, то читы очень легко заметны по простому поведению игрока: его передвижениям, прицеливанию, поведению.
                                                            Если ты хочешь, чтобы эти вещи тебя не выдавали, но нужно очень хорошо понимать суть игры, т.е. играть на высоком уровне.
                                                            Недавний скандал с профессиональным датским игроком в CS 1.6 ColoN'ом тому подтверждение. Даже профессионалов выдает излишняя наглость: www.youtube.com/watch?v=vh1EfnOJ2tE
                                                              0
                                                              «умея играть читы становятся не нужны»

                                                              Многие игроки тщеславны/честолюбивы, и они хотят быть на первом месте во что бы то ни стало. И если реально они играют не лучше всех, то они как раз будут играть с читами, повышая свои шансы.

                                                              Так же замечено, что в админы игрового сервера часто идут игроки ради того что бы можно было безнаказанно юзать читы. Хотя можно было бы подумать, что админ-игрок лучше бы следил за честностью игры… не тут-то было!
                                                              +1
                                                              Были у меня дешевые наушники в детстве, шум в которых в паре сантиметров влево или вправо от прицела слишком сильно повышал громкость в соответствующем ухе. Эту ошибку я использовал в полной мере и стрелял по стенам не жалея патронов. А уж админы меня за это не жалели :)
                                                                0
                                                                Wall Hack неплохо выявляется модераторами, если последить пару раундов за игроком. Обычно сразу видно как игрок иногда посматривает в стенку :)Тех, кто включил читы и не выдает себя очень мало.
                                                                0
                                                                Вы видать просто не стали всю это портянку просматривать.

                                                                GetFov( VoidCSS.g_pMyPlayer->BaseEnt()->GetAbsAngles(), VoidCSS.g_pMyPlayer->BaseEnt()->EyePosition(), vPlayer ) > fov
                                                                

                                                                Ну а стиль игры игрок сам выбирает, опытный читер долго может прятаться :(
                                                                +6
                                                                Вышел из CS, перед сном решил на Хабр зайти… простите меня, но я НЕНАВИЖУ читеров!!! Всей душой!!!
                                                                И самое для меня загадочное — зачем?! Зачем играть с читами? Ведь это как в NFS играть и всем говорить, что у меня стаж за рулём 10 лет, сотни аварий и ни одного штрафа — от этого никакого реального опыта и ни какого скилла. Простите за эмоции.
                                                                  +1
                                                                  Не-на-ви-жу… да-да.
                                                                  • UFO just landed and posted this here
                                                                      0
                                                                      А ещё в КС трудно играть. То есть как бы всё просто, но разрыв между геймером зашедшим раз в неделю получить удовольствие и игроками которые играют постоянно, он слишком большой и мешает получению этого самого удовольствия. Не совсем казуальная игра.

                                                                      Я просто валю из игры (нет времени и желания восстанавливать скилл), а кто-то наверно читы включает…
                                                                        +3
                                                                        Вряд ли причина в этом. Человек, который когда-то играл много и помнит те чувства, не захочет включать читы, потому что ему это ничего не даст. Только если он всегда с читами играл.

                                                                        Я не раз в неделю — я раз в полгода захожу (в основном когда болею, а работа уже поперек горла). У меня не возникает желания искать читы. Мне интереснее зайти на сервера, на которых раньше играл. Увидеть там знакомые лица, пообщаться, поиграть. Мне интереснее наблюдать как за какие-то пару/тройку часов навыки возвращаются. Руки то помнят. Это вызывает какую-то детскую радость. Хотя понятно, что на прежний уровень так быстро не выйти, но и зачем? А читы этому тоже не помогут, так что бессмысленно.
                                                                          +1
                                                                          Еще сначала конкретно прёт после полугодового перерыва, а потом отпускает и понимаешь что восстанавливаться будешь очень долго и забиваешь.
                                                                    +1
                                                                    Я в Teeworlds делал аимботов для общего развития — разобраться с системой предсказаний и создать «непалящегося» аимбота (что мне в принципе удалось — можно было стрелять самому, но если кто-то рядом с линией огня находился, аимбот корректировал прицел и стрелял сам). Из некоторых аимботов в дальнейшем сделал полноценных ботов, они даже флаги таскать умели, было забавно :-) Даже устраивали матчи — команда людей против команды ботов (люди выигрывали за счет того, что боты бегали плохо и везде застревали :-)).
                                                                      –3
                                                                      А мне нравится иногда заходить на сервера и тролить, что бы отцы срали кирпичами и кричали как они ненавидят читеров, так забавно, особенное если включен тимспик. Правда я играю без читов, и не в CS, а в TF2 или TeeWorlds, в первом классно инженером или медиком бесить. А во втором можно с флаг долго не ставить или крюком своих скидывать в ямы «как бы случайно» (=
                                                                        +2
                                                                        Really BAD BOY
                                                                          –3
                                                                          А то, даже в карму срать начали.
                                                                      0
                                                                      FindPattern это функция Microsoft Detours? Любопытный метод поиска vtable.
                                                                        0
                                                                        нет, это довольно распространенная функция:

                                                                        DWORD FindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)
                                                                        {
                                                                            for(DWORD i=0; i < dwLen; i++)
                                                                                if( bCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
                                                                                    return (DWORD)(dwAddress+i);
                                                                        
                                                                            return 0;
                                                                        } 
                                                                        
                                                                          0
                                                                          И как, надежно действует, или от версии либы к версии приходится менять шаблон?
                                                                            0
                                                                            Использую что-то подобное для одного достаточно часто (раз в две недели) обновляемого приложения. Шаблон менять не надо, проблемы, в основном, возникают со структурами данных. То vftable поменялся, добавили функцию. То поле добавили, такое, в общем. Код меняется редко. Хотя, конечно, это зависит от того какие разработчики вносят изменения. Еще очень помогает в автоматическом поиске дизассемблерный движок, чтобы пройтись по коду от места которое можно однозначно найти.
                                                                              0
                                                                              *какие изменения вносят разработчики
                                                                      • UFO just landed and posted this here
                                                                          0
                                                                          Примерно так же, как и с искусственным интеллектом, т.е. далеко от идеала, а в FPS еще и бесполезно. Тут мобов фармить и экспу качать не нужно, так что практической пользы от них нет.
                                                                          +2
                                                                          Насчет отсутствия бана в VAC я бы не был так уверен. Стим он хитрый, может месяцами давать возможность играть с читами, а потом бац и вечный бан.
                                                                            0
                                                                            две недели. И вроде как банится только одна игра, т.е где читерил. Остальные игры на аккаунте останутся доступны.
                                                                              0
                                                                              При бане аккаунта в VAC, то нельзя зайти на сервера с его поддержкой. А это как минимум все сорсовые игры, контра, кал оф дьюти и что-то еще.

                                                                              Время специально не зафиксировано, чтобы создатели читов не могли связать бан с использованием конкретного чита.

                                                                              У меня как-то аккаунт забанили за покупку не из своего региона, так они 3 месяца ждали.
                                                                            0
                                                                            А как VAC работает, не просветите? Хочу одной старой игрушке свой античит написать, не знаю с чего начать. Те же проблемы — аимбот, воллхак… (
                                                                              0
                                                                              Сигнатуры и никакой эвристики.
                                                                                0
                                                                                Не знаю как точно работает VAC, но там точно идет проверка файлов игры на внесение изменений.
                                                                                punkbuster периодически делает скриншоты экрана игрока и сопоставляет с чистым. Правда там свои косяки бывают, когда видеокарта выдает артефакты.
                                                                                  0
                                                                                  >>но там точно идет проверка файлов игры на внесение изменений.
                                                                                  Это делает сам клиент при подключении, при ConVar sv_pure 2, как я помню
                                                                                    0
                                                                                    При sv_pure 1 тоже ведётся проверка данных, но список проверяемых файлов определяет сервер.
                                                                                0
                                                                                myAC блокирует инъекцию кода в процесс hl2.exe. Лучший античит, имхо.
                                                                                  +1
                                                                                  Античиты палят все подобные программы благодаря примитивным методам внедрения и нехилой системе перехватов. Вместо WriteProcessMemory (ее палят из за перехвата Zw* функции, а некоторые античиты ставят свой драйвер в систему и замещают ssdt) надо использовать хуки основанные на KeInsertQueueApc прочие(смотрите poc stuxnet'а). Так же стоит выпилить всю систему хуков (снять и восстановить) античита

                                                                                  Only users with full accounts can post comments. Log in, please.