• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья [0x9]Легкий Геймхакинг: Шаг за шагом.

Unseen

(L3) cache
Пользователь
Регистрация
17.01.2022
Сообщения
262
Реакции
246
Автор: Unseen
Специально для xss.pro


Предыдущая часть:
https://xss.pro/threads/114098/

Вступление…
Доброго времени суток дорогие форумчане! Давно не было новых частей в нашем цикле статей из-за нехватки времени. Перед новым годом как раз появилось свободное время и я решил заполнить этот пробел! Поехали =)

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

Теоретическая часть …
Ну как вы могли догадаться по самому переводу слова «Internal» - внутренний, говорит само за себя, это когда программа(чит) загружается в саму игру, в ее процесс – виртуальное адресное пространство. Чаще всего Internal представляет собой файл DLL ( в виде динамической библиотеки). Но файлы DLL не могут быть запущены сами по себе - как программы .exe, на то и они динамически подключаемые. Их нужно как-то загрузить в адресное пространство процесса для доступа к их внутреннему функционалу и коду. А если более подробно рассмотреть:
DLL (Dynamic-Link Library) (<-ТЫК) — это динамическая библиотека, которая предоставляет набор функций и ресурсов, доступных для использования другими программами. Она позволяет разделить функциональность на модули и использовать её повторно в разных приложениях. Даже мы когда используем, какие-то функции из WinAPI фактически загружаем такие DLL в виртуальное адресное пространство своего процесса. Когда программа взаимодействует с ОС, она часто вызывает функции, реализованные в этих библиотеках.

Например:
kernel32.dll
предоставляет функции для работы с процессами, потоками и памятью. Допустим те же: WriteProcessMemory, ReadProcessMemory, все они находятся в этом файле DLL.

В отличие от External( внешних) читов, которые функционируют независимо от игры и обычно взаимодействуют с ней через внешние программы или модификации, Internal(внутренние) читы загружаются в виртуальное адресное пространство процесса игры и работают изнутри, как часть этого процесса. Мы получаем прямой доступ к внутренней памяти игры, функциям, разным структурам, объектам этого процесса.

Что дает такой способ? Какие преимущества и недостатки?

Преимущества и отличия от External:
  • Доступ к внутренним функциям: Возможность напрямую вызывать функции игры и использовать её ресурсы (например, рендерить на экране, изменять физику, изменять эти сами функции, ставить хуки).
  • Скорость: Работа с памятью и данными происходит быстрее, так как код выполняется внутри процесса. Нам не нужно постоянно извне через WinAPI делать запрос к процессу игры, для чтения или записи данных из памяти как с External. Вместо этого мы можем напрямую обращаться к памяти. Это очень эффективно и скорость работы будет очень отличаться.
  • Широкий функционал: Можно интегрироваться в игровой движок для получения сложных функций, таких как ESP (показ скрытых объектов) или AIMBOT (автоприцеливание).
  • Обход античитов: При правильной реализации такие читы сложнее обнаружить, так как они не зависят от внешних API вроде ReadProcessMemory.
Недостатки:
  • Более сложная разработка, требующая знаний об архитектуре процесса игры и Windows API.
  • Высокий риск краша игры при ошибках в коде чита.
  • Нужен хороший инжектор для загрузки DLL в процесс, что может привлечь внимание античитов.
Ключевые отличия Internal и External читов:
1.png
Хочу добавить, что External обнаружить легче из юзермода, пока о читах в режиме драйвера не идет речи!
Но как же тогда загрузить наш Internal чит в адресное пространство процесса игры? В этом нам поможет такая техника как DLL-инъекция( DLL-injection )
При помощи DLL-инъекции мы можем заставить процесс игры загрузить наш чит в свою память. А программа, которая будет это делать называется инжектором.

Практическая часть…
В этом разделе статьи я предлагаю для начала исследовать использование динамических библиотек – DLL и понять их принцип работы. Будем придерживаться концепции от легкого к сложному. В дальнейшем понимание таких вещей облегчит изучение более сложных методов. А затем к концу статьи попробуем реализовать свой простой инжектор и провести первый инжект своего чита в процесс игры! Затем поговорим об других методах инжекции.

