Сейчас на форуме: bezumchik, tyns777, Lohmaty (+7 невидимых)

 eXeL@B —› Вопросы новичков —› Анализ одного шахматного бота.
Посл.ответ Сообщение

Ранг: 0.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 июня 2019 07:13 · Поправил: artbotva
· Личное сообщение · #1

Доброго времени суток!

Решил освоить реверс-инжиниринг, хотя бы в общих чертах. Первым объектом была программа для тестов, но там оказалось слишком просто. Хотелось бы попробовать что-то по сложнее, но без фанатизма. Выбрал один из ботов для шахмат.
Есть 2 версии, собственно демо и полная. Полную купить не получилось, работаем с демо, разница в том, что в демо они как-то его испортили что просчитывает ходы он так себе (просто ужасно), и имеет 6 ходов, после 6 ходов программу нужно перезапускать.

Окей, кидаю программу в peid, пишет защиты нету, компилятор delphi 7.


Закидываю в ida, вижу что есть сегмент .upx0.


Хорошо, ищу чем распаковать. Находятся куча всякого софта, но он как и полагается не работает, и не видит сам upx. На этом моменте я решил не продолжать копать в направлении распаковки.
Немного поигрался в ollydbg, строчки за которые можно зацепится он не находит (именно за строчки я цеплялся при кряке теста). Почитав информацию, я предположил что нужные строчки скрыл upx.

Решил попробовать другие exe исследователи, один выдал такое:


Честно говоря я не совсем понял зачем там это API, потому что цеплял различные дебаггеры и изменений в работе программы не видел (может плохо смотрел?). В документации к этому API всё просто, когда есть дебаггер возвращает not null, когда нет null. Находим в дебаггере работу этой функции

Заменяю на
Code:
  1. mov byte ptr [rax+02],00

Собственно никаких изменений в работе я не обнаружил.

Дальше я решил поискать значения (как я понял на этом форуме это не признают), ведь известно сколько даётся ходов, и скорее всего где-то счетчик. Окей, находим это:


Если заморозить значения то программа магическим образом работает 12 ходов вместо 6, а после просто перестает работать. Очень странно (для меня). Собственно вот сколько раз вызываются инструкции к одному из найденных адресов после завершения 7 "бесплатных ходов". (Программа то дает 6 ходов, то 7, но это скорее всего баг).

Вообще мне это очень сильно напоминает счетчик, пробую поставить
Code:
  1. nop
вместо
Code:
  1. mov eax,[edx]
И тут программа пишет что количество ходов исчерпано, хотя я походил только 1 раз. Ну я посчитал это каким-никаким прогрессом, только ни на какую гениальную мысль это меня, к сожалению, не наводит. Какие-то очевидные решения по типу поменять регистры местами не приводят не к чему.

Собственно на этом пока я и остановился, я не стал расписывать свои попытки работы в дебаггере, потому что они собственно не дали никаких результатов. Может кто-нибудь из местных спецов наведет на правильную мысль?

P.S. Мне эта программа совершенно не нужна, она не может обыграть бота 5 лвл, не ставит мат в очевидных местах (искусственные ограничения). Даже я играю лучше. Так что все мои исследования это чистый спортивный интерес.

P.S.S. Не уверен что тут принято распространят exe и ссылки, поэтому напишу просто что бот находится первой же строчкой по запросу chess bot в гугле. Триал версия скачивается там же без регистрации и смс



Ранг: 262.5 (наставник), 337thx
Активность: 0.340.25
Статус: Участник

Создано: 07 июня 2019 07:48
· Личное сообщение · #2

Господа, торжественно объявляю открытие 20го сезона Битвы Экстрасенсов!




Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 07 июня 2019 08:00 · Поправил: plutos
· Личное сообщение · #3

artbotva пишет:
Может кто-нибудь из местных спецов наведет на правильную мысль?

я так и не понял, в чем вопрос... много слов, слишком много...

-----
Give me a HANDLE and I will move the Earth.




Ранг: 0.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 июня 2019 08:17
· Личное сообщение · #4

plutos пишет:
я так и не понял, в чем вопрос


