2 x 2 = 3 или сказ о том, как я Visual Basic реверсил

—

от автора

Жив еще Visual Basic: программы еще живы. Байт-код VB выполняется виртуальной машиной msvbvm60.dll , которая до сих пор живет в каталоге C:\Windows .

Задача — разгадать алгоритм проверки ключей.
zira’s ZittoKeygenme https://crackmes.one/crackme/648b452233c5d4393891390d

Борьба с упаковщиком

Первое препятствие — программа упакована. Слабость такой защиты — программа при каждом запуске сама себя распаковывает. Наша задача — найти место перехода к точке входа программы.

ASPack мешает дизассемблеру распознавать команды. Дизассемблер читает байты последовательно, но, когда встречает команду call, встает перед выбором:

  • Пойти по адресу вызова, дизассемблировать процедуру, вернуться и продолжить работу после call

  • Оставить разбор процедуры на потом и дизассемблировать следующую за call команду

IDA оставляет разбор процедуры на потом, поэтому следующей командой прочтет E9 EB 04 5D 45 jmp. Процессор же сперва выполнит call, а за ним и другой код: 5D pop ebp.

Команда call толкает в стек адрес следующей инструкции .aspack:00405007 и передает управление loc_40500A. Код снимает со стека адрес, увеличивает на 1 и возвращает управление на .aspack:00405008: jmp short loc_40500E. Вот так лишний байт E9 в потоке инструкций ослепляет дизассемблер.

Распаковщик вычисляет ImageBase — адрес начала кода в памяти, а затем и точку входа программы, записывает адрес OEP в инструкцию push. Теперь знаем, где остановить отладчик, чтобы сделать снимок программы.

Дизассемблирование Visual Basic кода

Отладчик показывает, что программа передает управление msvbvm60.ThunRTMain — запускает виртуальную машину Visual Basic. Программа передает msvbvm60.ThunRTMain структуру VBHeader, что описывает проект Visual Basic. Visual Basic компилируется в P-код, который исполняется виртуальной машиной, либо в Native машинный код процессора, который обращается к некоторым API виртуальной машины. VBDec помогает разметить структуры, объекты и процедуры Visual Basic в IDA.

Размер обработчиков Form1_Command1_Click и Form1_Command2_Click подсказывает, что Command1 — кнопка Register. Form1_Command1_Click обращается и к строкам «Thank you for registering this keygenme» и «Incorrect registration information», что выдает и защитный механизм.

Упаковщик скрыл импорты функций из msvbvm60.dll , поэтому дизассемблер вместо имен функций показывает call ds:dword_*** . Отладчик сохранил адреса DLL-функций в памяти на момент взятия снимка программы, а по адресам найдем имена.

Последовательность вызовов __vbaI4Var, rtcMidCharVar, rtcUpperCaseVar, rtcAnsiValueBstr подсказывает что цикл работает с каждой буквой строки. Отладчик подтверждает: строка — UserName.

Интуиция подсказывает, что следующие __vbaVarMul и __vbaVarAdd работают с кодом символа, однако в дизассемблере следы переменной var_E0 с кодом символа к этим функциям не ведут. Отладчик показывает, что __vbaVarMul принимает значения 2 и 2, а возвращает 3. Что за…

Арифметические функции msvbvm60.dll работают со структурами типа VARIANT и передают работу библиотеке oleaut32.dll . __vbaVarMul вызывает oleaut32.VarMul . Документация к oleaut32.dll говорит: VarMul работает с аргументами типа VARIANT. «OAIdl.h» из Windows SDK описывает структуру VARIANT, а «wtypes.h» определяет константы VT_I2 = 2, VT_I4 = 3 для VARTYPE vt. Умножение двух VARIANT типа VT_I2 дает VARIANT типа VT_I4.

struct tagVARIANT     {     union          {         struct __tagVARIANT             {             VARTYPE vt;             WORD wReserved1;             WORD wReserved2;             WORD wReserved3;             union                  {                 LONGLONG llVal;                 LONG lVal;                 BYTE bVal; /*...*/

Среди стандартных структур в IDA найдем VARIANT и объединим переменные dword на стеке.

Программа вычисляет хеш User Name так:

int32_t accum = 0; int32_t hash = 0; for (char c: name) {   accum += (0x1749 * toupper(c));   hash = accum - name.length(); }

а за ним — ключ регистрации:

string reg_number = "Zitto - "s + to_string(hash);

Ссылки

http://sandsprite.com/vbdec/
https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-varmul
https://hex-rays.com/products/ida/support/tutorials/unions/


ссылка на оригинал статьи https://habr.com/ru/articles/745798/