;Anscheinend hält Windows (64bit) die 8 KByte IOPM in jedem TSS bereit.
;Daher genügt es, den Limit-Wert in der GDT entsprechend zu ändern.
.code
extern KdDebuggerNotPresent:qword ;Zeiger auf Byte
;void EachProcessorDpc(KDPC*Dpc, PVOID Context, PVOID Arg1, PVOID Arg2)
EachProcessorDpc proc
push r9 ;Arg2 = Zeiger auf Affinitätsmaske
mov rcx,r8 ;Arg1 = Argument
call rdx ;Context = Prozedurzeiger
pop rcx
movzx eax,byte ptr gs:[184h] ;KeGetCurrentProcessorNumber() für AMD64
lock btr dword ptr[rcx],eax ;Für diesen Prozessor als erledigt markieren
ret
EachProcessorDpc endp
;Zeiger in GDT für TSS beschaffen ->RAX
GetTssDesc proc private
sub rsp,16
sgdt [rsp+6]
str rax ;Windows: 0x40
add rax,[rsp+8]
add rsp,16
ret
GetTssDesc endp
;GDT-Eintrag für aktuellen TSS auslesen, Offset->RAX, Länge->ECX
;Typischer Aufbau: 00700067 05008B3F FFFF8000 00000000
;Anscheinend reserviert Windows (Vista/7/8) bereits 8K Platz, da sind Nullen drin.
;Daher würde es genügen, einfach das Limit in der GDT (den GDTs) zu erhöhen.
;Bei Windows10 geht der Ansatz allerdings in die Hose:
;Ein Teil des Speichers ist nicht präsent.
GetTSS proc
call GetTssDesc
xchg rcx,rax
mov eax,[rcx+8]
shl rax,16
mov ah,[rcx+7]
mov al,[rcx+4]
shl rax,16
mov ax,[rcx+2]
; movzx ecx,word ptr[rcx] ;Länge (für ein TSS genügt das)
; inc ecx
ret
GetTSS endp
;GDT-Eintrag für aktuellen TSS ändern, Offset=RDX, Länge=CX
SetTSS proc
call GetTssDesc
mov r8,[rax+8]
mov r9,[rax]
dec ecx
mov [rax],cx
mov [rax+2],dx
shr rdx,16
mov [rax+4],dl
mov [rax+7],dh
shr rdx,16
mov [rax+8],edx
str edx
and byte ptr[rax+5],not 2 ;Busy-Bit in GDT löschen (sonst kracht's beim nächsten Befehl)
ltr dx ;Lade CPU-internen Cache des Task-Registers
; mov rdx,qword ptr[KdDebuggerNotPresent]
; cmp byte ptr[rdx],0
; jz @f ;Springe wenn Debugger vorhanden
; mov byte ptr[rax+1],0 ;Das geht wirklich! PatchGuard austricksen
;@@
mov [rax],r9 ;GDT restaurieren (beißt sich mit Kernel-Debugger, nicht schlimm)
mov [rax+8],r8
ret
SetTSS endp
RevertTSS proc
call GetTssDesc
str edx
and byte ptr[rax+5],not 2 ;Busy-Bit in GDT löschen
ltr dx
ret
RevertTSS endp
_movsq proc
xchg rdi,rdx
xchg rsi,r8
rep movsq
xchg rsi,r8
xchg rdi,rdx
ret
_movsq endp
end
Vorgefundene Kodierung: ANSI (CP1252) | 4
|
|