DLL (Dynamic Link Library) — это библиотеки, содержащие общие функции и данные, которые могут быть использованы несколькими приложениями одновременно. В отличие от исполняемых файлов EXE, DLL не могут запускать код самостоятельно. Вместо этого эти библиотеки загружаются другими программами для выполнения необходимых операций. Возьмем, к примеру, функцию ReadProcessMemory, которая экспортируется из библиотеки kernel32.dll. Если процесс хочет вызвать эту функцию, он должен сначала загрузить kernel32.dll в свое виртуальное адресное пространство, чтобы получить доступ к этой функции.

Есть и такие DLL, которые загружаются автоматически в каждый процесс, поскольку они содержат функции, без которых стабильная работа процесса невозможна. Например, библиотеки ntdll.dll, kernel32.dll и kernelbase.dll — это те, что обычно загружаются по умолчанию, так как они предоставляют базовые функциональные возможности для работы системы и приложений.

Давайте к примеру посмотрим, какие модули DLL загружены в процесс Steam:
2.png

В операционных системах Windows используется концепция системного базового адреса для загрузки некоторых DLL по одинаковому адресу в виртуальном адресном пространстве всех процессов на компьютере. Это позволяет оптимизировать использование памяти и повысить производительность системы. Например, библиотека kernel32.dll может загружаться на один и тот же базовый адрес (например, 0x76c30000) во всех процессах, которые её используют. В этом случае кодовая часть библиотеки будет общей для всех процессов, а данные — индивидуальными, так как каждый процесс будет работать со своими собственными данными в отдельном адресном пространстве. Давайте для примера сравним два процесса имеющие одинаковую разрядность (x86):
3.png

Как видим базовые адреса системных модулей kernel32.dll, ntdll.dll совпадает в обоих процессах.
В DLL можно указать функцию точки входа, которая будет выполняться при наступлении определённых событий, например, когда процесс загружает библиотеку. Эта функция позволяет выполнить необходимые действия при работе с DLL, такие как инициализация ресурсов или настройка состояния.

Существует четыре основных момента, когда может быть вызвана функция точки входа:
  • Когда процесс загружает DLL в своё адресное пространство.
  • При создании нового потока в процессе.
  • Когда поток завершает свою работу (нормальный выход).
  • Когда процесс выгружает DLL из своей памяти.
Каждое из этих событий может инициировать выполнение кода, прописанного в точке входа, чтобы корректно обработать работу с библиотекой.

Создание DLL

Давайте теперь создадим свою первую программу в виде DLL. Откройте всеми любимую IDE – Visual Studio, у меня 2022года выпуска. Далее «Создание проекта». Затем в окне выбора шаблонов – «Библиотека динамической компоновки (DLL)» или же ENG: Dynamic-Link Library (DLL). Далее даем название проекту, у меня к примеру xss_dll_inject. Далее у нас создается проект с файлом dllmain.cpp:
4.png

С таким содержимым:
5.png

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

Готовый фрагмент кода:
C++:
// dllmain.cpp : Определяет точку входа для приложения DLL.
#include "pch.h"
#include <stdio.h>
#include <Windows.h>

VOID MessageBoxHello() {

    MessageBoxA(NULL, "xss.pro Unseen 0x9", "DLL loaded...", MB_OK);

}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: { //Когда процесс загружает DLL в своё адресное пространство
        MessageBoxHello();
        break;
    }
    case DLL_THREAD_ATTACH:  //При создании нового потока в процессе.

    case DLL_THREAD_DETACH:  //Когда поток завершает свою работу (нормальный выход).

    case DLL_PROCESS_DETACH: //Когда процесс выгружает DLL из своей памяти.
        break;
    }
    return TRUE;
}

