Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Получение базы kernel32.dll [Asm] (https://forum.antichat.xyz/showthread.php?t=172211)

isqad88 20.01.2010 22:34

Получение базы kernel32.dll [Asm]
 
Вот решил провести эксперимент и написал (не без помощи сайтов) прогу (masm32), которая определяет адрес базы kernel32.dll:
Код:

.386
option casemap:none
.model flat, stdcall
;----------------------------include---------------------
includelib \masm32\lib\kernel32.lib
include \masm32\include\kernel32.inc
;--------------------------------------------------------

.data
    db 0

.code
    start:
        mov esi, [esp]
        call GetBase; после вызова в eax база kernel32.dll
        invoke ExitProcess, 0

;#####################################GetBase###############################
;
;                Получение базы kernel32.dll
;
;###########################################################################
GetBase:
 
        push esi;сохраняем все регистры, которые используются
        push ecx

        pushf;сохраняем регистр флагов
        and esi,0FFFF0000H;гранулярность выделения памяти
        mov ecx,6;счетчик страниц

_@1:            ;проверка очередной страницы
         
        cmp word ptr [esi], "ZM"
        jz WeGotBase
_@2:
        sub esi, 10000h
        loop _@1
WeFailed:
        mov eax, 00000000h ;база не найдена
        jmp EndGetBase
WeGotBase:
    xchg eax, esi
       

EndGetBase:       
        popf;восстанавливаем значения флагов
        pop ecx
        pop esi;восстанавливаем значения регистров
        ret

;#########################################################################
;Конец процедуры GetBase
;#########################################################################
end start

В Windows XP SP3 я получил адрес базы 7C800000h в Windows 7 77140000h

Hiro Protagonist 20.01.2010 23:30

cmp word ptr [esi], "ZM"
jz WeGotBase

после этого чекай на PE. А вообще байан редкостный. Тем более для dll не подходит.

isqad88 21.01.2010 00:06

cmp word ptr [esi], "ZM" - разве это не есть проверка на PE

slesh 21.01.2010 00:38

спрашивается а нафига её искать методом поиска?
Если же можно тупо взять из PEB
Вариант с подмененным и неправильным PEB'ом можно расценивать как манию приследывания и последюю стадию шизофрении. Так что лучше юзать через PEB
Под 2k, XP, 2k3 ты получишь адрес kernel32.dll а под w7 - адрес KERNELBASE
KERNELBASE - это считай жалкий аналог kernel32.dll
Но есть хитрость. В них в обоих есть функции GetProcAddress и LoadLibraryExA
через который можно загрузить любую либу (хотябы туже kernel32 для w7)
Для всякого малвара своего юзаю примерно такую схему:

Код:

__declspec(naked) HMODULE GetKernel32(void)
{
        __asm
        {
                push    esi
                xor    eax,eax
                mov    eax,fs:[0x30]
                js      find_kernel_9x
                mov    eax,[eax+0x0c]
                mov    esi,[eax+0x1c]
                lodsd
                mov    eax,[eax+0x8]
                jmp    find_kernel_end
find_kernel_9x:
                mov                eax,[eax+0x34]
                lea                eax,[eax+0x7c]
                mov                eax,[eax+0x3c]
find_kernel_end:
                pop    esi
                ret
        }
}

KERNELBASE = GetKernel32();
*(void* *)&_LoadLibraryExA = HideGetProcAddress(KERNELBASE, "LoadLibraryExA");
*(void* *)&_GetProcAddress = HideGetProcAddress(KERNELBASE, "GetProcAddress");

if (!_LoadLibraryExA || !_GetProcAddress) return 0;

kernel32_dll = _LoadLibraryExA("kernel32.dll", 0, 0);
итд итп.

HideGetProcAddress - самописная функция поиска адреса функции (когдато выкладывал тут её)
И пашет идеально на всей линейке NT начиная от 2k

Другое дело в ядре искать адрес загрузки ядра, Там это уже нужно осуществлять перебор.
Вот пример
Код:

mov esi, dword ptr ds:[0ffdff038h]; адрес обработчика для IDLE
 lodsd
 cdq
 lodsd
base_loop:
 dec eax
 cmp dword ptr [eax], 00905a4dh ; сигнатура для файла ядра MZ+P+0x00
 jnz base_loop 
 mov lib, eax

Но этот код очень удобно юзать под ядром. Вернее под ядром его тока и можно заюзать )

