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

MasterGH

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

    2 999
  • Зарегистрирован

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

    129

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

  1. Akama, уже все давно узнали, что есть такая таблица ) И давно решили изучать её или нет... Отлавливать функции нажатия клавиш надо для работы в отладке, чтобы определить как код игры реагирует на ввод пользователя. Если интересуют подробности, то их нужно искать в отладке...
  2. Можно этим способом, а можно используя: generateAPIHookScript(address, addresstojumpto, addresstogetnewcalladdress OPT)
  3. В первый раз вижу такое меню. Хоть бы ссылку привёл этого видео. D3DWindower помогает не всегда, у нас есть статьи по нему. Возможно стоит поискать в Интернете способ установки оконного режима именно для какой-то игры. Если его нет, тогда лесть в отладку. По этому поводу у нас тоже есть статьи.
  4. Мне туторы делать некогда Подсказать не могу, т.к. для каждой игры свой случай. Вот статья, там и видео про фильтры
  5. Кое-что не совсем правильно. И немного не удобно в том, что нет выбора между остановкой просто на функции и остановкой по равенству кода сообщения... я потом поправлю, сейчас нет времени. И на будущее createStringlist() в твоём случае постоянно создаёт новый и новый список. Старый при этом не разрушается и происходит "утечка памяти". Достаточно создать список только один раз. Также лучше пользоваться просто print() я что-то "перенасоветовал". Когда я советовал я забыл, что ты ведёшь логи с остановками в Отладчике для пользователя. В этом случае проще использовать print() c длинной строкой (через string.fortmat)... Ладно, как уже писал, позже поправлю.
  6. Актуально: local Function = getAddress("TranslateMessage") Для лучшей производительности лучше: 1) cтроку: local Condition = 0x202 -- MSG==202 //WM_LBUTTONUP вынести из function debugger_onBreakpoint(). 2) строку : if (EIP == Function) then заменить на: if (EIP ~= Function) then return 1 end 3) Возможно лучше использовать объект от Stringlist вместо множественного построчного print(). Метод "strings_getText( твой Stringlist )" может сразу возвратить большую строку лога, которую уже можно обработать через print Также помимо кодов сообщений можно логировать и адрес возврата по [esp+0]. А также другую информацию: BOOL TranslateMessage( const MSG* lpMsg // Указатель на структуру MSG, которая содержит информацию о сообщении извлеченную из очереди сообщений вызывающего потока при помощи использования функции GetMessage или PeekMessage. ); typedef struct { HWND hwnd; // Дескриптор окна, оконная процедура которого принимает сообщение. UINT message; // Определяет код сообщения. Приложения могут использовать только младшее слово; старшее слово зарезервировано системой. WPARAM wParam; // Определяет дополнительную информацию о сообщении. Точное значение зависит от значения члена структуры message. LPARAM lParam; // Определяет дополнительную информацию о сообщении. Точное значение зависит от значения члена структуры message. DWORD time; // Определяет время, в которое сообщение было помещено в очередь. POINT pt; // Устанавливает позицию курсора, в экранных координатах, в момент, когда сообщение было помещено в очередь. } MSG, *PMSG;
  7. Ссылка на тему человека Recifense, там же есть файл .CT таблицы. В [pGold] есть запись, посмотри внимательно. А вот в [iPlayerID] записи нет, потому что это просто переменная для чтения. В этой переменной идентификатор игрока, он всегда равен единице. По поводу того, что Recifense лучше меня... Скорее всего так и есть, т.к. у него большой опыт в нахождении связей между указателями. Скорее всего, он не работает с декомпиляторами. Это только я так заморачиваюсь. Метод у него, скорее всего, такой. Если он не может сделать один чит, то он делает другой и ищет связи между поинтерами в структурах сделанных читов. Т.е. в его случае из Dessect Data окна он не вылазит вообще и наверняка активно пользуется сканером памяти в поиске адресов и указателей в структурах... так же, скорее всего, он часто ставит бряки на адреса указателей. Указатели эти расположены в структурах, где они характерны только для данной структуры. Мне надо было обратить внимание на смещение +0x44 в структуре "Передвижения" и искать связь этого указателя со структурой где расположен адрес золота моего героя. Ведь и адрес золота, и адрес очков хождения должны обязательно принадлежать герою за которого я играю. Таблица Recifense показала, что надо думать головой в направлении принадлежности адресов к структурам, которые каким-то образом связаны между собой. Т.е. если мы не можем идентифицировать принадлежность адреса очков ходов к герою за которого играем, то надо найти через бряк структуру этого адреса очков ходов и, например, структуру адреса золота и попытаться найти связи между этим структурами... По поводу этой игры. Подобная сложность создания читов почти всегда характерна для похожих игр, где много юнитов
  8. Тебе нужно знать программирование под Windows. Нужно знать как работать с WinApi функиями чтения, записи в память. Через чтение можно осуществлять чтение цепочек указателей. Нужно знать как изменить блок защиты памяти с защиты чтения на защиту записи, чтобы писать в него без исключений... Нужно знать работу с поиском dll-ок и принадлежности их к процессам. Нужно знать как сделать поиск процесса по названию его окна или по имени процесса, подключение к процессу. Нужно знать где закрывать дескрипторы. Нужно знать работу с обработкой сообщений чек боксов. Если будешь писать на C++, то нужно знать как создавать окно и привязывать функцию к этому окну. Тебе оно надо? Это ещё не все. Тебе надо будет самостоятельно искать примеры или самому написать "правильный инжект в выделенную память".
  9. Akama, не уже ли ты не сможешь разобраться "методом тыка" как генерировать трейнер в CE 6.1, если уже есть таблица? Лучше задавай конкретные вопросы... У тебя, наверно, есть один большой скрипт и несколько адресов активации. Ну в генерируемом трейнере укажи хот-кеи на большой скрипт - "клавиша Inc", на остальные - другие клавиши. И ничего сложного...
  10. Попробуй сделать и узнаешь правильно ли это
  11. Я что-то потерялся в дебрях вызовов и упёрся в аргумент функции "location_manager().update_positions". Эта функция постоянно работает с позициями.... Внизу есть другая функция, которая может вызывать "подставляемые" функции. Одну функцию может вызвать для бота и совершенно другую для пользователя. По какому принципу это делается нет времени разбирать, т.к. похоже это надолго. Всё-таки надо было ставить бряк на изменение курсора или на клик. Но для этого париться с хуками directX, на это тоже надо какое-то время. Но у меня есть не плохие новости. Есть же уже готовая таблица Recifense - ещё тот Гуру по таким случаям.
  12. Ликбез. На карте Мира могут быть войска Пользователя и ботов. За Пользователя играет Пользователь, за остальных компьютер. Все войска Пользователя разделим на Армии в составе которой есть руководитель. Именно Армии мы можем передвигать на карте Мира. Армию можно делить на отряды по классам: конница, лучники и т.п. Каждый отряд имеет коэффициент усталости. От него зависит дальность хода. Таким образом в Армии быстрые отряды не могут идти дальше чем медленные отряды. Итак, когда Пользователь передвигает Армию, то код игры смотрит принадлежит ли Армия пользователю, если нет, то идти не разрешается, если да, то код игры перебирает отряды и двигает их на расстояние указанное пользователем с вычетом сделанных ходов ранее и вычитом усталости самого уставшего отряда. Если вы что-то не поняли или запутались просто поиграйте в игру и всё поймете. Конница не может оставить лучников в армии, если двигается вся армия... Путь Вхождений моего героя из глубины вверх. Три функции ниже связаны с объектом пользователя или бота и параметром а2 - шагов сколько Армия должна сделать. Именно Армия. При чём неавжно какая армия. И в этих трёх функция не определяется сравнение с Армией пользователя или Бота. Да и важно понимать, что псевдокод может отображать не все параметры передаваемые в функцию.
  13. Это в теории его должны применять в большинстве. На практике могут и не писать такую поддержку, а могут даже наоборот "перестараться" и добавить опцию включения и отключения аппаратного курсора для мышки. Насколько я предполагаю если эта поддержка выключения, то клики будут обрабатываться стандартно от сообщений обрабатываемых в функции привязанной к окну.... По теме... Перевел я на псевдокод функцию уменьшающие шаги: int __thiscall sub_10654450(void *this, int a2) void *this - указатель на некоторую структуру Пользователя или бота int a2 - кол-во шагов которое желает выполнить *this return - наверно значение ошибки... Функция перебирает группы привязанные к *this и отнимает шаги перемещения. Эта функция находиться в окрестностях адреса вычитания очков перещения: Shogun2.dll+68DEB2 - 89 50 6C - mov [eax+6C],edx int __thiscall sub_10654450(void *this, int a2) { int result; // eax@1 char *v3; // ecx@1 int v4; // esi@1 int v5; // eax@2 int v6; // edx@2 v3 = (char *)this + 148; v4 = *((_DWORD *)v3 + 5); for ( result = v4 + 4 * *((_DWORD *)v3 + 4); // начальное значения для начала цикла v4 != result; // условие выполнение цикла пока истино v4 != result result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) // действие при каждой повторении цикла { v5 = **(_DWORD **)v4; // v5 = адрес группы (v5 теперь является подгруппой *this) v6 = *(_DWORD *)(v5 + 0x6C); // v6 = разрешённых шагов для группы v5 if ( v6 <= a2 ) // если разрешённых шагов меньше например 3, когда попытка пойти на 5, то *(_DWORD *)(v5 + 0x6C) = 0; // присвоить v5 перемещение 0 else // иначе *(_DWORD *)(v5 + 0x6C) = v6 - a2; // присворить v5 разность между разршенными шагами и "сделанными" *(_DWORD *)(v5 + 0x898) = -1; // какое-то интересное смещение +0x898, что означает точно не понятно. // по карайне мере понятно, что оно стаиться в -1, когда v5 было установленно // кол-во разрешённых шагов v4 += 4; // перебираем следующую группу } return result; } Переписываем функцию так, чтобы она давала шаги отряду вместо того чтобы забирать их. int __thiscall Cheat_SetPointMove(void *unit, int a2) { int result; // eax@1 char *v3; // ecx@1 int v4; // esi@1 int v5; // eax@2 int v6; // edx@2 v3 = (char *)unit + 148; v4 = *((_DWORD *)v3 + 5); for ( result = v4 + 4 * *((_DWORD *)v3 + 4); v4 != result; result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) { v5 = **(_DWORD **)v4; v6 = *(_DWORD *)(v5 + 0x6C); if ( v6 <= 1000000 ) *(_DWORD *)(v5 + 0x6C) = a2; *(_DWORD *)(v5 + 0x898) = -1; v4 += 4; } return result; } Эта функция обязательно пригодиться, когда при инициализации чита нужно чтобы сарзу всем героям Пользователя дать необходимое кол-во очков например 500000. void units = GetPlayerObjects(); Cheat_SetPointMove(void &units, 500000); Дальше нужно не вызывать функцию sub_10654450 если units принадлежит не Player. Для этого нужно изменить sub_10654450: int __thiscall sub_10654450(void *this, int a2) { int result; // eax@1 char *v3; // ecx@1 int v4; // esi@1 int v5; // eax@2 int v6; // edx@2 // инъекция пвсевод-кода void playerUnits = GetPlayerObjects(); if (playerUnits==this) { Cheat_SetPointMove(playerUnits,500000) return; } //===================== v3 = (char *)this + 148; v4 = *((_DWORD *)v3 + 5); for ( result = v4 + 4 * *((_DWORD *)v3 + 4); // начальное значения для начала цикла v4 != result; // условие выполнение цикла пока истино v4 != result result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) // действие при каждой повторении цикла { v5 = **(_DWORD **)v4; // v5 = адрес группы (v5 теперь является подгруппой *this) v6 = *(_DWORD *)(v5 + 0x6C); // v6 = разрешённых шагов для группы v5 if ( v6 <= a2 ) // если разрешённых шагов меньше например 3, когда попытка пойти на 5, то *(_DWORD *)(v5 + 0x6C) = 0; // присвоить v5 перемещение 0 else // иначе *(_DWORD *)(v5 + 0x6C) = v6 - a2; // присворить v5 разность между разршенными шагами и "сделанными" *(_DWORD *)(v5 + 0x898) = -1; // какое-то интересное смещение +0x898, что означает точно не понятно. // по карайне мере понятно, что оно стаиться в -1, когда v5 было установленно // кол-во разрешённых шагов v4 += 4; // перебираем следующую группу } return result; } Чтобы функцию перевести на машинныкод, лучше скопироват старую в машинном коде и изменить её. Дальше исследовать пока нет времени. Надо идти вверх по call-ам и разобраться с указателем ecx передаваемым в функцию sub_10654450... Фактически мы должны дойти до развилки имеет ли право идти игрок. Там должен быть код определения игрока. Если это игрок, если его очки хода больше 0, то разрешить ему перемещение. Возможно, будет сложно. Например, один поток который собирает сообщение от ДайректИнпут запишет некоторой новое событие в в некотурую очередь собщений о том что надо пердвинуть отряд, а другой поток будет читать эту очередь... Ладно, дальше будет видно. Что касается вопросов по OllyDbg. OllyDbg видимо снёс Xipho. Поэтому этот вопрос прямо к нему у нас была OllyShadow. Иногда OllyDbg не может обрабатывать инструкции и неизбежно придётся перезагружать процесс игры. И это касается трейсинга. Возможно не повезло. А возможно стоит поставить игнор исключений в настройках. Долго об этом писать. movq вообще интресная инструкция связанная с глюками. Если например она работать с адресом не кратным "как это говорят параграфу", то что-то будет нестабильное... Я думаю если можно как-то в трейсинге отметить что такой-то участок не трейсить, то предлагаю это сделать. По пункту два. Это обычное явление... более прокомментировать как решить проблему с трассировкой не могу, т.к. без понятия.
  14. Как написал Xipho по этому скрипту нет ответа почему именно такие смещения прибавляются к регистрам. Эти смещения я когда-то давно искал в отладчике реверсингом совместно со сканером памяти. Суть в том что по выражению [[core.dll+00155744h]+350h]+43Ch находится указатель на адрес здоровья героя. И если этот адрес совпадает с eax на участке кода куда была сделана инъекция, то записать в этот адрес 250 очков здоровь. Если этого не сделать, то все игроки будут бессмертными. Но что здесь неправильно, а то что имея полноценный указатель чуть более правильнее записывать в него данные без сравнения. Именно эту запись нужно делать циклически [[[core.dll+0x00155744]+0x350]+0x43C] = 250 Вот так... push ebx mov ebx,[core.dll+00155744] mov ebx,[ebx+350] mov byte ptr [ebx+43C],#250 pop ebx originalcode: mov ecx,[eax] mov edx,[esp+04] ....
  15. Откуда такая информация что в большинстве? Лично я в Дисайплс 3 когда-то давно именно таким способом что-то делал и всё работало. На Чемаксе мои посты есть по этому поводу. И никаких хуков на ДайректИнпут я не ставил. //bronis, по заданному вопросу отвечу позже
  16. Может быть и нет разницы... Какое у тебя сообщение вылазит из этих: .rdata:1001C308 aUsingGameVer_0 db 'Using game version 1.0.1',0 .rdata:1001C308 ; DATA XREF: sub_100050D0:loc_10005176o .rdata:1001C321 align 4 .rdata:1001C324 aInitialization db 'Initialization failed -- Unknown game version',0 .rdata:1001C324 ; DATA XREF: sub_100050D0+99o .rdata:1001C352 align 4 .rdata:1001C354 ; char aFailedToDetect[] .rdata:1001C354 aFailedToDetect db 'Failed to detect game version',0 .rdata:1001C354 ; DATA XREF: sub_100050D0:loc_10005152o .rdata:1001C372 align 4 .rdata:1001C374 ; char aUsingGameVersi[] .rdata:1001C374 aUsingGameVersi db 'Using game version 1.0.2',0 .rdata:1001C374 ; DATA XREF: sub_100050D0+5Bo .rdata:1001C38D align 10h .rdata:1001C390 ; char aAutoDetectingG[] .rdata:1001C390 aAutoDetectingG db 'Auto detecting game version',0 .rdata:1001C390 ; DATA XREF: sub_100050D0+2Do .rdata:1001C3AC ; char aProcessBaseAdd[] .rdata:1001C3AC aProcessBaseAdd db 'Process base address: 0x%x',0 Наверно, это "Failed to detect game version" ? ---------------- Меня что-то глюкнуло. Оказывается *.Lib файл это файл содержащий информацию экспорта и импорта относительно ScriptHook.dll описания. Файл нужен для компоновщика чтобы построить SampleCustom.dll корректно работающего с функциями ScriptHook.dll.
  17. Сложно сказать в этом духе или в другом... Смотря как разработчики код игры написали. То что на видео, это сравнение данных структур. Можно не стесняться и брать мног структур. Своего героя, пару ботов из твоей команды и по паре ботов из двух других команд... Определяешь группы и ищешь чем они отличаются. Если найдёшь отличие, то сможешь сделать "фильтр" для совершения какого-то действия...
  18. Приаттач твою SampleCustom.dll в архиве в посте. Что-то я свою SampleCustom.dll собрать не могу из-за ошибок в настройках проекта портированного на VS2010. Завтра я проверю её под отладкой. --- Да и кстати в АА-скриптах CE есть команда "LOADLIBRARY(filename)". Попробуй её. Нужно заранее приаттачить процесс игры. В filename указать полный путь.
  19. На видео вижу только адреса без указателей. Что конкретно не понятно?
  20. По поводу указателей, которые ты привёл на картинке я знаю что они меняются с перезапуском игры. Я не акцентировал внимание на это. Это просто небольшая зацепка для дальнейших поисков статичных указателей и "постоянных фильтров". Но пока я не попробовал метод об определении кто свой, а кто чужой с помощью бряка на щелок мышки, лучше с фильтрами не возиться. Я попробую завтра. Как ставить бряк на клик мышью?! Тут полная статья о клике на кнопку, хотя не важно на что кликать... Но лучше чтобы я это сделал, потому что у меня опыта больше. Так что до завтра.
  21. Пока ничем помочь не могу, может быть на недели попробую разобраться чтобы всё работало.
  22. Если про GTAIV, то для компиляции своей dll-ки нужен файл "ScriptHook.lib", а ScriptHook.dll не требуется. В примере проекта из SVN (на который я указывал ссылку) этот файл ScriptHook.libимеется. Можно скомпилировать пример из SVN например SampleCustom, получится SampleCustom.dll. Её кладём в директории игры и используем асилоадер или просто загружаем эту SampleCustom.dll через Cheat Engine загрузчик без выполнения каких-либо определённых функций в ней. Активируем клавиши и играем со спавном. Разве не так должно быть? Просто я этого не делал, поэтому точно не знаю.
×
×
  • Создать...

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

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