Глава 6. Исправление исполняемых модулей
Сразу скажу, что исправление исполняемых модулей - дело тонкое и требует не столько знаний, сколько навыков. Впрочем, без знания ассемблера Вам не обойтись. Но если Вы дошли до данной главы, то с этим, я думаю, все в порядке. В предисловии я уже обосновывал необходимость изучения методов изучения и исправления кода программ. Считаю, что общество и государство нуждается в специалистах и по защите, и по взлому компьютерных систем, как оно нуждается в профессиональной армии. В своей книге я лишь слегка касаюсь исправления модулей.
I
Сейчас мы рассмотрим простой57 пример, демонстрирующий некоторые приемы такого типа работы. Задача, которую ставим перед собой, не так сложна, и решить ее можно, воспользовавшись только дизассемблером W32Dasm.
Данная программа (Allscreen - программа, с помощью которой можно "снимать" окна и отдельные части экрана) попала ко мне как Shareware Release. Программа написана на Delphi, но мы увидим, что решить поставленную задачу можно, и не зная, на чем написана программа. При запуске ее на экране появляется окно, изображенное на Рис. 4.6.1. Ближе познакомившись с предметом, Вы убедитесь, что чаще всего приходится искать место в программе, соответствующее какому-либо визуальному эффекту: открытие окна, закрытие окна, вывод текста и т.п.
Рис. 4.6.1. Окно, появляющееся при запуске программы Allscreen.
При выборе кнопки "Accept" возникает задержка секунд в шесть (см. Рис. 4.6.2.). Далее программа работает нормально.
Рис. 4.6.2. Окно задержки.
После 15-ти запусков появляется окно Рис. 4.6.3 и происходит выход из программы.
Рис. 4.6.3. Сообщение об истечении времени работы программы.
Таким образом, следует решить две проблемы:
- Устранить весьма раздражающую задержку.
- Сделать так, чтобы программа работала при любом количестве запусков.
Рис. 4.6.2 являет собой явный "прокол" авторов программы. Дело в том, что
окно и все его содержимое можно спрятать в ресурсы. Но когда на том же окне
появляется новая запись - это уже программный код. Итак, запускаем W32Dasm и
считываем туда программу All Screen. Запускаем окно SDR
(String
Data Reference), ищем строку Shareware Delay
, дважды щелкаем по ней
и, закрыв его, оказываемся в нужном месте программы. Вот этот фрагмент (Рис.
4.6.4.).
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004420BC(C) | :00442123 33D2 xor edx, edx :00442125 8B83B0010000 mov eax, dword ptr [ebx+000001B0] :0044212B E8541DFDFF call 00413E84 :00442130 33D2 xor edx, edx :00442132 8B83B4010000 mov eax, dword ptr [ebx+000001B4] :00442138 E8471DFDFF call 00413E84 :0044213D 33D2 xor edx, edx :0044213F 8B83B8010000 mov eax, dword ptr [ebx+000001B8] :00442145 E83A1DFDFF call 00413E84 :0044214A BA50000000 mov edx, 00000050 :0044214F 8B83BC010000 mov eax, dword ptr [ebx+000001BC] :00442155 E8D618FDFF call 00413A30 * Possible StringData Ref from Code Obj ->"Shareware Delay" :0044215A BAA8214400 mov edx, 004421A8 :0044215F 8B83BC010000 mov eax, dword ptr [ebx+000001BC] :00442165 E8EE1DFDFF call 00413F58 :0044216A 33D2 xor edx, edx :0044216C 8B83C0010000 mov eax, dword ptr [ebx+000001C0] :00442172 E80D1DFDFF call 00413E84 :00442177 33D2 xor edx, edx :00442179 8B83C4010000 mov eax, dword ptr [ebx+000001C4] :0044217F E8001DFDFF call 00413E84 :00442184 33D2 xor edx, edx :00442186 8B83C8010000 mov eax, dword ptr [ebx+000001C8] :0044218C E8F31CFDFF call 00413E84 :00442191 8B83CC010000 mov eax, dword ptr [ebx+000001CC] :00442197 E8E8D4FFFF call 0043F684 :0044219C 5B pop ebx :0044219D C3 ret
Рис. 4.6.4. Фрагмент кода, осуществляющего, в частности, задержку.
Я сразу взял несколько больше кода, захватив и несколько верхних строк. По
сути дела, перед нами вся процедура задержки. Нет смысла пытаться понять, что
означает та или иная команда call
, хотя легко сообразить, что,
например, call 00413E84
убирает строку с экрана.
Для того чтобы решить проблему задержки, достаточно "выключить" этот фрагмент
из программы. Проще всего это можно сделать, поставив в начало команды pop
ebx / ret
, используя такой редактор, как HIEW
. В результате
задержка исчезает.
Перейдем теперь ко второй проблеме — ограничение на количество запусков. Уже из самого вида окна ясно, что оно формируется в самой программе. Следовательно, опять можно попытаться найти текст, который изображается на экране, в самой программе.
:00443326 8ВС0 mov eax, eax :00443328 53 push ebx :00443329 8BD8 mov ebx, eax :0044332B 803DEC56440001 cmp byte ptr [004456EC], 01 :00443332 7546 jne 0044337A :00443334 A124564400 mov eax, dword ptr [00445624] :00443339 E84E2CFEFF call 00425F8C :0044333E A1D8564400 mov eax, dword ptr [004456D8] :00443343 E87816FEFF call 004249CO :00443348 FF05F0564400 inc dword ptr [004456F0] :0044334E C605EC56440000 mov byte ptr [004456EC], 00 :00443355 833DF05644000F cmp dword ptr [004456FO], 0000000F :0044335C 7E1C jle 0044337A :0044335E 6AOO push 00000000 :00443360 668BODB0334400 mov cx, word ptr [004433B0] :00443367 B202 mov dl, 02 * Possible StringData Ref from Code Obj ->"This Software Has Been Used Over" | :00443369 B8BC334400 mov eax, 004433BC :0044336E E8BDAEFEFF call 0042E230 :00443373 8BC3 mov eax, ebx :00443375 E84214FEFF call 004247BC * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00443332(C), :0044335C(C) :0044337A 33D2 xor edx, edx :0044337C 8B83F4010000 mov eax, dword ptr [ebx+000001F4] :00443382 E8A52DFFFF call 0043612C :00443387 33D2 xor edx, edx :00443389 8B83F8010000 mov eax, dword ptr [ebx+000001F8] :0044338F E8982DFFFF call 0043612C :00443394 33D2 xor edx, edx :00443396 8B83FC010000 mov eax, dword ptr [ebx+000001FC] :0044339C E88B2DFFFF call 0043612C :004433A1 33D2 xor edx, edx :004433A3 8B8314020000 mov eax, dword ptr [ebx+00000214] :004433A9 E87E2DFFFF call 0043612C :004433AE 5B pop ebx :004433AF C3 ret
Рис. 4.6.5. Фрагмент кода проверки количества запусков.
Опять мы представляем весь необходимый фрагмент. Найденной выше ссылкой на искомую строку легко обнаруживаем "подозрительные" команды:
cmp dword ptr [004456F0], 0000000F jle 0044337A
Вспомним, что программа перестает работать как раз после пятнадцати запусков.
Проще всего исправить ситуацию, "забив" фрагмент программы с 0044335E по
00443375 командами NOP
(90
), используя редактор
HIEW
.