-
#1
Автор темы
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Всем ку, не буду мучать вас долгими вступлениями, в общем.
Для работы нам понадобится:
1. IDA PRO
2. Scylla x64
3. Умение воспринимать информацию, ее чтение и восприятие шуток как смысл жизни
4. Игра
Я возьму на примере поиск смещений адреса SSGE, ну или ССистем глобале инвайромент……
— Первый шаг
Запускаем с корневой папки игры Game.exe (Находится в папке Bin64Release)
— Второй шаг
Открываем Scylla x64.exe и выбираем процесс игры Game.exe
Нажимаем IAT Autosearch затем Get Imports и в конце Dump (сохраняем в отдельно созданную папку, я назвал ГЕИ)
В эту же папку ГЕИ мы закидываем с вами 2 файла из корневой папочки игры — CrashRpt1402.dll и ocevogyv.dll (инач нихера не получица)
— После столь долгой и мучительной работы, третий шаг
Открываем IDA PRO — New — «Название вашего дампа» — OK
Ждете загрузки… она долгая…
— После загрузки у вас должна появится надпись внизу, она сопровождается звуком взлома пентагона через консоль с 15 ip адресов ( )
— После заходите вверху программы View — Open Subviwes — Strings
— Ждете загрузки стрингов, затем жмете Cntrl+F (быстрый поиск) и вписываете ai_CompatibilityMode
— Жмякаем по этому названию 2 раза ЛКМ — Выделяем aAiCompatibilit (чтоб она была желтая)
— Жмем X и нажимаем «ОК»
— После сразу кликаем F5, у вас будет происходить декомпиляция (если у вас 4 шаг выполнен, то декомпиляция займет секунды 3)
У вас выскачит такая шняга
— Значение qword_»цифры» — это сам адрес SSGE (все пастеры за это уже шарят думаю объяснять нече)
— САМОЕ ГЛАВНОЕ!!!!!!!!!!!
— Выделяем всю надпись qword… и нажимаем ПКМ — Rename — Пишем SSGE
Вот таки должно получица
— Дальше опять заходим в список String и вписываем например…EntityId
— В итоге делаете все также как и с поиском адреса SSGE, только вместо ai_… вы пишите EntityId
— По итогу вы получаете такую вылебобину:
Тут мы видим нашу надпись SSGE (aka адрес) и число 216. Это число — и есть смещение адреса (офсет) для EntityId. Но вы спросите, а как получить из этого значение по типу 0xD3E?
Легко. Выделяете это значение, нажимаете правой кнопкой мыши по нему и нажимаете на Hexadecimal
Из этого мы получаем 216 = 0xD8. Вот и все
Туториал закончен, всем спс подписывайтесь на сливки шов
Последнее редактирование модератором: 25 Апр 2021
When every god dead, I can live a normal life…
-
#2
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Во первый лучше было сделать тему тут *Тык*, во вторых тема Крайслера ещё актуальна *Тык* (правда скрины из-за юга, ну да ладно) Ну а так тема +- нормальная, лучше было показать как искать другие оффсеты. Упд: а делить на 8?
-
#3
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Уберут они aAiCompatibilit и что ты будешь делать?
-
#4
Автор темы
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Уберут они aAiCompatibilit и что ты будешь делать?
вопрос не ко мне, я то найду
-
#5
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
вопрос не ко мне, я то найду
![]()
Вот и нефик пастить всякую ерунду.
-
#6
Автор темы
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Вот и нефик пастить всякую ерунду.
Совсем не ерунда, достаточно познавательный гайд, особенно для чайников
-
#7
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Совсем не ерунда, достаточно познавательный гайд, особенно для чайников
![]()
Да, ты прав, что для чайников.
-
#8
выложите пж сегодняшние адреса
-
#9
Автор темы
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
выложите пж сегодняшние адреса
-
#10
создал гайд, в итоге сам пользуется адрес дампером
-
#11
создал гайд, в итоге сам пользуется адрес дампером
как эту хуeту исправить
return (SSystem*)*(uintptr_t*)((uintptr_t) * (uintptr_t**)SSGE + 0xE8);
ошибку выдает
как эту о
как эту хуeту исправить
return (SSystem*)*(uintptr_t*)((uintptr_t) * (uintptr_t**)SSGE + 0xE8);
ошибку выдает
-
#12
Такс, не нужно щас писать что я чайник и тд и тп. Я это уже сам знаю.
Но кто нибудь скажет мне где и как скачать Scylla x64 я гугле их вообще нету. Только нашёл исходники и компилировать их не могу.
И пж кто нибудь скиньте мне крякнутую IDA
-
#13
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Такс, не нужно щас писать что я чайник и тд и тп. Я это уже сам знаю.
Но кто нибудь скажет мне где и как скачать Scylla x64 я гугле их вообще нету. Только нашёл исходники и компилировать их не могу.
И пж кто нибудь скиньте мне крякнутую IDA
-
974.9 KB
Просмотры: 24
When every god dead, I can live a normal life…
-
#14
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
-
#16
У меня отправляет вот сюда когда нажымаю на ai_CompatibilityMode
-
429.5 KB
Просмотры: 21
When every god dead, I can live a normal life…
-
#17
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
У меня отправляет вот сюда когда нажымаю на ai_CompatibilityMode
Потом X чтобы перейти в xrefs
F5
-
#18
В этом то и дело что оно не находит xrefs
Вот я нажимаю по нему 2 раза
И вот куда меня кинуло
А теперь каким то магическим образом оно появилось. Ахахха Понимаюю…
-
654 KB
Просмотры: 26
-
- Поделиться
Уважаемые знатоки и профессионалы. Помогите пожалуйста. Конкретную игру не привожу так как эта инструкция встречается часто и в многих играх. Инструкция такая, на примере: mov [eax],ebx. Проблема: как найти и вычеслить смещение. Опишите пожалуйста принцип пошагово. Можно в разных вариациях.
Ссылка на комментарий
Поделиться на другие сайты
-
Ответов
63 -
Создана
8 г -
Последний ответ
8 г
Топ авторов темы
-
4
-
7
-
26
-
17
-
- Поделиться
Смотри вторую часть моего видео по взлому Bulletstorm. Поиск по форуму поможет тебе найти это видео.
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Спасибо, но ранее я смотрел все эти видео, но этого не достаточно, не совсем всё понимаю. Или вы имеете в виду метод проб и ошибок ?
Нет, это не нулевое смещение. Такая инструкция работает с кучей адресов и под инструкций. Например мне нужно найти смещение адреса x предмета, как это сделать?
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
*** мне нужно найти смещение адреса x предмета, как это сделать?
смещение в подобном случае понимается как +38 в ниже представленном примере
add eax,[rbx+38]
Но я кажется понял о чем ты спросил. Хотя, как правило, в структуре обязательно будет и ID и само название предмета просто нужно раскрывать и читать указатели выше-ниже по структуре…
1.Попробуй отсортировать адрес предмета через сравнение регистров, по содержимому стека и т.д.
2.Попробуй использовать анализ кода/структур, найди выше 2,3 и выше указатель затем инструкцию которая с ним работает,запиши на бумажку смещение от найденого указателя до требуемого адреса,затем делай инжект на инструкцию обновления указателя, сортируй там по регистру и читай/пиши по смещению.
3. Сравнением значения «экранного» и обаратываемого адреса.
4. Попробуй найти инструкцию чтения указателей инвентаря…
5. то как я еще не догадался
Способов тысячи, подобное часто встречается в «затаблеченных» играх. Всетаки укажи на название твоей мишени. Будет время поможем.
Изменено 17 декабря, 2014 пользователем Tiger
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Да, это мне частично понятно, но для начала мне интересно вот что,это начало структуры таких инструкций как (mov [eax],ebx )и т.д, как писал Sergant : смещение = 0. Так вот это и будет начало структуры каждого адреса находящигося в этой инструкции ? Если нет, то как мне выйти на начало её ?
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Так в моем видео, о котором говорил выше, и рассказывается, как выйти на начало структуры путем анализа стека.
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Вот напримере, если поставить бряк на число зелья, при срабатавании можно ли в стеке найти то что работает с этим предметом, например эффект, время его действия ?
Изменено 19 декабря, 2014 пользователем Жажда Знаний
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Это зависит от игры. Надо анализировать стек и структуру зелья.
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Огромное спасибо за верное наставление, только вот еще проблемка. Смещение нашел, а теперь как бы её записать правильно что бы работала. Смещение 12c, инструкция: mov xmm0,[rax+rbx]
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Такой вариант не работает, а как будет вариант с фильтром, с переходом ? Напримере как : cmp [rax+12c],?
Изменено 19 декабря, 2014 пользователем Жажда Знаний
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Мало данных,что за смещение, что за игра? смещение в стеке или смещение по анализу структур?
mov xmm0,[rax+rbx] инструкция чтения.
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Это смещение по анализу структур, вышел на него через по регистру rbx,на его начало. Эта интрукция постоянно обращается к адресу. Но вот как лучше внедрить в игру правильный код незнаю, игра сворачивается. Сама игра наз. Zombie … Дальше не помню
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
newmem:
cmp rbx,12C
je instruction
jmp originalcode
instruction: // сюда если rbx(смещение равно 12С)
mov [rax+rbx],(float)100 //к примеру
mov xmm0,[rax+rbx]
jmp returnhere
originalcode: //сюда во всех остальных случаях
mov xmm0,[rax+rbx]
jmp returnhere
-
1
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Ок. Спасибо. Подскажи пожайлуста как вычислить погрешность критического урона.(инструкции), скорость атаки. Проблема с игрой Nevewinter night 2, не как не получается найти скорость атаки и действия игрока, перепробовал все что на ум приходило. Дело в том что находит кучу адресов которые не поддаются заморозки. Все что хотел сделал, а это ни как. Нашел время способностей через сравнение регистров(60сек), т.е исходное начало таймера, единственное что получилось с временем. Оч сложна она.
Изменено 20 декабря, 2014 пользователем Жажда Знаний
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
newmem:
cmp rbx,12C
je instruction
jmp originalcode
instruction: // сюда если rbx(смещение равно 12С)
mov [rax+rbx],(float)100 //к примеру
mov xmm0,[rax+rbx]
jmp returnhere
originalcode: //сюда во всех остальных случаях
mov xmm0,[rax+rbx]
jmp returnhere
Что то не получается такой вариант, может я что делаю нет так . Пробовал не нескольких играх, не сработало, игры сворачиваются. На примере игра Dragon Age 2, Ищу смещение на скорость Атаки(адрес 203E7F94). Ставя чтение на доступ на этот адрес Вылезает инструкция ( fld dword ptr [esi+04] ). Затем ставя бряк на Адрес срабатывают такие регистры как :
eax 005AE690
ebx 203D47E4 (Анализ структур провожу по регистру ebx) , бряк на адресе 203E7F94
ecx 203E7F90
edx 00BF5C1C
esi 203E7F90
edi 203D45F0
ebp 205895D0
По нему нахожу постоянное смещение (D84)
Вот Скрипт который я делал newMem:
cmp [ebx],d84
mov [esi+04],или [esi+d84] (float)100
je @f
@@:
fld dword ptr [esi+04]
mov ecx,[esi+14]
jmp returnHere
DragonAge2.AK::MemoryMgr::GetPoolName+81EA6:
jmp newMem
nop
returnHere:
[DISABLE]
DragonAge2.AK::MemoryMgr::GetPoolName+81EA6:
fld dword ptr [esi+04]
mov ecx,[esi+14]
dealloc(newMem)
что я делаю не так ?
Изменено 21 декабря, 2014 пользователем Жажда Знаний
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Data Breakpoint не пробовал ставить? Как у меня в видео? Но для этого нужно, чтобы игра была в оконном режиме, иначе не свернешь, при срабатывании бряка.
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
а зачем в ebx ковырятся? то есть по вашему логика фильтра получается такая
значение по адресу [ebx] то есть в вашем случае [203D47E4] равно d84. То есть по адресу лежит ЗНАЧЕНИЕ d84.
Надо сравнивать значения а не смещения. К примеру.
Вот ваша инструкция
fld dword ptr [esi+04] анализируем
[esi+04] = [203E7F90+4] то есть адрес по нему некое значение.
где 203E7F90=esi=базовый адрес этой инструкции
+04 смещение от базового адреса то есть 203E7F94
в инструкции типа [esx+ebx]
тут как раз в регистре ebx хранится смещение и поэтому по нему можно писать фильтр.
А то что вы понаписали сверху я вообще не вкурил…
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Data Breakpoint не пробовал ставить? Как у меня в видео? Но для этого нужно, чтобы игра была в оконном режиме, иначе не свернешь, при срабатывании бряка.
Я именно так и делал.
а зачем в ebx ковырятся? то есть по вашему логика фильтра получается такая
значение по адресу [ebx] то есть в вашем случае [203D47E4] равно d84. То есть по адресу лежит ЗНАЧЕНИЕ d84.
Надо сравнивать значения а не смещения. К примеру.
Вот ваша инструкция
fld dword ptr [esi+04] анализируем
[esi+04] = [203E7F90+4] то есть адрес по нему некое значение.
где 203E7F90=esi=базовый адрес этой инструкции
+04 смещение от базового адреса то есть 203E7F94
А то что вы понаписали сверху я вообще не вкурил…
Если брать смещение -04,то любой адрес с этой инструкции будет на одном и том же смещении. На смещении ( 04 )
Изменено 21 декабря, 2014 пользователем Жажда Знаний
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Вам что конкретно нужно сделать? Отсеять лишние адреса?
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Нет,найти правильное смещение и внедрить его в код.
В ebx’е искать, потому что при бряке идет выгрузка регистров с самого нижнего, заканчивая eax. Ebx больше подходит на начало структуры.
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Все. Всем спасибо, Разобрался. Я как понял, что можно и не ставить условные прыжки..
Ссылка на комментарий
Поделиться на другие сайты
-
- Поделиться
Проблема: как найти и вычеслить смещение. Опишите пожалуйста принцип пошагово. Можно в разных вариациях.
Че, блин?
Ну ты хоть теорию почитай. Или уроки посмотри у кодера или Михаила Ремизова (keng) — они понятно объясняют.
В моем понимании — смещение это отклонение регистра от нуля на указанное количество байт. Смещение и адреса всегда в hex (16-ричная система исчистления).
К примеру, из записи mov [eax+18],xmm0 мы можем видеть, что eax — регистр, а 18 — смещение.
Однако, лайф хак: чтобы в анализе структур увидеть значение регистра уже со смещением — просто возьми начальный адрес регистра и прибавь смещение.
К примеру, если адрес регистра eax — 485E24A5 то в анализе структур запиши 485E24A5+18, где 18 — наше смещение. Тогда нулевой адрес будет наш адрес, уже со смещением.
Так же, из записи mov [eax+18],xmm0 мы можем видеть, что регистр xmm0 копируется в смещение [eax+18].
Т.е:
- На первом месте идет глагол. То, что мы делаем с инструкцией. К примеру: mov — записать (сдвинуть) смещение, dec — вычесть 1, inc — прибавить 1, cmp — сравнение (используется в бессмертии и OHK)
- На втором месте идет «подопытный». То, с чем мы проводим операцию. В нашем случае — это смещение. Однако «подопытным» может быть и адрес и многое другое.
- На третьем месте идет «виновник торжества». Объект нашего действия. Он будет выполнять действие, указанное на первом месте, с тем, что указано на втором месте. Формулировка мутная, но думаю ты поймешь
P.s. Я вижу тут тебе уже помогли, но малоли… Может все же будет полезно.
Ссылка на комментарий
Поделиться на другие сайты
- Автор
-
- Поделиться
Че, блин?
Ну ты хоть теорию почитай. Или уроки посмотри у кодера или Михаила Ремизова (keng) — они понятно объясняют.
В моем понимании — смещение это отклонение регистра от нуля на указанное количество байт. Смещение и адреса всегда в hex (16-ричная система исчистления).
К примеру, из записи mov [eax+18],xmm0 мы можем видеть, что eax — регистр, а 18 — смещение.
Однако, лайф хак: чтобы в анализе структур увидеть значение регистра уже со смещением — просто возьми начальный адрес регистра и прибавь смещение.
К примеру, если адрес регистра eax — 485E24A5 то в анализе структур запиши 485E24A5+18, где 18 — наше смещение. Тогда нулевой адрес будет наш адрес, уже со смещением.
Так же, из записи mov [eax+18],xmm0 мы можем видеть, что регистр xmm0 копируется в смещение [eax+18].
Т.е:
- На первом месте идет глагол. То, что мы делаем с инструкцией. К примеру: mov — записать (сдвинуть) смещение, dec — вычесть 1, inc — прибавить 1, cmp — сравнение (используется в бессмертии и OHK)
- На втором месте идет «подопытный». То, с чем мы проводим операцию. В нашем случае — это смещение. Однако «подопытным» может быть и адрес и многое другое.
- На третьем месте идет «виновник торжества». Объект нашего действия. Он будет выполнять действие, указанное на первом месте, с тем, что указано на втором месте. Формулировка мутная, но думаю ты поймешь
P.s. Я вижу тут тебе уже помогли, но малоли… Может все же будет полезно.
Благодарю за разьяснение, но это я все уже знал давно и нового не извлёк. Такое впечатление что ни кто не понимает о чем тут речь. Ни кто не помогал, разобрался сам.
Ссылка на комментарий
Поделиться на другие сайты
struct a
{
struct b
{
int i;
float j;
}x;
struct c
{
int k;
float l;
}y;
}z;
Can anybody explain me how to find the offset of int k
so that we can find the address of int i
?
asked Sep 11, 2013 at 19:10
3
Use offsetof()
to find the offset from the start of z
or from the start of x
.
offsetof()
— offset of a structure member
SYNOPSIS
#include <stddef.h>
size_t offsetof(type, member);
offsetof()
returns the offset of the field member from the
start of the structure type.
EXAMPLE
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
struct s {
int i;
char c;
double d;
char a[];
};
/* Output is compiler dependent */
printf("offsets: i=%ld; c=%ld; d=%ld a=%ldn",
(long) offsetof(struct s, i),
(long) offsetof(struct s, c),
(long) offsetof(struct s, d),
(long) offsetof(struct s, a));
printf("sizeof(struct s)=%ldn", (long) sizeof(struct s));
exit(EXIT_SUCCESS);
}
You will get the following output on a Linux, if you compile with GCC:
offsets: i=0; c=4; d=8 a=16
sizeof(struct s)=16
Lii
11.4k8 gold badges63 silver badges88 bronze badges
answered Sep 11, 2013 at 19:34
GangadharGangadhar
10.2k3 gold badges31 silver badges50 bronze badges
2
It’s been 3 years since the question has been asked, I’m adding my answer for the sake of completeness.
The hacky way of getting the offset of a struct member goes like this
printf("%pn", (void*)(&((struct s *)NULL)->i));
It doesn’t look pretty, I can’t think of anything in pure C (which can get you the offset of the member, without knowing anything else about the structure. I believe the offsetof
macro is defined in this fashion.
For reference, this technique is used in the linux kernel, check out the container_of
macro :
http://lxr.free-electrons.com/source/scripts/kconfig/list.h#L18
A more elaborate explanation can be found in this article:
http://radek.io/2012/11/10/magical-container_of-macro/
answered Oct 1, 2016 at 10:37
silensilen
5246 silver badges5 bronze badges
4
struct a foo;
printf("offset of k is %dn", (char *)&foo.y.k - (char *)&foo);
printf("offset of i is %dn", (char *)&foo.x.i - (char *)&foo);
foo.x.i
refers to the field i
in the struct x
in the struct foo
.
&foo.x.i
gives you the address of the field foo.x.i
.
Similarly, &foo.y.k
gives you the address of foo.y.k
;
&foo
gives you the address of the struct foo
.
Subtracting the address of foo
from the address of foo.x.i
gives you the offset from foo
to foo.x.i
.
As Gangadhar says, you can use the offsetof()
macro rather than the pointer arithmetic I gave. But it’s good to understand the pointer arithmetic first.
Alexis Wilke
18.8k10 gold badges83 silver badges150 bronze badges
answered Sep 11, 2013 at 19:15
4
As already suggested, you should use the offsetof()
macro from <stddef.h>
, which yields the offset as a size_t
value.
For example:
#include <stddef.h>
#include <stdio.h>
#include "struct_a.h" /* Header defining the structure in the question */
int main(void)
{
size_t off_k_y = offsetof(struct c, k);
size_t off_k_z = offsetof(struct a, y.k);
size_t off_i_x = offsetof(struct b, i);
size_t off_i_z = offsetof(struct a, x.i);
printf("k = %zu %zu; i = %zu %zun", off_k_y, off_k_z, off_i_x, off_i_z);
return 0;
}
Example output:
k = 0 8; i = 0 0
answered Sep 11, 2013 at 19:37
Jonathan LefflerJonathan Leffler
726k140 gold badges900 silver badges1275 bronze badges
2
To find the offset, this is one way we can go about it.
struct a{
struct b
{
int i;
float j;
}x;
struct c
{
int k;
float l;
}y;
}z;
int main(){
struct a* foo = &z;
printf("%dn", foo); //address of z
printf("%dn", &(foo->y)); //address of z.y
printf("%dn", &( (&(foo->y))->k )); //address of z.y.k
int offset_k = (char*)&( (&(foo->y))->k ) - (char*)foo ;
printf("%dn", offset_k);
return 0;
}
Output would be similar to this:
4225552 //address of z
4225560 //address of z.y
4225560 //address of z.y.k
8 //offset
In this particular case, since int i is the first member of the struct, the base address of the struct will be that of int i as well. Otherwise, you could compute the offset of int i in a similar manner.
int offset_i = (char*)&( (&(foo->x))->i ) - (char*)foo; //0 in this case
NOTE: The offset will be negative or positive depending on how you define it (if it’s with respect to base address or member z.y.k). Here, it is defined to be with respect to base address of struct.
answered Dec 6, 2019 at 17:17
Here’s a generic solution that works with both newer and older versions of GNU C:
<!-- language: C -->
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define GNUC_PREREQ(minMajor, minMinor)
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((minMajor) << 16) + (minMinor))
#else
# define GNUC_PREREQ 0
#endif
#if GNUC_PREREQ(4, 0)
# define OFFSETOF(type, member) ((int)__builtin_offsetof(type, member))
#else
# define OFFSETOF(type, member) ((int)(intptr_t)&(((type *)(void*)0)->member) )
#endif
UPDATE: Someone asked for a usage example:
struct foo {
int bar;
char *baz;
}
printf("Offset of baz in struct foo = %dn",
OFFSETOF(foo, baz));
Would print 4, if int
compiles into 4 bytes on the architecture of the machine it runs on.
answered Jul 6, 2019 at 4:57
clearlightclearlight
12.1k11 gold badges57 silver badges75 bronze badges
3
-
2010-07-06, 02:42 AM
#1
Пошаговое руководство по определению базового адреса и смещений для игровых величин (HP, MP и т.д.).
В целом, процедура абсолютно одинакова для большинства программ, посему, раз прочитав подобное руководство для другой игры, которых хватает на нашем ресурсе, читать уже для Jade Dynasty особого смысла нет. Хотя, здесь я приведу несколько дополнительных вещей и пояснений.
Note:
— здесь не дается определения базовому адресу, смещениям и т.п.
— здесь нет детального описания функций и окон CE
— здесь нет детального описания ассемблерных команд
— данное руководство на 90% применимо и для Perfect World’а, т.к. движки у этих двух игр одинаковые.
— перед многими значениями стоит символ «$». Используется для идентификации шестнадцатеричных величинПриступим.
Загружаем клиент Jade Dynasty, запускаем Cheat Engine (CE) и присоединяем последний к процессу игры «elementclient.exe». Объектом поиска будет самая доступная величина – количество жизней (HP), в моем случае, равная 779 единиц.
В поле «Value» CE вводим значение 779, выбираем тип сканирования «Exact value» и тип величины «4 bytes», и начинаем сканирование «first scan»По завершению первого сканирования, CE отобразит список адресов (если он не очень велик), значения которых в момент поиска равнялись 779. Таких адресов может быть 10, может быть и сотни тысяч. Поэтому, нам требуется точно определить нужный адрес. Возвращаемся в игру и любым способом меняем значение HP, например, снимем с чара какую-либо вещь, дающую прирост HP:
Как только значение изменится, продолжаем поиск в CE, при этом тип сканирования оставляя «Exact value»
Найдено 4 адреса. Можно еще раз изменить значение HP и посмотреть, как будут меняться значения у этих адресов.
Через несколько секунд становится ясно: два первых адреса не имеют отношения к искомой величине, а два последних – текущее значение HP и максимальное.
Добавляем оба адреса в список и, выбрав «HP max», вызываем контекстное меню.
Нам требуется отыскать участок кода, который записывает значения в выбранный адрес $1265F098: «Find out what writes to this address»
Выполнив указанную команду, CE отобразит окно со списком опкодов (operation code, код операции)
Код операции, операционный код, опкод — часть машинного языка, называемой инструкцией, определяющей операцию, которая должна быть выполнена.
Убедимся, что отображаются все опкоды, для чего требуется вернуться в клиент и изменить значение HP
Посмотрим дополнительную информацию для инструкции по адресу «$0046b5ca»:
CE отобразит окно, где будут указаны значения регистров и дизассемблированный участок кода клиента; инструкция mov [esi + $288], ecx как раз и отвечает за запись величины HP по адресу $1265F098, а значение указателя равно $1265EE10.
Смещение: +288.
$1265EE10 – следующая величина для поиска.Note: если не будет найдено ни одного значения, значит требуется повторить процедуру по определению значения указателя (просмотр списка опкодов)
Берем первый из найденных адресов (совсем не обязательно, что данный адрес даст какой-либо результат), добавляем его в список (название +$288 для более легкой идентификации смещений) и теперь начнем поиск того, что обращается к данному адресу
Список опкодов достаточно велик, что, по большей части, свидетельствует о правильности поиска.
Рассмотрим две инструкции.
первая по адресу: $004c2ad2Видим, что значение указателя уже было использовано нами для поиска, следовательно, требуется выбрать другую инструкцию.
вторая по адресу: $004d11c8
Человек, знакомый с ассемблером, сразу видит результат… К этому результату вернемся чуть позже, т.к. завершим процедуру поиска базового адреса по выработанному алгоритму.
$039F6E20 – следующая величина для поиска.Осуществив сканирование, CE выдаст список и выделит первый адрес зеленым цветом, что означает «статический адрес»
Это и есть «почти» базовый адрес, которым пользуются большинство ботоделов. Используя его, и указанные ранее смещения, можем записать:
[$00B06B5C] + $28 + $288 – Максимальное значение HP
Однако (возвращаясь к ассемблеру), хоть мы и нашли статический адрес, но этот адрес является адресом «структуры игрока», в то время как истинный базовый адрес — $00B03064mov eax, [00B03064]
mov eax, [eax+1c]
mov eax, [ecx+28]Итог:
[Базовый адрес] = $00B03064
[BA] + $1C + $28 + $288 – Максимальное значение HPNote: Текущее значение HP искать нет уже необходимости, т.к. адрес был найден на первых шагах и он отличается от HP max на 18 байт, т.е.:
[BA] + $1C + $28 + $270 — Текущее значение HP
(c) Dwar
копирование материала разрешено только с указанием автора и адреса источникаPlease, post your questions on forum, not by PM or mail
I spend my time, so please pay a little bit of your time to keep world in equilibrium
-
The Following 2 Users Say Thank You to Dwar For This Useful Post:
-
2010-07-17, 07:19 PM
#2
re: Поиск базового адреса, смещения. Jade Dynasty
Originally Posted by Dwar
Note: Текущее значение HP искать нет уже необходимости, т.к. адрес был найден на первых шагах и он отличается от HP max на 8 байт, т.е.:
[BA] + $1C + $28 + $280 — Текущее значение HPотличается не на 8 а на 18 байт
[BA] + $1C + $28 + $270 — Текущее значение HP
За гайд спс
-
2010-07-18, 01:26 AM
#3
re: Поиск базового адреса, смещения. Jade Dynasty
точно
. подправил
Please, post your questions on forum, not by PM or mail
I spend my time, so please pay a little bit of your time to keep world in equilibrium
-
2010-11-29, 03:58 PM
#4
New member
- Rep Power
- 0
re: Поиск базового адреса, смещения. Jade Dynasty
спасибо кое что новое узнал….если же у кого то знание ассемблера и команд на уровне табуретки (вопщем как у меня)я думаю вам поначалу будет проще использовать Artmoney (качаете последнюю версию ,открываете хелп и переходите к пункту 10 все подробно описано )
-
2012-01-26, 11:55 AM
#5
Guest
- Rep Power
- 0
Катит только для jd на forsaken world не идет .
-
2012-03-28, 04:51 AM
#6
Guest
- Rep Power
- 0
А как быть если «js EXECryptor_RegConst_7+927C4»?
Попробовал «Unpacker ExeCryptor» говорит не упакован.Это не из Jade, но всё же.
Cheat Engine – программа для гейм-хакеров, предназначается для читерства в компьютерных играх. Принцип работы заключается в том, что показатели игры – достижения, жизни, патроны, ресурсы – хранятся в виде цифр по определенным адресам оперативной памяти компьютера. Указатели — память, которая содержит не значение параметра, а адрес нахождения параметра. Сканирование памяти игры в Cheat Engine делает доступным эти адреса найти и изменить цифры на те, которые нужны.
Для чего нужен поиск указателей
Переменные объекта в игре создаются динамически, чтобы не нагружать оперативную память игры и процесса – с текущими параметрами игр оперативной памяти не хватит. Соответственно, ведется учет, где в памяти размещается тот или иной параметр. Базовый элемент — указатель, а внутри – параметры здоровья, ресурсов, опыта, патронов, денег. При каждом новом запуске игры или нового уровня, адреса динамических игровых параметров переезжают в другую область памяти. Для изменения приходится снова и снова находить. Для того, что бы этого не делать применяется поиск указателей.
Найти одноуровневый указатель
Запускаем Cheat Engine. Находим и копируем в нижнее окно адрес переменной, которая отвечает за нужный параметр. Правым кликом по адресной строке вызываем меню, находим строку «Find out what writes to this address». Ставим break на запись и разрешаем запуск отладчика. Идем в игру и тратим часть золота или теряем одну жизнь — чтобы изменить показатель. Возвращаемся к Cheat Engine и видим в окне отладчика новые строки. Выбираем одну типа mov и переходим во вкладку «More information». Правым кликом открываем меню и выбираем «Copy info to clipboard» — скопированное переносим в блокнот, закрываем отладчик.
Далее переходим в главное окно программы и в поисковой строке вводим адрес из указанной области 07AF.., отмечаем галочкой НЕХ и тип значения 4Б, — запускаем поиск. В результатах поиска ищем постоянный адрес – выделяется зеленым. Копируем в нижнее окно и кликаем дважды по строке «Adress».
Копируем адрес сверху, отмечаем галочкой «Pointer» и вставляем в нижнее выпавшее поле. Тип определяем исходный. Далее при помощи вендового калькулятора рассчитываем смещение между первоначальным адресом, копированным в блокнот и найденным зеленым. Результат вставляем во второе поле снизу и жмем «Ок». После этого правым кликом по значению – «Value» выбираем в меню «Show as decimal» — отражать показатели в десятичном формате. Итог сохраняем в типе файла *.СТ. При загрузке этого файла в Cheat Engine с запуском уровня не надо будет снова искать переменные.
Найти многоуровневый указатель
Многоуровневый – это такой, который ссылается не на искомую информацию, а на другой указатель. Таких уровней может найтись сколько угодно. Многоуровневая адресация усложняет процесс поиска цепочки указателей. Обработка занимает время. Сканирование памяти проводится 8-12 раз с перезапуском игры до тех пор, пока не выявится постоянный результат и один показатель не отразит хоть раз одинаковый результат с игровым параметром при перезагрузке.