Реверсинг программы с использованием базовых команд. Часть 2

Дата публикации 22 мар 2019 | Редактировалось 17 май 2019
Применение базовых команд не дает никакого преимущества перед использованием API-функции lstrcmp. В этом случае достигается не только разнообразие вариантов программ с запросом пароля, но и детализация внутреннего алгоритма проверки вводимых символов пароля.
Особенностью программы можно считать применение функции WriteConsole, которую так же надо было применить в программе 2.1. Эта функция выводит сообщение с просьбой ввести пароль в консольном окне.
В связи с тем, что эта программа является консольной, то необходимо в среде masm64 использовать bat-файл с командными словами SUBSYSTEM:CONSOLE.
Функция WriteConsole записывает символьную строку в экранный буфер консоли, начинающийся с текущей позиции курсора.

Синтаксис:
Код (C):
  1. BOOL WriteConsole(
  2. HANDLE hConsoleOutput,  // дескриптор экранного буфера
  3. CONST VOID * lpBuffer,  // буфер записи
  4. DWORD nNumberOfCharsToWrite,  // число символов для записи
  5. LPDWORD lpNumberOfCharsWritten, // число записанных символов
  6. LPVOID lpReserved  // зарезервировано
  7. );
Параметры:
  • hConsoleOutput – дескриптор экранного буфера консоли. Дескриптор должен иметь право доступа GENERIC_READ. Для получения дополнительной информации, см. статью Защита буфера и права доступа в консоли;
  • lpBuffer – указатель на буфер, содержащий символы, которые будут записаны в экранный буфер консоли. Общий размер должен быть меньше чем 64 кб;
  • nNumberOfCharsToWrite – число TCHARs для чтения;
  • lpNumberOfCharsWritten – указатель на переменную, которая принимает число фактических записей TCHARs;
  • lpReserved – зарезервировано, должно быть ПУСТО (NULL).
Возвращаемые значения:
  • если функция завершается успешно, величина возвращаемого значения – не ноль;
  • если функция завершается с ошибкой, величина возвращаемого значения – ноль.
Чтобы получать расширенные данные об ошибках необходимо воспользоваться функцией GetLastError (System Error Codes).
Программа 2.4. Проверка пароля при использовании базовых команд:
Код (ASM):
  1. include win64a.inc
  2. .data
  3. Password db "12345" ; пароль
  4. len1 equ ($-Password)/type Password ; число символов
  5. Buf dq 5 ;
  6. Err1 dq 0
  7. Msg1 db "Пароль совпал",0
  8. Msg2 db "Пароль не корректен",0
  9. Title1 db "Проверка пароля",0
  10. stdout dq 0  ;
  11. stdin dq 0  ;
  12. cRead dq 0  ;
  13. cWritten dq 0 ;
  14. Msg db "Please enter your password, 5 characters",0dh,0ah,0 ;
  15. .code
  16. WinMain proc
  17. sub rsp,28h; cтек: 28h=32d+8; 8 - возврат
  18. mov rbp,rsp
  19. invoke GetStdHandle,STD_OUTPUT_HANDLE
  20. mov stdout,rax
  21. invoke GetStdHandle,STD_INPUT_HANDLE
  22. mov stdin,rax
  23. invoke WriteConsole,stdout,ADDR Msg,sizeof Msg,ADDR cWritten,0
  24. invoke ReadConsole,stdin,ADDR Buf,5,ADDR cRead,0
  25. lea rsi,Password ; загрузка адреса нахождения Password
  26. lea rdi,Buf  ; загрузка адреса буфера введенных символов
  27.   mov rcx,len1  ; счетчик символов
  28. m1:
  29. mov al,[rsi] ; загрузка адреса нахождения пароля
  30. mov bl,[rdi] ;
  31. cmp al,bl    ; сравнение символов
  32. jz m2    ; если совпали символы
  33. inc Err1  ; счетчик несовпадений
  34. m2:
  35. add rsi,1  ; inc адреса
  36. add rdi,1  ;
  37. loop m1
  38. .if (Err1==0) ;  &&(cRead==len1)
  39. invoke MessageBox,0,addr Msg1,addr Title1,MB_OK
  40. .else
  41. invoke MessageBox,0,addr Msg2,addr Title1,MB_OK
  42. .endif
  43. invoke RtlExitUserProcess,0 ;ExitProcess,0
  44. WinMain endp
  45. end
