на главную
новости сайта  
раздел для начинающих
хелп по-русски
советы по программированию на VB
примеры программ
ActiveX в VB
Win32API в VB
базы данных в VB
Раздел РАЗНОЕ (статьи, описания ...)
карта сайта


 
 

Код VB6 под лупой SoftICE

В этой статье я бы хотел показать вам как выглядит скомпилированный код VB6 глазами SoftICE. (SoftICE - это мощный отладчик фирмы Numega. Он работает в 0-вом кольце защиты и может прервать работу не только программ, но и самой ОС.).

Краткое знакомство с принципами работы SoftICE'а:

Здесь я привожу только ОЧЕНЬ краткое описание отладчика, полное описание вы можете найти на соответствующих сайтах.

Для вызова окна SoftICE нужно нажать комбинацию клавиш Ctrl+D. Появится окно, схематично изображённое ниже:

|------------------| - здесь отображается содержимое 
| окно регистров | регистров процессора
|------------------|
| |
| окно кода | - здесь отображается дизассемблированный
| | код программы
|------------------|
| окно команд | - здесь вводятся команды (консоль)
|------------------|

Замечательной особенностью SoftICE является то, что Вы можете устанавливать точки прерывания на вызовы API-функций. Установив точку прерывания на некоторую строку программы, Вы сообщаете SoftICE, что при достижении этой строки программа должна прервать свое выполнение и возвратить управление отладчику. Например, Вы установили точку прерывания на выполнение команды по адресу 40А00020, а затем запускаете программу с адреса 40А00000. Дойдя до строки с адресом 40А00020, программа прервется, управление вновь вернется в SoftICE, и Вы сможете узнать содержимое регистров процессора, участков памяти, а также, при необходимости, что-то изменить!

Попробуем всё в деле:

Давайте посмотрим на код программы, которая будет вычислять сумму двух чисел. Для этого создадим форму, поместим на неё кнопку и вставим следующий код:

Option Explicit

Private Declare Function SetCursorPos Lib "user32" _
(ByVal x As Long, ByVal y As Long) As Long

Private Sub Command1_Click()
Dim a As Long, b As Long, c As Long
SetCursorPos 256, 256
a = 2
b = 5
c = a + b
SetCursorPos 512, 512
End Sub

Функция SetCursorPos объявляется для того, чтобы попасть в SoftICE. Первый вызов будет означать начало, второй - конец. Я использовал координаты курсора 256 и 512 чтобы в SoftICE'е было проще ориентироваться, т.к. он все данные отображает в hex формате, а 256 и 512 это соответственно 100 и 200. Теперь откомпилируем и запустим программу. Откроем сайс (SoftICE) и напишем команду

bpx SetCursorPos

Это команда поставит брикпоинт на вызов функции SetCursorPos. Выходим из сайса и нажимаем на кнопочку нашей формы. Попадаем в сайс. Видим следующий код:

.............
.............
push 00000100
push 00000100
call 004016D4 - прыгает на SetCursorPos
mov esi,[MSVBVM60!__vbaSetSystemError]
call esi
push 00000200
mov eax,00000007
push 00000200
call 004016D4 - прыгает на SetCursorPos
.............
.............

И что мы видим? Ничего даже не складывается, а сразу присваивается значение 7! Причём почему-то команда mov eax,7 вставилась между двух push. Функцию [MSVBVM60!__vbaSetSystemError] VB вызывает очень часто, причём я так и не выяснил зачем (внутри этой функции идёт какая-то проверка на ошибки). Ну да ладно, продолжим!

Теперь поместим на форму текстовое поле и исследуем вот такой код:

Private Sub Command1_Click()
Dim a As Long, b As Long, c As Long
SetCursorPos 256, 256
Dim a As String
a = Text1.Text
SetCursorPos 512, 512
End Sub


Итак в сайсе мы видим вот такой код:

.............
.............
push 00000100
push 00000100
mov [ebp-18],edi
mov [ebp-20],edi
mov [ebp-24],edi
call 00401794 - прыгает на SetCursorPos
mov ebx,[MSVBVM60!__vbaSetSystemError]
call ebx
mov edx,[esi]
push esi
call [edx+00000300] - готовит строку a
push eax
lea eax,[ebp-24]
push eax
call [MSVBVM60!__vbaObjSet] - для получения содержимого Text1
mov esi,eax
lea edx,[ebp-20]
push edx
push esi
mov ecx,[esi]
call [ecx+000000A0]
cmp eax,edi
fclex
jge 00401c0d
push a0
push 004017c0
push esi
push eax
call [MSVBVM60!__vbaHRezultCheckObj]
mov edx,[ebp-20]
lea ecx,[ebp-18] - теперь в ecx находится адрес строки в Text1
mov [ebp-20],edi
call [MSVBVM60!__vbaStrMove] - a = Text1.Text
lea ecx,[ebp-24]
call [MSVBVM60!__vbaFreeObj]
push 00000200
push 00000200
call 00401794
.............
.............

Как видите код не очень чистый. Очень много вызовов функций библиотеки Msvbvm. Однако, основная масса этих функций сделана очень качественно, поэтому код работает достаточно быстро.

Интересной возможностью является изменение кода после компиляции. Например, пусть есть программа, которая при каждом запуске выдаёт раздражающий Msgbox с сообщением "Добро пожаловать!", который никак нельзя отключить (ф-циями самой программы, вы можете сделать так чтобы это окно больше никогда вас не беспокоило! К примеру вставим в форму вот такой код:

Private Sub Command1_Click()
MsgBox "Добро пожаловать!"
Form1.Caption = "Программа XXX версии X.0XX :)"
End Sub

Функция MsgBox хранится во всё той же библиотеке MSVBVM. Именуется она rtcMsgBox. Поставим на неё брикпоинт и попадём в сайс:

что-то
.............
.............
несколько команд push

call [MSVBVM60!rtcMsgBox] - вызов MsgBox
.............
.............
что-то

Мы может изменить код на такой:

что-то
.............
.............
jmp Адрес№1 - перепрыгиваем вызов MsgBox адрес Адрес№1
остаточные push

call [MSVBVM60!rtcMsgBox] - вызов MsgBox
Адрес№1: .............
.............
что-то

Код изменяется командой "a" SoftICE'а. Далее можно вводить ассемблерные мнемоники. После ввода кода нажмите 2 раза Enter и выходите из SoftICE. Однако, изменённый код будет существовать только до закрытия программы. После повторного запуска код восстановится и MsgBox появиться вновь. Для того, чтобы изменить его навсегда, необходимо подправить необходимую последовательность чисел в самом exe файле.

Правда с правкой кода будьте осторожны, неверное движение и ...
"программа выполнила недопустимую операцию..." или ещё хуже - синий экран.

Автор - Волков Антон.

 
 

Завтра будут мыши для компьютера в новосибирске.