Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #90, ИЮНЬ 2006 г.

Полный ПИ

GPcH (admin@vb-decompiler.org)

Хакер, номер #090, стр. 090-082-4


адрес строки = ProcTable.DataConst + следующие за командой 2 байта.

Строка представлена в юникоде и заканчивается двумя нулями. Допустим, что там строка "Test", следовательно, имеем push "Test". 04 - FLdRfVar, то есть push - переменная. Переменная вычисляется, как и раньше: FF70 = var_90. 34 - CStr2Ansi. Считывает из стека два элемента и первому присваивает второй, то есть в стеке на данный момент находится переменная var_90 и строка "Test", следовательно, эту команду можно читать как var_90 = "Test". Далее следует 59 - PopTmpLdAdStr. Резервирует в переменной var_88 содержимое верхней ячейки стека, при этом занося заново это содержимое на вершину стека, чтобы оно не терялось. 0A - ImpAdCallFPR4. Вот тут уже запахло чем-то вкусным... Мы видим Call на функцию, адрес которой отсчитывается от блока данных по традиции. Пока не забыл: эти два байта прежде чем суммироваться с адресом блока данных, умножаются на 4 - правило, которое нужно учесть. Итак, что же мы имеем в блоке данных? А имеем мы VA на следующую заглушку:

A1A0634000 mov eax,[004063A0]

0BC0 or eax,eax

7402 je .000402A77

FFE0 jmp eax

68542A4000 push 000402A54

B870104000 mov eax,000401070

FFD0 call eax

В этой конструкции нам важен push 402A54. Виртуальный адрес 402A54 указывает на структуру вида:

Структура CallAPI

strLibraryName Long

strFunctionName Long

Два виртуальных адреса указывают на имя Dll и имя функции, которая должна быть вызвана. Вот разработчики намудрили с виртуальной машиной, правда?

Теперь-то мы знаем, почему VB так тормозит. Чтобы вызвать любую API-функцию, необходимо пройти немыслимое количество структур и заглушек, что тратит золотые такты процессора и жутко снижает скорость. Как видишь, никакой таблицы импорта нет. Мы имеем дело с именем Dll и функциями, которые вызываются динамически функцией DllFunctionCall (экспортируется из всеми нами замусоленной msvbvm60.dll).

B870104000 mov eax,000401070 --?3

FFD0 call eax

Эти строки получают адрес на этот переходник:

jmp DllFunctionCall

И вызывают его через call eax, который находится в функции DllFunctionCall:

hLib = GetModuleHandle(strLibraryName)

hProc = GetProcAddress(hLib, strFunctionName)

Call hProc

В нашем же случае strLibraryName - это user32.dll, а strFunctionName - ShellExecute. Теперь-то ясно, зачем в пикоде было столько push'ей и резервирований? Это всего лишь подготовка стека для вызова ShellExecut. Если свернуть все полученные нами данные, то выйдет что-то вроде:

loc_4043F1: var_90 = "Test"

loc_4043FB: var_8C = "Test2"

Назад на стр. 090-082-3  Содержание  Вперед на стр. 090-082-5
Hosted by uCoz