Здесь мы объявляем функцию MessageBoxLoad, и размещаем в ней код, который выводит диалоговое окно с неким содержимым. Затем размещаем вызов этой функции, как точку входа в блоке DLL_PROCESS_ATTACH, и теперь, когда наш DLL успешно будет загружена, будет вызвана эта функция. Теперь скомпилируйте наш проект нажатием F7. После компиляции в папке проекта у нас появится готовый файл DLL:
6.png
Загрузка DLL
Теперь предлагаю создать второй проект, в этой программе мы будем загружать наш готовый DLL в память своего процесса. Создайте новый проект, в шаблонах выберите «Пустой проект» , дайте логичное имя и «Создать». Затем кликнув в обозревателе решений по папке «Исходные файлы» ПКМ добавить элемент и файл main.c
7.png
Для загрузки других DLL в свой процесс снова пригодится WinAPI, а именно функция LoadLibraryA. Она предназначена для динамической загрузки библиотек DLL в адресное пространство вызывающего процесса, которым в данном случае является текущий процесс. Эта функция принимает в качестве входного параметра путь к DLL-файлу на диске и производит его загрузку. При успешной загрузке вызывается точка входа DLL, что соответствует событию DLL_PROCESS_ATTACH. Таким образом, если в DLL определена функция, например, MessageBoxLoad, она выполнится автоматически, и на экране появится диалоговое окно. Если функция выполнена успешно, возвращаемое значение представляет собой дескриптор модуля. Если функция не срабатывает, возвращаемое значение равно NULL. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError(). Давайте напишем код, который соответствует нашей задаче.

Синтаксис фукнции LoadLibraryA:
C:
HMODULE LoadLibraryA(
  [in] LPCSTR lpLibFileName
);
C:
#include <stdio.h>
#include <Windows.h>


int main() {
   
    /* dll_name - массив хранящий путь до нашего DLL */
    char dll_name[] = "C:\\Users\\Unseen\\source\\repos\\xss_dll_inject\\x64\\Debug\\xss_dll_inject.dll";
    printf("[+] Loading dll... \n");
    if (LoadLibraryA(dll_name) == NULL) {
        printf("[-] LoadLibrary Error! Code: %d\n", GetLastError());
        return -1;
    }
   
    printf("[+] Good! DLL loaded!\n");

    printf(" <<< PRESS ENTER - QUIT >>> \n");
    getchar();

    return 0;
}
P.S. Не забудьте вставить путь до вашего DLL в массив dll_name!

Как и ожидалось после выполнения кода, у нас загрузилась DLL в память нашего процесса и выполнилась функция MessageBoxLoad() из нашей DLL:
8.png

Но как это поможет нам при загрузке нашего чита в виде DLL в память процесса игры? Ведь функция LoadLibraryA загружает DLL в адресное пространство того процесса, который её вызывает. Однако наша цель — загрузить DLL в удалённый процесс, а не в локальный. Поэтому прямой вызов LoadLibraryA в данном случае невозможен!
А вот тут начинается самая простая техника инъекции. Выше мы обсуждали, что некоторые системные библиотеки DLL по умолчанию загружаются в память любого процесса для их нормальной работы. А сама функция LoadLibraryA экспортируется из библиотеки kernel32.dll, а как мы знаем у таких библиотек базовый системный адрес одинаковый во всех процессах, где они подгружены. Выше на практике мы в этом убедились сами, сравнив два процесса.

Теперь давайте разберёмся, как же реализовать удалённую загрузку DLL в чужой процесс. Эта техника известна как инъекция DLL и является одной из самых популярных методик внедрения кода.

Как работает инъекция DLL?
Суть заключается в следующем: мы передаём путь к нашей DLL в адресное пространство целевого процесса и заставляем этот процесс вызвать функцию LoadLibraryA, чтобы он сам загрузил нашу библиотеку. Для этого потребуется использовать несколько функций WinAPI, а также аккуратно работать с памятью процесса. Еще добавлю то, что процесс, в который вы хотите внедрить DLL, должен совпадать по разрядности с самой DLL. И так же сам инжектор тоже. Это связано с особенностями работы операционной системы и загрузки библиотек. То есть, например для CS2 ваш чит dll, инжектор должны быть 64-битными.

Итак наш план действий следующий:

1)Получить доступ к целевому процессу.

Для работы с памятью и потоками другого процесса нужен дескриптор этого процесса. Мы используем функцию OpenProcess.

