Тема: Solutions
Показать сообщение отдельно

  #12  
Старый 09.06.2008, 05:57
Ra$cal
Постоянный
Регистрация: 16.08.2006
Сообщений: 640
Провел на форуме:
1354067

Репутация: 599


По умолчанию

При rivm, равном 0x0A мы получим содержимое vm_eip. Но не это главное. Код операции - 3. А это запись по декодированному rvim2 декодированного rvim1. Т.е. то, что обсуждалось выше - это принудетльное задание адреса следующей команды, эмуляция безусловного перехода с абсолютным адресом. Прокрутите окно выше и вы увидите, куда идет прыжок - 004014D9: 43 03 -> mov rvm3, [rvm0] ;// в rvm3 лежит 4 байта - букв из имени. Т.е. повторение чтения байтов, смещенных на один символ, ксор на константу, и прибавление к rvm4 результата ксора. И так, пока не уйдем за конец строки. Как мы проскочим цикл? Нада поставить бряк на обработчике опкода 0x14, и ждать, когда LE_F будет = 0. Встали тут

Код:
004023D4   .  ADD ESI, 0A
0040151F: 0F 74 -> cmp rvm4, rvm7 ;// сравнить регистр, в котором сумма хэшей с регистром, в котором введенный номер. rvm4 = 568AA687

00401529: 10 00 jnz vm_eip+20


Код:
004023DC   > CMP BYTE PTR SS:[EBP-14], 10
004023E0   . JNZ SHORT crackme_.004023F0
004023E2   . CMP BYTE PTR DS:[<Z_F>], 1
004023E9   . JE SHORT crackme_.004023EE
004023EB   . ADD ESI, 0A
004023EE   > JMP SHORT <crackme_.lbl_end_command>
Проверка флага нуля. У нас не ноль, поэтому проходит через одну команду. Запоминаем это место.

0040153D: 03 C4 00000000 00000000 -> mov rvm4, 0

00401547: 3F 00 -> ret

Код:
00402440   > \807D EC 3F            CMP BYTE PTR SS:[EBP-14], 3F
00402444   .  75 11                 JNZ SHORT crackme_.00402457
00402446   .  83C6 08               ADD ESI, 8
00402449   .  8935 28144000         MOV DWORD PTR DS:[<vm_eip>], ESI
0040244F   .  30C0                  XOR AL, AL
00402451   .  FEC0                  INC AL
00402453   .  C9                    LEAVE
00402454   .  C3                    RETN
При 3F vm_eip правится, и в al кладется 1, что вызовет прекращение работы цикла, выполняющего пикод. Значит это ret. Теперь отпускаем по F9, ставим хард бряк на доступ к байту 00401529 (10), но вводим в поле ключа 568AA687. Считываение проходим, идем до проверки флага. Флаг = 1, и перепрыгивания команды не происходит. Смотрим, какую пикод команду выполнит интерпритатор

00401533: 03 C8 00000000 87148712 -> mov rvm8, 87148712
Дальше опять выполняется обнуление rvm4 и выход. Теперь выходим и топаем медленно, высматривая сравнения

Код:
00402501  |.  CMP DWORD PTR DS:[401420], 87148712
0040250B  |.  JNZ SHORT crackme_.0040250E
0040250D  |.  INC EAX
Вот и все. Последний момент - таблица опкодов и алгоритм.

Код:
6 - xor r2, r1
3 - mov r2, r1
4 - add r2, r1
A - inc r1; mov r2, r1
F - cmp r2, r1
14 - jg $+0x0A
10 - jnz $+0x0A
3F - ret
Код:
mov r0, name
mov r1, E98FB720
mov r7, key

xor r4, r4

mov r5, name
add r5, name_len

lbl_NEXT_1:
mov r3, dword_ptr [r0]
xor r3, r1
add r4, r3
inc r0 ;// к следующей букве имени
cmp r0, r5
jle lbl_NEXT_1

cmp r4, r7
jnz lbl_EXIT
mov r8, 87148712
lbl_EXIT:
mov r4, 0
ret

Заключение: эта вм не представляет никаких сложностей, т.к. написана прямо и без мусора. Работает она скорее как эмулятор, так как у нее нет специфичных своих команд, мы с легкостью перевели каждую команду вм в команду процессора x86. Нету ни банальной смены логического базиса, ни разложения команд на мелкие, мы смогли на глаз декомпилировать пикод команды, так что это очень хорошая мишень для начинающих. Кстати структура команд очень напоминает мне микрокоманды процессора, для которого в этом семестре в качестве курсового проекта я кодировал микропрограммы в машкодах =)
ЗЫ: объемно получилось, ибо разжевывал подробно, чтобы могли понять общий алгоритм и ход действия при отломе вм.

Последний раз редактировалось Ra$cal; 14.06.2008 в 16:15..
 
Ответить с цитированием