RtlCopyMemory, RtlMoveMemory
Отличаются эти две функции тем, что RtlCopyMemory просто берет и
копирует буфера командой movs,
а RtlMoveMemory сначала анализирует esi и edi, а потом копирует буфер по
одному байту, причем начиная либо с начала либо с конца буфера.
Таким образом RtlMoveMemory корректно обработает перекрывающиеся области
esi...esi+ecx и edi...edi+ecx.
mov eax, i2E_RtlCopyMemory ; or RtlMoveMemory
lea edx, stk
int 2Eh
...
stk: dd 0BFF7xxxxh ; edi (destination)
dd offset vir_code ; esi (source)
dd vir_size ; ecx (length in bytes)
READ_REGISTER_BUFFER_UCHAR/ULONG/USHORT
Реализации команд REP MOVSB, REP MOVSD и REP MOVSW соответственно.
push ecx
push edi
push esi
mov edx, esp
mov eax, i2E_READ_REGISTER_BUFFER_ULONG
int 2Eh
add esp, 3*4
WRITE_REGISTER_BUFFER_UCHAR/ULONG/USHORT
Аналогично предыдущим: REP MOVSB, REP MOVSD и REP MOVSW,
НО источник и приемник поменялись местами.
push ecx
push esi
push edi
mov edx, esp
mov eax, i2E_WRITE_REGISTER_BUFFER_ULONG
int 2Eh
add esp, 3*4
READ_REGISTER_UCHAR/ULONG/USHORT
Считать BYTE/DWORD/WORD.
(MOV AL,[ESI], MOV EAX,[ESI] и MOV AX,[ESI])
Значение возвращается в EAX.
push esi
mov edx, esp
mov eax, i2E_READ_REGISTER_UCHAR
int 2Eh
add esp, 1*4
WRITE_REGISTER_UCHAR/ULONG/USHORT
Записать BYTE/DWORD/WORD.
(MOV [EDI],AL, MOV [EDI],EAX и MOV [EDI],AX)
push eax
push edi
mov edx, esp
mov eax, i2E_WRITE_REGISTER_UCHAR
int 2Eh
add esp, 2*4
READ_PORT_BUFFER_UCHAR/ULONG/USHORT
Выполнить REP INSB, REP INSD и REP INSW соответственно.
push ecx
push edi
push edx
mov edx, esp
mov eax, i2E_READ_PORT_BUFFER_ULONG
int 2Eh
add esp, 3*4
WRITE_PORT_BUFFER_UCHAR/ULONG/USHORT
REP OUTSB, REP OUTSD и REP OUTSW
push ecx
push esi
push edx
mov edx, esp
mov eax, i2E_WRITE_PORT_BUFFER_ULONG
int 2Eh
add esp, 3*4
READ_PORT_UCHAR/ULONG/USHORT
Выполнить IN AL,DX, IN EAX,DX и IN AX,DX соответственно.
push edx
mov edx, esp
mov eax, i2E_READ_PORT_ULONG
int 2Eh
add esp, 1*4
WRITE_PORT_UCHAR/ULONG/USHORT
OUT DX,AL, OUT DX,EAX и OUT DX,AX.
push eax
push edx
mov edx, esp
mov eax, i2E_WRITE_PORT_UCHAR
int 2Eh
add esp, 2*4
IoGetCurrentProcess, PsGetCurrentProcess
Обе функции указывают на один и тот же обработчик. Хендл текущего
процесса возвращается в EAX.
mov eax, i2E_IoGetCurrentProcess
int 2Eh
Обработчик GetCurrentProcess'а изнутри реализует следующее:
call ntoskrnl!KeGetCurrentThread
mov eax, [eax+4]
ret
Коментарии
Совершенно непонятно как обстоит дело с функциями для работы с файлами.
(IoCreateFile, NtCreateFile, ZwCreateFile, ZwReadFile, ZwWriteFile,
DeviceIoControlFile, etc.)
Я слышал, есть книжка про недокументированные возможности WinNT.
Но те параметры, которые там описаны для соответствующих функций, передаются
из программы в кернел, а ведь из кернела в ноль передаются уже совсем
другие вещи, даже число параметров не совпадает. Ну а трассировать
обработчик CreateFile выясняя все его 11 хитроизъебских параметров --
как-то лениво.
Существуют также функции для работы с registry.
(RtlDeleteRegistryValue, RtlQueryRegistryValues, RtlWriteRegistryValue,
IoOpenDeviceInterfaceRegistryKey, IoOpenDeviceRegistryKey,
может быть -- ZwCreateKey, ZwDeleteKey, ZwEnumerateKey, ZwEnumerateValueKey,
ZwOpenKey и т.п.)
Этих функция я не проверял, но они явно показывают на какой-то нормальный
код и могут быть вызваны.
Большинство функций, для которых не указано число параметров (в
ntoskrnl.inc написан '-'),
являются ВНУТРЕННИМИ, то есть параметры им передаются,
но не на стэке а в регистрах, и вызвать их, минуя похеривание
регистров в обработчике INT 2E нет никакой возможности.
Обычно эти функции написаны полностью маленькими буквами или
начинаются с подчеркивания, типа memmove, memset, qsort, rand, sprintf,
_except_handler2, _global_unwind2 и т.п.
* * *
см. также примеры в ntoskrnl.zip
(c) 1999 Z0MBiE, z0mbie.cjb.net