2)Выделить память в адресном пространстве целевого процесса.

С помощью функции VirtualAllocEx мы выделим участок памяти, куда запишем путь к нашей DLL.

3)Записать путь к DLL в память целевого процесса.

Это выполняется с помощью нам известной WriteProcessMemory.

4)Вычислить адрес функции LoadLibraryA

При помощи функций WinAPI: GetModuleHandle и GetProcAddress можно узнать адрес функции в модуле.

5)Создать поток внутри целевого процесса.

Мы вызовем функцию CreateRemoteThread, чтобы заставить целевой процесс выполнить функцию LoadLibraryA, передав ей путь к нашей DLL.
9.png

Давайте напишем код, поэтапно выполняя все по плану:
Вначале функции main() объявим нужные переменные:
C:
/*
    - Создаем массив в котором хранится путь до нашего DLL
    - Размер массива сохраним в переменную size_dll_name
    - PID целевого процесса сохраним в переменной pid
    - Объявим нужные нам перенные для дальнейших действий в коде:
    ->    HANDLE hProcess         - будет хранить дескриптор удаленного процесса
    ->    LPVOID pRemotePath     - будет хранить адрес памяти куда запишем путь до нашего DLL
    ->    LPVOID pLoadLibraryA - будет хранить адрес функции LoadLibraryA
    ->    HANDLE hThread         - будет хранить дескриптор потока в удаленном процессе


*/
char   dll_name[]     = "C:\\Users\\exbyroot\\source\\repos\\xss_dll_inject\\x64\\Debug\\xss_dll_inject.dll";
int       size_dll_name = sizeof(dll_name);
int    pid             = !УКАЖИТЕ ТУТ PID ПРОЦЕССА;
HANDLE hProcess         = NULL;
LPVOID pRemotePath   = NULL;
LPVOID pLoadLibraryA = NULL;
HANDLE hThread         = NULL;

1)Открываем процесс:

Сначала нужно получить идентификатор целевого процесса (PID). Это можно сделать, например, через диспетчер задач или с помощью кода из прошлых частей. В этой части, чтобы не отходить от самой темы, определим PID процесса вручную через ProcessHacker. Затем получаем дескриптор процесса с помощью OpenProcess.
C:
printf("[+] OpenProcess... Process Open!\n");
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL) {
    printf("[-] OpenProcess Error! Code :%d\n", GetLastError());
    return -1;
}

2. Выделяем память:

В адресном пространстве целевого процесса выделяем память для строки с путём к нашей DLL. В этом нам поможет функция VirtualAllocEx. Она принимает дескриптор удаленного процесса, размер буфера который необходимо выделить в памяти, тип распределения и защиту памяти. В нашем случае мы выделяем размер памяти необходимый, чтобы туда вместилось путь до нашего DLL. А так же делаем этот регион памяти доступным на чтение и запись. Функция вернет начальный адрес выделенной памяти.
C:
printf(" PRESS ENTER - VirtualAllocEx! \n");
getchar();
pRemotePath = VirtualAllocEx(hProcess, NULL, size_dll_name, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pRemotePath == NULL) {
    printf("[-] VirtualAllocEx Error! Code :%d\n", GetLastError());
    return -2;
}
printf("Memory allocated! Size buffer: %d | Address pRemotePath: 0x%p\n", size_dll_name, pRemotePath);

3. Записываем путь к DLL:

После успешного выделения памяти в адресном пространстве удалённого процесса можно воспользоваться функцией WriteProcessMemory для записи данных в этот выделенный буфер. В нашем случае, туда записывается строка с именем DLL, которая была заранее подготовлена.
C:
printf("  PRESS ENTER - WriteProcessMemory! \n");
getchar();
if (!WriteProcessMemory(hProcess, pRemotePath, dll_name, size_dll_name, NULL)) {
    printf("[-] WriteProcessMemory Error! Code :%d\n", GetLastError());
    VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
    return -3;
}
printf("[+] Dll path writed in buffer!\n");

4. Ищем адрес функции LoadLibraryA:

