У меня имеется оффсет: 0x0264FEF8 по которому (или в котором) должен храниться массив всех возможных цветов главного меню тестового ПО.
К примеру, цветом заднего плана меню установлен белый, он хранится под номер «0», но я хочу поставить зеленый, а он хранится под номером «3».
Каким образом получить доступ к этому массиву имея «оффсет» и руками выбрать приемлемый цвет, а также что такое offset и с чем его «едят»?
- Вопрос задан более года назад
- 1271 просмотр
1 комментарий
Простой 1 комментарий
Откуда у вас такое условие, скиньте его целиком. Пока что я понимаю это так, что по адресу 0x0264FEF8 находится массив цветов. Чтобы извлечь нужный цвет, нужно сначала вычислить его адрес, а потом разыменовать указатель:
color_t c = *(0x0264FEF8 + i*sizeof(color_t));
Но вообще странно, сейчас бинарники на c/c++ обычно position independent, поэтому заранее адрес предсказать нельзя.
Как искать оффсеты | Cheat Engine | Читаем значения csgo на C++ | Урок 1 | Создание читов на ПК
Решения вопроса 0
Ответы на вопрос 4
Участник OpenStreetMap
0x0264FEF8 + (размер элемента цвета) * (индекс цвета)
Ответ написан более года назад
Комментировать
Нравится 1 Комментировать
Еда — это святое
Для начала разобраться, смещение в чём и относительно чего
Ответ написан более года назад
Комментировать
Нравится Комментировать
Developer, ex-admin
offset — смещение (от какого-то базового адреса).
Т.е. адрес вашего объекта вычисляется так: base address + offset.
Осталось узнать базовый адрес и можно работать с цветами.
Ответ написан более года назад
Комментировать
Нравится Комментировать
Делай добро и бросай его в воду.
Что такое offset?
«offset» — в данном контексте это адрес массива в памяти.
Теоретически элементы в этом «массиве» не обязаны храниться в памяти аналогичному тому, как это происходит в C++, потому что в Lua любой «массив» — это на самом деле хеш-таблица, и может содержать элементы разных типов.
Как обратиться к информации, что хранится в нём?
Зависит от того, чем именно вы хотите обратиться, какие у вас средства. Например, если Lua встроен в ваше же собственное приложение, из которого вы и хотите получит доступ, то лучше делать это средствами API самого Луа, то есть вынимать нужный элемент из таблицы и получать его на блюдечке.
Если же вы хотите прочитать память другого процесса, то по сути это взлом и универсальных рецептов здесь не может быть.
Можете изучить память того приложения каким-нибудь образом, можно теми же утилитами для читов в играх — ArtMoney или более серьёзный аналог CheatEngine. Изменяя цвет в самом приложении, ищите его в памяти, пока не найдёте точный адрес. А дальше смотрите, как он устроен, от чего зависит и т.д.
Как пользоваться IDA PRO. Как найти оффсеты в любой игре
Источник: qna.habr.com
Оффсет
Оффсет — один из видов встречных сделок, который по своей сути очень похож на встречные закупки, бартер или компенсационные операции. Главное отличие оффсета — ориентированность на определенные виды товаров (к примеру, продукцию военного назначения). При оформлении оффсета стороны выдвигают встречные требования в отношении вложений доли капитала в экономику стороны-импортера.
Оффсет — одна из форм сделок, подразумевающая выдвижение стороной-заказчиком встречных требований в отношении поставщика продукции.
Оффсет — процесс закрытия открытой ранее позиции на продажу или покупку инструмента посредством создания эквивалентной позиции, но уже в противоположенном направлении.
Оффсет: сущность, цели, формы
Операции типа «оффсет» являются частью компенсационных коммерческих операций и представляют собой вариант встречной торговли. По своей сущности оффсет — вариант джентльменского договора, заключаемого в устном виде. Это неформальное соглашение, которое никак не закрепляется документально. Основной взаимоотношений являются взаимодоверительные начала.
Главная особенность сделок типа «оффсет» в том, что в их пределах можно оформить не только неформальный вид сделки на обмен услугами (товарами), но и предоставить стороне-импортеру по договору возможность вложить средства для дальнейшего получения от стороны-экспортера льгот и услуг. Как следствие, офсетные операции имеют все признаки промышленного сотрудничества сторон.
Цель оффсета — компенсация затрат на покупку дорогостоящей техники. Если говорить на бизнес сленге, то оффсет часто называют «откатом».
К основным формам сделки типа «оффсет» можно отнести:
1. Торговую. В этом случае осуществляется импорт определенного товара экспортирующей страной в другое государство.
2. Инвестиционную. Здесь подразумевается вложение капитала в одну из отраслей со стороны, продающей определенный вид товара. При этом не обязательно, чтобы объект инвестиций был связан по характеристикам с самим товаром.
.4. Образовательную. Такой вид офсетной сделки подразумевает подготовку специалистов, обслуживающих закупаемую технику.
Оффсет: отличительные черты, виды
Главное отличие оффсета от сделок, предполагающих товарообмен между участниками договора — формализация нескольких (как правило, двух) подписываемых договоров с группой взаимных требований, связывающих участников определенными обязательствами. Суть последних — в проведении контрпокупки в определенный временной промежуток.
Еще одна особенность оффсета — отсутствие законной силы для обязательств стороны-экспортера касательно встречной покупки товара. И это при том, что экспортер дает свое согласие на закупку определенной партии товара у стороны-импортера для компенсации цены договора. Единственное, объем такой сделки юридически не установлен.
При заключении офсетной операции стороны могут согласовать цену оффсета, которая может быть больше общей цены заключенного контракта на экспорт. Такие сделки весьма популярным для компаний, работающих в развитых странах. Как правило, они имеют тесную связь с покупками оборудования для АЭС, закупок военной техники и так далее. Наиболее активно такие операции применяются в Индии и Малайзии. К примеру, передача товаров военного назначения в Малайзию осуществляется на условиях встречной покупки пальмового масла.
Особенность оффсета — включение в операцию определенных поставок, имеющих непосредственную связь с экспортируемой продукцией. Цена встречной поставки, как правило, засчитывается стороной-экспортером в форме пропорционального снижения полной цены международного соглашения купли-продажи.
Компенсационные коммерческие операции в границах встречных торговых отношений подразумевают процесс встречной поставки объекта сделки в определенный период времени. Поставка производится на базе более сложного контракта на куплю-продажу, указанного договора или приложенных к нему соглашений об авансовых и встречных закупках.
В плане вычислений оффсет отличается согласованным механизмом финансовых расчетных операций, обусловленных встречными и реальными финансовыми (в том числе товарными) потоками между участниками соглашения. Взаимозачет производится в различной форме:
— посредством применения клирингового механизма, где арбитражную функцию берет на себя клиринговая палата;
— через переводы твердой валюты (наличности).
Если исходить из специфики поставок товаров и расчетов между ними, можно выделить несколько видов сделок :
— краткосрочные;
— по встречным закупкам;
— по авансовым закупкам.
В свою очередь, краткосрочные операции можно разделить на несколько форм — с полной или частичной компенсацией, а также с 3-х сторонним вариантом компенсации. Последний тип представляет собой нечто среднее между товарообменными и компенсационными операциями.
Сделки, подразумевающие полную компенсацию, имеют в основе эквивалентную закупку продукции со стороны экспортера на величину, равную или большую цене поставки стороны-экспортера. Процесс развития таких операций имеет ряд основных этапов:
— оценка товаров, которые подлежат обмену (в финансовой форме);
— взаимные поставки товара в определенном сторонами объеме и в оговоренные сроки;
— проведение взаимозачетной операции, что часто производится путем особой выручки от реализации поставляемой компенсационной продукции стороны-импортера против средств, которые формируют долг за поставленный экспортером объект сделки.
В операциях с частичной компенсацией происходит покрытие лишь определенной доли поставляемого экспортером товара.
Источник: utmagazine.ru
Чтож вы такое, Оффсеты?
Очень часто на форуме встречаются посты, из которых видно, что многие не могут понять, что такое офсеты.
И я подумал, если попробовать «разжевать» данную тему, вопросов будет меньше.
Я не профессионал в программировании(просто хобби), потому, если будут недочёты, прошу извинить и поправить.
Для понимания попробуем подробно рассмотреть небольшой пример. Я думаю все понимают, что почти в любой программе существует динамическое выделение памяти.
Примером может быть программа, которая работает с различными массивами, размерность которых не всегда одна и та же. Например с массивом типа «вектор», в котором может быть заранее неизвестное количество элементов, и которые будут туда добавляться и удаляться динамически.
Для работы с динамически созданными экземплярами данных и нужны указатели.
Предлагаю написать простенькую программу, и на примере её разобрать что к чему.
Я буду использовать C++Builder6.
Создадим новый проект и сохраним в отдельную папку. Так же для удобства создадим два файла в папке проекта с названиями structs.h и structs.cpp. В них напишем наши тестовые структуры, которые и будем рассматривать.
Тут тестовая структура Party, содержащая указатель на цепочку добавляемых элементов, описывающих параметры членов пати PartyMember.
#ifndef STRUCTS_H #define STRUCTS_H #include //структура члена пати class PartyMember < public: PartyMember(); //конструктор int level; //уровень int hp; //жизни PartyMember * next; //указатель на следующего члена пати, или NULL, если последний >; // структура пати class Party < public: Party(); //конструктор ~Party(); //деструктор void AddRandomMember(); //добавление рандомного члена в пати void Clear(PartyMember * m);//очистка void DecHP(PartyMember * m);//уменьшение на 1 ХП всех членов пати void GetInfo(TListBox * lb);//вывод инфы о всех членах int count; //количество сопартийцев PartyMember * chain; //указатель(адрес) на первого члена пати, либо NULL, если их нет >; #endif //STRUCTS_H
structs.cpp
#include «structs.h» //конструктор структуры пати Party::Party() < count = 0; //в начале ни одного члена нет chain = NULL; //обнулим адрес первого члена >//деструктор пати Party::~Party() < if (chain != NULL) Clear(chain); //удалим цепочку членов, если она не пуста count = 0; >//добавление члена в конец цепочки void Party::AddRandomMember() < if (chain == NULL) //если в пати ещё нет членов < //динамически выделим память, chain будет содержать адрес первого chain = new PartyMember(); //тут вызовется конструктор члена пати count++; return; >//если это не первый член, «присоединим» его к последнему PartyMember * m = chain; while (m->next != NULL) m = m->next; m->next = new PartyMember(); count++; > //очистка пати void Party::Clear(PartyMember * m) < //рекурсивно удалим членов if (m == NULL) return; Clear(m->next); delete m; //освободим память, занятую текущим членом m = NULL; //адрес обнулим, чтоб не указывал на уже свободные адреса > //уменьшение ХП всех членов в цепочке void Party::DecHP(PartyMember * m) < if (m == NULL) return; DecHP(m->next); if (m->hp > 0) m->hp—; > void Party::GetInfo(TListBox * lb) < lb->Clear(); PartyMember * curent = chain; int num = 0; while (curent != NULL) < lb->Items->Add(«№» + IntToStr(num) + » Level — » + IntToStr(curent->level) + » HP — » + IntToStr(curent->hp)+ » ADDR — » + IntToStr(int(curent))); curent = curent->next; num++; > > //конструктор члена пати PartyMember::PartyMember() < level = 10 + 90*(rand()/float(RAND_MAX)); hp = 1000 + 9000*(rand()/float(RAND_MAX)); next = NULL; //адрес следущего члена пока обнулён >
На форму кинем ListBox, в который будем выводить данные по персонажам. А так же адрес переменной структуры пати.
И одну кнопку, при нажатии на которую у членов пати будут убывать ХП и обновляться информация в листбоксе.
Подключим наш заголовочник в главном модуле, а так же подключим файл реализации к проекту.
//————————————————————————— #include #pragma hdrstop #include «Unit1.h» #include «structs.h» //————————————————————————— #pragma package(smart_init) #pragma resource «*.dfm» TForm1 *Form1; Party party; .
Тут же в главном модуле объявим глобальную переменную paty.
В событии создания формы мы должны добавить туда к примеру 3 члена, и вывести инфо о них.
void __fastcall TForm1::FormCreate(TObject *Sender) < party.AddRandomMember(); party.AddRandomMember(); party.AddRandomMember(); party.GetInfo(ListBox1); ListBox1->Items->Add(«party ADDR = » + IntToStr(int( >
А в событии кнопки вызовем функцию уменьшения хп и опять же обновим инфо в листбоксе.
void __fastcall TForm1::Button1Click(TObject *Sender) < party.DecHP(party.chain); party.GetInfo(ListBox1); ListBox1->Items->Add(«party ADDR = » + IntToStr(int( >
Тестовая программка будет представлять собой примерно такое.
Теперь давайте запустим её, подцепимся к ней с помощью Cheat Engine и с помощью темы https://zhyk.ru/forum/showthread.php?t=116666 попытаемся найти базовый адрес(и не только).
Сначала найдём ХП последнего члена в списке(если не с первого раза нашли, кнопкой уменьшаем ХП и отсеиваем, пока не останется одно значение).
В поле Description лучше сразу писать те значения, которые прибавляются к значениям регистров в окошке MoreInformation
И далее как в вышеуказаной теме ищем адреса, пока не доберёмся до базового адреса(в данном случае базового адреса модуля Project1.exe, который кстати меняется после перезапуска).
Получится примерно такая картина.
В итоге мы добравшись до базового адреса нашли эту самую цепочку офсетов(смещений), которая ведёт до значения ХП третьего члена пати.
BA + 48C4 + 8 + 8 + 4 = HP
Но что это за значения, и откуда они взялись? Давайте разбираться.
Сначала переведём значение адреса party ADDR (последняя строчка листбокса нашей программки) в HEX и получим 004048C0.
А как мы помним, в программе это адрес нашей глобальной переменной Paty.
Но последняя строчка списке адресов Cheat Engine имеет значение 004048C4.
Ага, почти тоже самое, но на 4 больше. Смотрим на структуру нашей Paty и видим, первое поле int count; 4 байта — это значение лежит в начале нашей структуры(на объявления функций не смотрим), то-есть по адресу 004048C0.
А за ней на 4 байта дальше(по адресу 004048C4) находится PartyMember * chain.
Так как наша переменная party — глобальная, её адрес всегда будет один и тот же, и смещение от базового адреса до неё будет одно и то же. Делаем вывод, что + 48C4 — это и есть оффсет(смещение) до структуры party от базового адреса, но не до начала, а до второго её поля. A там лежит адрес структуры первого члена.
Далее по всей логике стройкой выше идёт смещение +8 от начала структуры первого члена. Смотрим в код и видим, что от начала структуры члена пати на 8 байт у нас описано PartyMember * next — указатель на начало структуры следущего члена. То-есть по этим последовательным смещениям мы идём по цепочке адресов членов пати, но последняя строчка со смещением +04. А в структуре на 4 от начала у нас описано int hp;
Вот и всё сошлось, эти офсеты — это смещение до глобальной переменной, потом смещения до адресов динамических структур, которые по цепочке указывают друг на друга, до последнего. То-есть все эти офсеты — это смещения от начала структуры до её определённых полей. Структура элемента от запуска к запуску не меняется(меняются только адреса расположения), соответственно и офсеты(смещения от начала до нужных полей) тоже не меняются.
Чтоб было нагладнее, можно проилюстрировать наш примёр.
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 22.10.2020 в 00:51 . Причина: ранее «Делаем вывод, что BA + 48C4 — это и есть оффсет(смещение) до структуры party» — некорректно
Источник: zhyk.org