在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
PrintMem PROTO :DWORD,:DWORD
ReadMem PROTO :DWORD,:DWORD,:DWORD
AdjustPrivilege PROTO :DWORD,:DWORD
MEM_STRUCT struct
pAddr dd ?
Reserved1 dd ?
pBuf dd ?
NumBytes dd ?
MEM_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
szPrintFormat1 db "%02X ", 0
szPrintFormat2 db 13, 10, "%08X: %02X ", 0
szPrintFormat3 db "%c ", 0
szPrintFormat4 db "%c ", 0
.data?
pFunSysDbgCtrl dd ?
hStdOut dd ?
.data
szPrintBuffer db 128 dup(0)
.code
MyAppStart:
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
mov hStdOut, eax
INVOKE AdjustPrivilege, addr szSeDebugPrivilege, 1
cmp eax, 0
je Exit
INVOKE GetModuleHandle, addr szNtDllName
cmp eax, NULL
je Exit
mov ebx, eax
INVOKE GetProcAddress, ebx, addr szZwSystemDebugControl
cmp eax, NULL
je Exit
mov pFunSysDbgCtrl, eax
INVOKE PrintMem, 64cf800h, 512
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
je Exit_Failed
INVOKE LookupPrivilegeValue, NULL, szPrivilege, addr @tp.Privileges.Luid
cmp eax, 0
je Exit_Failed
mov @tp.PrivilegeCount, 1
mov @tp.Privileges.Attributes, SE_PRIVILEGE_ENABLED
cmp bEnable, 0
jne @F
mov @tp.Privileges.Attributes, SE_PRIVILEGE_REMOVED
@@:
INVOKE AdjustTokenPrivileges, @ht, 0, addr @tp, 0, 0, 0
cmp eax, 0
je Exit_Failed
Exit_Succeed:
mov @retval, 1
Exit_Failed:
Exit_Clean:
cmp @ht, NULL
je @F
INVOKE CloseHandle, @ht
mov @ht, NULL
@@:
mov eax, @retval
ret
AdjustPrivilege endp
PrintMem proc pStart:DWORD, cbSize:DWORD
LOCAL @val :DWORD
LOCAL @pVM :DWORD
mov @pVM, NULL
INVOKE GetProcessHeap
INVOKE HeapAlloc, eax, HEAP_ZERO_MEMORY, cbSize
mov @pVM, eax
cmp eax, NULL
je Exit_Failed
INVOKE ReadMem, pStart, cbSize, @pVM
mov ecx, 0
@@:
push ecx
mov ebx, @pVM
xor eax, eax
mov al, BYTE PTR [ebx + ecx]
mov @val, eax
INVOKE wsprintf, addr szPrintBuffer, addr szPrintFormat1, @val
pop ecx
push ecx
test ecx, 0fh
jnz Z220
add ecx, pStart
INVOKE wsprintf, addr szPrintBuffer, addr szPrintFormat2, ecx, @val
Z220:
INVOKE lstrlen, addr szPrintBuffer
mov edx, eax
INVOKE WriteFile, hStdOut, addr szPrintBuffer, edx, addr @val, NULL
pop ecx
inc ecx
cmp ecx, cbSize
jl @B
Exit_Failed:
Exit_Clean:
cmp @pVM, NULL
je @F
INVOKE GetProcessHeap
INVOKE HeapFree, eax, 0, @pVM
mov @pVM, NULL
@@:
ret
PrintMem endp
ReadMem proc pStart:DWORD, cbSize:DWORD, DataPtr:DWORD
LOCAL @Mem :MEM_STRUCT
LOCAL @retn :DWORD
INVOKE RtlZeroMemory, addr @Mem, sizeof MEM_STRUCT
push pStart
pop @Mem.pAddr
push cbSize
pop @Mem.NumBytes
push DataPtr
pop @Mem.pBuf
lea eax, @retn
push eax
mov eax, 0
push eax
mov eax, NULL
push eax
mov eax, sizeof MEM_STRUCT
push eax
lea eax, @Mem
push eax
mov eax, 10
push eax
call pFunSysDbgCtrl
ret
ReadMem endp
end MyAppStart