Почему при заморозке значений программа даёт 12 ходов вместо 6?
Почему никакая из программ не может найти upx? Я прочитал что это опенсорс проект, значит ли это что упаковщик модифицировали?
Зачем в программе isDebuggerPresent, если на обнаружение не задано последующих действий. Могут ли быть какие-то скрытые инструкции? Как их найти.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 08:28
· Личное сообщение · #5

artbotva

> Почему при заморозке значений программа даёт 12 ходов вместо 6?

А кто его знает, вы ведь не привели саму обработку, логика не известна.

> Дальше я решил поискать значения (как я понял на этом форуме это не признают)

Скан памяти хороший способ найти нужный счётчик. Вот только если он не фиксирован как какое то смещение, то такой адрес совершенно бесполезен. Тогда привязка делается к выбирающему по адресу коду.

Лучшего способа чем скан нет, точнее более простого. В идеале следует сравнить два CFG, но для этого нет готовых инструментов с кнопками.

> Почему никакая из программ не может найти upx?

Зачем вам знать что там слой протектора, если это не вирт машина, вы же с памятью работаете - там всё распаковано и настроено. Думать про протектор следует при внесении изменений в сам файл, причём без использования загрузчиков, только лишь в этом случае нужна распаковка.

-----
vx





Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 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.





Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 10:30
· Личное сообщение · #7

Code:
  1. 008A787D mov edx,dword ptr ds:[eax]
  2. 008A787F neg cl
  3. 008A7881 mov dword ptr ds:[edi],edx
  4. 008A7883 clc
  5. 008A7884 bt ecx,eax
  6. 008A7887 mov ecx,dword ptr ds:[esi]
  7. 008A7889 stc
  8. 008A788A test edi,77D11FBE
  9. 008A7890 lea esi,dword ptr ds:[esi+4]
  10. 008A7896 xor ecx,ebx
  11. 008A7898 ror ecx,1
  12. 008A789A cmp di,si
  13. 008A789D test cl,0E1
  14. 008A78A0 not ecx
  15. 008A78A2 test cx,bp
  16. 008A78A5 lea ecx,dword ptr ds:[ecx+E64AEE8A]
  17. 008A78AB test sp,di
  18. 008A78AE cmp bx,di
  19. 008A78B1 neg ecx
  20. 008A78B3 clc
  21. 008A78B4 xor ebx,ecx
  22. 008A78B6 cmc
  23. 008A78B7 clc
  24. 008A78B8 add ebp,ecx
  25. 008A78BA push ebp
  26. 008A78BB ret


Похоже на vmp.

> Вообще мне это очень сильно напоминает счетчик, пробую поставить

NOP не изменяет контекст, тоесть регистр содержит произвольные данные, а не значение счётчика.

> Если заморозить значения то программа магическим образом работает 12 ходов

Что такое заморозить" ?

Добавлено спустя 11 минут
А есчо я не пойму как такое может быть, что у вас функция 86(те mov EAX), а ассемблируется в 64:

> mov byte ptr [RAX+02],00

Эти инструкции кодируются по разному. Вы что то напутали с отладчиком

-----
vx





Ранг: 271.2 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 07 июня 2019 11:15
· Личное сообщение · #8

Проверка наличия отладчика далеко не всегда часть защиты, сами эти функции не ради защит существуют, а для более эффективной отладки. Программа может например DbgPrint'ом выводить информацию в отладчик, если его обнаружит, или что-то еще в этом роде.

-----
2 оттенка серого





Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 11:19
· Личное сообщение · #9

f13nd

Там условная конструкция, внутри вызовы гуя и есчо каких то функций. Внутри тоже условная конструкция, которая не выполняется. Тоесть это не просто холостой вызов.

-----
vx





Ранг: 271.2 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 07 июня 2019 11:20
· Личное сообщение · #10

difexacaw
Очевидно какая-то опция в настройках проекта не включена, дельфи чемпион по избыточному коду.

-----
2 оттенка серого





Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 07 июня 2019 11:23
· Личное сообщение · #11

artbotva пишет:
кидаю программу в peid, пишет защиты нету

а в другие ?




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 11:27
· Личное сообщение · #12

f13nd

Вот это место:

Code:
  1. 0063BCC0  cmp dword ptr ds:[69A450],0
  2. 0063BCC7  je short 0063BCD0
  3. 0063BCC9  call dword ptr ds:[69A450]                                      ; kernel32.IsDebuggerPresent
  4. 0063BCCF  ret
  5. 0063BCD0  mov al,1
  6. 0063BCD2  ret


Code:
  1. 005B471C  call 0063BCC0
  2. 005B4721  test al,al
  3. 005B4723  jnz short 005B4756
  4. 005B4725  mov eax,dword ptr ds:[ebx+34]
  5. 005B4728  mov eax,dword ptr ds:[eax+264]
  6. 005B472E  call 0046C2E4
  7. 005B4733  push eax
  8. 005B4734  call <jmp.&user32.UpdateWindow>
  9. 005B4739  push 485
  10. 005B473E  push 0
  11. 005B4740  push 0
  12. 005B4742  mov eax,dword ptr ds:[ebx+34]
  13. 005B4745  mov eax,dword ptr ds:[eax+264]
  14. 005B474B  call 0046C2E4


Далее вложенные функи и проверка:

Code:
  1. 0046C2C3  cmp dword ptr ds:[ebx+180],0
  2. 0046C2CA  jnz short 0046C2E2


Завершающая вызов. А есчо импорт динамический этой апи. Тоесть тс ошибся утверждая что вызов холостой.

-----
vx




Ранг: 0.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 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 раз. Это многое поменяло для меня.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 07 июня 2019 11:41
· Личное сообщение · #14

а более современных и актуальных детекторов не нашлось ?




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 11:53
· Личное сообщение · #15

artbotva

> Каждые 100мс cheat engine меняет значение на то, которое было когда ты замораживал значение.

Так за это время может быть сколько угодно изменений и чтений переменной. Тоесть ваши действия с переменной асинхронны и не ясно как влияют на апп. Так нельзя делать, в произвольный момент времени менять значение.

-----
vx




Ранг: 0.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 июня 2019 12:56
· Личное сообщение · #16

reversecode пишет:
а более современных и актуальных детекторов не нашлось ?


А можете привести пару примеров современных детекторов? Я видимо плохо искал.


difexacaw пишет:
Так за это время может быть сколько угодно изменений и чтений переменной. Тоесть ваши действия с переменной асинхронны и не ясно как влияют на апп. Так нельзя делать, в произвольный момент времени менять значение.


В настройках можно поставить 1мс, но даже так в теории будет асинхронно. Я это написал к тому, что это действие имеет эффект, и возможно как-то косвенно связан с тем самым нужным счетчиком.

Хотел уточнить что при заморозке программа завершает часть себя без ошибки (без заморозки она пишет что мол что это была триальная версия бла-бла-бла). Т.е. как мне кажется при старте (именно при нажатии кнопки запуска бота) программа подгружает какой-то из своих сегментов (наверное как раз один из тех что обозвали upx), и возможно тот запакованный сегмент содержит свой автономный счетчик. А тот что я нашел сканированием это счетчик для вывода сообщения об окончании бесплатных ходов. В таком случае остается вопрос к инструкциям 0095615F и 009DC560, почему при их модификации они могут остановить программу раньше времени (до 6 ходов) и вывести сообщение триальной версии.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 07 июня 2019 12:57 · Поправил: reversecode
· Личное сообщение · #17

попробуйте внимательно посмотреть
--> Link <--




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 13:05
· Личное сообщение · #18

artbotva

> В таком случае остается вопрос к инструкциям 0095615F и 009DC560

А как вы их нашли собственно, там выборка каких то строк по этим адресам, а не обращение к счётчику.

> почему при их модификации они могут остановить программу

При патче на nop инструкция удаляется, контекст становится не определённым. Соответственно поведение апп тоже.

Одна и та же функция может обращаться к разным областям памяти, не только к вашему счётчику. Если тупо убрать из кода такую инструкцию, то всё сломается.

Если ты думаешь что парой тулз с кнопками это можно решить, то тебя ждёт epic fail.

-----
vx




Ранг: 0.4 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 июня 2019 13:23 · Поправил: artbotva
· Личное сообщение · #19

