PDA

Просмотр полной версии : [Руководство] Руководство по написанию чит программ. Часть 1 by Тигрь!


Тигрь
07.05.2009, 06:05
Руководство по написанию чит программ. Часть 1
by Тигрь!
Данное руководство я решил написать для ознакомительных целей, так как большинство людей пользуются такими программами, но мало кто из них знает, как они устроены и по какому принципу работают.

Так как руководство основано на опытных пользователей, то необходимы некоторые знания:

• Знание языков программирования (примеры будут написаны на Delphi и C++ Builder), но в принципе если вы хорошо знаете другой язык программирования то вам не составит труда перенести код на него
• Умение пользоваться программами на подобии ArtMoney(знать что такое указатели, разбираться в адресации памяти и т.д)
• Знать что такое шестнадцатеричная система счисления, уметь переводить числа из десятичной в шестнадцатеричную и обратно

Но думаю и новички, почерпнут из нее много нового и интересного, а так же приобретут желание к изучению материала и повышению своих знаний.

Итак, начнем. Немного теории:

Чит программы – это программы которые позволяют автоматизировать использование того или иного бага. Как известно баги бывают как минимум пяти видов пакетные(использование TCP/IP пакетов для отправки на сервер или клиент модифицированных данных), memory баги(модификация значений в памяти игрового клиента), файловые(модификация файлов игрового клиента), текстурные (проход сквозь текстуры и т.д) и баги игрового клиента(ошибки в игровом клиенте, приводящие к выполнению действие не задуманных разработчиками) а так же различные их комбинации. В чит программах используются первые три вида, остальные два используются посредством самого игрового клиента без каких либо дополнительных программ.

Вообще тема написания чит программ довольно обширна, поэтому данное руководство разделено на несколько частей. Сегодня я остановлюсь на написании чит программ использующих memory баги. Как было сказано выше, memory баги модифицируют значения в памяти игрового клиента. На их основе реализованы такие известные баги как “ChatHack”, “WallHack”, “SpeedHack”, “FlyHack” и другие (прим. Так же возможна реализация этих багов на пакетном уровне).

Практически все современные игры используют DMA. DMA - - dynamic memory allocation (динамическое распределение памяти). Иными словами DMA игры хранят значения в памяти по адресам, которые изменяются после каждого запуска, перезапуска, загрузки сохранения, перехода в другую локацию или уровень и т.д. С этим многие сталкивались когда “ломали” не онлайн игры на “на деньги” например с помощью ArtMoney и после приведенных выше действий таблицы со “взломами” переставали работать. Но с этим легко бороться, достаточно лишь один раз найти указатель на нужный нам адрес. Указатель - это адрес, в котором содержится адрес на интересующее нас значение. Адреса же указателей не изменяются в отличие от остальных. Так же не меняются смещения других адресов относительно адреса, на который указывает указатель. Таким образом, для написания чит программы нам нужно считать из указателя адрес, а потом по этому адресу модифицировать значение.

Перейдем к практике:

Рассмотрим написание чит программы на примере всем известного “SpeedHack”.

Как использовать “SpeedHack” через ArtMoney я расскажу вкратце так это руководство не по поиску багов а по написанию программ с их применением. Дам несколько советов по поиску значения скорости, так как в игре скорость является дробью, то тип значения выбираем с точкой. Размерность выбираем 4 байта, так как большинство значений в современных играх 4-х байтные (за некоторым исключением). Указав такие условия поиска, мы значительно его сократим. Затем устанавливаем значение поиска равное значению в игре, выполняем поиск. Заходим в игру, одеваем оружие на бег и отсеиваем новое значение. И так пока не останется одно значение. Добавляем его в таблицу и видим адрес этого значения в памяти (для использования “SpeedHack’а”, нужно установить желаемое значение и “заморозить” его). Допустим оно у нас равно 0134EA80. Но так ига использует DMA, просто адрес нас не устроит, так как при следующем входе в игру он изменится. Поэтому мы будем искать указатель на этот адрес, который как говорилось выше не изменяется. Как искать указатели я тут рассказывать тоже не буду, так как статья не об этом (читайте руководство пользователя ArtMoney). После поиска указателя он оказался равным 00D1B4F0 а смешение адреса в котором находится значение скорости равно 2356. Важно отметить, что указатель в ArtMoney указывается в шестнадцатеричной системе счисления, а смещение в десятичной. Ну да ладно, что же нам теперь делать с найденными значениями. А вот теперь-то мы и будем писать программу, которая по этим значениям будет модифицировать память игрового клиента.