Так как LoadLibraryA экспортируется из kernel32.dll, её адрес можно получить с помощью GetModuleHandle и GetProcAddress. Это работает, потому что адрес функции LoadLibraryA будет таким же в удаленном процессе, как и в локальном процессе.
C:
pLoadLibraryA = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
if (pLoadLibraryA == NULL) {
    printf("[-] GetProcAddress or GetModuleHandle Error! Code :%d\n", GetLastError());
    return -4;
}
printf("[+] Address LoadLibraryA :0x%p\n", pLoadLibraryA);

5. Создаём поток в удаленном процессе:

После успешной записи пути к DLL в выделенный буфер памяти, следующий шаг — создание нового потока в удалённом процессе с помощью функции CreateRemoteThread.

На этом этапе требуется адрес функции LoadLibraryA, которая будет использоваться для загрузки нашей DLL. Этот адрес передаётся в качестве начальной точки выполнения нового потока.

В качестве аргумента для LoadLibraryA мы укажем адрес выделенного буфера, где записан путь к DLL (переменная pRemotePath). Это достигается передачей pRemotePath в параметр lpParameter функции CreateRemoteThread. Таким образом, удалённый поток выполнит вызов LoadLibraryA, загрузив указанную DLL в адресное пространство целевого процесса.
C:
printf(" PRESS ENTER - CreateRemoteThread! \n");
getchar();
hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)pLoadLibraryA, pRemotePath, NULL, NULL);
if (hThread == NULL) {
    printf("[-] CreateRemoteThread Error! Code :%d\n", GetLastError());
    return -5;
}

6. Завершаем работу:

После завершения работы освобождаем ресурсы:
C:
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
printf(" .... DLL loaded! .... \n");

printf(" PRESS ENTER - QUIT \n");
getchar();

return 0;

C:
#include <stdio.h>
#include <Windows.h>


int main() {
    /*
        - Создаем массив в котором хранится путь до нашего DLL
        - Размер массива сохраним в переменную size_dll_name
        - PID целевого процесса сохраним в переменной pid
        - Объявим нужные нам перенные для дальнейших действий в коде:
        ->    HANDLE hProcess         - будет хранить дескриптор удаленного процесса
        ->    LPVOID pRemotePath     - будет хранить адрес памяти куда запишем путь до нашего DLL
        ->    LPVOID pLoadLibraryA - будет хранить адрес функции LoadLibraryA
        ->    HANDLE hThread         - будет хранить дескриптор потока в удаленном процессе

   
    */
    char   dll_name[]     = "C:\\Users\\exbyroot\\source\\repos\\xss_dll_inject\\x64\\Debug\\xss_dll_inject.dll";
    int       size_dll_name = sizeof(dll_name);
    int    pid             = 6024;
    HANDLE hProcess         = NULL;
    LPVOID pRemotePath   = NULL;
    LPVOID pLoadLibraryA = NULL;
    HANDLE hThread         = NULL;

    printf("[+] OpenProcess... Process Open!\n");
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (hProcess == NULL) {
        printf("[-] OpenProcess Error! Code :%d\n", GetLastError());
        return -1;
    }

    printf(" PRESS ENTER - VirtualAllocEx! \n");
    getchar();
    pRemotePath = VirtualAllocEx(hProcess, NULL, size_dll_name, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (pRemotePath == NULL) {
        printf("[-] VirtualAllocEx Error! Code :%d\n", GetLastError());
        return -2;
    }
    printf("Memory allocated! Size buffer: %d | Address pRemotePath: 0x%p\n", size_dll_name, pRemotePath);
   
    printf("  PRESS ENTER - WriteProcessMemory! \n");
    getchar();
    if (!WriteProcessMemory(hProcess, pRemotePath, dll_name, size_dll_name, NULL)) {
        printf("[-] WriteProcessMemory Error! Code :%d\n", GetLastError());
        VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
        return -3;
    }
    printf("[+] Dll path writed in buffer!\n");


    pLoadLibraryA = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
    if (pLoadLibraryA == NULL) {
        printf("[-] GetProcAddress or GetModuleHandle Error! Code :%d\n", GetLastError());
        return -4;
    }
    printf("[+] Address LoadLibraryA :0x%p\n", pLoadLibraryA);

    printf(" PRESS ENTER - CreateRemoteThread! \n");
    getchar();
    hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)pLoadLibraryA, pRemotePath, NULL, NULL);
    if (hThread == NULL) {
        printf("[-] CreateRemoteThread Error! Code :%d\n", GetLastError());
        return -5;
    }

    WaitForSingleObject(hThread, INFINITE);
    VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    printf(" .... DLL loaded! .... \n");

    printf(" PRESS ENTER - QUIT \n");
    getchar();

    return 0;
}

