- •Курсовая работа
- •Постановка задачи на курсовую работу
- •Внешнее предварительное исследование программного продукта
- •Предварительный анализ кода программы в отладчике
- •3.1. Точки останова
- •3.2. Поиск введенных данных
- •0012F63c 00404ff7 return to textguar.00404ff7 from textguar.004030d0
- •00404Ff2 |. E8 d9e0ffff call textguar.004030d0
- •00405008 |. E8 c3e0ffff call textguar.004030d0
- •«Жесткий» взлом
- •00404Da9 |. 75 03 |jnz short textguar.00404dae
- •00405024 |. E8 b7010000 call textguar.004051e0
- •00405029 |. 85C0 test eax,eax
- •0040502B |. 74 39 je short textguar.00405066
- •Подробный анализ механизма защиты. Осуществление мягкого взлома.
- •Блок-схема алгоритма модуля защиты
- •Рекомендации по улучшению механизма защиты
- •Заключение
00405008 |. E8 c3e0ffff call textguar.004030d0
После выполнения процедуры, вызываемой по адресу 00405008, сегмент данных по адресу 004147C4, как и предполагалось, содержал введенный пароль:
004147C0 00 00 00 00 31 32 33 34 ....1234
004147C8 35 00 00 00 00 00 00 00 5.......
После сделанных выводов о том, что введенное имя пользователя хранится по адресу 00414744, а введенный пароль хранится по адресу 004147C4, я приступила к дальнейшему анализу кода программы.
«Жесткий» взлом
После процедуры считывания введенного пароля, располагается следующий код:
0040500D |. 68 44474100 PUSH textguar.00414744 ; ASCII "dilyara"
00405012 |. E8 69FDFFFF CALL textguar.00404D80
00405017 |. 68 C4474100 PUSH textguar.004147C4 ; ASCII "12345"
0040501C |. E8 0FFEFFFF CALL textguar.00404E30
С точки зрения взлома программы, нам будут интересны две процедуры. В первую передается введенное мной имя пользователя, во вторую - пароль. Эти процедуры вызываются командами CALL textguar.00404D80 и CALL textguar.00404E30 соответственно. Рассмотрим подробнее первую процедуру:
00404D80 /$ 56 PUSH ESI
00404D81 |. 8B7424 08 MOV ESI,DWORD PTR SS:[ESP+8]
00404D85 |. 6A 40 PUSH 40 ; /DataSize = 40 (64.)
00404D87 |. 56 PUSH ESI ; |DataAddress
00404D88 |. FF15 64E04000 CALL DWORD PTR DS:[<&KERNEL32.IsBadWritePtr>]
; \IsBadWritePtr
Здесь мы видим вызываемую функцию KERNEL32.IsBadWritePtr, которая предназначена для проверки того, что вызывающий процесс имеет право на осуществление записи по определенному участку памяти (из справочника по API функциям). Далее мы видим команды, в которых проверяется результат вызова данной функции:
00404D8E |. 85C0 TEST EAX,EAX
00404D90 |. 0F85 8E000000 JNZ textguar.00404E24
При пошаговом исполнении программы, регистр EAX был равен нулю и переход не был осуществлен (то есть вызывающий процесс имеет право на осуществление записи). Смотрим далее:
00404D96 |. 33C9 XOR ECX,ECX
00404D98 |> 8A0431 /MOV AL,BYTE PTR DS:[ECX+ESI]
00404D9B |. 3C 20 |CMP AL,20
00404D9D |. 74 0C |JE SHORT textguar.00404DAB
00404D9F |. 3C 0D |CMP AL,0D
00404DA1 |. 74 08 |JE SHORT textguar.00404DAB
00404DA3 |. 3C 0A |CMP AL,0A
00404DA5 |. 74 04 |JE SHORT textguar.00404DAB
00404DA7 |. 3C 09 |CMP AL,9
00404Da9 |. 75 03 |jnz short textguar.00404dae
00404DAB |> 41 |INC ECX
00404DAC |.^ EB EA \JMP SHORT textguar.00404D98
00404DAE |> 8A1431 MOV DL,BYTE PTR DS:[ECX+ESI]
В результате работы этого участка кода в регистр AL был занесен код первого символа имени пользователя, и затем данный регистр последовательно был сравнен со значениями 20, 0D, 0A и 09. Поскольку код первого символа (d) = 64, он не был равен ни с одним из этих кодов. Поэтому, был выполнен переход на 00404DAE (выделенная строка кода), где в регистр DL вновь заносится код первого символа имени пользователя.
00404DB1 |. 03CE ADD ECX,ESI
00404DB3 |. 33C0 XOR EAX,EAX
00404DB5 |. 84D2 TEST DL,DL
00404DB7 |. 74 67 JE SHORT textguar.00404E20
00404DB9 |. 8BD1 MOV EDX,ECX
00404DBB |> 8A0A /MOV CL,BYTE PTR DS:[EDX]
00404DBD |. 80F9 20 |CMP CL,20
00404DC0 |. 74 14 |JE SHORT textguar.00404DD6
00404DC2 |. 80F9 0D |CMP CL,0D
00404DC5 |. 74 0F |JE SHORT textguar.00404DD6
00404DC7 |. 80F9 0A |CMP CL,0A
00404DCA |. 74 0A |JE SHORT textguar.00404DD6
00404DCC |. 80F9 09 |CMP CL,9
00404DCF |. 74 05 |JE SHORT textguar.00404DD6
00404DD1 |. 880C30 |MOV BYTE PTR DS:[EAX+ESI],CL
00404DD4 |. EB 20 |JMP SHORT textguar.00404DF6
00404DD6 |> 85C0 |TEST EAX,EAX
00404DD8 |. 7E 1D |JLE SHORT textguar.00404DF7
00404DDA |. 8A4C30 FF |MOV CL,BYTE PTR DS:[EAX+ESI-1]
00404DDE |. 80F9 20 |CMP CL,20
00404DE1 |. 74 14 |JE SHORT textguar.00404DF7
00404DE3 |. 80F9 0D |CMP CL,0D
00404DE6 |. 74 0F |JE SHORT textguar.00404DF7
00404DE8 |. 80F9 0A |CMP CL,0A
00404DEB |. 74 0A |JE SHORT textguar.00404DF7
00404DED |. 80F9 09 |CMP CL,9
00404DF0 |. 74 05 |JE SHORT textguar.00404DF7
00404DF2 |. C60430 20 |MOV BYTE PTR DS:[EAX+ESI],20
00404DF6 |> 40 |INC EAX
00404DF7 |> 8A4A 01 |MOV CL,BYTE PTR DS:[EDX+1]
00404DFA |. 42 |INC EDX
00404DFB |. 84C9 |TEST CL,CL
00404DFD |.^ 75 BC \JNZ SHORT textguar.00404DBB
00404DFF |. 85C0 TEST EAX,EAX
00404E01 |. 7E 1D JLE SHORT textguar.00404E20
Смысл данного участка кода в том, что в регистр CL последовательно заносятся коды введенного имени пользователя, и затем данный регистр сравнивается со значениями 20, 0D, 0A и 09. Поскольку во введенном мной имени символов с данными кодами не содержалось, цикл завершился. В результате регистр EAX содержал значение 00000007, интерпретируя которое, можно понять, что это длина введенного имени. Последние две строчки предназначены для проверки данного значения. В случае, если длина имени равна нулю, программа переходит по адресу 00404E20. В нашем случае программа продолжает свое выполнение:
00404E03 |> 8A4C06 FF /MOV CL,BYTE PTR DS:[ESI+EAX-1]
00404E07 |. 80F9 20 |CMP CL,20
00404E0A |. 74 0F |JE SHORT textguar.00404E1B
00404E0C |. 80F9 0D |CMP CL,0D
00404E0F |. 74 0A |JE SHORT textguar.00404E1B
00404E11 |. 80F9 0A |CMP CL,0A
00404E14 |. 74 05 |JE SHORT textguar.00404E1B
00404E16 |. 80F9 09 |CMP CL,9
00404E19 |. 75 05 |JNZ SHORT textguar.00404E20
00404E1B |> 48 |DEC EAX
00404E1C |. 85C0 |TEST EAX,EAX
00404E1E |.^ 7F E3 \JG SHORT textguar.00404E03
00404E20 |> C60430 00 MOV BYTE PTR DS:[EAX+ESI],0
00404E24 |> 5E POP ESI
00404E25 \. C3 RETN
Здесь в регистр CL заносится код последнего символа имени, который затем сравнивается со значениями 20, 0D, 0A и 09. А так как код последнего символа равен 61, происходит переход на строчку кода, в которой в сегмент данных в следующем байте после последнего байта имени пользователя записывается символ с кодом 00.
Можно сделать вывод, что вся эта процедура предназначена для отделения имени от остальных данных, хранящихся в сегменте данных. Это может быть необходимо в случае, если пользователь после ввода длинного имени, пробует ввести короткое. И для правильного его считывания необходимо ограничить конец вводимого имени от других данных. Кроме того, программа проверяет имя пользователя на наличие символов с кодами 09, 0A, 0D, 20. Поэтому с точки зрения взлома программы нам этот участок кода не интересен.
Перейдем к рассмотрению второй процедуры, в которую передается введенный пароль – CALL textguar.00404E30:
00404E30 /$ 56 PUSH ESI
00404E31 |. 8B7424 08 MOV ESI,DWORD PTR SS:[ESP+8]
00404E35 |. 6A 40 PUSH 40 ; /DataSize = 40 (64.)
00404E37 |. 56 PUSH ESI ; |DataAddress
00404E38 |. FF15 64E04000 CALL DWORD PTR DS:[<&KERNEL32.IsBadWritePtr>]
00404E3E |. 85C0 TEST EAX,EAX
00404E40 |. 75 2C JNZ SHORT textguar.00404E6E
Здесь мы вновь видим вызываемую функцию KERNEL32.IsBadWritePtr, которая предназначена для проверки того, что вызывающий процесс имеет право на осуществление записи по определенному участку памяти. Процесс имеет право записи, поэтому код выполняется далее:
00404E42 |. 8A06 MOV AL,BYTE PTR DS:[ESI]
00404E44 |. 33D2 XOR EDX,EDX
00404E46 |. 84C0 TEST AL,AL
00404E48 |. 74 20 JE SHORT textguar.00404E6A
00404E4A |. 8BCE MOV ECX,ESI
00404E4C |> 8A01 /MOV AL,BYTE PTR DS:[ECX]
00404E4E |. 3C 20 |CMP AL,20
00404E50 |. 74 10 |JE SHORT textguar.00404E62
00404E52 |. 3C 0D |CMP AL,0D
00404E54 |. 74 0C |JE SHORT textguar.00404E62
00404E56 |. 3C 0A |CMP AL,0A
00404E58 |. 74 08 |JE SHORT textguar.00404E62
00404E5A |. 3C 09 |CMP AL,9
00404E5C |. 74 04 |JE SHORT textguar.00404E62
00404E5E |. 880432 |MOV BYTE PTR DS:[EDX+ESI],AL
00404E61 |. 42 |INC EDX
00404E62 |> 8A41 01 |MOV AL,BYTE PTR DS:[ECX+1]
00404E65 |. 41 |INC ECX
00404E66 |. 84C0 |TEST AL,AL
00404E68 |.^ 75 E2 \JNZ SHORT textguar.00404E4C
00404E6A |> C60432 00 MOV BYTE PTR DS:[EDX+ESI],0
00404E6E |> 5E POP ESI
00404E6F \. C3 RETN
Как видно, данная процедура аналогична предыдущей, поскольку здесь берутся коды каждого символа введенного пароля и вновь сравниваются с кодами 09, 0A, 0D, 20. После сравнения всех символов введенного пароля, программа записывает справа от введенного пароля в сегменте данных символ с кодом 00 командой MOV BYTE PTR DS:[EDX+ESI],0, поскольку сумма регистров EDX и ESI указывает на ту область.
Значит, эти две процедуры не играют никакой роли в принятии программой решения о правильности пароля.
После этих двух процедур располагается следующий код:
00405021 |. 83C4 08 ADD ESP,8