![]() |
eXeL@B —› Вопросы новичков —› Анализ одного шахматного бота. |
Посл.ответ | Сообщение |
|
Создано: 07 июня 2019 07:13 · Поправил: artbotva · Личное сообщение · #1 Доброго времени суток! Решил освоить реверс-инжиниринг, хотя бы в общих чертах. Первым объектом была программа для тестов, но там оказалось слишком просто. Хотелось бы попробовать что-то по сложнее, но без фанатизма. Выбрал один из ботов для шахмат. Есть 2 версии, собственно демо и полная. Полную купить не получилось, работаем с демо, разница в том, что в демо они как-то его испортили что просчитывает ходы он так себе (просто ужасно), и имеет 6 ходов, после 6 ходов программу нужно перезапускать. Окей, кидаю программу в peid, пишет защиты нету, компилятор delphi 7. ![]() Закидываю в ida, вижу что есть сегмент .upx0. ![]() Хорошо, ищу чем распаковать. Находятся куча всякого софта, но он как и полагается не работает, и не видит сам upx. На этом моменте я решил не продолжать копать в направлении распаковки. Немного поигрался в ollydbg, строчки за которые можно зацепится он не находит (именно за строчки я цеплялся при кряке теста). Почитав информацию, я предположил что нужные строчки скрыл upx. Решил попробовать другие exe исследователи, один выдал такое: ![]() Честно говоря я не совсем понял зачем там это API, потому что цеплял различные дебаггеры и изменений в работе программы не видел (может плохо смотрел?). В документации к этому API всё просто, когда есть дебаггер возвращает not null, когда нет null. Находим в дебаггере работу этой функции ![]() Заменяю на Code:
Собственно никаких изменений в работе я не обнаружил. Дальше я решил поискать значения (как я понял на этом форуме это не признают), ведь известно сколько даётся ходов, и скорее всего где-то счетчик. Окей, находим это: ![]() Если заморозить значения то программа магическим образом работает 12 ходов вместо 6, а после просто перестает работать. Очень странно (для меня). Собственно вот сколько раз вызываются инструкции к одному из найденных адресов после завершения 7 "бесплатных ходов". (Программа то дает 6 ходов, то 7, но это скорее всего баг). ![]() Вообще мне это очень сильно напоминает счетчик, пробую поставить Code:
Code:
Собственно на этом пока я и остановился, я не стал расписывать свои попытки работы в дебаггере, потому что они собственно не дали никаких результатов. Может кто-нибудь из местных спецов наведет на правильную мысль? P.S. Мне эта программа совершенно не нужна, она не может обыграть бота 5 лвл, не ставит мат в очевидных местах (искусственные ограничения). Даже я играю лучше. Так что все мои исследования это чистый спортивный интерес. P.S.S. Не уверен что тут принято распространят exe и ссылки, поэтому напишу просто что бот находится первой же строчкой по запросу chess bot в гугле. Триал версия скачивается там же без регистрации и смс ![]() |
|
Создано: 07 июня 2019 07:48 · Личное сообщение · #2 |
|
Создано: 07 июня 2019 08:00 · Поправил: plutos · Личное сообщение · #3 |
|
Создано: 07 июня 2019 08:17 · Личное сообщение · #4 plutos пишет: я так и не понял, в чем вопрос Почему при заморозке значений программа даёт 12 ходов вместо 6? Почему никакая из программ не может найти upx? Я прочитал что это опенсорс проект, значит ли это что упаковщик модифицировали? Зачем в программе isDebuggerPresent, если на обнаружение не задано последующих действий. Могут ли быть какие-то скрытые инструкции? Как их найти. ![]() |
|
Создано: 07 июня 2019 08:28 · Личное сообщение · #5 artbotva > Почему при заморозке значений программа даёт 12 ходов вместо 6? А кто его знает, вы ведь не привели саму обработку, логика не известна. > Дальше я решил поискать значения (как я понял на этом форуме это не признают) Скан памяти хороший способ найти нужный счётчик. Вот только если он не фиксирован как какое то смещение, то такой адрес совершенно бесполезен. Тогда привязка делается к выбирающему по адресу коду. Лучшего способа чем скан нет, точнее более простого. В идеале следует сравнить два CFG, но для этого нет готовых инструментов с кнопками. > Почему никакая из программ не может найти upx? Зачем вам знать что там слой протектора, если это не вирт машина, вы же с памятью работаете - там всё распаковано и настроено. Думать про протектор следует при внесении изменений в сам файл, причём без использования загрузчиков, только лишь в этом случае нужна распаковка. ----- vx ![]() |
|
Создано: 07 июня 2019 08:48 · Поправил: plutos · Личное сообщение · #6 artbotva пишет: Зачем в программе isDebuggerPresent, если на обнаружение не задано последующих действий ну это вопрос к автору программы: зачем он влепил проверку? Бывают страные программисты: мне пришлось разбирать программу, написаную одной дурой из Индии. Она в UI налепила чуть не 20 check box'oв и НИ СТРОЧКИ КОДА в EVENT HANDLERS, реагирующих на их state. Зато UI выглядел очень презентабельно! Так что ломать голову не стоит, вам же меньше хлопот. ----- Give me a HANDLE and I will move the Earth. ![]() |
|
Создано: 07 июня 2019 10:30 · Личное сообщение · #7 Code:
Похоже на vmp. > Вообще мне это очень сильно напоминает счетчик, пробую поставить NOP не изменяет контекст, тоесть регистр содержит произвольные данные, а не значение счётчика. > Если заморозить значения то программа магическим образом работает 12 ходов Что такое заморозить" ? Добавлено спустя 11 минут А есчо я не пойму как такое может быть, что у вас функция 86(те mov EAX), а ассемблируется в 64: > mov byte ptr [RAX+02],00 Эти инструкции кодируются по разному. Вы что то напутали с отладчиком ![]() ----- vx ![]() |
|
Создано: 07 июня 2019 11:15 · Личное сообщение · #8 |
|
Создано: 07 июня 2019 11:19 · Личное сообщение · #9 |
|
Создано: 07 июня 2019 11:20 · Личное сообщение · #10 |
|
Создано: 07 июня 2019 11:23 · Личное сообщение · #11 |
|
Создано: 07 июня 2019 11:27 · Личное сообщение · #12 f13nd Вот это место: Code:
Code:
Далее вложенные функи и проверка: Code:
Завершающая вызов. А есчо импорт динамический этой апи. Тоесть тс ошибся утверждая что вызов холостой. ----- vx ![]() |
|
Создано: 07 июня 2019 11:38 · Личное сообщение · #13 difexacaw пишет: у вас функция 86(те mov EAX), а ассемблируется в 64 Oops, видимо не туда посмотрел когда писал. difexacaw пишет: Что такое заморозить" ? Каждые 100мс cheat engine меняет значение на то, которое было когда ты замораживал значение. reversecode пишет: а в другие ? Пробовал пак с этого сайта, все программы ничего не показывали. Тот же RDG Packer Detector (его вроде не было в паке) показал только что присутствует isDebuggerPresent. Я только сейчас обнаружил что различие в числе ходов связано так: когда advisor mode (когда ты ходишь вручную) включен ты можешь походить 6-7 раз, когда он выключен (за тебя ходит программа) ходишь 12 раз. Это многое поменяло для меня. ![]() |
|
Создано: 07 июня 2019 11:41 · Личное сообщение · #14 |
|
Создано: 07 июня 2019 11:53 · Личное сообщение · #15 artbotva > Каждые 100мс cheat engine меняет значение на то, которое было когда ты замораживал значение. Так за это время может быть сколько угодно изменений и чтений переменной. Тоесть ваши действия с переменной асинхронны и не ясно как влияют на апп. Так нельзя делать, в произвольный момент времени менять значение. ----- vx ![]() |
|
Создано: 07 июня 2019 12:56 · Личное сообщение · #16 reversecode пишет: а более современных и актуальных детекторов не нашлось ? А можете привести пару примеров современных детекторов? Я видимо плохо искал. difexacaw пишет: Так за это время может быть сколько угодно изменений и чтений переменной. Тоесть ваши действия с переменной асинхронны и не ясно как влияют на апп. Так нельзя делать, в произвольный момент времени менять значение. В настройках можно поставить 1мс, но даже так в теории будет асинхронно. Я это написал к тому, что это действие имеет эффект, и возможно как-то косвенно связан с тем самым нужным счетчиком. Хотел уточнить что при заморозке программа завершает часть себя без ошибки (без заморозки она пишет что мол что это была триальная версия бла-бла-бла). Т.е. как мне кажется при старте (именно при нажатии кнопки запуска бота) программа подгружает какой-то из своих сегментов (наверное как раз один из тех что обозвали upx), и возможно тот запакованный сегмент содержит свой автономный счетчик. А тот что я нашел сканированием это счетчик для вывода сообщения об окончании бесплатных ходов. В таком случае остается вопрос к инструкциям 0095615F и 009DC560, почему при их модификации они могут остановить программу раньше времени (до 6 ходов) и вывести сообщение триальной версии. ![]() |
|
Создано: 07 июня 2019 12:57 · Поправил: reversecode · Личное сообщение · #17 |
|
Создано: 07 июня 2019 13:05 · Личное сообщение · #18 artbotva > В таком случае остается вопрос к инструкциям 0095615F и 009DC560 А как вы их нашли собственно, там выборка каких то строк по этим адресам, а не обращение к счётчику. > почему при их модификации они могут остановить программу При патче на nop инструкция удаляется, контекст становится не определённым. Соответственно поведение апп тоже. Одна и та же функция может обращаться к разным областям памяти, не только к вашему счётчику. Если тупо убрать из кода такую инструкцию, то всё сломается. Если ты думаешь что парой тулз с кнопками это можно решить, то тебя ждёт epic fail. ----- vx ![]() |
|
Создано: 07 июня 2019 13:23 · Поправил: artbotva · Личное сообщение · #19 difexacaw пишет: Если тупо убрать из кода такую инструкцию, то всё сломается. Разве не на это идет изначальный замысел? Разница ведь в том, что сейчас программа сломалась в обратную от нужной сторону. difexacaw пишет: Если ты думаешь что парой тулз с кнопками это можно решить, то тебя ждёт epic fail. Для меня был бы фейл если бы эта программа сломалась парой кнопок. Я же написал, что она мне совершенно не нужна, это всего лишь объект для изучения. difexacaw пишет: В идеале следует сравнить два CFG Можете поподробнее рассказать что вы имеете ввиду. ![]() |
|
Создано: 07 июня 2019 13:31 · Личное сообщение · #20 artbotva >> В идеале следует сравнить два CFG > Можете поподробнее рассказать что вы имеете ввиду. Поведение кода отличается после проверки счётчика. Сам поток инструкций это абстракция, он описывается графом(cfg). Соответственно значение счётчика изменяет граф. Но для этого нужно как минимум собрать трассу. Вы это сделать не сможете, так как нет нужных инструментов, либо их нужно компилировать, те кодить. ----- vx ![]() |
|
Создано: 07 июня 2019 14:10 · Личное сообщение · #21 difexacaw пишет: Соответственно значение счётчика изменяет граф. Извините, мэтр, что вмешиваюсь, но вроде бы должен меняться только путь обхода графа? Вот ТС и недоумевает, какие графы надо сравнивать? Граф-то может поменяться, если вы в код вносить изменения будете. Вы уж постарайтесь выражаться поосторожней и поконкретней (это без всякой иронии и подколов), если хотите, чтоб вас читали и не привязывались к отдельным словам и оборотам. ![]() |
|
Создано: 07 июня 2019 16:27 · Личное сообщение · #22 |
|
Создано: 07 июня 2019 17:21 · Поправил: reversecode · Личное сообщение · #23 |
|
Создано: 07 июня 2019 18:51 · Личное сообщение · #24 |
|
Создано: 07 июня 2019 21:08 · Личное сообщение · #25 |
|
Создано: 12 июня 2019 10:01 · Личное сообщение · #26 |
|
Создано: 24 июня 2019 15:38 · Поправил: difexacaw · Личное сообщение · #27 Nightshade Решил идею проверить. Условные ветвления отмечаются в битовой карте, так же там помечается результат ветвления, простейшее накопление ветвлений по сути. Взял для теста первое что под руку попалось - winhex. Сначала ветвления накапливаются, я выполняю действия с двумя дампами, но у которого размер больший не сохраняю. Затем ветвления начинают накапливаться во вторую карту и я сохраняю дамп, появляется сообщение про ограничение размера. Далее сравниваются две карты, разница в лог. ![]() Если сбросить карты и действия повторить, то лог будет содержать менее десятка событий. Как видно метод рабочий, просто его нужно проработать, что бы фильтровать события. ![]() ----- vx ![]() |
![]() |
eXeL@B —› Вопросы новичков —› Анализ одного шахматного бота. |