Автор: Чубченко Сергей. Дата публикации: 13.05.2004
Введение
Знатоки таких языков высокого уровня, как Delphi и C++, сейчас скажут, что только данные языки способны воспринимать низкоуровневые конструкции, причем ключевого слова Asm вполне достаточно. Частично с этим утверждением можно согласиться – в Visual Basic 6.0 так просто встроить ассемблерный код нельзя, но поверьте, прочитав данную статью для Вас это будет также просто сделать и на Visual Basic.
Для начала рассмотрим методику вставки. Для вызова ассемблерного кода используется API функция "CallWindowProc", содержащаяся в библиотеке "user32.dll", которая входит в поставку Windows. Она имеет 1 основной и 4 дополнительных параметра. В первый мы будем передавать адрес первой ячейки массива, содержащего массив байт (откомпилированную ассемблерную процедуру), а в остальные – параметры, необходимые для работы ассемблерной функции.
Для начала создадим новый проект и объявим эту функцию:
Теперь создадим функцию, которая преобразует HEX строку машинных кодов в байтовый массив и возвратит адрес первой ячейки массива:
И наконец перейдем непосредственно к созданию ассемблерной функции.
Подготовка ассемблерного кода
При создании новой функции будем использовать следующий шаблон:
Комментарий: первый параметр, передаваемый функции всегда находится по адресу ebp+8, остальные в зависимости от их длины расположены дальше по стеку. Строки передавать в функцию не стоит, так как они в Unicode и потребуется масса дополнительного кода для их обработки. Также компилятор nasmw не понимает команды db, поэтому работать с переменными, созданными в этой функции вам пока не получится. Использование API, а также создание переменных рассмотрено во второй части статьи. При вызове более 2-х параметров в конце функции необходимо корректировать стек и вместо ret ставить ret 8 при использовании 3-х параметров и ret 8+<длина параметра(чаще всего 4)> при использовании 4-х параметров.
Теперь у Вас возникнет вопрос: "Как это все теперь перевести в HEX строку, которую мы будем передавать ранее написанной функции?". Резонный вопрос. Для начала необходимо перевести этот ассемблерный код в BIN файл, содержащий машинные коды, для чего можно использовать nasmw – компилятор ассемблера (командная строка: nasmw.exe -f bin YouProgram.asm -o YouProgram.bin), а затем написать небольшую программку для перевода BIN файла в HEX строку. Я же рекомендую не геморроиться и использовать написанную мной утилиту Asm to VB, которая без проблем переведет код, написанный по вышеприведенному шаблону в BIN файл или HEX строку. В Asm to VB я уже встроил компилятор nasmw, поэтому кроме этой программы для написания ассемблерных функций Вам ничего не потребуется.
Добавление ассемблерных процедур в код на Visual Basic 6.0
У нас есть Hex строка и функция, передавая в которую Hex строку создается массив машинных инструкций и возвращается ссылка на первую ячейку массива. Поверьте этого достаточно.
Теперь запустим функцию с параметрами (если в функцию передаётся не 4, а меньше параметров, то остальные параметры забиваются нулями, если этого не сделать, функция не будет работать!), предварительно присвоив переменной sHex Hex строку, которую мы получили в предыдущем шаге:
Теперь в переменной sRetVal результат работы функции.
Вот так вот все просто. Желаю удачи!
Вставка ассемблерных процедур в код Visual Basic: миф или реальность?
- Введение
- Подготовка ассемблерного кода
- Добавление ассемблерных процедур в код на Visual Basic 6.0
Введение
Знатоки таких языков высокого уровня, как Delphi и C++, сейчас скажут, что только данные языки способны воспринимать низкоуровневые конструкции, причем ключевого слова Asm вполне достаточно. Частично с этим утверждением можно согласиться – в Visual Basic 6.0 так просто встроить ассемблерный код нельзя, но поверьте, прочитав данную статью для Вас это будет также просто сделать и на Visual Basic.
Для начала рассмотрим методику вставки. Для вызова ассемблерного кода используется API функция "CallWindowProc", содержащаяся в библиотеке "user32.dll", которая входит в поставку Windows. Она имеет 1 основной и 4 дополнительных параметра. В первый мы будем передавать адрес первой ячейки массива, содержащего массив байт (откомпилированную ассемблерную процедуру), а в остальные – параметры, необходимые для работы ассемблерной функции.
Для начала создадим новый проект и объявим эту функцию:
Private Declare Sub CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal ptrMC As Long, ByRef P1 As Long, ByVal P2 As Long, ByVal P3 As Long, ByVal P4 As Long)
Теперь создадим функцию, которая преобразует HEX строку машинных кодов в байтовый массив и возвратит адрес первой ячейки массива:
Private Bytes() As Byte
Private Function LoadAsmFunction(CodeString As String) As Long
Dim i As Long
If Len(CodeString) = 0 Then Exit Sub
ReDim Bytes(Len(CodeString) \ 2 - 1)
For i = 0 To Len(CodeString) \ 2 - 1
Bytes(i) = CByte("&H" & Mid(CodeString, i * 2 + 1, 2))
Next i
LoadAsmFunction = VarPtr(Bytes(0))
End Function
И наконец перейдем непосредственно к созданию ассемблерной функции.
Подготовка ассемблерного кода
При создании новой функции будем использовать следующий шаблон:
[BITS 32] ;Делаем процедуру 32 битной
; Считываем данные из стека
push ebp
mov ebp, esp
push ebx
push esi
push edi
; Код нашей процедуры
; Если в процедуру передавалось два параметра
mov eax, [ebp+8] ; Считываем первый
mov ebx, [ebp+12] ; Считываем второй
xor eax, ebx ; Производим операцию над параметрами
; Регистр EAX всегда должен содержать то, что возвращает функция
; Записываем данные в стек
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Комментарий: первый параметр, передаваемый функции всегда находится по адресу ebp+8, остальные в зависимости от их длины расположены дальше по стеку. Строки передавать в функцию не стоит, так как они в Unicode и потребуется масса дополнительного кода для их обработки. Также компилятор nasmw не понимает команды db, поэтому работать с переменными, созданными в этой функции вам пока не получится. Использование API, а также создание переменных рассмотрено во второй части статьи. При вызове более 2-х параметров в конце функции необходимо корректировать стек и вместо ret ставить ret 8 при использовании 3-х параметров и ret 8+<длина параметра(чаще всего 4)> при использовании 4-х параметров.
Теперь у Вас возникнет вопрос: "Как это все теперь перевести в HEX строку, которую мы будем передавать ранее написанной функции?". Резонный вопрос. Для начала необходимо перевести этот ассемблерный код в BIN файл, содержащий машинные коды, для чего можно использовать nasmw – компилятор ассемблера (командная строка: nasmw.exe -f bin YouProgram.asm -o YouProgram.bin), а затем написать небольшую программку для перевода BIN файла в HEX строку. Я же рекомендую не геморроиться и использовать написанную мной утилиту Asm to VB, которая без проблем переведет код, написанный по вышеприведенному шаблону в BIN файл или HEX строку. В Asm to VB я уже встроил компилятор nasmw, поэтому кроме этой программы для написания ассемблерных функций Вам ничего не потребуется.
Добавление ассемблерных процедур в код на Visual Basic 6.0
У нас есть Hex строка и функция, передавая в которую Hex строку создается массив машинных инструкций и возвращается ссылка на первую ячейку массива. Поверьте этого достаточно.
Теперь запустим функцию с параметрами (если в функцию передаётся не 4, а меньше параметров, то остальные параметры забиваются нулями, если этого не сделать, функция не будет работать!), предварительно присвоив переменной sHex Hex строку, которую мы получили в предыдущем шаге:
sRetVal = CallWindowProc(LoadAsmFunction(sHex),0,0,0,0)
Теперь в переменной sRetVal результат работы функции.
Вот так вот все просто. Желаю удачи!
Комментарии |
отсутствуют |
Добавление комментария |