Структура программы Visual BasicStructure of a Visual Basic Program. Visual basic программа
Руководство по исследованию программ, написанных на Visual Basic 6.0
Приводим статью, которая увидела свет еще в середине 2005-го года на станицах ресурса WASM.RU. Приводим статью полностью, без редактирования. Актуальность информации (Visual Basic 6.0 и ОС тех лет), а также актуальность приведенных ссылок требует дополнительного анализа. Но речь не об этом.
Многие почему то считают, что Visual Basic это примитивный язык программирования, который не может компилировать программы, работать с адресами переменных в памяти и не позволяющий вставлять ассемблерные процедуры в код. Так вот, все это неправда. Начиная с версии 5.0 данный язык позволяет компилировать программы в Native Code, а также имеется возможность работы с адресами переменных в памяти (для этого существует функция varptr). Ассемблерные процедуры вставлять тоже можно, но не так просто. Для этого я написал уже 2 части статьи по вставке ассемблерных процедур в код на Visual Basic. Эти статьи можно найти на сайте www.dotfix.net. Как видите, недостатков у VB не так уж и много, а преимуществ настолько много, что я расскажу лишь о самых очевидных и важных:
[Функции]
Самые непонятные исследователям функции — функции для преобразования данных из одного типа в другой. Чуть ниже я для удобства приведу существующие типы данных, используемых в Visual Basic 6.0 и функции для работы с ними. За большую часть данной информации хотелось бы поблагодарить Eternal_Bliss (http:\\crackmes.cbj.net) и авторов сайта http://www.infonegocio.com/vbcrack/, хотя на момент второй редакции статьи (которую Вы сейчас видите перед собой) мне прилось значительно расширить эту информацию основываясь на собственном опыте.Часть имени каждой функции преобразования данных представляет собой набор аббревиатур, обозначающих типы исходных и конечных данных. Вот их расшифровка:
Тип данных | Расшифровка |
bool | boolean |
str | string |
i2 | byte or integer (2 битный integer) |
ui2 | unsigned integer (2 битный unsigned integer) |
i4 | long (4 битный integer) |
r4 | single (4 битный real) |
r8 | double (8 битный real) |
cy | currency |
var | variant (VB) или variable (OLEAUT) |
fp | число с плавающей точкой |
cmp | сравнение |
comp | сравнение |
Ниже представленые функции, экспортируемые библиотекой MSVBVM60.DLL. Если Вам потребуется вызывать эти вункции из своих программ, то имейте ввиду, что у VB свои типы данных, отличные в некоторых случаях от тех, которые используются в Delphi и С++. Строки вообще имеют свой особый формат (в начале строки два (или четыре) байта указывают на длину, затем идет строка). Отсюда бессмысленно пытаться вызвать перечисленные ниже функции из Delphi или C++ — такой вызов скорее всего приведет к ошибке. Что касается конвенции вызовов, то VB использует stdcall и другие не поддерживает, из чего логично сделать вывод, что Dll написанную на C++ с конвенцией вызова cdecl вызвать из VB практически невозможно.
__vbaI2Str | преобразует String в Integer |
__vbaI4Str | преобразует String в Long |
__vbar4Str | преобразует String в Single |
__vbar8Str | преобразует String в Double |
VarCyFromStr | преобразует String в Currency |
VarBstrFromI2 | преобразует Integer в String |
__vbaStrCopy | копирует строку в память — аналог API функции HMEMCPY |
__vbaVarCopy | копирует переменный тип (variant) в память |
__vbaVarMove | копирует переменный тип (variant) в память |
__vbavaradd | сложение двух переменных типа Variant |
__vbavarsub | деление двух переменных типа Variant |
__vbavarmul | умножение двух переменных типа Variant |
__vbavaridiv | сложение двух переменных типа Variant с выводом результата в переменную типа Integer |
__vbavarxor | XOR |
__vbavarfornext | используется в конструкциях For… Next… (Loop) |
__vbafreestr | удаление переменной |
__vbafreeobj | удаление объекта |
__vbastrvarval | получения численного значения из строки |
multibytetowidechar | преобразование кодировки |
rtcMsgBox | показывает сообщение — аналог API messagebox/a/exa |
__vbavarcat | объединяет две переменные типа Variant |
__vbafreevar | удаляет переменную типа Variant |
__vbaobjset | создает объект |
__vbaLenBstr | определяет длину строки |
rtcInputBox | показывает форму с полем ввода (используются также API функции getwindowtext/a, GetDlgItemtext/a) |
__vbaNew | аналог API функции Dialogbox |
__vbaNew2 | аналог API функции Dialogboxparam/a |
rtcTrimBstr | удаляет пробелы вначале и в конце строки |
__vbastrcomp | сравнивает 2 строковые переменные — аналог API функции lstrcmp |
__vbastrcmp | сравнивает 2 строковые переменные — аналог API функции lstrcmp |
__vbavartsteq | сравнивает 2 Variant переменные |
__vbaFpCmpCy | сравнивает значение с плавающей точкой с Currency значением |
[Разблокирование элементов управления]
Любой элемент управления на форме может быть видимым или невидимым, доступным или заблокированным. Очень часто для взлома программы бывает нужно разблокировать отдельные элементы управления на форме. Для установки свойств объектов существует функция __vbaObjSet. Именно с помощью нее можно заблокировать или разблокировать элемент управления и изменить любое из его свойств. Поэтому нам необходимо отлавливать вызов именно этой функции. Откроем например Olly Debugger, найдем эту функцию среди вызываемых программой и поставим на нее бряк нажав кнопку F2. Затем запустим исследуемую программу. Когда бряк сработает — посмотрите окружающий код. Если он напоминает
CODE NOW! |
50 push eax52 push edxFFD7 call edi8BD8 mov ebx, eax6A00 push 0053 push ebx8B03 mov eax, dword ptr [ebx] |
то вы на верном пути. Как вы думаете, что это за «push 00»? 00h в VB означает FALSE, а FFh TRUE, из этого следует, что данная команда устанавливает свойство в FALSE, то есть возможно это и есть блокировка элемента управления на форме. Но это может быть и установка любого другого свойства формы в TRUE. Так как синтаксис один и тот же, что принадлежность данной команды к изменению свойства блокировки можно установить только анализом окружающего кода, но умаю с этой мелочью вы справитесь сами.
[Методика взлома простейших проверок пароля]
Нижеследующий текст — мой вольный перевод статьи How to Research Visual Basic Cracking с сайта http://www.infonegocio.com/vbcrack/. За английскую версию текста спасибо ее авторам.
Что нам может понадобиться? Любой дизассемблер/отладчик. Подойдет Win32Dasm или Olly Debugger Если вы используете W32Dasm, то функции, используемые программой вы можете посмотреть в меню «Functions» -> «Imports».
Если вы будете исследовать базу данных Jet, которая использует драйвера Micro$oft, то помните, что названия функции не говорят сами за себя и вам будет трудно узнать действие, которое выполняет та или иная функция. в данном случае Вам остается только смотреть рекомендации к функциям, которые любезно оставлены программистами Micro$oft. Дыр же в этих драйверах практически нет, поэтому исследовать программы для работы с базами данных довольно сложно.
Рассмотрим пример защиты программы паролем. Для удобства поиска нужного кода поставим MessageBox. Откройте Visual Basic, добавьте на форму текстовое поле и кнопку, затем в обработчике щелчка по кнопке напишите следующий код:
CODE NOW! |
Private Sub Command1_Click()Dim X&X = 43690MsgBox «Testing password»If CLng(Trim$(Text1.Text)) = X Then MsgBox («GoodBoy»)End Sub |
Теперь откроем Olly Debugger, загрузим в него прогу (предварительно прогу нужно откомпилировать) и ищем вызов функции rtcMsgBox.
CODE NOW! |
00401F54 FF1520104000 CALL [MSVBVM60!rtcMsgBox] ;MsgBox «Testing password»00401F5A 8D459C LEA EAX,[EBP-64]00401F5D 8D4DAC LEA ECX,[EBP-54]00401F60 50 PUSH EAX00401F61 8D55BC LEA EDX,[EBP-44]00401F64 51 PUSH ECX00401F65 8D45CCLEA EAX,[EBP-34]00401F68 52 PUSH EDX00401F69 50 PUSH EAX00401F6A 6A04 PUSH 0400401F6C FF1508104000 CALL [MSVBVM60!__vbaFreeVarList]00401F72 8B0E MOV ECX,[ESI]00401F74 83C414 ADD ESP,1400401F77 56 PUSH ESI00401F78 FF9104030000 CALL [ECX+00000304]00401F7E 8D55DCLEA EDX,[EBP-24]00401F81 50 PUSH EAX00401F82 52 PUSH EDX00401F83 FF1524104000 CALL [MSVBVM60!__vbaObjSet]00401F89 8BF0 MOV ESI,EAX00401F8B 8D4DE4LEA ECX,[EBP-1C]00401F8E 51 PUSH ECX00401F8F 56 PUSH ESI00401F90 8B06 MOV EAX,[ESI]00401F92 FF90A0000000 CALL [EAX+000000A0]00401F98 3BC7 CMP EAX,EDI00401F9A DBE2 FCLEX00401F9C 7D12 JGE 00401FB000401F9E 68A0000000 PUSH 000000A000401FA3 6804184000 PUSH 0040180400401FA8 56 PUSH ESI00401FA9 50 PUSH EAX00401FAA FF1518104000 CALL [MSVBVM60!__vbaHresultCheckObj] ;получение содержимого Text1.Text00401FB0 8B55E4MOV EDX,[EBP-1C]00401FB3 52 PUSH EDX00401FB4 FF1514104000 CALL [MSVBVM60!rtcTrimBstr] ;Trim$00401FBA 8BD0 MOV EDX,EAX00401FBC 8D4DE0 LEA ECX,[EBP-20]00401FBF FF1584104000 CALL [MSVBVM60!__vbaStrMove]00401FC5 50 PUSH EAX00401FC6 FF1568104000 CALL [MSVBVM60!__vbaI4Str] ;CLng00401FCC 33C9 XOR ECX,ECX00401FCE 3DAAAA0000 CMP EAX,0000AAAA ;Число 43690 в HEX виде00401FD3 8D55E0LEA EDX,[EBP-20]00401FD6 8D45E4LEA EAX,[EBP-1C]00401FD9 0F94C1 SETZ CL00401FDC 52 PUSH EDX00401FDD 50 PUSH EAX00401FDE F7D9 NEG ECX00401FE0 6A02 PUSH 0200401FE2 8BF1 MOV ESI,ECX00401FE4 FF156C104000 CALL [MSVBVM60!__vbaFreeStrList]00401FEA 83C40C ADD ESP,0C00401FED 8D4DDC LEA ECX,[EBP-24]00401FF0 FF1594104000 CALL [MSVBVM60!__vbaFreeObj]00401FF6 663BF7 CMP SI,DI00401FF9 7463 JZ 0040205E ;переход на GoodBoy код (MsgBox «GoodBoy»)00401FFB B804000280 MOV EAX,8002000400402000 8D558C LEA EDX,[EBP-74]00402003 8D4DCCLEA ECX,[EBP-34]00402006 8945A4 MOV [EBP-5C],EAX00402009 895D9C MOV [EBP-64],EBX0040200C 8945B4 MOV [EBP-4C],EAX0040200F 895DAC MOV [EBP-54],EBX00402012 8945C4 MOV [EBP-3C],EAX00402015 895DBC MOV [EBP-44],EBX00402018 C7459418184000 MOV DWORD PTR [EBP-6C],004018180040201F C7458C08000000 MOV DWORD PTR [EBP-74],0000000800402026 FF157C104000 CALL [MSVBVM60!__vbaVarDup]0040202C 8D4D9C LEA ECX,[EBP-64] |
Чтобы взломать данную программу — нужно изменить переход по адресу 00401FF9с условного на абсолютный. Для этого меняем JE на JMP (то есть 74h на EBh).Как видите — простенькие защиты VB программ ломаются не сложнее чем в программах, написанных наDelphi или C++
[Взлом паролей в виде разных типов данных]
Нижеследующий тест — мой вольный перевод статей:Cracking Visual Basic Serials — Strings, integers and LongsCracking Visual Basic Serials — Single, Double and XORс сайта http://www.infonegocio.com/vbcrack/. За английские версии этих статей спасибо их авторам.
CODE NOW! |
Exported fn(): __vbaStrCopy — Ord:008Ah:66024532 56 PUSH ESI:66024533 57 PUSH EDI:66024534 85D2 TEST EDX, EDX:66024536 8BF9 MOV EDI, ECX:66024538 0F84C2350200 JE 66047B00:6602453E FF72FC PUSH [EDX-04] ;по этому адресу лежит строка:66024541 52 PUSH EDX |
CODE NOW! |
00401BC7 50 PUSH EAX ;то что Вы ввели00401BC8 6880174000 PUSH 00401780 ;верный пароль00401BCD FF1530104000 CALL [MSVBVM60!__vbaStrComp] |
CODE NOW! |
00401B77 FF155C104000 CALL [MSVBVM60!__vbaI4Str]00401B7D 8D4DE0 LEA ECX, [EBP-20]00401B80 8BF8 MOV EDI, EAX00401B82 FF157C104000 CALL [MSVBVM60!__vbaFreeStr]00401B88 8D4DDC LEA ECX, [EBP-24]00401B8B FF1580104000 CALL [MSVBVM60!__vbaFreeObj]00401B91 81FFB168DE3A CMP EDI, 3ADE68B1 ; 3ADE68B1 — это пароль00401B97 7520 JNZ 00401BB9 ;функция вернет ноль;если пароли верны, следовательно этот переход;сработает только при неверном пароле |
Тут мы можем узнать верный пароль или отключить проверку пароля (для этого нужно JNZ заменить на NOP (то есть в данном случае менять нужно байты по адресу 00401B97 с 7520 на 9090)
CODE NOW! |
00401C0C FF153C104000 CALL [MSVBVM60!_vbaR4Str]00401C12 D95DE4 FSTP REAL4 PTR [EBP-1C]00401C15 8D4DDC LEA ECX, [EBP-24]00401C18 8D55E0 LEA EDX, [EBP-20]00401C1B 51 PUSH ECX00401C1C 52 PUSH EDX00401C1D 6A02 PUSH 0200401C1F FF1570104000 CALL [MSVBVM60!__vbaFreeStrList]00401C25 83C40C ADD ESP, 0C00401C28 8D4DD8 LEA ECX, [EBP-28]00401C2B FF1594104000 CALL [MSVBVM60!__vbaFreeObj]00401C31 817DE43A92FC42 CMP DWORD PTR [EBP-1C], 42FC923A00401C38 7520 JNZ 00401C5A ;если ноль, то пароль неправильный |
Замените инструкцию по адресу 00401C38 на 9090 (чтобы в данном месте не выполнялось никаких операций) или измените условный переход на противоположный. Программисты на Visual Basic не смогут проверить то, что вы заменили эти байты на два NOP’а (9090). Если у Вас все же возникают опасения, что программа перестанет работать при отсутствии команд, просто введите команды, которые ничего не поменяют, например:
Эти команды однобайтовые и как раз впишутся на место условного перехода
CODE NOW! |
00401C55 FF1510104000 CALL [MSVBVM60!rtcTrimBstr]00401C5B 8BD0 MOV EDX, EAX00401C5D 8D4DD8 LEA ECX, DWORD PTR [EBP-28]00401C60 FF1580104000 CALL [MSVBVM60!__vbaStrMove]00401C66 50 PUSH EAX00401C67 FF1560104000 CALL [MSVBVM60!__vbaR8Str]00401C6D DC1DD8104000 FCOMP REAL8 PTR [004010D8] ;сравнение паролей00401C73 DFE0 FSTSW AX ;обработка сопроцессором00401C75 F6C440 TEST AH, 40 ;проверка правильности пароля00401C78 7409 JE 00401C83 ;переход, если пароль верный |
Замените инструкцию по адресу 00401C78 на 9090 (чтобы в данном месте не выполнялось никаких операций) или измените условный переход на противоположный. Программисты на Visual Basic не смогут проверить то, что вы заменили эти байты на два NOP’а (9090). Если у Вас все же возникают опасения, что программа перестанет работать при отсутствии команд, просто введите команды, которые ничего не поменяют, например:
Эти команды однобайтовые и как раз впишутся на место условного перехода
CODE NOW! |
00401E6C 50 PUSH EAX00401E6D FF1544104000 CALL [MSVBVM60!rtcMidCharBstr]00401E73 8BD0 MOV EDX, EAX00401E75 8D4DC8 LEA ECX, [EBP-38]00401E78 FFD6 CALL ESI00401E7A 50 PUSH EAX00401E7B FF1518104000 CALL [MSVBVM60!rtcAnsiValueBstr]00401E81 0FBFC8 MOVSX ECX, AX00401E84 81F191000000 XOR ECX, 00000091 ;ANSI XOR 9100401E8A 51 PUSH ECX ;результат XOR’а00401E8B FF1570104000 CALL [MSVBVM60!rtcBstrFromAnsi] |
Ставим бряк на 00401E8A 51 PUSH ECX и отслеживаем изменение содержимого регистра ECX при прохождении цикла. Когда программа пройдет весь цикл — вы получите полный пароль.
CODE NOW! |
CALL [MSVBVM60!rtcMidCharBstr] ;получает один символ из пароляCALL [MSVBVM60!rtcAnsiValueBstr] ;получает из символа Ansi код.CALL [MSVBVM60!rtcBstrFromAnsi] ;преобразует Ansi код в строку |
В этом случае ниже скорее всего будет сравнение и переход, при этом CALL [MSVBVM60!__vbaStrComp] может быть использован для сравнения строк. Если не производится обращение к MSVBVM60!rtcBstrFromAnsi тогда с паролем производятся определенные математические манипуляции, при этом он может быть представлен как 2х или 4х битное число или число с плавающей точкой. Об этих случаях было сказано выше.
[Заключение]
Надеюсь, что прочитав данную статью Вас уже больше не пугает исследование VB кода. Чтобы потренироваться советую поисследовать мои крякми (лежат на www.dotfix.net в разделе «Разное»), о взломе первого из которых написана статья (лежит на www.dotfix.net в разделе «Статьи»). Второй мой крякми еще никто не взломал 😉
Еще раз благодарю авторов сайта http://www.infonegocio.com/vbcrack/, так как если бы не их туториалы на английском, то этой статьи возможно и не было бы.
Удачи и спасибо за то, что дочитали статью до конца
[C] GPcH
sciencestory.ru
Структура программы Visual Basic | Microsoft Docs
- 07/20/2015
- Время чтения: 6 мин
- Соавторы
В этой статье
Программа Visual Basic построена из стандартных блоков.A Visual Basic program is built up from standard building blocks. Объект решения состоит из одного или нескольких проектов.A solution comprises one or more projects. Объект проекта в свою очередь может содержать одну или несколько сборок.A project in turn can contain one or more assemblies. Каждый сборки компилируется из одного или нескольких исходных файлов.Each assembly is compiled from one or more source files. Объект исходный файл содержит определения и реализации классов, структур, модули и интерфейсы, которые в конечном счете содержит весь код.A source file provides the definition and implementation of classes, structures, modules, and interfaces, which ultimately contain all your code.
Дополнительные сведения об этих стандартных блоках программы на Visual Basic см. в разделе решения и проекты и сборки и глобальный кэш сборок.For more information about these building blocks of a Visual Basic program, see Solutions and Projects and Assemblies and the Global Assembly Cache.
Элементы программирования уровня файлаFile-Level Programming Elements
При запуске проекта или файла и открыть редактор кода, вы видите часть кода, имеющуюся в правильном порядке.When you start a project or file and open the code editor, you see some code already in place and in the correct order. Любой код, написанный должны создаваться в следующей последовательности:Any code that you write should follow the following sequence:
Option ИнструкцииOption statements
Imports ИнструкцииImports statements
Namespace инструкции и элементы уровня пространства именNamespace statements and namespace-level elements
Введите инструкции в другом порядке, может привести к ошибкам компиляции.If you enter statements in a different order, compilation errors can result.
Программа также может содержать операторы условной компиляции.A program can also contain conditional compilation statements. Можно соединять, их в исходном файле среди инструкций предыдущей последовательности.You can intersperse these in the source file among the statements of the preceding sequence.
Параметры инструкцииOption Statements
Option Операторы устанавливают основные правила для последующего кода, способствуя предотвращению синтаксических и логических ошибок.Option statements establish ground rules for subsequent code, helping prevent syntax and logic errors. Оператор Option Explicit гарантирует, что все переменные объявляются и написаны правильно, что сокращает время отладки.The Option Explicit Statement ensures that all variables are declared and spelled correctly, which reduces debugging time. Оператор Option Strict позволяет свести к минимуму потерю ошибок и данных логику, которая может возникнуть при работе с переменными различных типов данных.The Option Strict Statement helps to minimize logic errors and data loss that can occur when you work between variables of different data types. Option Compare Statement указывает способа сравнения строк друг с другом на основе их Binary или Text значения.The Option Compare Statement specifies the way strings are compared to each other, based on either their Binary or Text values.
Оператор ImportsImports Statements
Можно включить оператор Imports (пространство имен .NET и тип) для импорта имена, определенные вне проекта.You can include an Imports Statement (.NET Namespace and Type) to import names defined outside your project. Imports Оператор разрешает коде для ссылки на классы и другие типы, определенные в импортированном пространстве имен без их уточнения.An Imports statement allows your code to refer to classes and other types defined within the imported namespace, without having to qualify them. Можно использовать любое количество Imports соответствующих операторов.You can use as many Imports statements as appropriate. Дополнительные сведения см. в разделе ссылки и оператор Imports.For more information, see References and the Imports Statement.
Операторы пространств именNamespace Statements
Пространства имен помогают организовывать и классифицировать элементы программирования для упрощения группирования и доступ к.Namespaces help you organize and classify your programming elements for ease of grouping and accessing. Вы используете оператор Namespace для классификации следующих операторов в определенном пространстве имен.You use the Namespace Statement to classify the following statements within a particular namespace. Дополнительные сведения см. в разделе Пространства имен в Visual Basic.For more information, see Namespaces in Visual Basic.
Операторы условной компиляцииConditional Compilation Statements
Операторы условной компиляции могут использоваться практически в любом месте в файле исходного кода.Conditional compilation statements can appear almost anywhere in your source file. Они смогут причинить части кода нужно включить или исключить во время компиляции в зависимости от определенных условий.They cause parts of your code to be included or excluded at compile time depending on certain conditions. Вы также их можно использовать для отладки приложения, поскольку условный код выполняется только в режиме отладки.You can also use them for debugging your application, because conditional code runs in debugging mode only. Дополнительные сведения см. в разделе условной компиляции.For more information, see Conditional Compilation.
Элементы программирования уровня пространства именNamespace-Level Programming Elements
Классы, структуры и модули содержат весь код в файле исходного кода.Classes, structures, and modules contain all the code in your source file. Они являются уровня пространства имен элементы, которые могут отображаться в пространстве имен или на уровне исходного файла.They are namespace-level elements, which can appear within a namespace or at the source file level. Они содержат описания всех элементов программирования.They hold the declarations of all other programming elements. Интерфейсы, которые определяют подписи элементов, но не выполняют реализацию, также отображаются на уровне модуля.Interfaces, which define element signatures but provide no implementation, also appear at module level. Дополнительные сведения об элементах уровня модуля см.For more information on the module-level elements, see the following:
Элементы данных на уровне пространства имен, перечисления и делегаты.Data elements at namespace level are enumerations and delegates.
Элементы программирования уровня модуляModule-Level Programming Elements
Процедуры, операторы, свойства и события являются единственными элементами программирования, которые могут содержать исполняемый код (инструкции, которые выполняют действия во время выполнения).Procedures, operators, properties, and events are the only programming elements that can hold executable code (statements that perform actions at run time). Они являются уровня модуля элементы программы.They are the module-level elements of your program. Дополнительные сведения об элементах уровня процедуры см.For more information on the procedure-level elements, see the following:
Элементы данных на уровне модуля, переменные, константы, перечисления и делегаты.Data elements at module level are variables, constants, enumerations, and delegates.
Элементы программирования уровня процедурыProcedure-Level Programming Elements
Большая часть содержимого уровня процедуры элементы, исполняемые операторы, которые составляют код времени выполнения программы.Most of the contents of procedure-level elements are executable statements, which constitute the run-time code of your program. Весь код, исполняемый файл должен быть в некоторой процедуры (Function, Sub, Operator, Get, Set, AddHandler, RemoveHandler, RaiseEvent).All executable code must be in some procedure (Function, Sub, Operator, Get, Set, AddHandler, RemoveHandler, RaiseEvent). Дополнительные сведения см. в разделе Выписки.For more information, see Statements.
Элементы данных на уровне процедуры ограничиваются локальных переменных и констант.Data elements at procedure level are limited to local variables and constants.
Основная процедураThe Main Procedure
Main Процедура — это первый код для выполнения при загрузке приложения.The Main procedure is the first code to run when your application has been loaded. Main служит в качестве начальной точки и общего управления для приложения.Main serves as the starting point and overall control for your application. Существуют четыре вида Main:There are four varieties of Main:
Sub Main()
Sub Main(ByVal cmdArgs() As String)
Function Main() As Integer
Function Main(ByVal cmdArgs() As String) As Integer
Наиболее распространенный этой процедуры является Sub Main().The most common variety of this procedure is Sub Main(). Дополнительные сведения см. в разделе процедура Main в Visual Basic.For more information, see Main Procedure in Visual Basic.
См. такжеSee Also
Процедура Main в Visual BasicMain Procedure in Visual BasicСоглашения об именах Visual BasicVisual Basic Naming ConventionsОграничения в Visual BasicVisual Basic Limitations
docs.microsoft.com
Visual Basic | Microsoft Docs
- 03/28/2018
- Время чтения: 2 мин
- Соавторы
В этой статье
Visual Basic предназначен для эффективного создания типобезопасных и объектно-ориентированных приложений.Visual Basic is engineered for productively building type-safe and object-oriented applications. Visual Basic позволяет разработчикам создавать приложения Windows, веб-приложения и приложения для мобильных устройств.Visual Basic enables developers to target Windows, Web, and mobile devices. Программы, написанные на языке Visual Basic, как и на других языках, предназначенных для платформы Microsoft .NET Framework, отличаются безопасностью и поддержкой взаимодействия.As with all languages targeting the Microsoft .NET Framework, programs written in Visual Basic benefit from security and language interoperability.
Современное поколение Visual Basic поддерживает традиции, предоставляя возможность легко и быстро создавать приложения на основе платформы .NET Framework.This generation of Visual Basic continues the tradition of giving you a fast and easy way to create .NET Framework-based applications.
Если у вас нет Visual Basic, вы можете получить версию Visual Studio с бесплатным Visual Basic на сайте Visual Studio .If you don't already have Visual Basic, you can acquire a version of Visual Studio that includes Visual Basic for free from the Visual Studio site.
В этом разделеIn This Section
Начало работыGetting StartedПомогает приступить к работе и содержит список новых возможностей и возможностей, доступных в различных выпусках продукта.Helps you begin working by listing what is new and what is available in various editions of the product.
Основные понятия программирования Основные понятия языка Visual Basic, которые наиболее важны для программистов.Programming Concepts Presents the language concepts that are most useful to Visual Basic programmers.
Соглашения о структуре программы и кодеProgram Structure and Code ConventionsСодержит документацию по базовой структуре и соглашениям кода Visual Basic, таким как соглашения об именовании, комментарии в коде и действующие в Visual Basic ограничения.Contains documentation on the basic structure and code conventions of Visual Basic such as naming conventions, comments in code, and limitations within Visual Basic.
Возможности и элементы языка Visual BasicVisual Basic Language FeaturesСодержит ссылки на разделы с описанием важных элементов Visual Basic, включая LINQ и XML-литералы.Provides links to topics that introduce and discuss important features of Visual Basic, including LINQ and XML literals.
Справочник по Visual BasicVisual Basic ReferenceСодержит сведения о языке Visual Basic и компиляторе.Contains the Visual Basic language and compiler information.
Разработка приложений в Visual BasicDeveloping Applications with Visual BasicЗатрагивает многие аспекты разработки в Visual Basic, такие как безопасность, обработка исключений и использование библиотеки классов .NET Framework.NET Framework.Discusses various aspects of development in Visual Basic, such as security, exception handling, and using the .NET Framework.NET Framework class library.
COM-взаимодействиеCOM InteropРассматривает проблемы взаимодействия, связанные с созданием и использованием объектов модели COM в Visual Basic.Explains the interoperability issues associated with creating and using component object model (COM) objects with Visual Basic.
ПримерыSamplesОписание примеров.Contains information about samples.
Пошаговые руководстваWalkthroughsСсылки на пошаговые инструкции для стандартных сценариев.Provides links to step-by-step instructions for common scenarios.
Начало разработки в Visual StudioGet Started Developing with Visual StudioСсылки на разделы об основах Visual Studio.Provides links to topics that help you learn about the basics of Visual Studio.
Браузер API .NET.NET API BrowserСодержит вводные данные о библиотеке классов, интерфейсах и типах значений, включенных в Microsoft .NET Framework.NET Framework SDK.Provides entry to the library of classes, interfaces, and value types that are included in the Microsoft .NET Framework.NET Framework SDK.
docs.microsoft.com
Руководство по исследованию программ, написанных на Visual Basic 6.0
Руководство по исследованию программ, написанных на Visual Basic 6.0 — Архив WASM.RU
[Вступление]Многие почему то считают, что Visual Basic это примитивный язык программирования, который не может компилировать программы, работать с адресами переменных в памяти и не позволяющий вставлять ассемблерные процедуры в код. Так вот, все это неправда. Начиная с версии 5.0 данный язык позволяет компилировать программы в Native Code, а также имеется возможность работы с адресами переменных в памяти (для этого существует функция varptr). Ассемблерные процедуры вставлять тоже можно, но не так просто. Для этого я написал уже 2 части статьи по вставке ассемблерных процедур в код на Visual Basic. Эти статьи можно найти на сайте www.dotfix.net. Как видите, недостатков у VB не так уж и много, а преимуществ настолько много, что я расскажу лишь о самых очевидных и важных:
Так вот, начинающие исследователи программ почему то считают, что программы, написанные на VB невозможно сломать. Если программа скомпилирована в pcode - я частично с ними соглашусь, но даже для этого вида компиляции уже написано множество отладчиков, способных понимать псевдокодовые инструкции. Что же касается Native Code, то тут все ломается также, как и любая другая программа, написанная например на C++ или Delphi. Но есть ряд особенностей. Все операции, которые выполняет программа выполняются с использованием узкоспециализированных функций из библиотеки MSVBVM60.DLL. Имена этих функций напоминают операторы Visual Basic'а, поэтому глядя на названия большинства из них, можно понять, какие операции они позволяют выполнять. Но есть и такие, которые не поддаются логике. О них я и расскажу в данной статье.
[Функции]
Самые непонятные исследователям функции - функции для преобразования данных из одного типа в другой. Чуть ниже я для удобства приведу существующие типы данных, используемых в Visual Basic 6.0 и функции для работы с ними. За большую часть данной информации хотелось бы поблагодарить Eternal_Bliss (http:\\crackmes.cbj.net) и авторов сайта http://www.infonegocio.com/vbcrack/, хотя на момент второй редакции статьи (которую Вы сейчас видите перед собой) мне прилось значительно расширить эту информацию основываясь на собственном опыте. Часть имени каждой функции преобразования данных представляет собой набор аббревиатур, обозначающих типы исходных и конечных данных. Вот их расшифровка:
Тип данных | Расшифровка |
bool | boolean |
str | string |
i2 | byte or integer (2 битный integer) |
ui2 | unsigned integer (2 битный unsigned integer) |
i4 | long (4 битный integer) |
r4 | single (4 битный real) |
r8 | double (8 битный real) |
cy | currency |
var | variant (VB) или variable (OLEAUT) |
fp | число с плавающей точкой |
cmp | сравнение |
comp | сравнение |
Ниже представленые функции, экспортируемые библиотекой MSVBVM60.DLL. Если Вам потребуется вызывать эти вункции из своих программ, то имейте ввиду, что у VB свои типы данных, отличные в некоторых случаях от тех, которые используются в Delphi и С++. Строки вообще имеют свой особый формат (в начале строки два (или четыре) байта указывают на длину, затем идет строка). Отсюда бессмысленно пытаться вызвать перечисленные ниже функции из Delphi или C++ - такой вызов скорее всего приведет к ошибке. Что касается конвенции вызовов, то VB использует stdcall и другие не поддерживает, из чего логично сделать вывод, что Dll написанную на C++ с конвенцией вызова cdecl вызвать из VB практически невозможно.
__vbaI2Str | преобразует String в Integer |
__vbaI4Str | преобразует String в Long |
__vbar4Str | преобразует String в Single |
__vbar8Str | преобразует String в Double |
VarCyFromStr | преобразует String в Currency |
VarBstrFromI2 | преобразует Integer в String |
__vbaStrCopy | копирует строку в память - аналог API функции HMEMCPY |
__vbaVarCopy | копирует переменный тип (variant) в память |
__vbaVarMove | копирует переменный тип (variant) в память |
__vbavaradd | сложение двух переменных типа Variant |
__vbavarsub | деление двух переменных типа Variant |
__vbavarmul | умножение двух переменных типа Variant |
__vbavaridiv | сложение двух переменных типа Variant с выводом результата в переменную типа Integer |
__vbavarxor | XOR |
__vbavarfornext | используется в конструкциях For... Next... (Loop) |
__vbafreestr | удаление переменной |
__vbafreeobj | удаление объекта |
__vbastrvarval | получения численного значения из строки |
multibytetowidechar | преобразование кодировки |
rtcMsgBox | показывает сообщение - аналог API messagebox/a/exa |
__vbavarcat | объединяет две переменные типа Variant |
__vbafreevar | удаляет переменную типа Variant |
__vbaobjset | создает объект |
__vbaLenBstr | определяет длину строки |
rtcInputBox | показывает форму с полем ввода (используются также API функции getwindowtext/a, GetDlgItemtext/a) |
__vbaNew | аналог API функции Dialogbox |
__vbaNew2 | аналог API функции Dialogboxparam/a |
rtcTrimBstr | удаляет пробелы вначале и в конце строки |
__vbastrcomp | сравнивает 2 строковые переменные - аналог API функции lstrcmp |
__vbastrcmp | сравнивает 2 строковые переменные - аналог API функции lstrcmp |
__vbavartsteq | сравнивает 2 Variant переменные |
__vbaFpCmpCy | сравнивает значение с плавающей точкой с Currency значением |
[Разблокирование элементов управления]
Любой элемент управления на форме может быть видимым или невидимым, доступным или заблокированным. Очень часто для взлома программы бывает нужно разблокировать отдельные элементы управления на форме. Для установки свойств объектов существует функция __vbaObjSet. Именно с помощью нее можно заблокировать или разблокировать элемент управления и изменить любое из его свойств. Поэтому нам необходимо отлавливать вызов именно этой функции. Откроем например Olly Debugger, найдем эту функцию среди вызываемых программой и поставим на нее бряк нажав кнопку F2. Затем запустим исследуемую программу. Когда бряк сработает - посмотрите окружающий код. Если он напоминает
CODE NOW! |
50 push eax 52 push edx FFD7 call edi 8BD8 mov ebx, eax 6A00 push 00 53 push ebx 8B03 mov eax, dword ptr [ebx] |
то вы на верном пути. Как вы думаете, что это за "push 00"? 00h в VB означает FALSE, а FFh TRUE, из этого следует, что данная команда устанавливает свойство в FALSE, то есть возможно это и есть блокировка элемента управления на форме. Но это может быть и установка любого другого свойства формы в TRUE. Так как синтаксис один и тот же, что принадлежность данной команды к изменению свойства блокировки можно установить только анализом окружающего кода, но умаю с этой мелочью вы справитесь сами.
[Методика взлома простейших проверок пароля]
Нижеследующий текст - мой вольный перевод статьи How to Research Visual Basic Cracking с сайта http://www.infonegocio.com/vbcrack/. За английскую версию текста спасибо ее авторам.
Что нам может понадобиться? Любой дизассемблер/отладчик. Подойдет Win32Dasm или Olly Debugger Если вы используете W32Dasm, то функции, используемые программой вы можете посмотреть в меню "Functions" -> "Imports".
Если вы будете исследовать базу данных Jet, которая использует драйвера Micro$oft, то помните, что названия функции не говорят сами за себя и вам будет трудно узнать действие, которое выполняет та или иная функция. в данном случае Вам остается только смотреть рекомендации к функциям, которые любезно оставлены программистами Micro$oft. Дыр же в этих драйверах практически нет, поэтому исследовать программы для работы с базами данных довольно сложно.
Рассмотрим пример защиты программы паролем. Для удобства поиска нужного кода поставим MessageBox. Откройте Visual Basic, добавьте на форму текстовое поле и кнопку, затем в обработчике щелчка по кнопке напишите следующий код:
CODE NOW! |
Private Sub Command1_Click() Dim X& X = 43690 MsgBox "Testing password" If CLng(Trim$(Text1.Text)) = X Then MsgBox ("GoodBoy") End Sub |
Теперь откроем Olly Debugger, загрузим в него прогу (предварительно прогу нужно откомпилировать) и ищем вызов функции rtcMsgBox.
CODE NOW! |
00401F54 FF1520104000 CALL [MSVBVM60!rtcMsgBox] ;MsgBox "Testing password" 00401F5A 8D459C LEA EAX,[EBP-64] 00401F5D 8D4DAC LEA ECX,[EBP-54] 00401F60 50 PUSH EAX 00401F61 8D55BC LEA EDX,[EBP-44] 00401F64 51 PUSH ECX 00401F65 8D45CCLEA EAX,[EBP-34] 00401F68 52 PUSH EDX 00401F69 50 PUSH EAX 00401F6A 6A04 PUSH 04 00401F6C FF1508104000 CALL [MSVBVM60!__vbaFreeVarList] 00401F72 8B0E MOV ECX,[ESI] 00401F74 83C414 ADD ESP,14 00401F77 56 PUSH ESI 00401F78 FF9104030000 CALL [ECX+00000304] 00401F7E 8D55DCLEA EDX,[EBP-24] 00401F81 50 PUSH EAX 00401F82 52 PUSH EDX 00401F83 FF1524104000 CALL [MSVBVM60!__vbaObjSet] 00401F89 8BF0 MOV ESI,EAX 00401F8B 8D4DE4LEA ECX,[EBP-1C] 00401F8E 51 PUSH ECX 00401F8F 56 PUSH ESI 00401F90 8B06 MOV EAX,[ESI] 00401F92 FF90A0000000 CALL [EAX+000000A0] 00401F98 3BC7 CMP EAX,EDI 00401F9A DBE2 FCLEX 00401F9C 7D12 JGE 00401FB0 00401F9E 68A0000000 PUSH 000000A0 00401FA3 6804184000 PUSH 00401804 00401FA8 56 PUSH ESI 00401FA9 50 PUSH EAX 00401FAA FF1518104000 CALL [MSVBVM60!__vbaHresultCheckObj] ;получение содержимого Text1.Text 00401FB0 8B55E4MOV EDX,[EBP-1C] 00401FB3 52 PUSH EDX 00401FB4 FF1514104000 CALL [MSVBVM60!rtcTrimBstr] ;Trim$ 00401FBA 8BD0 MOV EDX,EAX 00401FBC 8D4DE0 LEA ECX,[EBP-20] 00401FBF FF1584104000 CALL [MSVBVM60!__vbaStrMove] 00401FC5 50 PUSH EAX 00401FC6 FF1568104000 CALL [MSVBVM60!__vbaI4Str] ;CLng 00401FCC 33C9 XOR ECX,ECX 00401FCE 3DAAAA0000 CMP EAX,0000AAAA ;Число 43690 в HEX виде 00401FD3 8D55E0LEA EDX,[EBP-20] 00401FD6 8D45E4LEA EAX,[EBP-1C] 00401FD9 0F94C1 SETZ CL 00401FDC 52 PUSH EDX 00401FDD 50 PUSH EAX 00401FDE F7D9 NEG ECX 00401FE0 6A02 PUSH 02 00401FE2 8BF1 MOV ESI,ECX 00401FE4 FF156C104000 CALL [MSVBVM60!__vbaFreeStrList] 00401FEA 83C40C ADD ESP,0C 00401FED 8D4DDC LEA ECX,[EBP-24] 00401FF0 FF1594104000 CALL [MSVBVM60!__vbaFreeObj] 00401FF6 663BF7 CMP SI,DI 00401FF9 7463 JZ 0040205E ;переход на GoodBoy код (MsgBox "GoodBoy") 00401FFB B804000280 MOV EAX,80020004 00402000 8D558C LEA EDX,[EBP-74] 00402003 8D4DCCLEA ECX,[EBP-34] 00402006 8945A4 MOV [EBP-5C],EAX 00402009 895D9C MOV [EBP-64],EBX 0040200C 8945B4 MOV [EBP-4C],EAX 0040200F 895DAC MOV [EBP-54],EBX 00402012 8945C4 MOV [EBP-3C],EAX 00402015 895DBC MOV [EBP-44],EBX 00402018 C7459418184000 MOV DWORD PTR [EBP-6C],00401818 0040201F C7458C08000000 MOV DWORD PTR [EBP-74],00000008 00402026 FF157C104000 CALL [MSVBVM60!__vbaVarDup] 0040202C 8D4D9C LEA ECX,[EBP-64] |
Чтобы взломать данную программу - нужно изменить переход по адресу 00401FF9 с условного на абсолютный. Для этого меняем JE на JMP (то есть 74h на EBh). Как видите - простенькие защиты VB программ ломаются не сложнее чем в программах, написанных на Delphi или C++
[Взлом паролей в виде разных типов данных]
Нижеследующий тест - мой вольный перевод статей: Cracking Visual Basic Serials - Strings, integers and Longs Cracking Visual Basic Serials - Single, Double and XOR с сайта http://www.infonegocio.com/vbcrack/. За английские версии этих статей спасибо их авторам.
Когда VB копирует строку в память - Вы ее можете отловить. Для этого нужно поставить бряк на функцию __vbaStrCopy и когда бряк сработает, посмотрите код после je 66047B00 (он содержится в библиотеке и един для всех программ). вам нужно посмотреть содержимое edx-04 (в SoftICE нужно ввести команду d edx-04). При этом вы увидите строчку, с которой работает в данный момент функция.
CODE NOW! |
Exported fn(): __vbaStrCopy - Ord:008Ah :66024532 56 PUSH ESI :66024533 57 PUSH EDI :66024534 85D2 TEST EDX, EDX :66024536 8BF9 MOV EDI, ECX :66024538 0F84C2350200 JE 66047B00 :6602453E FF72FC PUSH [EDX-04] ;по этому адресу лежит строка :66024541 52 PUSH EDX |
Поставьте бряк на функцию __vbaStrComp и чуть выше ее вызова будут два push'а - они заносят в стек две Variant переменные для сравнения. Посмотрите содержимое EAX чтобы просмотреть адрес теста. Просмотрите, что лежит по этому адресу, наверняка это правильный пароль.
CODE NOW! |
00401BC7 50 PUSH EAX ;то что Вы ввели 00401BC8 6880174000 PUSH 00401780 ;верный пароль 00401BCD FF1530104000 CALL [MSVBVM60!__vbaStrComp] |
Поставьте бряк на функцию __vbai4str. Эта функция используется программой для перевода введенной текстовой строки в 4х байтовое число. Когда бряк сработает - посмотрите код ниже - там наверняка будет проца сравнения паролей. Но значение пароля будет в HEX виде (например десятичное число 987654321 равно шестнадцатеричному 3ADE68B1).
CODE NOW! |
00401B77 FF155C104000 CALL [MSVBVM60!__vbaI4Str] 00401B7D 8D4DE0 LEA ECX, [EBP-20] 00401B80 8BF8 MOV EDI, EAX 00401B82 FF157C104000 CALL [MSVBVM60!__vbaFreeStr] 00401B88 8D4DDC LEA ECX, [EBP-24] 00401B8B FF1580104000 CALL [MSVBVM60!__vbaFreeObj] 00401B91 81FFB168DE3A CMP EDI, 3ADE68B1 ; 3ADE68B1 - это пароль 00401B97 7520 JNZ 00401BB9 ;функция вернет ноль ;если пароли верны, следовательно этот переход ;сработает только при неверном пароле |
Тут мы можем узнать верный пароль или отключить проверку пароля (для этого нужно JNZ заменить на NOP (то есть в данном случае менять нужно байты по адресу 00401B97 с 7520 на 9090)
Отличие от предыдущего примера в том, что нужно ставить бряк на функцию __vbai2Str. Но иногда предварительно производится преобразование строки сначала в 4х байтовое число посредством функции __vbaI2I4, а затем 4х байтовое число преобразуется в двухбайтовое.
Эту проверку обойти довольно просто. Если Вашей целью является написание патча, то ставьте бряк на функцию __vbaR4Str и когда он сработает - пролистните код вниз. Вы увидите переход после проверки. Просто измените условие перехода на обратное.
CODE NOW! |
00401C0C FF153C104000 CALL [MSVBVM60!_vbaR4Str] 00401C12 D95DE4 FSTP REAL4 PTR [EBP-1C] 00401C15 8D4DDC LEA ECX, [EBP-24] 00401C18 8D55E0 LEA EDX, [EBP-20] 00401C1B 51 PUSH ECX 00401C1C 52 PUSH EDX 00401C1D 6A02 PUSH 02 00401C1F FF1570104000 CALL [MSVBVM60!__vbaFreeStrList] 00401C25 83C40C ADD ESP, 0C 00401C28 8D4DD8 LEA ECX, [EBP-28] 00401C2B FF1594104000 CALL [MSVBVM60!__vbaFreeObj] 00401C31 817DE43A92FC42 CMP DWORD PTR [EBP-1C], 42FC923A 00401C38 7520 JNZ 00401C5A ;если ноль, то пароль неправильный |
Замените инструкцию по адресу 00401C38 на 9090 (чтобы в данном месте не выполнялось никаких операций) или измените условный переход на противоположный. Программисты на Visual Basic не смогут проверить то, что вы заменили эти байты на два NOP'а (9090). Если у Вас все же возникают опасения, что программа перестанет работать при отсутствии команд, просто введите команды, которые ничего не поменяют, например:
CODE NOW! |
inc eax dec eax |
Это также сделать очень просто. Если хочется обойтись битхаком - ставьте бряк на функцию __vbaR8Str и пролистните ком чуть ниже бряка, Вы увидите процедуру сравнения (FCOMP REAL8 PTR [Address]), после нее идет TEST и jump. Измените условие перехода на противоположное.
CODE NOW! |
00401C55 FF1510104000 CALL [MSVBVM60!rtcTrimBstr] 00401C5B 8BD0 MOV EDX, EAX 00401C5D 8D4DD8 LEA ECX, DWORD PTR [EBP-28] 00401C60 FF1580104000 CALL [MSVBVM60!__vbaStrMove] 00401C66 50 PUSH EAX 00401C67 FF1560104000 CALL [MSVBVM60!__vbaR8Str] 00401C6D DC1DD8104000 FCOMP REAL8 PTR [004010D8] ;сравнение паролей 00401C73 DFE0 FSTSW AX ;обработка сопроцессором 00401C75 F6C440 TEST AH, 40 ;проверка правильности пароля 00401C78 7409 JE 00401C83 ;переход, если пароль верный |
Замените инструкцию по адресу 00401C78 на 9090 (чтобы в данном месте не выполнялось никаких операций) или измените условный переход на противоположный. Программисты на Visual Basic не смогут проверить то, что вы заменили эти байты на два NOP'а (9090). Если у Вас все же возникают опасения, что программа перестанет работать при отсутствии команд, просто введите команды, которые ничего не поменяют, например:
CODE NOW! |
inc eax dec eax |
Алгоритм работы бейсиковской процедуры таков. Введенный пароль посимвольно переводится в ASCII коды, которые по очереди XORятся. Затем производится обратный перевод, возможно с предварительными математическими манипуляциями с ASCII кодами. ANSI коды могут XORиться со случайным или фиксированным числом.
CODE NOW! |
00401E6C 50 PUSH EAX 00401E6D FF1544104000 CALL [MSVBVM60!rtcMidCharBstr] 00401E73 8BD0 MOV EDX, EAX 00401E75 8D4DC8 LEA ECX, [EBP-38] 00401E78 FFD6 CALL ESI 00401E7A 50 PUSH EAX 00401E7B FF1518104000 CALL [MSVBVM60!rtcAnsiValueBstr] 00401E81 0FBFC8 MOVSX ECX, AX 00401E84 81F191000000 XOR ECX, 00000091 ;ANSI XOR 91 00401E8A 51 PUSH ECX ;результат XOR'а 00401E8B FF1570104000 CALL [MSVBVM60!rtcBstrFromAnsi] |
Ставим бряк на 00401E8A 51 PUSH ECX и отслеживаем изменение содержимого регистра ECX при прохождении цикла. Когда программа пройдет весь цикл - вы получите полный пароль.
CODE NOW! |
CALL [MSVBVM60!rtcMidCharBstr] ;получает один символ из пароля CALL [MSVBVM60!rtcAnsiValueBstr] ;получает из символа Ansi код. CALL [MSVBVM60!rtcBstrFromAnsi] ;преобразует Ansi код в строку |
В этом случае ниже скорее всего будет сравнение и переход, при этом CALL [MSVBVM60!__vbaStrComp] может быть использован для сравнения строк. Если не производится обращение к MSVBVM60!rtcBstrFromAnsi тогда с паролем производятся определенные математические манипуляции, при этом он может быть представлен как 2х или 4х битное число или число с плавающей точкой. Об этих случаях было сказано выше.
[Заключение]
Надеюсь, что прочитав данную статью Вас уже больше не пугает исследование VB кода. Чтобы потренироваться советую поисследовать мои крякми (лежат на www.dotfix.net в разделе "Разное"), о взломе первого из которых написана статья (лежит на www.dotfix.net в разделе "Статьи"). Второй мой крякми еще никто не взломал ;)
Еще раз благодарю авторов сайта http://www.infonegocio.com/vbcrack/, так как если бы не их туториалы на английском, то этой статьи возможно и не было бы.
Удачи и спасибо за то, что дочитали статью до конца© GPcH
wasm.in