slesh 21.01.2010 00:43

>>>> cmp word ptr [esi], "ZM" - разве это не есть проверка на PE
это проверка на дос заголовок. В досовских exe файлах и в старом LE нету PE заголовка )
Проверка на PE делается так
1) находится ImageBase и проверяется сигнатура MZ
2) ImageBase + 0x3С - по этому офсету хранится DWORD указывающий смещение (относительно ImageBase) на PE заголовок
3) ImageBase + офсет на PE и по этому адресу проверяется двойное слово
на сигнатуру 'P' 'E' 0x00 0x00

Hiro Protagonist 21.01.2010 07:39

2slesh
жесть, зачем это делать ассемблерной вставкой? али влом структуры описывать и пользоваться макросами для LIST_ENTRY?

slesh 21.01.2010 10:47

по старинке юзаю из шелкодов )
Но вообще некоторые операции без асм вставки будут некрасиво выглядеть. Допустим та же mov eax,fs:[0x30], которую придется заменить на соотвествующую апишку

Hiro Protagonist 21.01.2010 12:51

дык понятно, я это тоже вставкой делаю. Но доступ то к полям пеба )))

desTiny 21.01.2010 16:40

Код:

mov    esi,[eax+0x1c]
lodsd
mov    eax,[eax+0x8]

зачем тут еsi?)

А ещё сравнил бы на всякий случай имя библиотеки

Hiro Protagonist 21.01.2010 17:21

2desTiny
как зачем, а указать lodsd откуда грузить значение? Мы ж обращаемся ко второму LDR_MODULE_ENTRY в цепочке.
а проверять не нужно, там постоянно ntdll->kernel32->[user32]->...

desTiny 21.01.2010 17:53

mov esi,[eax+0x1c]
lodsd

~

mov eax, [eax+0x1c]
mov eax, [eax]

и нафиг не нужны эти первый пуш и последний поп

>> там постоянно
никто ничего не обещает. Вот если ты так уверен в порядке - ну-ка сходу скажи, где в цепочке будет kernelbase.dll?

isqad88 21.01.2010 18:59

как получать API? Сколько кода просмотрел нигде не нашел рабочего

desTiny 21.01.2010 19:00

почитай например http://www.phrack.com/issues.html?issue=62&id=7

Adio 21.01.2010 19:13

Таких пару статей прочитьтать и на дурку )))

Hiro Protagonist 21.01.2010 19:59

2desTiny
а зачем мне kernelbase.dll?
главное я чотко уверен, что под всей линейкой ntdll->kernel32. Остальное в принципе не интересно ) в данном случае. Поэтому проверять не надо.

desTiny 21.01.2010 21:06

>>главное я чотко уверен
А вот семёрке плевать на твою уверенность.

Hiro Protagonist 21.01.2010 21:38

ладно, пойду семерку ставить на виртуалку и смотреть )

slesh 21.01.2010 22:21

Для самоуверенных читать мой пост где я кинул кусок кода и там описал что и как.
И То что нужно искать там LoadLibraryExA/W потому что других подобных нету.
Это пришлось сделать именно из-за W7 потому как именно kernelbase там получалась а не kernel32.

isqad88 22.01.2010 01:02

Верно ли написан код получения GetProcAddress ? Вроде все как в туториале
Код:

.386
.model flat, stdcall
option casemap:none

includelib \masm32\lib\kernel32.lib

ExitProcess PROTO : DWORD
.data
        db 0
        ProcAd db "GetProcAddress",0h
        Counter db 0h
        OrdinalTableVA db 0h
        AddressTableVA db 0h
        Kernel db 0h
.code
       
       
start:
        ;считаем дельта смещение
        call VirDelta
        VirDelta:
                sub dword ptr [esp], offset VirDelta
                push dword ptr [esp]
                ;jmp ReadSEH
       
                ; Читаем SEH
ReadSEH:
    xor    edx, edx              ; edx = 0
    assume fs:flat
    mov    eax, fs:[edx]        ; читаем элемент SEH
    dec    edx                  ; edx = 0FFFFFFFFh

; Ищем элемент со значением 0FFFFFFFFh
SearchKernel32:
    cmp    [eax], edx            ; сравниваем очередной с 0FFFFFFFFh
    je    CheckKernel32        ; прыгаем, если нашли
    mov    eax, [eax]            ; получаем следующее значение
    jmp    SearchKernel32        ; если не нашли - ищем дальше

; Определяем адрес Kernel32
CheckKernel32:
    mov    eax, [eax + 4]        ; получаем адрес ГДЕ-ТО в
                                ; kernel32.dll
    xor    ax, ax                ; выравниваем полученный адрес

; Ищем сигнатуру MZ
SearchKernelMZ:         
    cmp word ptr [eax], 5A4Dh    ; сверяем сигнатуру MZ
    je  CheckKernelMZ            ; сигнатура верна, переходим на
                                ; проверку сигнатуры PE
    sub eax, 10000h              ; если не равна MZ, то ищем дальше
    jmp SearchKernelMZ

; Проверяем сигнатуру PE
CheckKernelMZ:       
    mov  edx, [eax + 3Ch]        ; переходим на PE-заголовок
    cmp  word ptr [eax + edx], 4550h ; сверяем сигнатуру
    jne  _Exit                  ; неверная сигнатура, поэтому
                                ; выходим
        call GetAPI
       
_Exit:
                invoke ExitProcess, 0h
       
;поиск адреса GetProcessAddress
GetAPI:
mov edx, offset Kernel
mov [edx], eax
mov esi, offset ProcAd
mov edx, esi
@_1:
        cmp byte ptr [esi], 0; конец строки?
        jz @_2
        inc esi
        jmp @_1
@_2:
        inc esi
        sub esi, edx
        mov ecx, esi
;;теперь в ecx и esi находится размер имени функции GetProcessAddress (12h символов)


mov ebx, eax
xor eax, eax
mov esi, ebx
add esi, 3Ch ;заголовок PE
lodsw
add eax, ebx
mov esi, [eax + 78h] ;RVA таблицы экспортов
add esi, ebx ;указатель на RVA таблицы адресов
add esi, 1ch

lodsd ;eax = RVA таблицы адресов
add eax, ebx ;eax VA таблицы адресов
mov edx, offset AddressTableVA
mov[edx], eax
;push eax ;сохраняем

lodsd ;eax = RVA таблицы указателей на имена
add eax, ebx ; eax = VA таблицы указателей на имена

push eax ;сохраняем

lodsd ;eax = RVA таблицы ординалов
add eax, ebx
mov edx, offset OrdinalTableVA
mov [edx], eax
;push eax
pop esi
@_3: push esi ;сохраняем VA таблицы указателей на имена
        lodsd
        add eax, ebx
        mov esi, eax
        mov edi, offset ProcAd
        push ecx
        cld
        repe cmpsb
        pop ecx
        jz @_4
        pop esi
        add esi, 4
        mov edx, [offset Counter]
        inc edx
        push ecx
        mov ecx, offset Counter
        mov [ecx], edx
        pop ecx
        jmp @_3
        @_4:
        pop esi
        mov edx, offset Counter
        mov eax, [edx]
        shl eax, 1
        mov edx, offset OrdinalTableVA
        add eax, [edx]
        shl eax, 2
        mov edx, offset AddressTableVA
        add eax, [edx]
        mov edx, offset Kernel
        add eax, [edx]
        ret
       



       
               

end start

по идее в EAX должен остаться адрес этой функции...Сильно не ругайте за корявый код я только начал учить асму


Время: 01:42