В программе функцией WriteConsole выводится пригласительное окно консоли с сообщением "Please enter your password, 5 characters".
Метка m1 организует цикл чтения пяти символов пароля по значению счетчика в регистре rcx.
Переменная Err1 служит счетчиком несовпадений символов пароля. В случае, если хотя бы один символ не правильный, то выводится сообщение "Пароль не корректен".
В связи с тем, что эта программа мало чем отличается от рассмотренной ранее, то вкратце рассмотрим этапы поиска пароля:

  1. Запускаем отладчик x64Dbg и открываем исследуемый ехе-файл. Для этого открываем в отладчике x64Dbg ехе-файл анализируемой программы и нажимаем F9 для ее выполнения (рис. 2.6).

    [​IMG]
  2. Находим функцию вывода сообщения. Для этого последовательно нажимаем в отладчике x64Dbg на клавишу F8 до момента приглашения ввода пароля функцией WriteConsole. Вводим пароль, например, 123. И обязательно нажимаем на клавиатуре Enter. В консольном окне, вроде бы ничего и не отображается. Однако, если продолжать нажимать F8 для выполнения каждой строки кода, то после выполнения функции ReadConsole введенный ранее пароль отобразится и процесс анализа кода продолжится (рис. 2.7).

    [​IMG]

    Следующие три этапа (нахождение места анализа паролей, изменение команды ветвления, внесение изменений) ничем от ранее рассмотренного варианта не отличаются, кроме других адресов ячеек памяти.
  3. Находим место анализа паролей. Продолжаем выполнять строки кода в пошаговом режиме, нажимая на клавишу F8. Немного ниже видны строки кода
    Код (ASM):
    1. mov al,byte ptr ds:[rsi]
    2. mov bl,byte ptr ds:[rdi]
    3. cmp al,bl
    В этих строках кода в регистр al заносится из памяти один символ, а в регистр bl – символ из буфера. А команда сравнения cmp сравнивает эти символы. При анализе всегда надо сначала обращать серьезное внимание командам сравнения (конечно, если не применены специальные приемы для того, чтобы спрятать такие строки).
    После команды сравнения двух символов (эталоного и считываемого) располагается команда ветвления je – переход, если равно. А после перехода строки кода
    Код (ASM):
    1. add rsi,1
    2. add rdi,1
    увеличивают адреса расположения сравниваемых символов.
    В блоке кода
    Код (ASM):
    1. loop pas2-64.7FF652071093
    2. cmp qword ptr ds:[7FF65207300D],0
    3. jne pas2-64.7FF6520710D1
    в первой строке во внутри команды loop как раз и располагается команда jnz – переход по адресу, если значения в счетчике не совпали.
  4. Изменение команды ветвления. В последнем блоке кода найдена команда ветвления jne по признаку, которую необходимо изменить. Следовательно, необходимо чтобы строки кода выполнялись ниже без переходов или поставить вместо команды jne команды nop (что в нашем случае проще).
    Чтобы заменить команду jne на команды nop подводим курсор к команде, которую надо заменить, дважды нажимаем левую клавишу мышки, выбираем Заполнить командами NOP, вводим в поле имя NOP и нажимаем ОК (рис. 2.8).


    [​IMG]
  5. Внесение изменений.
Внести изменения в отладчике x64Dbg можно двумя способами.
Первый способ: выбираем Файл/ Исправить файл. В новом окне выбрать пункт Исправить файл. Затем – новое имя и расширение ехе.
Второй способ: выбрать пиктограмму с названием Исправления, нажать на кнопку Исправить файл, а далее новое имя и расширение ехе.
После внесенных изменений ехе-файл с новым именем на любой пароль реагирует как на лицензионный.

0 2.152
Alex81524

Alex81524
New Member

Регистрация:
12 фев 2008
Публикаций:
5