Итоги...

Как видим наша DLL успешно загрузилась в память игры и вызвалась функция из DLL MessageBoxLoad();
10.png

А теперь, чтобы было еще понятнее взглянем визуально на все эти моменты поэтапно в отладчике x64dbg(Тык) и ProcessHacker(Тык). Итак, после запуска у нас открывается процесс и выделяется в нем память(буффер) с размером равный размеру массива, который содержит путь до DLL. Можем увидеть в x64dbg:
11.png

Далее идем в ProcessHacker и продолжаем следить за процессом cs2.exe в разделе потоки. Видим, что у нас создался новый поток с функцией LoadLibraryA:
12.png

Далее можем посмотреть раздел модули этого процесса и обнаружить наш xss_dll_inject.dll То есть наша библиотека успешно загрузилась в память:
13.png

Таким образом, мы создали простой метод для загрузки DLL в адресное пространство чужого процесса. Но сразу хочу сказать, что античит VAC такие действия детектит. Ибо все наши действия с процессом происходят в открытую. В этой части изначально планировалось рассказать и о других методах инжекта таких как manualmap, но подумал это заняло бы еще столько текста. О других методах будет рассказано далее в следующих частях. Научимся работать с памятью игры как раз из нашего DLL. Вообщем все, что не успели рассмотреть в этой части будет рассказано в следующей части. Если будут вопросы задавайте под постом - постараюсь ответить!

Всех с наступающими праздниками! Ваш Unseen!
 
На виндовс 10 не работает, что твой код этого метода что код на википедии русской с таким же методом loadlib, да действительно адрес у всех один даже завершается корректно но исполнения почему то нет...
 
На виндовс 10 не работает, что твой код этого метода что код на википедии русской с таким же методом loadlib, да действительно адрес у всех один даже завершается корректно но исполнения почему то нет...
Предполагаю, что ты компилишь инжектор или саму длл не в той разрядности. А так для диагностики твоей проблемы мало данных)
 
Предполагаю, что ты компилишь инжектор или саму длл не в той разрядности. А так для диагностики твоей проблемы мало данных)
компилятор 64 mingw система 64 битная процесс 64 бит
 
Предполагаю, что ты компилишь инжектор или саму длл не в той разрядности. А так для диагностики твоей проблемы мало данных)
сделал процесс жертву для теста с ним вообще поток не завершается и не выполняет нечего
 
сделал процесс жертву для теста с ним вообще поток не завершается и не выполняет нечего
антивирус что то подозревал потом вообще залочил я его оффнул все заработало вот в чем проблема была
 
антивирус что то подозревал потом вообще залочил я его оффнул все заработало вот в чем проблема была
теперь интересно будет как обойти антивирусы
 
Братан, я тебе могу дать исход internal AOB рабочий. Мб там в некст свои статьи воткнёшь подтянешь.
Я пытаюсь патчить комманду по адресу, найденную через AOB сканер - игра вылетает. Комманду патчит, но нон ворк.
Пытался повторить действие патчинга CheatEngine скриптов, с выделением памяти и jmp на адрес с коммандой - всё сделал, но также но происходит вылет при патчинге.
А у CheatEngine всё окей.
А то указатели такая тема базовая, работающая через раз, надо двигаться дальше.
Скоро Цива7 выйдет в феврале надо бы её первым пощупать.
 
