Перейти к содержанию

keng

Ветераны
  • Постов

    1 635
  • Зарегистрирован

  • Посещение

  • Победитель дней

    55

Весь контент keng

  1. Что-то я не совсем догоняю, как при этом СЕ видит процессы удалённой машины.
  2. Если это будет полноэкранное приложение - то рисовать поверх него форму - не лучшая затея.
  3. А если просто: [ENABLE] "Burnout Paradise. The Ultimate Box.exe"+9205F: nop nop nop nop nop nop [DISABLE] "Burnout Paradise. The Ultimate Box.exe"+9205F: mov [ecx+000000A0],edx //Alt: db 89 91 A0 00 00 00 ? Т.е. не обязательно делать code-cave с jmp-инструкциями туда-сюда, если тебе надо одну-единственную инструкцию затереть nop-ами. Тут главное баланс байт сохранить (оригинальная инструкция = 6 байт длиной, затираем шестью nop-ами по одному байту каждая). А ругаться он может просто потому, что СЕ иногда глючит со своим дизассемблером\ассемблером - не знает, как обратно в память записать "mov [eax+123], ebx". На других версиях СЕ та же картина наблюдается?
  4. Я тут нагуглил, что кнопку можно сделать и вручную (это ведь тоже окно): CreateWindow(L"BUTTON", L"hello", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 100, 100, 100, 100, h, 0, hInst, 0); При этом советуют поиграться со стилем WS_EX_TRANSPARENT, а совсем уж извращенцы создают null-brush и рисуют: SetBkMode(HDC, TRANSPARENT) Предварительно указав кнопку в качестве области рисования. Ящитаю, что такие вещи лучше по-возможности делать на более HLL, вроде плюсов\шарпа\дельфи, но попытаться можно, конечно. Сам я пошёл чуток другим путём - у меня вообще нет кнопок - есть области, клик по которым эти самые кнопки символизирует. Т.е. изначально в качестве фона висит полупрозрачная картинка, на которой нарисована кнопка. Кликаешь в области этой кнопки - область рисуется другим цветом (выделяется) и происходит нужное действие. Всё это висит на обработке WM_LBUTTONDOWN и расчёте координат курсора из wParam и lParam. Не то, чтобы дофига удобно, но я привык. Мне больше интересно, зачем нужна кнопка, которая постоянно меняет свои координаты.
  5. Так а чего тут урок писать? Ищешь через любой вид поиска (другой тип, неизвестное, блабла), находишь значение, но видишь, что оно не соответствует экранному. Отлаживаешь (или допираешь головой), что надо его на что-нибудь разделить\умножить\итд, чтобы получить реальное. Делов-то.
  6. Из отладчика, ящитаю. Экспериментальным путём.
  7. В инициализации достаточно сделать так: invoke SetLayeredWindowAttributes,hWnd,0,180,LWA_ALPHA Подробнее - в [MSDN]. Т.е.: push 0x2 //LWA_ALPHA push 0xB4 //180 из 255 push 0 //COLORREF = 0 push hWnd //Хэндл окна call SetLayeredWindowAttributes Перед этим можно дёрнуть нужную функцию из User32.dll: push 'user32.dll' call LoadLibrary И затем - нужную функцию: push 'setlayeredwindowattributes' push eax call GetProcAddress Итого: push hWnd pop ebx //Запихиваем хэндл окна в ebx, т.к. этот регистр не используется WinAPI-функциями push 'user32.dll' call LoadLibrary //Подгружаем нужную dll push 'setlayeredwindowattributes' push eax //В eax - хэндл подгруженной user32.lib* call GetProcAddress //Получаем адрес SetLayeredWindowAttributes push 0x2 //LWA_ALPHA push 0xB4 //180 из 255 push 0 //COLORREF = 0 push ebx //Хэндл окна call eax //Вызываем найденную функцию * Если функция не найдётся - возвратит 0 в eax и всё накроется тазиком, так что тут надо быть аккуратнее. Вот, типа того. Возможно, ещё надо что-то нахимичить в RC-файле диалога, но я точно не помню. Опять же, проще через отладчик проверить, грузит ли трейнер себе user32.dll (наверняка грузит). PS: Да, можно или в RC выставить, или через SetWindowLong. PPS: Я не знаю, сработает ли это с любым элементом окна, т.к. все элементы по сути - окна разного типа, так что поиграться можно, передавая разные хэндлы. Проще, имхо, на C# своих контролов набросать.
  8. Показалось! А может, я ошибся. Один и всегда только один может быть адрес какого-то значения - здоровья, патронов и так далее. Указателей же (рабочих) на этот один-единственный адрес может быть и много. Скажем, есть у нас количество здоровья: Player { health = 100; } И есть несколько разных функций для работы с этим значением: SpawnPlayer() { positionX = 20; positionY = 50; positionZ = 10; player = new Player(); player.Place(positionX, positionY, positionZ); } KillPlayer(Player player) { if(player.health == 0) { player.body.Explode(); player.weapon.Drop(); } } Получается, что две разных функции работают с нашим адресом здоровья. Ну, абстрактно говоря. Я не сильно хочу углубляться и рассказывать, откуда берётся много цепочек указателей, но абсолютно не страшно, если их несколько и они работают. Т.е. по факту, указатель - это просто адрес, хранящий адрес какого-то объекта. Например, переменной здоровья. Как только у нас получается, к примеру, объект, хранящий этот объект, скажем, массив игроков: playerList = { player1, player2, player3 }; То указатель становится на уровень больше, т.е. было: player1.health; А стало: playerList[0].health; Штука в том, что предыдущий указатель при этом никуда не девается (пока его не убьёт сам код игры или сборщик мусора, если решит, что такой указатель больше игре не нужен). В общем, ещё раз - не страшно, если на один адрес указывает много указателей, использовать можно любой из них.
  9. Скорее всего, dll-ки используются для отрисовки графики или ещё какие-нибудь функции из них дёргаются - это не сильно важно. В общем и целом, абсолютно любой указатель можно найти вручную, часто - даже без отладчика, а пользуясь одним лишь дизассемблером. Собственно, в найденных вариантах автоматического сканера что тебя не устраивает? Или тебя смущает, что там много вариантов и все работают?
  10. Кагбе, цепочка указателей далеко не всегда лежит в главном исполняемом файле - как ты помнишь, процесс состоит из модулей, куда входят и подгружаемые dll-ки. Так что это - вполне нормально. Мне вот стало интересно, как ты определил, что тут "нет статического адреса", если указатель в принципе указывает на статику (в этом их смысл)? А то, что значение меняется - вполне может быть цикл, бегающий через каждую машину и читающий, к примеру, скорость. Что-нибудь в духе: foreach(var car in carList) { UpdateSpeed(car.speed); }
  11. Ещё можно: 1. Попробовать взять другую инструкцию ([ecx+08], а не [esi+08). 2. Поиграться в главном окне с галочками "Быстрый поиск" и тремя галочками над ней - быстрый поиск отключить, а три галочки выше поставить в "среднее" положение - чтобы было не важно, какими правами обладает страница памяти. В этом случае может случиться, что указатель будет лежать в участке с правами "только чтение" - права можно посмотреть в окне отладчика.
  12. Ура! Приятно знать, что писал такую простыню не зря.
  13. Окей, давай ещё раз покажу. Вот картинка: 1 - окно кода, в нём видно дизассемблированные команды программы (игры). 2 - окно данных, в нём видно значения переменных, констант и всё то, что, по сути, кодом не является, т.е. не выполняется. Вот тут выделено и обведено красненьким три команды. Вот эти: 00460D26 /. 55 PUSH EBP 00460D27 |. 8BEC MOV EBP,ESP 00460D29 |. 6A FF PUSH -1 Первый столбик - адрес, по которому команда хранится в памяти. Второй - [опкод] этой операции в 16-ричной системе счисления, третий - [мнемоника] это команды, или её более человеческое представление. Процессор понимает и оперирует исключительно опкодами, если очень огрубить, мнемоники созданы исключительно для программистов - чтобы можно было понимать\читать\писать код. Третья картинка: Выделено четыре байта и адрес памяти, по которому эти четыре байта хранятся. Вот эти байты: 0046F000: 00 00 00 00 Соответственно, первый столбик - адрес памяти, второй - сами байты, которые хранятся по этому адресу. В чём же состоит магия? Магия в том, что код, как и данные, хранится в памяти. Оперативной, ага. В неё загружается вся программа целиком, управление передаётся на первую инструкцию кода, он начинает выполняться, для всяких же переменных и прочих данных тоже выделяется память. Вторая часть магии в том, что [исполняемые файлы] начинаются всегда с одного и того же адреса, положим, что 0x400000. Почему он определённый - читай про формат этих самых исполняемых файлов, документацию найти не трудно. Вспомним команды, которые у нас были в окне кода: 00460D26 /. 55 PUSH EBP 00460D27 |. 8BEC MOV EBP,ESP 00460D29 |. 6A FF PUSH -1 Учитывая то, что код всегда начинается с одного адреса, вычитаем: 0x00460D26 - 0x00400000 = 0x00060D26 60D26 - это смещение относительно начала секции кода. Одна из особенностей формата - он делится на секции. Кода, данных, импорта, экспорта - всё есть в документации. Дык вот. Это самое смещение не меняется. Нам это только на руку - всякий раз, как программа загрузится в оперативную память, код будет расположен по одним и тем же смещениям относительно начала секции кода (0х400000). Самое интересное в том, что данные при этом [раскидываются как угодно] - просто выделяется кусок оперативки достаточного размера, даётся его первый адрес, например: 0x123456 И туда запихиваются все данные, а уже потом просчитываются смещения. Поэтому-то адреса всех переменных - патронов, здоровья и прочего - меняются при перезапуске. Просто меняется начальный адрес куска, в котором хранятся все данные. Надеюсь, что это более-менее понятно. Теперь, чем же нам поможет сигнатура? У нас есть набор опкодов: 55, 8B, EC, 6A, FF Эти опкоды обозначают команды со второй картинки (их там аж три штуки). Мы знаем, что начало кода - всегда на 0х400000. Мы знаем размер файла. Поэтому мы можем перебрать каждую последовательность байт и если она совпадает с той, что повыше написана - значит мы наткнулись на нужную нам последовательность команд. Возвращаем её адрес - вуаля, можно записать туда что-нибудь ещё, например команду nop или прыжок на код-кейв. Т.е. даже если расположение этих команд внутри секции кода поменяется - скажем, разработчики патч напишут - мы всё равно сможем найти новый адрес по сигнатуре. В секции же данных такое не прокатит, потому что по факту это - большущая помойка, одной только винде известно, как упорядоченная. Меняется там всё каждый запуск, каждый клик мыши. Куски данных меняются относительно начала, относительно друг друга и так далее - создаются и уничтожаются переменные, память выделяется, освобождается, в общем - разнообразных действий много. Именно это - та причина, по которой сигнатуры в этом случае не помогут. Помогут тут указатели или изменение тех инструкций кода, которые читают нужные нам адреса. Доступно? Если не очень - спроси, что не понял.
  14. Сигнатуры призваны искать код в памяти, адреса же могут в ней быть раскиданы как угодно. Т.е. вот это: 0x1234567: mov al,ah сканер тебе найдёт, а вот это: 0x2233445: 1000 скорее всего - нет. Для этого лучше использовать указатели.
  15. Привет! Цитирую и перевожу с официальных форумов СЕ: aobscan(name,89 4D FC 8A 5D 08 83 FF 01 76 09 89 F8 89 FA FF 52 34 89 C6 85 F6) После срабатывания скрипта в переменной name будет находиться 0x0053F2B3, согласно картинке, т.е. адрес этой инструкции. Туда можно будет что-нибудь записать, например - jmp newmem. Если это строчка определённых байт, то такая сигнатура называется wildcard, если я не ошибаюсь - в ней все байты уникальны. Если есть маска вида xxxx???xxxxx, в которой вместо "?" могут быть любые байты - то это вроде как просто сигнатура. Само собой, в скрипте команд aobscan может быть сколько угодно - лишь бы имена переменных были разные.
  16. А чем не пример-то? У тебя есть камера, которая по своей сути представляет трапецию. Центр меньшего основания - точка обзора, от неё до объекта - некоторое расстояние. У тебя есть координаты точки обзора, координаты объекта, вычитаешь два вектора - получаешь расстояние от тебя (камеры) до объекта, на который смотришь. После этого строишь проекцию, зная расстояние, координаты и углы обзора камеры (рёбер трапеции). Готовый код никто предоставлять не будет, а решение уже дали.
  17. Если тебе нужно научиться координаты из 3D в 2D переводить - почитай в википедии про [проекции]. Если надо научиться рисовать в чужом окне - погугли соответствующие слова, если что не получится - приводи тут код и пиши, что не получилось. Если нужно всё и сразу - за тебя никто ничего делать не станет, увы.
  18. Или ищи общий список по количеству живых игроков, или попробуй найти читающую инструкцию для здоровья - если она бегает в цикле, то бегает скорее всего через каждую структуру живого игрока, там уже найдёшь нужное смещение до координат.
  19. А int3 - не прерывание, что ли? 0_о
  20. Я тут подумал, ну, вдруг кто не знает - есть два замечательных ресурса для усваивания основ, правда, требуют знания английского на уровне неуверенного, сбивчивого чтения. Во-первых, [TryRuby], а во-вторых - [Codeacademy] Если вы в принципе не представляете, что это за чёрная магия - программирование - начните вот с этих двух штук, там всё практически на пальцах и очень доступно.
  21. Игру качаю, не знаю на счёт 100%, но помочь попробую.
  22. №14, ага, я тоже. Но его ты написал, а я - только процитировал.
  23. №12, а не проще было: newmem: movss xmm0,(float)300 movss [esi+34],xmm0 или даже: newmem: mov [esi+34],(float)300 ?
  24. Зависит от твоих навыков: 1. Поиск неизвестного значения. 2. Поиск указателя. 3. Нахождение базового адреса структуры, например, через оружие. 4. Подбор полей этой структуры. 5. Создание аналогичной структуры на С++, чтение\запись из\в память. Если там действительно класс, а не структура, то будет чуток сложнее в пунктах 2-3-4. Всё, в принципе, делается при помощи Cheat Engine.
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.