R G T X
14.06.2019, 21:26
Привет, сегодня мы создадим наш первый External-чит для ксго. Создавать мы будем вх, так как вх - идеален, чтобы рассматривать его как основу. Я постараюсь расписать все максимально понятно и по шагам, чтобы вы поняли как что работает, а не просто спастили код и ничему не научились.
Итак, приступим.
1. Создаем простой C++ проект в Visual Studio.
2. Создаем файл main.cpp, здесь и будет весь наш код.
3. Пишем в начало файла следующий код:
C++:
#include
#include
#include
#include
здесь мы подключили нужные библиотеки для работы, если у вас какой-то нет, то скачайте или подключите через параметры проекта (можете посмотреть в интернете уроки, если не знаете, как это делать, их полно).
4. Теперь самое время сделать переменные с оффсетами. Почему именно переменные? Да потому что их легко обновлять, и не нужно лазить по всему коду и вспоминать, какой оффсет для чего и где.
C++:
const
DWORD dwLocalPlayer
=
0xCBD6A4
;
const
DWORD dwEntityList
=
0x4CCDCBC
;
const
DWORD m_iTeamNum
=
0xF4
;
const
DWORD m_iGlowIndex
=
0xA3F8
;
const
DWORD dwGlowObjectManager
=
0x520DAE0
;
разберем каждое ключевое слово в коде:
const - мы делаем именно константы (не переменные), чтобы им нельзя было присвоить другие значения, кроме тех, которые мы уже задали.
DWORD - класс. Переменные имеют тип экземляра именно класса DWORD.
5. Сейчас мы определим переменные, с которыми мы будем работать на протяжении всего написания чита.
C++:
HANDLE process
;
// непосредственно сам процесс CSGO
DWORD clientBase
;
// клиентская часть
DWORD engineBase
;
// игровая часть (движок)
Мы объявили необходимые переменные, комментарии, обозначающие "что зачем и почему" я написал в самом коде.
6. Что же, теперь приступим к написанию нашего чита непосредственно.
Первое, что нам нужно - это возможность включать или выключать те или иные функции (в нашем случае - вх).
Если вы подумали о переменной типа boolean, определяющей статус функции - вы правы.
C++:
bool
wh
=
false
;
Мы объявили переменную, которая определяет статус функции, по умолчание вх выключено, значит значение переменной false.
7. Так как мы создаем External-чит, нам нужно читать память и изменять ее.
Добавим следующий код, необходимый нашему читу. Что и зачем расскажу по ходу дела.
C++:
DWORD
getModuleBaseAddress
(
DWORD pid
,
const
char
*
name
)
{
HANDLE snapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
,
pid
)
;
MODULEENTRY32 mEntry
;
mEntry
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
do
{
if
(
!
strcmp
(
mEntry
.
szModule
,
name
)
)
{
CloseHandle
(
snapshot
)
;
return
(
DWORD
)
mEntry
.
modBaseAddr
;
}
}
while
(
Module32Next
(
snapshot
,
&
mEntry
)
)
;
}
данный код находит в нашей оперативной памяти именно то приложение, которое нам нужно (по его id - pid, который передается функции).
C++:
template
T
readMem
(
DWORD address
)
{
T buffer
;
ReadProcessMemory
(
process
,
(
LPVOID
)
address
,
&
buffer
,
sizeof
(
buffer
)
,
0
)
;
return
buffer
;
}
template
void
writeMem
(
DWORD address
,
T value
)
{
WriteProcessMemory
(
process
,
(
LPVOID
)
address
,
&
value
,
sizeof
(
value
)
,
0
)
;
}
эти стандартные функции читают и пишут память, именно с помощью них мы будем взаимодействовать с игрой.
8. Теперь создадим входную точку, без которой не будет работать ни одно приложение C++. Это int main().
C++:
SetConsoleTitle
(
"Top non-pasted shit 1337"
)
;
// устанавливаем заголовок нашей консоли
std
::
cout
9. Теперь пора создать сам вх. Создадим метод (пусть будет wallhack())
C++:
[CODE]
Void
wallhack
(
)
{
while
(
true
)
// создаем бесконечный цикл
{
Sleep
(
10
)
;
// таймаут 10 мс, чтобы не грузить процессор под 100
if
(
!
wallhack
&&
!
readMem
(
readMem
(
clientBase
+
dwLocalPlayer
)
+
0xED
)
)
// если вх выключено или не удается прочитать память - выходим из цикла
continue
;
DWORD glowObj
=
readMem
(
clientBase
+
dwGlowObjectManager
)
;
// создаем объект glowObj из модельки игрока
DWORD myTeam
=
readMem
(
readMem
(
clientBase
+
dwLocalPlayer
)
+
m_iTeamNum
)
;
// создаем объект тиммейтов
for
(
int
x
=
0
;
x
(
clientBase
+
dwEntityList
+
x
*
0x10
)
;
// обычный игрок
if
(
player
==
0
)
continue
;
bool
dormant
=
readMem
(
player
+
0xED
)
;
// спектатор
if
(
dormant
)
continue
;
DWORD team
=
readMem
(
player
+
m_iTeamNum
)
;
// тиммейт
if
(
team
!=
2
&&
team
!=
3
)
continue
;
DWORD currentGlowIndex
=
readMem
(
player
+
m_iGlowIndex
)
;
// текущий индекс игрока
if
(
team
!=
myTeam
)
// если игрок не тиммейт
{
// делаем его обводку красным
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x4
,
255
)
;
// red
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x8
,
0
)
;
// green
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0xC
,
0
)
;
// blue
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x10
,
255
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x24
,
true
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x25
,
false
)
;
}
else
// если игрок тиммейт
{
// делаем его обводку синим
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x4
,
0
)
;
// red
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x8
,
0
)
;
// green
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0xC
,
255
)
;
// blue
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x10
,
255
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x24
,
true
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x25
,
false
)
;
}
}
}
}
10. Теперь нам нужно где-то вызывать наш метод. Конечно же в main()!
Теперь вызовем наш метод:
std::thread whThread(wallhack)
И создадим в нашем главном методе бесконечный цикл.
C++:
while
(
true
)
{
if
(
GetAsyncKeyState
(
VK_F9
)
)
// если нажали f9
{
wh
=
!
wh
;
// заменяем значение переменной на противоположное
if
(
wh
)
std
::
cout
(
"wh: on\n"
)
;
// если wallhack - true, то пишем, что вх включен
else
std
::
cout
(
"wh: off\n"
)
;
// иначе пишем, что вх выключен
Sleep
(
100
)
;
// таймаут, чтобы сбросить нагрузку
}
}
На этом все,тема будет дополнятся.
Итак, приступим.
1. Создаем простой C++ проект в Visual Studio.
2. Создаем файл main.cpp, здесь и будет весь наш код.
3. Пишем в начало файла следующий код:
C++:
#include
#include
#include
#include
здесь мы подключили нужные библиотеки для работы, если у вас какой-то нет, то скачайте или подключите через параметры проекта (можете посмотреть в интернете уроки, если не знаете, как это делать, их полно).
4. Теперь самое время сделать переменные с оффсетами. Почему именно переменные? Да потому что их легко обновлять, и не нужно лазить по всему коду и вспоминать, какой оффсет для чего и где.
C++:
const
DWORD dwLocalPlayer
=
0xCBD6A4
;
const
DWORD dwEntityList
=
0x4CCDCBC
;
const
DWORD m_iTeamNum
=
0xF4
;
const
DWORD m_iGlowIndex
=
0xA3F8
;
const
DWORD dwGlowObjectManager
=
0x520DAE0
;
разберем каждое ключевое слово в коде:
const - мы делаем именно константы (не переменные), чтобы им нельзя было присвоить другие значения, кроме тех, которые мы уже задали.
DWORD - класс. Переменные имеют тип экземляра именно класса DWORD.
5. Сейчас мы определим переменные, с которыми мы будем работать на протяжении всего написания чита.
C++:
HANDLE process
;
// непосредственно сам процесс CSGO
DWORD clientBase
;
// клиентская часть
DWORD engineBase
;
// игровая часть (движок)
Мы объявили необходимые переменные, комментарии, обозначающие "что зачем и почему" я написал в самом коде.
6. Что же, теперь приступим к написанию нашего чита непосредственно.
Первое, что нам нужно - это возможность включать или выключать те или иные функции (в нашем случае - вх).
Если вы подумали о переменной типа boolean, определяющей статус функции - вы правы.
C++:
bool
wh
=
false
;
Мы объявили переменную, которая определяет статус функции, по умолчание вх выключено, значит значение переменной false.
7. Так как мы создаем External-чит, нам нужно читать память и изменять ее.
Добавим следующий код, необходимый нашему читу. Что и зачем расскажу по ходу дела.
C++:
DWORD
getModuleBaseAddress
(
DWORD pid
,
const
char
*
name
)
{
HANDLE snapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
,
pid
)
;
MODULEENTRY32 mEntry
;
mEntry
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
do
{
if
(
!
strcmp
(
mEntry
.
szModule
,
name
)
)
{
CloseHandle
(
snapshot
)
;
return
(
DWORD
)
mEntry
.
modBaseAddr
;
}
}
while
(
Module32Next
(
snapshot
,
&
mEntry
)
)
;
}
данный код находит в нашей оперативной памяти именно то приложение, которое нам нужно (по его id - pid, который передается функции).
C++:
template
T
readMem
(
DWORD address
)
{
T buffer
;
ReadProcessMemory
(
process
,
(
LPVOID
)
address
,
&
buffer
,
sizeof
(
buffer
)
,
0
)
;
return
buffer
;
}
template
void
writeMem
(
DWORD address
,
T value
)
{
WriteProcessMemory
(
process
,
(
LPVOID
)
address
,
&
value
,
sizeof
(
value
)
,
0
)
;
}
эти стандартные функции читают и пишут память, именно с помощью них мы будем взаимодействовать с игрой.
8. Теперь создадим входную точку, без которой не будет работать ни одно приложение C++. Это int main().
C++:
SetConsoleTitle
(
"Top non-pasted shit 1337"
)
;
// устанавливаем заголовок нашей консоли
std
::
cout
9. Теперь пора создать сам вх. Создадим метод (пусть будет wallhack())
C++:
[CODE]
Void
wallhack
(
)
{
while
(
true
)
// создаем бесконечный цикл
{
Sleep
(
10
)
;
// таймаут 10 мс, чтобы не грузить процессор под 100
if
(
!
wallhack
&&
!
readMem
(
readMem
(
clientBase
+
dwLocalPlayer
)
+
0xED
)
)
// если вх выключено или не удается прочитать память - выходим из цикла
continue
;
DWORD glowObj
=
readMem
(
clientBase
+
dwGlowObjectManager
)
;
// создаем объект glowObj из модельки игрока
DWORD myTeam
=
readMem
(
readMem
(
clientBase
+
dwLocalPlayer
)
+
m_iTeamNum
)
;
// создаем объект тиммейтов
for
(
int
x
=
0
;
x
(
clientBase
+
dwEntityList
+
x
*
0x10
)
;
// обычный игрок
if
(
player
==
0
)
continue
;
bool
dormant
=
readMem
(
player
+
0xED
)
;
// спектатор
if
(
dormant
)
continue
;
DWORD team
=
readMem
(
player
+
m_iTeamNum
)
;
// тиммейт
if
(
team
!=
2
&&
team
!=
3
)
continue
;
DWORD currentGlowIndex
=
readMem
(
player
+
m_iGlowIndex
)
;
// текущий индекс игрока
if
(
team
!=
myTeam
)
// если игрок не тиммейт
{
// делаем его обводку красным
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x4
,
255
)
;
// red
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x8
,
0
)
;
// green
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0xC
,
0
)
;
// blue
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x10
,
255
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x24
,
true
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x25
,
false
)
;
}
else
// если игрок тиммейт
{
// делаем его обводку синим
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x4
,
0
)
;
// red
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x8
,
0
)
;
// green
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0xC
,
255
)
;
// blue
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x10
,
255
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x24
,
true
)
;
writeMem
(
glowObj
+
currentGlowIndex
*
0x38
+
0x25
,
false
)
;
}
}
}
}
10. Теперь нам нужно где-то вызывать наш метод. Конечно же в main()!
Теперь вызовем наш метод:
std::thread whThread(wallhack)
И создадим в нашем главном методе бесконечный цикл.
C++:
while
(
true
)
{
if
(
GetAsyncKeyState
(
VK_F9
)
)
// если нажали f9
{
wh
=
!
wh
;
// заменяем значение переменной на противоположное
if
(
wh
)
std
::
cout
(
"wh: on\n"
)
;
// если wallhack - true, то пишем, что вх включен
else
std
::
cout
(
"wh: off\n"
)
;
// иначе пишем, что вх выключен
Sleep
(
100
)
;
// таймаут, чтобы сбросить нагрузку
}
}
На этом все,тема будет дополнятся.