Создадим новый проект в Delphi и разместим на форме элементы: Label, SpinEdit, Button, Timer всех по одному. Label будет содержать просто информацию, в SpinEdit будем задавать желаемое значение скорости, Timer будет осуществлять функцию “заморозки” (каждые 100 миллисекунд он будет обновлять наше значение), Button будет активировать/деактивировать Timer(“SpeedHack”).
Для работы с памятью игры мы будем использовать следующие API функции Windows:


function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL;

function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL;

function FindWindow(lpClassName, lpWindowName: PAnsiChar): HWND; stdcall;

function GetWindowThreadProcessId(hWnd: HWND; lpdwProcessId: Pointer): DWORD; stdcall;

function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle;

function CloseHandle(hObject: THandle): BOOL;


Подробное описание функций и значения их параметров я приводить не буду, кого заинтересует, могут посмотреть MSDN.
Основными функциями записи и чтения из памяти являются: ReadProcessMemory и WriteProcessMemory.
Ну вот собственно исходный код таймера который изменяет значение по найденному выше указателю:


procedure TForm1.Timer1Timer(Sender: TObject);
var
speed : single; //Это значение скорости
hWin: hWnd;
ProcId: Cardinal;
hProc: THandle;
NBW: Cardinal;
Adress: dword; //сюда прочитаем адрес из указателя.
readwrite: cardinal;

begin
hWin := FindWindow(nil, WindowTitle);

if hWin = 0 then begin
Timer1.Enabled := False;
Button1.Caption := 'Включить SpeedHack';
exit;
end; //Проверяем запущена ли игра если нет то выключаем "SpeedHack"

speed := SpinEdit1.Value;


GetWindowThreadProcessId(hWin, @ProcId);
hProc := OpenProcess(Process_All_Access, False, ProcId);
ReadProcessMemory(hProc, ptr($00D1B4F0), @Adress, 4, readwrite); //Читаем адрес из указателя
Adress := Adress + 2356; //Прибавляем к адресу смещение нашего значения

WriteProcessMemory(hProc, ptr(Adress), @speed, 4, NBW); //Записываем желаемое значение по полученному адресу
CloseHandle(hProc);
end;


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

Полные исходники качаем отсюда:
Delphi: [Ссылки могут видеть только зарегистрированные и активированные пользователи]
C++ Builder: [Ссылки могут видеть только зарегистрированные и активированные пользователи]
C++ Builder and Delphi одним архивом ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

Не забываем оставлять комментарии по поводу статьи. Так же задавать вопросы, если они возникли. Постараюсь ответить всем.

Авторские права и условия распространения материала:
Автором материала является Тигрь, то бишь я. Статья может распространяться свободно но без каких либо изменений, с обязательным указанием моего авторства, и с приведенными выше ссылками на исходные коды программ.

doit2night
19.06.2009, 19:33
ПРив
Посидев за компом окло 2 часов и съев весь пакет фисташек, я таки нашел то, что хотел. А точнее исходник Волл Хака...

Сразу говорю, ничего сверх магического не нашел (хотя бубен юзал и не раз).
На самом деле необходимо только прочитать/записать 3 значения из памяти (Х Y Z). Так как игру делали Корейцы (Корейский Рандом Самый Рандомный рандом в мире!), то в памяти координаты лежать не привычно для нас, а именно Х Z Y.

Читал значения так:

var
Wnd: HWND; // Handle Окна
ProcessId, hProcess, BitesRead: Cardinal; // ИД процесса, Handle Процесса, БайтПрочитано
Buffer: Single; // Считывать будем в эту переменную (Single - 4ех байтный тип)
begin
{ ПРОЦЕСС}
// находим окошко
Wnd := FindWindow(nil, 'RF Online');
// Находим поток процесса
GetWindowThreadProcessId(wnd, @ProcessId);
// находим процесс
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);

