-
Постов
1 635 -
Зарегистрирован
-
Посещение
-
Победитель дней
55
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент keng
-
Я, может, поздновато, но этот отладчик прекрасно работает под x64-системами, а игры до сих пор в 99% случаев собраны под х32. Версия olly для отладки x64-кода сейчас находится в разработке, насколько мне известно.
-
Ну, во-первых, если какой-то код глючит - его можно отладить. Исходник тоже есть, что сильно упрощает задачу. Во-вторых (цитирую): void DrawIndicator(void* self){ IDirect3DDevice9* dev = (IDirect3DDevice9*)self; // Из перехваченной Present получаем указатель на текущее d3d-устройство if (m_font == 0) // Если у нас до сих пор нету шрифта, то D3DXCreateFont(dev, 12, 0, 0, 0, 0, 1, 0, 0, 0, "Terminal", &m_font); // Создаем его IDirect3DDevice9_Clear(dev, 1, &rec, D3DCLEAR_TARGET, bkgColor, 1.0f, 0); // Очищаем прямоугольник размера с rec цветом bkgColor (m_font)->lpVtbl->DrawText(m_font, 0, "menu", -1, &fontRect, 0, fontColor); // Рисуем в нем текст}Я, возможно, разочарую, но не бывает так, что ты придумал какой-то алгоритм, реализовал его, а потом он работает до скончания веков. К программированию это относится очень и очень слабо. Собственные разработки постоянно приходится модифицировать, улучшать, подстраивать под текущие технологии, языки и системы. Можно дать гарантию, что на твоем собственном компьютере написанный, скомпилированный и отлаженный тобой исходный код будет работать, скажем, сутки. Мало ли выйдет патч к ОС. Или драйверу. Или к игре. Или еще что-нибудь. 99.5% времени приходится заниматься именно этим - исследованием, отладной, пробами и исправлением ошибок.
-
Так ты начни с простенького. Вот у меня в блоге описано, как выводить в окне игры текст. Чем не вариант начать с этого? И да, я вполне представляю, как это выглядит и как делается. Вариантов - куча. Только вот если не умеешь и не представляешь, как сделать - выдирать подобное из исполняемых файлов и пытаться разобраться в дизассемблированном листинге (в любом случае, в псевдокоде, а не исходниках) - еще тяжелее. Я бы сказал, что вообще бессмысленно и безрезультатно. Сядь, попей чаю, возьми бумажку и напиши словами алгоритм, что должна сделать твоя программа. По пунктам. Потом отметь те, которые не знаешь с ходу, как реализовать. Возьми новую бумажку и напиши отдельно этот пункт. Суть в том, что нужно брать большие задачи и дробить их на мелкие. В конце концов все сведется к логике и рисованию линий\точек\цифр\букв. А со временем сделаешь сколь угодно крутую реализацию своих задумок. Начать-то с чего-то все равно надо.
-
Выдирать - это плохо, фи. Во-первых, есть Fleep, записавший с десяток туториалов на эту тему. Во-вторых - тебе надо сесть и на бумажке (для начала) записать, как менюшка должна работать: -Нажали кнопку активации меню - на экран вывелся список опций\кнопок\пофиг. -Нажали кнопку, соответствующую какой-то опции - включили (выключили) опцию и каким-то образом отобразили это в меню - цвет поменяли, надпись, еще что-то. -Нажали кнопку активации меню еще раз - убрали с экрана список опций\кнопок. -Готово! Надо уметь две вещи - получить доступ к рисованию в окне игры и рисовать там, собственно. Например, текст. Или геометрические фигуры. Или еще что-то.
-
Это шутка такая. "бобра" созвучно с "добра". (: //NullAlex: именно) Ты меня понял
-
Обычно DLL инжектится в процесс через удаленный вызов функции LoadLibrary. Т.е. берешь тело dll, записываешь ее в адресное пространство процесса, а затем создаешь новый поток с указателем на нужную функцию этой dll, обычно - на ее точку входа, т.е. на dllmain. Задача - написать собственную LoadLibrary, которая не будет оповещать головной процесс о том, что в него была подгружена новая библиотека, как это происходит в обычном случае. Еще один вариант - инжектить код, а не библиотеку.
-
Можно собирать х32 и не париться, пока игра явно не будет под х64 собрана. Обычно в таких ситуациях там два исполняемых файла.
-
Я компилял все под х32, не уверен, что есть все необходимое под х64, учитывая то, что это DirectX 9.
-
Никто не помешает взломщику посмотреть код дизассемблером, а не во время работы трейнера. Автор, тебе зачем это все? Есть такой парень - Lingon, насколько я помню, долго зависал на cheathappens. Он на свои трейнеры навешивал протектор Themida (бывший X-Protector). Сказать "навороченный" - это ничего не сказать. Но даже этот прот можно снять, вот и лингона это не спасло - в какой-то момент его темные дела все равно вскрылись. Я советую лишний раз не быть параноиком, потому что на сколько-нибудь вменяемую защиту придется потратить или много времени или много денег.
-
У меня будет видеоурок на эту тему. Ожидайте. (:
-
Раз ни в какую не хочет - замени "Elseif" на просто "If" и пусть оно работает. По идее, ничего страшного случиться не должно.
-
Так, все оказалось просто. Нужно было вместо "Elsif" написать "Elseif". //NullAlex: так это ж очевидно жеж) Ваш К.О. //Не совсем - в самой программе написано "Elsif".
-
Tortoed, привет! Какие исходники и куда перезалить? Japonamat, я посмотрю после работы, сейчас нету доступа к Windows.
-
Так попробуй написать Elsif, как он хочет. Вроде бы там есть выпадающий список с доступными командами.
-
Если написать просто if, то будут проверены оба условия - сначала первое, затем второе. В моем же варианте если выполнится первое условие, то второе проверяться не будет и наоборот.
-
Я все еще не совсем понял, в чем именно твоя проблема состоит. То ли у тебя сканер сигнатур работает не так, как нужно вовсе, то ли тебе нужно искать сразу несколько адресов. Уникальность сигнатуры означает то, что такая последовательность байт встречается только один раз. У меня в уроках сканер был точно такой же с точки зрения логики и вполне нормально работыл - никаких жалоб не было. Если же тебе нужно искать несколько адресов, то делай список сигнатур и в цикле вызывай функцию сканирования для каждой.
-
Да, все верно. Разве что стоит отметить, что СЕ ассоциирует метку addr с адресом памяти. Когда срабатывает функция aobscan - addr заменяется на найденный ей адрес в случае успеха.
-
Привет! If 0EB6990C 00 ;Если выполняется условие 1 If 02134B22 01 ;Если выполняется условие 2 Poke 02134B21 00 00 00 00 ;Делаем замену байт EndIf ;Закрываем второе условие (по вложенности)ElsIf 0EB6990C 01 ;Иначе, если выполняется условие 3 If 02134B22 00 ;Если выполняется условие 4 Poke 02134B21 00 01 00 00 ;Делаем замену байт EndIf ;Закрываем условие 4EndIf; Закрываем условие 3
-
Ну, тебе все понятно из него? В смысле, почему именно так написано и что происходит в обеих секциях (enable и disable)?
-
Для этого не нужно делать инъекцию кода. Инъекция кода нужна только тогда, когда длина опкодов заменяемой инструкции меньше, чем длина заменяющей. Т.е. когда у тебя есть 5 байт, а заменить их надо на 25. [ENABLE] registersymbol(addr) aobscan(addr, 12345) addr: NOP NOP NOP [DISABLE] addr: MOV EAX,EBX unregistersymbol(addr)
-
Привет! Не совсем понял, что ты имеешь ввиду. Можешь поподробнее написать?
-
Привет! Я попробую объяснить максимально на пальцах, возможно что-то уже было сказано другими. 1. Что такое стек и с чем его едят? (На самом деле до сих пор в полной мере не представляю, что это такое). 2. Брекпойнты и условные брекпойнты на инструкции. 3. Реверс (как он делается? что мы можем получить из этого? ну и т.д.) 4. Более подробное описание опций СЕ (ну например что такое структурный паук, для чего он?) 1. Стек - это место, где хранятся какие-то данные программы во время ее выполнения. Хранятся временно, в пределах функции, скажем. Представь себе такую программу (в псевдокоде): переменная А = 2 переменная Б = 2 функция сложить: переменная В = А + Б У тебя объявлено две переменных - А и Б. Они видны (к ним есть доступ) как из единственной функции сложить, так и из других, если бы они были. Эти переменные - глобальные. Когда вызывается функция сложить, в процессоре передается управление на первую строчку этой функции, которая создает третью переменную - В, и в нее складывает результат сложения А и Б. Переменная В здесь - локальная, т.е. создана внутри функции, пока та выполнялась. Извне (из других функций программы) к этой переменной доступа нету. Дык вот эта самая переменная будет храниться в стеке. Глобальные переменные хранятся в общей памяти, которая выделена программе операционной системе. Т.е. запустил программу - в ее памяти висят переменные А и Б. Вызвал функцию сложить - внутри нее на стеке создалась переменная В. Почему глобальные переменные в общей памяти (ее обычно называют "куча"), а локальные - на стеке? Потому что стек быстрее работает. А если у функции есть аргументы, то при вызове этой функции они тоже сохраняются на стеке. 2. Тут стоит сказать, что в оперативной памяти хранятся как данные программы (ресурсы, звуки, надписи, переменные), так и код, который исполняется процессором. И в памяти все это хранится по адресам. Это значит, что можно найти адрес какой-то переменной (значения здоровья, например), а можно найти адрес, где лежит код, который что-то делает. Скажем, адрес функции, которая наносит урон по герою игры. Выключаешь ее - герой становится бессмертным, так как урон больше не наносится. Брейкпоинты в основном нужны затем, чтобы искать участки кода (или функции), которые работают с теми или иными данными (переменными). А адрес, находимый при срабатывании брейкпоинта (нужно узнать, какой код изменяет переменную здоровья - ставим брейкпоинт на запись - меняем здоровье - отладчик останавливается на участке кода, который изменил значение переменной - получаем адрес в памяти, где хранится код), можно использовать в трейнерах, чтобы каждый раз не искать нужную переменную и нужный участок кода, дабы его отключить. Условные брейкпоинты - все то же самое, но срабатывают они при соблюдении некоторых условий. Скажем, если в регистре EAX лежит 1 при выполнении инструкции, на адресе которой установлен брейкпоинт. Это нужно для отладки более сложных функций игры, например таких, которые работают со множеством значений (не только здоровье героя, но и противников). 3. Реверс по своей сути - это процесс понимания того, как работает программа, читая ее исходный код. Когда исходного кода нет, то исполняемый файл игры дизассемблируется, получается код на ассемблере. По сути - читаешь и думаешь\понимаешь, как оно работает и что делает. Нашел функцию, которая наносит противнику урон. Почитал поподробнее вверх и вниз - нашел место, где за врага герою игры дают опыт. Или из него выпадают деньги. Или что-нибудь еще происходит. 4. Смотря каких. Structure spider используется при сравнении и поиске в памяти игры похожих структур, а так же при поиске игровых объектов. Обычно это используется тогда, когда движок игры построен на скриптах - обычно, текстовых. С этим сталкиваются довольно редко, так что сразу это знать и помнить не необходимо.