Для сравнения вводимого пароля с эталонным значением чаще всего применяют строковые команды. Достоинством применения таких команд, в данном случае, является сокращение кода. Учитывать быстродействие при выполнении сравнения и медленном клавиатурном вводе как-то не уместно. В программе 2.5 применена процедура Pas1 proc, которая влияет только на оформление программы. Но если процедур будет достаточно много, то это сильно повлияет на поиск пароля. А если при этом предположить, что и сравнение паролей будет происходить в процедуре, то поиск пароля будет через чур затруднителен.
Программа 2.5. Использование строковых команд с запросом пароля:
Рассмотрим программу определения количества элементов массива, которые равняются 128 и вывода директории расположения этой программы на логическом диске. Эту программу в дальнейшем соединим с программой запроса пароля (программа 2.6).Код (ASM):
include win64a.inc ;Pas1 PROTO .data Password db "12345" ; проверка только первых пяти символов len1 equ ($-Password)/type Password Buf dq 5 ; Err1 dq 0 Msg1 db "Пароль совпал",0 Msg2 db "Пароль не корректен",0 Title1 db "Проверка пароля",0 stdout dq 0 ; stdin dq 0 ; cRead dq 0 ; cWritten dq 0 ; Msg db "Please enter your password, 5 characters",10,10,0 ; .code Pas1 proc lea rsi,Password ;адрес первого элемента строки lea rdi,Buf ;адрес второго элемента строки mov rcx,len1 repe cmpsb ;побайтно проверяется len раз jz m2 ; inc Err1 ; счетчик несовпадений m2: ret Pas1 endp WinMain proc sub rsp,28h; mov rbp,rsp invoke GetStdHandle,STD_OUTPUT_HANDLE mov stdout,rax invoke GetStdHandle,STD_INPUT_HANDLE mov stdin,rax invoke WriteConsole,stdout,ADDR Msg,sizeof Msg,ADDR cWritten,0 invoke ReadConsole,stdin,ADDR Buf,5,ADDR cRead,0 invoke Pas1 .if (Err1==0); invoke MessageBox,0,addr Msg1,addr Title1,MB_OK .else invoke MessageBox,0,addr Msg2,addr Title1,MB_OK .endif invoke RtlExitUserProcess,0 ;ExitProcess,0 WinMain endp end
Программа 2.6.
;Посчитать количество элементов массива, которые равны 128
;и вывести директорию расположения программы
Эта программа не консольная. Следовательно, при получении ехе-файла необходимо использовать bat-файл, в котором присутствуют командные слова SUBSYSTEM:WINDOWS.Код (ASM):
include win64a.inc ; .data mas1 db 5,17,128,69,5,17,128,69,5,17,128,128 ; массив данных len1 equ ($-mas1)/type mas1 ; длина массива titl1 db "Массив. (masm64)",0 buf1 dq 1 dup(0),0 ; fmt db "Вывести кол. элементов массива из 12 чисел, которые равняются 128.",10,10, "Количество повторений числа 128 - %d",10, "Директория программы: - %s",10,10, "Автор: Рысованый А.Н.,НТУ ХПИ",0 dir db 256 dup(0) ;переменная для хранения пути к текущей директории count_128 dq 0 .code WinMain proc sub rsp,28h mov rbp,rsp lea rdi,mas1 ; адрес начала элементов массива mov rcx,len1 ; кол. чисел массива cycle: movzx rax,byte ptr [rdi] ; занесение байтового адреса элемента массива cmp rax,128 ; сравнение элемента массива с 128 jz inc128 ; переход на inc128 при совпадении jmp skip ; иначе продолжить inc128: inc count_128 ; +1 к счётчику повторений числа 128 skip: inc rdi ; loop cycle invoke GetCurrentDirectory,255,addr dir; получение директории invoke wsprintf,addr buf1,addr fmt,count_128,addr dir invoke MessageBox,0,addr buf1,addr titl1,MB_OKCANCEL + MB_ICONQUESTION invoke RtlExitUserProcess,0 ; ExitProcess,0 WinMain endp end
Результат выполнения программы 2.6 приведен на рис. 2.9.
В начале программы командой lea rdi,mas1 заносится адрес начала массива. Счетчик количества чисел массива организован в регистре rcx.
Цикл анализа чисел массива на равенство числу 128 организован по метке cycle.
В этом цикле сначала считывается из массива первое число и расширяется до формата регистра rax, в которое и заносится. Затем командой cmp rax,128 сравнивается (операция вычитания) с числом 128. В случае, если числа совпали, то командой
inc count_128 в счетчик прибавляется единица.
В заключительной части программы считывается директория расположения программы, которая затем поочередно со значением счетчика совпадений функцией wsprintf преобразовывается в символы и выводится в упрощенное окно.
Объединим рассмотренные программы (программа 2.5 и 2.6) в общую программу (программа 2.7).
Программа 2.7.
Для упрощения объединения программ применена упрощенная сегментация (несколько сегментов data и code).Код (ASM):
include win64a.inc ;Pas1 PROTO .data Password db "12345" ; проверка только первых пяти символов len1 equ ($-Password)/type Password Buf dq 5 ; Err1 dq 0 Msg1 db "Пароль совпал",0 Msg2 db "Пароль не корректен",0 Title1 db "Проверка пароля",0 stdout dq 0 ; stdin dq 0 ; cRead dq 0 ; cWritten dq 0 ; Msg db "Please enter your password, 5 characters",10,10,0 ; .code Pas1 proc lea rsi,Password ; адрес первого элемента строки lea rdi,Buf ; адрес второго элемента строки mov rcx,len1 repe cmpsb ; по-байтно проверяется len раз jz m2 ; inc Err1 ; счетчик несовпадений m2: ret Pas1 endp WinMain proc sub rsp,28h; mov rbp,rsp invoke GetStdHandle,STD_OUTPUT_HANDLE mov stdout,rax invoke GetStdHandle,STD_INPUT_HANDLE mov stdin,rax invoke WriteConsole,stdout,ADDR Msg,sizeof Msg,ADDR cWritten,0 invoke ReadConsole,stdin,ADDR Buf,5,ADDR cRead,0 invoke Pas1 .if (Err1==0); invoke MessageBox,0,addr Msg1,addr Title1,MB_OK .data mas1 db 5,17,128,69,5,17,128,69,5,17,128,128 ; массив данных len2 equ ($-mas1)/type mas1 ; длина массива titl1 db "Массив. (masm64)",0 buf1 dq 1 dup(0),0 ; fmt db "Вывести кол. элементов массива из 12 чисел, которые равняются 128.",10,10, "Количество повторений числа 128 - %d",10, "Директория программы: - %s",10,10, "Автор: Рысованый А.Н.,НТУ ХПИ",0 dir db 256 dup(0) ;переменная для хранения пути к текущей директории count_128 dq 0 .code lea rdi,mas1 ; адрес начала элементов массива mov rcx,len2 ; количество чисел массива cycle: movzx rax,byte ptr [rdi] ; занесение байтового адреса элемента массива cmp rax,128 ; сравнение элемента массива с 128 jz inc128 ; переход на inc128 при совпадении jmp skip ; иначе продолжить inc128: inc count_128 ; +1 к счётчику повторений числа 128 skip: inc rdi ; loop cycle invoke GetCurrentDirectory,255,addr dir; получение директории invoke wsprintf,addr buf1,addr fmt,count_128,addr dir invoke MessageBox,0,addr buf1,addr titl1,MB_OKCANCEL+ MB_ICONQUESTION .else invoke MessageBox,0,addr Msg2,addr Title1,MB_OK .endif invoke RtlExitUserProcess,0 ;ExitProcess,0 WinMain endp end
При объединении особое внимание надо обращать на поиск одинаковых имен в разных программах. Например, в программе анализа массива присутствовала переменная с именем len1, которую в общей программе было переименовано в len2.
Детально рассмотрим этапы поиска пароля в программе 2.7.
Изменение команды ветвления
- Запускаем отладчик x64Dbg и открываем исследуемый ехе-файл. Для этого открываем в отладчике x64Dbg ехе-файл анализируемой программы и нажимаем F9 для ее выполнения.
- Находим функцию вывода сообщения. Для этого последовательно нажимаем в отладчике x64Dbg на клавишу F8 до момента приглашения ввода пароля функцией WriteConsole. В консольном окне появилось приглашение о вводе пароля: "Please enter your password, 5 characters".
Вводим пароль, например, 123. Нажимаем на клавиатуре Enter. В консольном окне, вроде бы ничего и не отображается. Переходим в окно отладчика x64Dbg. Продолжаем не спеша нажимать F8 для выполнения каждой строки кода. После выполнения функции ReadConsole введенный ранее пароль отобразится и процесс анализа кода продолжится (курсор сдвинется на следующую строчку кода).- Находим место анализа паролей
Найти пароль с первого прохода анализа кода не всегда возможно. Как правило, если пароль не обнаружен, то ищут сообщение о неправильном пароле. А затем анализируют ту часть кода, которая ограничена от последней рассмотренной команды до вывода сообщения о неправильном пароле. Необходимо найти место сравнения. Во многих случаях, когда не стараются скрыть пароль, сравнение происходит при помощи команды cmp. Теоретически сравнение можно произвести, в качестве примера, простой командой sub или другой, по результату выполнения которой устанавливаются необходимые для анализа признаки выполнения операции.
И так, возвращаемся к ранее проанализируемой функции ReadConsole. После этой функции следующей строкой есть вызов процедуры
call pas4-64-2.7FF666DD1000
А после вызова этой процедуры (рис. 2.10) расположена команда сравнения
cmp qword ptr ds:[7FF666DD300D],0
Всегда следует качественно анализировать содержимое полей команд сравнения.
Чтобы посмотреть значение ячейки памяти необходимо подвести курсор к строке с адресом ячейки, нажать правую клавишу мышки и выбрать Перейти к дампу / Константа.
В ячейке памяти с адресом 7FF78FE2300D находится значение 01, которое сравнивается со вторым операндом в команде (с нулем).
Следующей строкой после команды сравнения cmp расположена команда
jne pas4-64-2.7FF666DD1148, которая в случае неравенства операндов (по признаку ZF) перейдет на адрес 7FF666DD1148. А если по команде jnz содержимое ячейки памяти с адресом 7FF666DD300D и нуля совпадут, то можно сделать предположение, что пароли совпали. Поэтому надо исправить код операции так, чтобы после ввода произвольного пароля, результат был правильным.
В связи с тем, что в анализируемой программе следующая строчка кода относится к параметрам функции MessageBox, которая выводит сообщение о правильном пароле, то можно осуществить перенаправление двумя вариантами:
Чтобы исключить команду переходя по условию необходимо вставить команды nop. Для этого подводим курсор к строке с командой
- вставить команды nop;
- вставить команду jmp c новым адресом 00007FF78FE210B2. Этот вариант изменения является более универсальным.
jne pas4-64-2.7FF78FE21148,
дважды нажимаем левую клавишу мышки, ставим отметку в окошке Заполнить командами NOP и вводим NOP (рис. 2.11).
Внести изменения в отладчике x64Dbg можно двумя способами.
- Внесение изменений
Первый способ: выбираем Файл/ Исправить файл. В новом окне выбрать пункт Исправить файл. Затем – новое имя и расширение ехе.
Второй способ: выбрать пиктограмму с названием Исправления, нажать на кнопку Исправить файл, а далее новое имя и расширение ехе.
После внесенных изменений ехе-файл с новым именем на любой пароль реагирует как на лицензионный.
Реверсинг программы с использованием строковых команд. Часть 3
Дата публикации 22 мар 2019
| Редактировалось 17 май 2019