-
Постов
1 635 -
Зарегистрирован
-
Посещение
-
Победитель дней
55
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент keng
-
Чаще всего это некий таймер и пара инструкций - CMP для сравнения, не равна ли текущая кучность максимальной и за ней CALL для вызова функции, которая эту самую кучность реализует. Реализуется практически так же, как и no recoil.
-
Привет! Ассемблерные инструкции компилируются в опкоды, и эти самые инструкции состоят из операторов и операндов. Допустим: MOV EAX,EBX MOV ECX,[EDX+0x10] В первом случае ты получишь опкоды (это пример) "AABBCCDD", которые и будут сигнатурой. Во втором случае во втором операнде команды MOV есть смещение 0x10, которое нужно учитывать. Грубо говоря, сигнатура должна учитывать все вещи, которые существуют динамически - смещения, адреса и все такое. Поэтому если во втором случае ты имеешь такой опкод: AAEEFF10 То 10 тут нужно заменить на ??. Почему так? Потому что до сигнатуры можно добавить 10 байт кода и все адреса\смещения съедут на 10 байт вперед. Код при этом может и не измениться, но сигнатура работать уже не будет, поэтому смещение, которое может поменяться в следующем патче, стоит учесть.
-
1. В моем идеальном мире C# - прикладной язык высокого уровня для enterprise, никак не для создания трейнеров. Судя по наблюдениям, люди, которые хотят научиться программировать, натыкаются в русскоязычном сегменте интернета на статьи именно по C#, так как 3-5 лет назад он был сильно популяризован и затем стараются использовать его, как язык общего назначения. Я не спорю, что это возможно - сам смеха ради писал PureBasic, но для наших задач все еще более предпочтетельны языки низкого уровня - ассемблер и Си. 2. Пройти-то пройду - в ней ведь еще и мультиплеер есть.
-
Попробую подсказать - в современных версиях CS (Source и GO) есть разделение игроков на команды. Думаю, что такое же есть и в 1.6. Обычно это целое число, 0, 1 или 2. 0 в данном случае - "наблюдатель" (spectator), который бесплотным духом ездит по карте и просто смотрит, как другие играют. Соответственно, 1 и 2 - T и CT.
-
Думаю, что позже я лицензию приобрету, потому что с пираткой слишком уж много мороки - я за N лет уже подустал от этого. Ломать-то там можно кучу всего, не спорю, плюс много интересных возможностей по работе с групповым AI для жителей города\полицейских.
-
Прохожу потихоньку - игра оказалась интересной. Четвертая часть совсем не понравилась, а тут все намного лучше. Ломать пока что времени нет, да и я играю в пираточку.
-
Привет! Если мне не изменяет память, то во всех играх на движке Half-Life реальное значение здоровья - это экранное * 8.
-
Тогда пиши сюда, например, что ты меняешь и что при этом не работает, будем вместе разбираться. Я вряд ли ошибусь точно так же и напишу то же самое, что и ты, если сяду писать сам. Если не работает какой-то код - то этот код хочется хотя бы прочитать.
-
Привет! Тебе нужно объявить переменную, вызывать одну функцию, которая возвратит результат в эту переменную, а затем объявить вторую переменную, которая будет суммой первой и смещения. Зайди в поисковик, набери запрос "delphi GetModuleHandle example", прочитай пример, а затем пиши. Не получится - найди в том же поисковике любую книжку по delphi и почитай основы.
-
У меня в том примере на выходе был тип float, так что я в него и конвертировал. Ты конвертируй в нужный. А по поводу типов данных для адреса и смещений - лучше там использовать uint, то есть беззнаковое целое. Мой косяк, но небольшой, так что править не буду.
-
Вот она - очередная польза в хотя бы поверхностном знании ассемблера и устройства работы Windows! WinAPI-функции возвращают результат в регистр EAX. Мы выделяем 24 байта, используя GlobalAlloc, результат (адрес) получаем в EAX. Затем копируем его в ESI. Затем открываем и очищаем буфер обмена. После - копируем туда текст, используя его адрес, который у нас скопирован был в ESI. Закрываем буфер обмена и возвращаем выделенную память системе, опять же, указав адрес этой памяти.
-
Формат данных, который или один из стандартных, или же нестандартный (свой собственный), а так же указатель на кусок памяти с передаваемыми данными.
-
Привет! Текстовые строки напрямую не сравниваются, тут используется адресация, т.е. нужен указатель на строку. Как вариант решения "в лоб" - найди кусочек памяти и в скрипте через оператор DB впиши туда строчку, а в CMP после этого подставляй адрес памяти, где строка лежит. Я так понимаю, она должна быть 0-terminated, т.е. оканчиваться нулем, но могу тут ошибаться. Второй вариант - если в игре такая строка используется, то можно воспользоваться поиском в памяти игры с указанием типа "String", и использовать этот адрес.
-
Garik66, семья химиков и инженеров, ранее - всяких творческих личностей, музыкантов\художников. Дед преподавал в военноморском, бабушка - химию в одном из институтов.
-
Привет! У тебя для записи в память используется WinAPI-функция WriteProcessMemory, которая принимает в качестве аргументов адрес, размер и значение для записи. Соответственно, переменную adress, bytessize и массив байт bytes. Адрес при этом задан статический. Указатели по своей сути - это статический адрес + одно или несколько смещений от него, которые тоже хранят адрес, а самый последний - нужное значение. Для того, чтобы получить адрес, на который указывает некоторый указатель, нужно знать статический адрес этого указателя и смещения, а потом просто прочитать его, используя арифметику. Для чтения понадобится функция ReadProcessMemory, читать нужно будет, скорее всего, 4 байта. Тут я просто думаю, что игра 32-битная, а в 32-битном адресном пространстве адреса как раз по 4 байта каждый. Допустим, есть у тебя какой-то такой указатель: [[[0x1234567] + 0x10] + 0x20] Что тебе нужно сделать? А вот так вот: 0. Прочитать значение по адресу 0x1234567 (статический адрес). 1. Прибавить к полученному 0x10 (первое смещение). 2. Прочитать значение по полученному адресу. 3. Прибавить к полученному 0x20 (второе смещение). 4. Прочитать значение по полученному адресу. После 4-го шага в данном примере в переменной для чтения как раз и будет адрес, который дальше можно будет использовать для записи в память. PS: У меня в блоге даже нашлась [запись] на эту тему.
-
А какие сложности с поиском сигнатур? Это, по факту, поиск подстроки в строке.
-
Пытаешься избежать изучения языка на минимально доступном уровне или пытаешься избежать чтения документации? А почему?
-
Самый простой и один из самых эффективнейших алгоритмов - подучить английский. На уровне чтения он совсем легкий, зато какие же килотонны документации ты сможешь прочесть!
-
Привет! "Нет ничего путевого?" Ты [издеваешься]?
-
Во-первых, указатель может быть и не первого уровня, а больше. Смотря как организована коллекция. По факту, на низком уровне все один фиг сводится к массиву указателей, но все разработчики пишут по-разному и, соответственно, все движки тоже по-разному работают. В СЕ есть поиск по "маске" значений, который обычно и служит для поиска подобных массивов структур. Выглядит это как wildcard, т.е.: "float float float decimal decimal", то есть в памяти нужно найти 20 байт, 3 типа float и за ними 2 типа decimal, все это - подряд. Структуры ведь однотипные, в этом и штука.