{ ЧТЕНИЕ }
// читаем кординату Х
ReadProcessMemory(hProcess, Pointer($02C216B0), @Buffer, 4, BitesRead);
edtX.Text := FloatToStr(Buffer); // выводим или запоминем ее

// координата Y
ReadProcessMemory(hProcess, Pointer($02C216B8), @Buffer, 4, BitesRead);
edtY.Text := FloatToStr(Buffer);

// а сдесь Z
ReadProcessMemory(hProcess, Pointer($02C216B4), @Buffer, 4, BitesRead);
edtZ.Text := FloatToStr(Buffer);

// освобождаем память
CloseHandle(hProcess);
end;

Записываются значения на место аналогично:

var
Wnd: HWND; // читай выше
ProcessId, hProcess, BitesRead: Cardinal;
Buffer: Single;
begin
{ ПРОЦЕСС }
Wnd := FindWindow(nil, 'RF Online');

GetWindowThreadProcessId(wnd, @ProcessId);

hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);

{ ЗАПИСЬ }
// загоняем в переменную измененное знаечение кординаты Х
Buffer := StrToFloat(edtX.Text);
// пишем в память
WriteProcessMemory(hProcess, Pointer($02C216B0), @Buffer, 4, BitesRead);

// координата Y
Buffer := StrToFloat(edtY.Text);
WriteProcessMemory(hProcess, Pointer($02C216B8), @Buffer, 4, BitesRead);

// Z
Buffer := StrToFloat(edtZ.Text);
WriteProcessMemory(hProcess, Pointer($02C216B4), @Buffer, 4, BitesRead);

CloseHandle(hProcess);
end;
для ап5:confused:
автор дрож. все (с) ему)

ZliLO
19.06.2009, 22:24
Перейдем к практике:

Рассмотрим написание чит программы на примере всем известного “SpeedHack”.

Как использовать “SpeedHack” через ArtMoney я расскажу вкратце так это руководство не по поиску багов а по написанию программ с их применением. Дам несколько советов по поиску значения скорости, так как в игре скорость является дробью, то тип значения выбираем с точкой. Размерность выбираем 4 байта, так как большинство значений в современных играх 4-х байтные (за некоторым исключением). Указав такие условия поиска, мы значительно его сократим. Затем устанавливаем значение поиска равное значению в игре, выполняем поиск. Заходим в игру, одеваем оружие на бег и отсеиваем новое значение. И так пока не останется одно значение. Добавляем его в таблицу и видим адрес этого значения в памяти (для использования “SpeedHack’а”, нужно установить желаемое значение и “заморозить” его). Допустим оно у нас равно 0134EA80. Но так ига использует DMA

Leo_ня
11.07.2009, 20:53
-
Leo_ня (00:17:35 12/07/2009)
где-то читал, что WriteProcessMemory и ReadProcessMemory замедляют поиск в артмани и CE подобных прогах... А чем заменить можно?

-
Ivan_32 (00:18:02 12/07/2009)
Да это и вправду медленный способ. А заменить можно зондом)

-
Leo_ня (00:18:12 12/07/2009)
а что это?)

-
Ivan_32 (00:18:29 12/07/2009)
Зонд - DLL библиотека которой будешь передавать команды/сообщения а она там будет уже искать то что тебе нужно)

-
Leo_ня (00:19:05 12/07/2009)
библиотека, подключаемая к памяти программы? т.е. она ищет уже в своей памяти?

-
Ivan_32 (00:19:34 12/07/2009)
да можно и так сказать)

-
Leo_ня (00:19:38 12/07/2009)
))

-
Leo_ня (00:19:49 12/07/2009)
точнее не читал

-
Leo_ня (00:20:20 12/07/2009)
в CE есть опция:
Read/Write Process Memory (Will cause slower scans)

-
Ivan_32 (00:21:33 12/07/2009)
Хм, разве что еще есть вариант с драйвером который бы это делал)
.

Kill1005
08.05.2011, 19:40
Исходник на c++ скиньте плз..
А то тот удален :(
А читы до этого не когда не писал...

Тигрь
08.05.2011, 20:35
давненько это было. если найду то выложу.

maslo2011
10.03.2012, 09:33
А можно файлы презалить)

