Тема: KiGetTickCount -> LDT
Если значение регистра Cs отлично от 0x1B(KGDT_R3_CODE | RPL_MASK), то прерывание 0x2A сводится к вызову NtSetLdtEntries:
KiGetTickCount:
...
push 0 ; push dummy error code
ENTER_TRAP kitx_a, kitx_t
sti
xor eax, eax
mov ebx, [ebp+TsEbx]
mov ecx, [ebp+TsEcx]
mov edx, [ebp+TsEdx]
stdCall _NtSetLdtEntries <ebx, ecx, edx, eax, eax, eax>
mov [ebp+TsEax], eax
and dword ptr [ebp+TsEflags], 0FFFFFFFEH ; clear carry flag
cmp eax, 0 ; success?
je short ktgc10
or dword ptr [ebp+TsEflags], 1 ; set carry flag
ktgc10:
jmp _KiExceptionExitСледующий макрос создаёт дескриптор в лдт:
CREATE_DESCRIPTOR macro Base, Limit
mov eax,Base
mov edx,Limit
mov ecx,eax
and edx,0F0000H
shr eax,16
and ecx,0FF000000h
and eax,0FFH
lea edx,[eax + edx + 100H * 11111000B + 100000H * 1100B] ; Type 100B - code.
or edx,ecx
mov eax,Limit
mov ecx,Base
and eax,0FFFFH
shl ecx,16
lea ecx,[ecx + eax]
; Edx:Ecx
endm
CREATE_LDT_ENTRY macro Selector, Base, Limit
push ebp
push ebx
CREATE_DESCRIPTOR Base, Limit ; Edx:Ecx
mov ebp,0F0F0F0F1H
mov ebx,Selector
mov eax,ebp
; Eax = Ebp = 0xF0F0F0F1
Int 2AH ; KiGetTickCount
; Eax = NTSTATUS
; CF = 0 - STATUS_SUCCESS
pop ebx
pop ebp
endm
; Вызов:
TABLE_MASK equ 100B
...
CREATE_LDT_ENTRY Selector or TABLE_MASK, Base, LimitНеприятная особенность - нет способа изменить селектор кодового сегмента без вызова NtSetLdtEntries/ProcessLdtInformation. Retf позволяет загрузить теневую часть регистра, но вызов прерывания сбросит её ![]()
Отредактировано Indy (2009-10-04 17:57:45)