Взлом вашей первой программы

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

Обзор программы

Саму программу вы можете скачать здесь. (пароль от архива: crackmes.one). Её суть заключается в том, что она требует имя пользователя и пароль. Если имя пользователя для нас не очень важно, то вот пароль влияет на то, что выведет программа в итоге.

Как видите программа выводит надпись «Bad». Давайте это исправлять.

Как будем взламывать

Наша задача — сделать так, чтобы программа выводила «Good» в независимости от того, что пользователь ввёл в поле пароля. Если вы захотели декомпилировать данную программу, закинув EXE-файл в программу по типу dotPeek или ILSpy, то у вас ничего не выйдет. Ведь данная программа написана не на C#, исходный код которого можно легко посмотреть, а на C++, декомпилировать который нельзя.

Итак, если декомпилировать программу нельзя, значит мы будем её дизассемблировать, то есть изменять код ассемблера. Я не буду сильно углубляться в тему ассемблера, но если кратко, Assembler — это низкоуровневый язык программирования, приближенный к машинному коду. Когда вы запускаете какую-либо программу, неважно на каком языке она написана, в любом случае её исходный код будет переведён на язык ассемблера, а потом в машинный код.

Требуемое ПО

Чтобы взломать программу, нам понадобится следующее ПО:

  1. WinHex. Это шестнадцатеричный редактор, с помощью которого можно просматривать и изменять различные файлы.

  2. IDA Pro. Это тот самый дизассемблер, с помощью которого можно изучать исходный ассемблерный код программы.

Данные программы бесплатны, скачать их можно с официальных сайтов.

Взлом программы

Итак, запускаем IDA Pro и видим вот такую картину:

22c29cda7d1e296e970ec908eca7d283.png

Нажимаем New, выбираем EXE-файл, у вас откроется вот такое окно:

1363d3a2cee858bdae6bd4985c344000.png

Нажимаем OK, в следующем окне нажимаем No. Теперь у вас откроется ассемблерный код программы в виде графов. Нажмите ПКМ, а затем в появившемся окне на Text View, чтобы исходный код отобразился в виде текста, так удобнее.

Если пролистнуть немного вниз, то можно увидеть очень интересную область кода:

.text:000000014000F1E8
.text:000000014000F1E8 loc_14000F1E8:                          ; CODE XREF: main+124↓j
.text:000000014000F1E8                 movsx   ecx, byte ptr [rax]
.text:000000014000F1EB                 add     rax, 1
.text:000000014000F1EF                 add     edx, ecx
.text:000000014000F1F1
.text:000000014000F1F1 loc_14000F1F1:                          ; CODE XREF: main+113↑j
.text:000000014000F1F1                 cmp     rax, r8
.text:000000014000F1F4                 jnz     short loc_14000F1E8
.text:000000014000F1F6                 cmp     [rsp+0C8h+var_9C], edx
.text:000000014000F1FA                 jz      short loc_14000F216
.text:000000014000F1FC                 lea     rcx, aBad       ; "Bad\n"
.text:000000014000F203                 call    _Z6printfPKcz   ; printf(char const*,...)
.text:000000014000F208
.text:000000014000F208 loc_14000F208:                          ; CODE XREF: main+152↓j
.text:000000014000F208                 xor     eax, eax
.text:000000014000F20A                 add     rsp, 0A8h
.text:000000014000F211                 pop     rbx
.text:000000014000F212                 pop     rsi
.text:000000014000F213                 pop     rdi
.text:000000014000F214                 pop     rbp
.text:000000014000F215                 retn
.text:000000014000F216 ; ---------------------------------------------------------------------------
.text:000000014000F216
.text:000000014000F216 loc_14000F216:                          ; CODE XREF: main+12A↑j
.text:000000014000F216                 lea     rcx, aGood      ; "Good\n"
.text:000000014000F21D                 call    _Z6printfPKcz   ; printf(char const*,...)
.text:000000014000F222                 jmp     short loc_14000F208
.text:000000014000F222 main            endp
.text:000000014000F222

Нас интересуют следующие строчки:

.text:000000014000F1FA                 jz      short loc_14000F216
.text:000000014000F1FC                 lea     rcx, aBad       ; "Bad\n"
.text:000000014000F203                 call    _Z6printfPKcz   ; printf(char const*,..)

На первой строчке происходит перемещение в область кода с проверкой флага Z в регистре EFLAGS процессора. После данной проверки выводится надпись «Bad». Первая строчка перемещает в область кода, где выводится надпись «Good». То есть, скорее всего, первая строчка и проверяет корректность пароля. Нам остаётся изменить её на команду непроверяемого перехода, то есть jmp.

Переходим на строчку проверки и запоминаем смещение:

680e2370343507bd33c284a81fc69292.png

Смещение равно E7FA. Открываем WinHex, в нём открываем EXE-файл. В меню сверху переходим в пункт Navigation, нажимаем Go To Offset вводим E7FA и нажимаем OK. Программа переместит вас на место данной команды, теперь мы должны поменять код 74 на EB, потому что EB — это шестнадцатеричный аналог команды jmp в ассемблере.

1b84193752ee10b6f7a714e09583367a.png

Теперь сохраняем изменённый файл и тестируем.

Ура! Мы взломали программу. Поздравляю!

Да, я многое не объяснил, потому что одной статьи точно не хватит. Тренируйтесь и изучайте новые способы взлома. Удачи!

© Habrahabr.ru