Тигрь
15.03.2012, 07:56
Держи C++ Builder and Delphi одним архивом ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

den57
03.05.2013, 21:17
Не понятно, как найти адрес, указатель, и смещение. Плиз подкиньте литературы, только не на 300 страниц где автор льет воду, а типа этой статьи

Тигрь
04.05.2013, 20:19
Открываешь справку к артмани, там все прекрасно подробно написано.

-Emp-
03.07.2013, 17:47
Это же извращение - все это в таймер засунуть с интервалом в 100 мсек.

Tr0y
07.07.2013, 08:39
Это же извращение - все это в таймер засунуть с интервалом в 100 мсек.

предлагаешь проверку значения на изменение адреса так сделать? :
while i=1 do
begin
end;

делал так и в потоки толкал, в итоге 90% времени процессора впустую уходит как не крути на эти бестолковые проверки, таймер мне кажется самым оптимальным выбором. В СЕ заморозка ячеек тоже через таймер реализована =)

Тут критично кол-во чтения значений из памяти в одной процедуре, это можно минимизировать различными дополнительными IFами.

Хотя отчасти согласен, что вот эту часть в таймере от тигра:
hWin := FindWindow(nil, WindowTitle);

if hWin = 0 then begin
Timer1.Enabled := False;
Button1.Caption := 'Включить SpeedHack';
exit;
end; //Проверяем запущена ли игра если нет то выключаем "SpeedHack"

speed := SpinEdit1.Value;


GetWindowThreadProcessId(hWin, @ProcId);
hProc := OpenProcess(Process_All_Access, False, ProcId);
...Если надо читать/менять часто адрес, то эту часть я бы вывел в отдельную функцию, т.к. фактически таймер снова и снова будет искать одно и то же окно мног много раз... А так в целом код оптимальный помоему.:confused:

VeTaL_UA
07.07.2013, 09:49
предлагаешь проверку значения на изменение адреса так сделать?
надо чтобы клиент игры сам говорил, что у него изменилось нужное значение :)

Tr0y
07.07.2013, 12:40
надо чтобы клиент игры сам говорил, что у него изменилось нужное значение :)
dll и хукать? Просто интересно стало :pandal: но чтото мне подсказывает, что винда такими сообщшениями не оперирует, хз даж

это ([Ссылки могут видеть только зарегистрированные и активированные пользователи])?

Тигрь
07.07.2013, 14:58
Да это же всего пример как работать с апи для записи в память. И как сказал трой бесконечные циклы будут грузить проц на 100% и это вообще не вариант, а для того чтоб игра сама говорила когда меняется память, нужно к игре цеплять самописный отладчик, который будет ставить бряки на изменение памяти, но это не для новичков. Да и писал я это черт знает в каком году, когда только постигал азы читонаписания, сейчас реализую это все по другому.
P.S. Кстати, -Emp-, в место того чтоб флудить ты бы лучше написал правильную реализацию заморозки значений, чтоб новички знали как нужно делать.

-Emp-
09.07.2013, 08:45
Хотя отчасти согласен, что вот эту часть в таймере от тигра:
hWin := FindWindow(nil, WindowTitle);

if hWin = 0 then begin
Timer1.Enabled := False;
Button1.Caption := 'Включить SpeedHack';
exit;
end; //Проверяем запущена ли игра если нет то выключаем "SpeedHack"

speed := SpinEdit1.Value;


GetWindowThreadProcessId(hWin, @ProcId);
hProc := OpenProcess(Process_All_Access, False, ProcId);
...Если надо читать/менять часто адрес, то эту часть я бы вывел в отдельную функцию, т.к. фактически таймер снова и снова будет искать одно и то же окно мног много раз... А так в целом код оптимальный помоему.:confused:

Я это и имел ввиду. И ещё постоянное объявление переменных.

sm0keb0ng
09.07.2013, 20:27
У меня вопросик, с чего начать писать софт к примеру стилеры, с самых так сказать основ, сам в этом 0, желание имеется, подскажите пжл:bow:

Тигрь
09.07.2013, 20:38
У меня вопросик, с чего начать писать софт к примеру стилеры, с самых так сказать основ, сам в этом 0, желание имеется, подскажите пжл:bow:

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