Ребят не знаю что у вас не работает
На счет патчинга - возможно нужен протект памяти
Братан, я тебе могу дать исход internal AOB рабочий. Мб там в некст свои статьи воткнёшь подтянешь.
Я пытаюсь патчить комманду по адресу, найденную через AOB сканер - игра вылетает. Комманду патчит, но нон ворк.
Пытался повторить действие патчинга CheatEngine скриптов, с выделением памяти и jmp на адрес с коммандой - всё сделал, но также но происходит вылет при патчинге.
А у CheatEngine всё окей.
А то указатели такая тема базовая, работающая через раз, надо двигаться дальше.
Скоро Цива7 выйдет в феврале надо бы её первым пощупать.
 
Теоретическая часть …
Статья достаточно краткая, но при этом понятно

Когда я залезал по молодости в гейм хак - читал различные статье, пытался что то понять, написать свое, но было плохо понятно

Но в этой статье не плохо все описано

Стоило в статье написать про битность - у многих возникают с этим проблемы:

процесс для инжекта, инжектор, и целевая длл должны быть одной разрядности



Не хочу сейчас говорить по поводу читов в режиме ядре, скажу про юзермод

В интернал читах палится дллка как раз таки, и ее потоки - потому я бы выпилил ее в пебе, или грузил кастом загрузчиком

В экстернал читах палиться может наверное только сам процесс, но есть ряд нюансов - сложность работы с памятью игры например
 
Статья достаточно краткая, но при этом понятно

Когда я залезал по молодости в гейм хак - читал различные статье, пытался что то понять, написать свое, но было плохо понятно

Но в этой статье не плохо все описано

Стоило в статье написать про битность - у многих возникают с этим проблемы:

процесс для инжекта, инжектор, и целевая длл должны быть одной разрядности



Не хочу сейчас говорить по поводу читов в режиме ядре, скажу про юзермод

В интернал читах палится дллка как раз таки, и ее потоки - потому я бы выпилил ее в пебе, или грузил кастом загрузчиком

В экстернал читах палиться может наверное только сам процесс, но есть ряд нюансов - сложность работы с памятью игры например
Ну старался максимально понятно написать))
А так про битность я упоминал в самой статье. А про то что палится или нет, пока мы еще поговорим в следующих частях =)
Все же тема не про обходы или работу античитов)
А так благодарю за критику!
 
Ну старался максимально понятно написать))
А так про битность я упоминал в самой статье. А про то что палится или нет, пока мы еще поговорим в следующих частях =)
Все же тема не про обходы или работу античитов)
А так благодарю за критику!
Было бы интересно почитать статьи про читы в режиме ядра, борьбу с античитом который работае в ядре - как вариант создать некоторое "виртуальное окружение", т.е. подменять информацию которую он хочет получить
 
Обойти тему анти-читинга, возможно, заинтересует многих. Вы планируете выпустить отдельный выпуск на эту тему?
+
 
Понимаю, что цикл статей и технический, но было бы интересно почитать о финансовой и организационной стороне чит-индустрии, от человека который с ней связан:
- Сколько прибыли приносят качественные читы
- Какие игры наиболее интересны для входа на этот рынок
- Из каких специалистов состоят команды разработки
- Можно ли оформить такой бизнес в белую
И все остальные нюансы
 
Ребят не знаю что у вас не работает
На счет патчинга - возможно нужен протект памяти
нет там ситуация такая, вот допустим нашёл ты команду которая проверяет наличие баланса, сделал сигнатуру - aob scan, адрес находит стабильно. И ты думаешь, дай-ка заменю и делаешь просто запись лярдов по адресу проверки. - Крашит.
А cheat engine делает выделение памяти и в ебеня записывает там патч увеличивающий баланс, а потом просто комманду найденную заменяет на jmp adress(адрес с коммандой на увеличение).
Я попытался повторить то что предлагает cheat engine - не знаю, не вышло, вроде всё также, но крашит.
 
- Какие игры наиболее интересны для входа на этот рынок
Я для DayZ видел чит один приватный в kernel моде, так там разрабы организовали прострел и прокидку гранат через всю карту. Вот подобная ха интересна.
Много лет назад для чита cs go aimware была фишка - краш серверов в том числе официальных.
Короче вся подобная херня, уязвимости нормально так привлекают коммьюнити.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх