Source file: /~heha/hsn/giveio10.zip/amd64.asm

;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
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded