x64dbg: Пример работы с файлом CyberPro13_PatchMe_0x1.exe

0. Настройки точек останова такие (SettingsEvents):

Перевод, плюс дополнение к статье Messages Breakpoints in x64dbg. Там рассказывается о методе перехвата системных сообщений для работы с событиями (нажатие клавиши мыши, кнопки клавиатуры и т.п.). В принципе интересно, поэтому я и начал изучать статью, параллельно делая её перевод (на сколько мог, т.к. я не хакер и не переводчик).

 

1. Открываем файл в x32dbg (т.к. это 32-битное приложение)
FileOpen
2. Выбираем файл CyberPro13_PatchMe_0x1.exe
3. Дебаггер останавливается на системной точке останова:

System breakpoint reached

4. Возобновляем выполнение (F9 ):
MenuDebugRun
5. Происходит остановка на прерывании (INT3), поэтому продолжаем выполнять, для этого нажимаем клавишу F9 .
6. Запускается окошко CyberPro13_PatchMe_0x1:

7. Поскольку исследуемая программа полностью загрузилась, в дебаггере переходим на вкладку Handles (в данный момент содержимое вкладки пусто):

8. На пустом поле нажимаем правую кнопку мыши и выбираем Refresh (Либо сразу нажимаем F5 ):

9. В списке нужно будет выбрать класс кнопки «Check»:

10. Нажав на нём правую кнопку мыши, выбираем пункт Message Breakpoint:

11. Появится окошко, где нужно выбрать условие точки останова (здесь отметим пункт Break on current window only):

12. В выпадающем списке выберем нужное условие (WM_LBUTTONUP — произошёл щелчок левой кнопки мышки):

13. После этого в тестовом приложении нажимаем кнопку Check, что должно вызвать остановку по заданному в п.12 условию:

Логика программы


Мы добились результата — выполнение программы остановлено сразу же после нажатия левой кнопки мыши. При этом мы всё ещё находимся в системной библиотеке user32.dll, нам же нужна логика исследуемой программы. В ту часть можно попасть, если нажать Alt+F9 (Run to User Code). Также можно попасть в модуль самой программы, если перейти на вкладку Memory Map, после чего добавить ещё одну точку останова.

Run to User Code в данном примере у меня не сработал. Для примера из этой заметки всё работало! Баг это или особенность программы, но здесь это не работает (версия x32dbg Mar 12 2021, 02:08:45)

 

14. Добавим точку останова на обращение к адресу памяти (фрагмент кода программы):
[Executable code] ▶ Memory breakpointExecuteSingleshoot

15. Теперь в списке точек останова появилась новая запись:

16. Если теперь продолжить выполнение программы (F9 ), то она снова остановится, но на этот раз в середине кода, который мы ищем (в нашем случае это DLGPROC, в конце которого код вызова SendMessageA):

А дальше я не совсем понял, к чему мы идём, т.к. автор начал рассуждения на тему тонкостей Событийно-ориентированное программирования, а также сделал кучу цитат с msdn и всё это было бы наверное познавательно, если бы автор не начал с примера взлома программы. Пример взлома, который ничем не кончился! Я нашёл решение этой задачи (автор br0ken) и переведу его далее…

 

Решение от br0ken

Хакер (пусть будет хакер) br0ken, делал отладку на дебаггере Olly, но по сути он мало чем отличается от x64dbg, поэтому я лишь немного переделаю его решение.
Опущу первые шаги по изучению данного кода, т.к. для нас они большой роли не играют. Но, если интересно, можно изучить описание полностью (оно в самом конце страницы по ссылке на вкладке Solutions).
17. Открываем исследуемый файл в x32dbg.
18. Нажав F9 мы останавливаемся на первой точке останова — EntryPoint
19. Продолжаем выполнение до появления окошка программы
20. Правой кнопкой мышки вызываем контекстное меню и выбираем:
Search forCurrent ModuleString references
21. На вкладке с результатами поиска «Strings (cyberpro13_patchme_0x1.exe)» открываем первый результат со строкой «good job»:

22. Сделав на нём двойной щелчок мыши, перейдём к нужному адресу (00401914):

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

 

24. Запускаем поиск по вызовам между модулями (Intermodular Calls):
Search forCurrent ModuleIntermodular Calls
25. На вкладке с результатами поиска двойным щелчком мыши выбираем искомую строку (strlen):

Чтобы быть честным, отмечу, что в поиске присутствует два вызова функции проверки длины строки. Поскольку автор выбрал один из вариантов, я его и использовал в примере. Просто имейте ввиду, что был и второй вариант. А это может привести к совершенно другому результату ;)

 

26. Мы перешли к участку кода, где происходит проверка длины строки:

Можно пропатчить этот код так, чтобы потом происходил переход на нужный адрес (который мы нашли в п.22). Для этого сразу после вызова функции проверки длины строки, вызовем преход на нужный адрес.

 

27. Установим курсор на следующую строчку:

004012A1 | 89C2                     | mov edx,eax                                                   |

28. Теперь нажмём пробел Space , чтобы в окошко ввода вписать новую инструкцию:

jmp 0x00401914

29. Получилось так:

Результат


30. Нажимаем Ctrl+P и патчим файл:

31. Теперь после запуска программы и нажатия кнопки Check надпись сменится на нужную нам:

Я не считаю данное решение правильным, но оставляю его, т.к. на текущий момент у меня нет другого.

 

0 0 vote
Article Rating
Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments