在XP系统中,利用ZwSystemDebugControl函数在不需要驱动的情况下可以访问一些内核对象,如,I/O、物理内存、一些寄存器。但需要具有SeDebugPrivilege权限。XP中的User组是没有这个权限的,也没有权自己提升到这个级别。
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
include kernel32.inc
include advapi32.inc
includelib user32.lib
includelib kernel32.lib
includelib advapi32.lib
ReadPort PROTO :DWORD,:DWORD,:DWORD
WritePort PROTO :DWORD,:DWORD,:DWORD
PrintPCIDevIDs PROTO
AdjustPrivilege PROTO :DWORD,:DWORD
IO_STRUCT struct
dwAddr dd ?
dwReserved1 dd ?
dwBuf dd ?
dwNumBytes dd ?
dwReserved4 dd ?
dwReserved5 dd ?
dwReserved6 dd ?
dwReserved7 dd ?
IO_STRUCT ends
; DebugSysReadPhysicalMemory = 10,
; DebugSysReadIoSpace = 14,
; DebugSysWriteIoSpace = 15,
; DebugSysReadMsr = 16,
; DebugSysWriteMsr = 17
.const
szNtDllName db "ntdll.dll", 0
szSeDebugPrivilege db "SeDebugPrivilege", 0
szZwSystemDebugControl db "ZwSystemDebugControl", 0
szPrintFormat db "PCI %08X: VID=%04X,PID=%04X", 13, 10, 0
.data?
pFunSysDbgCtrl dd ?
hStdOut dd ?
.data
szPrintBuffer db 64 dup(0)
.code
MyAppStart:
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov hStdOut, eax
INVOKE AdjustPrivilege, addr szSeDebugPrivilege, 1
cmp eax, 0
jz Exit
INVOKE GetModuleHandle, addr szNtDllName
cmp eax, NULL
jz Exit
mov ebx, eax
INVOKE GetProcAddress, ebx, addr szZwSystemDebugControl
cmp eax, NULL
jz Exit
mov pFunSysDbgCtrl, eax
INVOKE PrintPCIDevIDs
Exit:
INVOKE ExitProcess, 0
;
AdjustPrivilege proc szPrivilege:DWORD, bEnable:DWORD
LOCAL @retval :DWORD
LOCAL @ht :DWORD
LOCAL @tp :TOKEN_PRIVILEGES
mov @ht, NULL
mov @retval, 0
INVOKE RtlZeroMemory, addr @tp, sizeof TOKEN_PRIVILEGES
INVOKE GetCurrentProcess
mov ebx, eax
INVOKE OpenProcessToken, ebx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr @ht
cmp eax, 0
jz Exit_Failed
INVOKE LookupPrivilegeValue, NULL, szPrivilege, addr @tp.Privileges.Luid
cmp eax, 0
jz Exit_Failed
mov @tp.PrivilegeCount, 1
mov @tp.Privileges.Attributes, SE_PRIVILEGE_ENABLED
cmp bEnable, 0
jnz @F
mov @tp.Privileges.Attributes, SE_PRIVILEGE_REMOVED
@@:
INVOKE AdjustTokenPrivileges, @ht, 0, addr @tp, 0, 0, 0
cmp eax, 0
jz Exit_Failed
Exit_Succeed:
mov @retval, 1
Exit_Failed:
Exit_Clean:
cmp @ht, NULL
jz @F
INVOKE CloseHandle, @ht
mov @ht, NULL
@@:
mov eax, @retval
ret
AdjustPrivilege endp
ReadPort proc port:DWORD, cbSize:DWORD, DataPtr:DWORD
LOCAL @Ios :IO_STRUCT
INVOKE RtlZeroMemory, addr @Ios, sizeof IO_STRUCT
push port
pop @Ios.dwAddr
push cbSize
pop @Ios.dwNumBytes
push DataPtr
pop @Ios.dwBuf
mov @Ios.dwReserved4, 1
mov @Ios.dwReserved6, 1
mov eax, NULL
push eax
mov eax, 0
push eax
mov eax, NULL
push eax
mov eax, sizeof IO_STRUCT
push eax
lea eax, @Ios
push eax
mov eax, 14
push eax
call pFunSysDbgCtrl
ret
ReadPort endp
WritePort proc port:DWORD, cbSize:DWORD, DataPtr:DWORD
LOCAL @Ios :IO_STRUCT
INVOKE RtlZeroMemory, addr @Ios, sizeof IO_STRUCT
push port
pop @Ios.dwAddr
push cbSize
pop @Ios.dwNumBytes
push DataPtr
pop @Ios.dwBuf
mov @Ios.dwReserved4, 1
mov @Ios.dwReserved6, 1
mov eax, NULL
push eax
mov eax, 0
push eax
mov eax, NULL
push eax
mov eax, sizeof IO_STRUCT
push eax
lea eax, @Ios
push eax
mov eax, 15
push eax
call pFunSysDbgCtrl
ret
WritePort endp
PrintPCIDevIDs proc
LOCAL @bs, @dv, @fn :DWORD
LOCAL @cbSize :DWORD
LOCAL @dwBuffer :DWORD
LOCAL @pciAddress :DWORD
mov @bs, 0
Do_Next1:
mov @dv, 0
Do_Next2:
mov @fn, 0
Do_Next3:
mov eax, @bs
shl eax, 16
mov ebx, @dv
and ebx, 01fh
shl ebx, 11
mov ecx, @fn
and ecx, 7
shl ecx, 8
or eax, 080000000h
or eax, ebx
or eax, ecx
mov @pciAddress, eax
INVOKE WritePort, 0cf8h, 4, addr @pciAddress
INVOKE ReadPort, 0cfch, 4, addr @dwBuffer
mov eax, @dwBuffer
cmp eax, 0ffffffffh
jz @F
xor ebx, ebx
mov bx, ax
shr eax, 16
and eax, 0ffffh
INVOKE wsprintf, addr szPrintBuffer, addr szPrintFormat, @pciAddress, ebx, eax
INVOKE lstrlen, addr szPrintBuffer
mov edx, eax
INVOKE WriteFile, hStdOut, addr szPrintBuffer, edx, addr @cbSize, NULL
@@:
inc @fn
cmp @fn, 8
jl Do_Next3
inc @dv
cmp @dv, 32
jl Do_Next2
inc @bs
cmp @bs, 16
jl Do_Next1
ret
PrintPCIDevIDs endp
end MyAppStart