difexacaw пишет:
Если тупо убрать из кода такую инструкцию, то всё сломается.

Разве не на это идет изначальный замысел? Разница ведь в том, что сейчас программа сломалась в обратную от нужной сторону.

difexacaw пишет:
Если ты думаешь что парой тулз с кнопками это можно решить, то тебя ждёт epic fail.

Для меня был бы фейл если бы эта программа сломалась парой кнопок. Я же написал, что она мне совершенно не нужна, это всего лишь объект для изучения.

difexacaw пишет:
В идеале следует сравнить два CFG


Можете поподробнее рассказать что вы имеете ввиду.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 13:31
· Личное сообщение · #20

artbotva

>> В идеале следует сравнить два CFG
> Можете поподробнее рассказать что вы имеете ввиду.

Поведение кода отличается после проверки счётчика. Сам поток инструкций это абстракция, он описывается графом(cfg). Соответственно значение счётчика изменяет граф. Но для этого нужно как минимум собрать трассу. Вы это сделать не сможете, так как нет нужных инструментов, либо их нужно компилировать, те кодить.

-----
vx




Ранг: 58.3 (постоянный), 50thx
Активность: 0.040.08
Статус: Участник

Создано: 07 июня 2019 14:10
· Личное сообщение · #21

difexacaw пишет:
Соответственно значение счётчика изменяет граф.


Извините, мэтр, что вмешиваюсь, но вроде бы должен меняться только путь обхода графа?
Вот ТС и недоумевает, какие графы надо сравнивать?
Граф-то может поменяться, если вы в код вносить изменения будете.
Вы уж постарайтесь выражаться поосторожней и поконкретней (это без всякой иронии и подколов),
если хотите, чтоб вас читали и не привязывались к отдельным словам и оборотам.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 16:27
· Личное сообщение · #22

DrVB_5_6

Верно, только какая разница. Ни ты и тем более тс это использовать не можете. У вас для этого нет инструмента. Идой чтоле трассировать на скриптах лол

-----
vx





Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 07 июня 2019 17:21 · Поправил: reversecode
· Личное сообщение · #23

надо сначала определить что там вмпрот и тему закрывать не флудя



Ранг: 44.8 (посетитель), 19thx
Активность: 0.040
Статус: Участник

Создано: 07 июня 2019 18:51
· Личное сообщение · #24

вы норкоманы чтоле? какие графы при исполнении?
выполняемый код линеен
максимум при исполнении кода может быть граф в предсказателе переходов но ето скрыто от программиста




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 07 июня 2019 21:08
· Личное сообщение · #25

SegFault

Можно и трассой назвать, мне более привычно графом. Короче последовательность инструкций. А как есчо найти счётчик ?

Последовательность изменится при переполнении счётчика. Для этого нужно сохранить эту последовательность. Я не уверен что это можно провернуть через отладчик.

-----
vx





Ранг: 241.9 (наставник), 107thx
Активность: 0.140.01
Статус: Участник

Создано: 12 июня 2019 10:01
· Личное сообщение · #26

А тебя не смущает, что трасса может легко меняться от расчетов бота или прилетающим сообщениям от системы и пользователя? Так годами можно трассу изучать.




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 24 июня 2019 15:38 · Поправил: difexacaw
· Личное сообщение · #27

Nightshade

Решил идею проверить. Условные ветвления отмечаются в битовой карте, так же там помечается результат ветвления, простейшее накопление ветвлений по сути. Взял для теста первое что под руку попалось - winhex.

Сначала ветвления накапливаются, я выполняю действия с двумя дампами, но у которого размер больший не сохраняю. Затем ветвления начинают накапливаться во вторую карту и я сохраняю дамп, появляется сообщение про ограничение размера. Далее сравниваются две карты, разница в лог.



Если сбросить карты и действия повторить, то лог будет содержать менее десятка событий. Как видно метод рабочий, просто его нужно проработать, что бы фильтровать события.

cd93_24.06.2019_EXELAB.rU.tgz - jcc.7z

-----
vx



 eXeL@B —› Вопросы новичков —› Анализ одного шахматного бота.
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати