Полный ПИ 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" |