format pe console
include 'win32ax.inc'
include 'equates\pestruct.inc'
entry start
;//----------
.data
struct OBJECT_ATTRIBUTES ;// структура, для передачи атрибутов в NtCreateFile()
Length dd sizeof.OBJECT_ATTRIBUTES
RootDirectory dd 0
ObjectName dd 0
Attributes dd 40h
SecurityDescriptor dd 0
SecurityQualityOfService dd 0
ends
struct UNICODE_STRING ;// структура описывает UNICODE-строку
Length dw 0
MaxLength dw 255
Buffer dd 0
ends
oa OBJECT_ATTRIBUTES
us UNICODE_STRING
iosb dd 0,0,0 ;// Io_Status_Block. Сюда возвращается статус операций
create dd 'N'+'t'+'C'+'r'+'e'+'a'+'t'+'e'+'F'+'i'+'l'+'e' ;// контрольная сумма имени fn.
write dd 'N'+'t'+'W'+'r'+'i'+'t'+'e'+'F'+'i'+'l'+'e'
close dd 'N'+'t'+'C'+'l'+'o'+'s'+'e'
NtCreate dd 0 ;// под SSN-номера сисколов
NtWrite dd 0
NtClose dd 0
Status db 10,' Return code: %08Xh',0
base dd 0
fHndl dd 0
fName db '\??\D:\Sysenter.txt',0 ;// имя создаваемого файла
fLen = $ - fName ;// его длина
align 4 ;// выравнивание на 4-байт границу
buff db 0 ;// здесь будет UNICODE-строка
;//----------
.code
start:
invoke SetConsoleTitle,<' .:: SYSENTER Example ::.',0>
invoke IsWow64Process,-1,buff
cmp [buff],1
jne @ok
cinvoke printf,<10,' ERROR! 64-bit system not support.',0>
jmp @exit
@ok: invoke GetModuleHandle,<'ntdll.dll',0>
mov [base],eax ;// база библиотеки,
xchg esi,eax ;// ...в регистр ESI
mov esi,[esi+0x3c] ;//
add esi,[base] ;// ESI = РЕ-заголовок
mov ebx,[esi+PE_HEADER.ExportRVA]
add ebx,[base]
mov esi,[ebx+EXPORT_TABLE.NamePointersRVA]
add esi,[base]
mov ecx,[ebx+EXPORT_TABLE.NumOfNamePointers]
;//==== ESI = указатель на таблицу имён, ECX = их счётчик. ====================
;//==== Начинаем поиск нужных функций в таблице-экспорта Ntdll.dll ============
@findFunctionSSN:
lodsd ;//
add eax,[base] ;// указатель на очередное имя
cmp word[eax],'Nt' ;// сравнить с маской
jne @fuck ;// прокол..
push eax esi ecx ;//
invoke GetProcAddress,[base],eax ;// иначе: EAX = точка-входа
pop ecx esi ebx ;// EBX = указатель на очередное имя
mov edx,[eax] ;// EDX = первый DWORD из точки-входа
cmp dl,0xb8 ;// проверить на сигнатуру SSN
jne @fuck ;// прокол..
shr edx,8 ;// иначе: EDX = SSN функции
push esi
xchg esi,ebx ;// ESI = указатель на имя
xor ebx,ebx ;// очистить регистры
xor eax,eax ;// ^^^^^
@hash: lodsb ;// считаем контрольную сумму очередного имени,
add ebx,eax ;// ..в регистр EBX,
or al,al ;// ..пока не встретим нуль.
jnz @hash ;//
pop esi
cmp ebx,[create] ;// сравить полученную контр.сумму с валидной, из секции-данных
jne @f ;// вниз, если промах..
mov [NtCreate],edx ;// иначе: запомнить в переменной её SSN.
@@: cmp ebx,[write] ;//
jne @f ;//
mov [NtWrite],edx ;//
@@: cmp ebx,[close] ;//
jne @fuck ;//
mov [NtClose],edx ;//
@fuck: loop @findFunctionSSN ;// продолжить поиск имён, по длинне ECX..
nop
;//==== Нашли SSN требуемых функций! ======================================
;//==== Теперь воспользуемся ими для создания файла через SYSENTER ========
;//========================================================================
mov esi,fName ;// ESI = адрсе строки с именем файла
mov edi,buff ;// EDI = адрес приёмного буфера
mov ecx,fLen ;// ECX = длина строки
xor eax,eax ;//
@unicode: ;// конвертируем в UNICODE..
lodsb ;// берём очередной байт из ESI
stosw ;// записываем его как слово в EDI
loop @unicode ;// повторить ECX-раз..
mov ecx,fLen ;// ECX = длина строки
dec ecx ;// Внимание! ..без терминального нуля!
shl ecx,1 ;// умножить длину на 2
mov [us.Length],cx ;// отправляем длину в структуру UNICODE_STRING
mov [us.Buffer],buff ;// туда-же адрес буфера со-строкой
mov [oa.ObjectName],us ;// определяем struct.Unicode как имя в OBJECT_ATTRIBUTES
;//==== Теперь всё готово для вызова SYSENTER ==============================
;// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntcreatefile
xor eax,eax
push eax ;// SecureLength = 0
push eax ;// SecureBuffer = 0
push 0x60 ;// Create Options = Non Dir
push 0x05 ;// Create Disposition = Max_Disposition
push eax ;// Share Access = 0
push 0x80 ;// File attributes = Normal
push eax ;// Allocation size = 0
push iosb ;// IoStatusBlock
push oa ;// ObjectAttributes
push 0xC0100080 ;// Desired Access = R/W
push fHndl ;// Handle
mov eax,@f ;// EAX = адрес-возврата
push eax eax ;// Внимание!!! Отправляем его дважды в стек!
mov eax,[NtCreate] ;// <----------- NtCreateFile
mov edx,esp ;// EDX = указатель на аргументы
sysenter ;// Первый пошёл..
@@: add esp,4*12 ;// вытолкнуть аргументы из стека 11+1
cinvoke printf,Status,eax
;//==== Таким-же макаром записываем в созданный файл ========================
;//==== в данном случае сбрасывается строка с именем файла ==================
xor eax,eax
push eax ;// Key = 0
push eax ;// ByteOffset = 0
push fLen ;// Length
push fName ;// Buffer
push iosb ;// IoStatusBlock
push eax ;// ApcContext = 0
push eax ;// ApcRoutine = 0
push eax ;// Event = 0
push [fHndl] ;// FileHandle
mov eax,@f ;// Retn-offset
push eax eax ;// Retn-address
mov eax,[NtWrite] ;// <----------- NtWriteFile
mov edx,esp ;// Arguments
sysenter
@@: add esp,4*10 ;// Clear Stack 9+1
cinvoke printf,Status,eax
;//==== Прихлопнем дескриптор открытого файла ===============================
push [fHndl] ;// FileHandle
mov eax,@f ;// Retn-offset
push eax eax ;// Retn-address
mov eax,[NtClose] ;// <----------- NtClose
mov edx,esp ;// Arguments
sysenter
@@: add esp,4*2 ;// Clear Stack 1+1
cinvoke printf,Status,eax
@exit: cinvoke gets,buff
cinvoke exit,0
;//----------
section '.idata' import data readable
library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll'
import msvcrt, printf,'printf',gets,'gets',exit,'exit'
include 'api\kernel32.inc'
Комментарии
9