GetServiceDescriptorTableShadowAddress proc uses esi edi ebx
local dwThreadId:DWORD
xor ebx, ebx ; = NULL. Assume ServiceDescriptorTableShadow will be not found
mov eax, KeServiceDescriptorTable
mov esi, [eax]
; Find KTHREAD.ServiceTable field
; For non-GUI threads this field == KeServiceDescriptorTable
; and it points to ServiceDescriptorTable
; For GUI threads
; ServiceDescriptorTableShadow
invoke KeGetCurrentThread
mov edi, 200h-4
.while edi
.break .if dword ptr [eax][edi] == esi
dec edi
.endw
.if edi != 0
; edi = offset to ServiceTable field in KTHREAD structure
mov dwThreadId, 080h
.while dwThreadId < 400h
push eax ; reserve DWORD on stack
invoke PsLookupThreadByThreadId, dwThreadId, esp
pop ecx ; -> ETHREAD/KTHREAD
.if eax == STATUS_SUCCESS
push dword ptr [ecx][edi]
fastcall ObfDereferenceObject, ecx
pop eax
.if eax != esi
mov edx, MmSystemRangeStart
mov edx, [edx]
mov edx, [edx]
.if eax > edx ; some stupid error checking
mov ebx, eax
invoke DbgPrint, $CTA0("FindShadowTable: Found in thread with ID: %X\n"), dwThreadId
.break
.endif
.endif
.endif
add dwThreadId, 4
.endw
.endif
mov eax, ebx
ret
GetServiceDescriptorTableShadowAddress endp
4.mj0011所说的搜索有效内存地址的办法
Copy code
/*
define structure for the system service table
*/
struct SYS_SERVICE_TABLE {
void **ServiceTable;
unsigned long CounterTable;
unsigned long ServiceLimit;
void **ArgumentsTable;
};
/*
Define KeServiceDescriptorTable based on the SST structure
*/
extern struct SYS_SERVICE_TABLE *KeServiceDescriptorTable;
/*
Declare function GetServiceDescriptorShadowTableAddress()
*/
//struct SYS_SERVICE_TABLE * GetServiceDescriptorShadowTableAddress ();
/*
Declare the KeAddSystemServiceTable. This is just a
handle to the call function, it will be used by the function
above to obtain the correct address of the KeServiceDescriptorShadowTable
*/
__declspec(dllimport) KeAddSystemServiceTable (ULONG, ULONG, ULONG, ULONG, ULONG);
struct SYS_SERVICE_TABLE * GetServiceDescriptorShadowTableAddress ()
{
// First, obtain a pointer to KeAddSystemServiceTable
unsigned char *check = (unsigned char*)KeAddSystemServiceTable;
int i;
//Initialize an instance of System Service Table, will be used to
//obtain an address from KeAddSystemServiceTable
struct SYS_SERVICE_TABLE *rc=0;
// Make 100 attempts to match a valid address with that of KeServiceDescriptorTable
for (i=0; i<=99; i++) {
__try {
// try to obtain an address from KeAddSystemServiceTable
rc = *(struct SYS_SERVICE_TABLE**)check;
// if this address is NOT valid OR it itself is the address of
//KeServiceDescriptorTable OR its first entry is NOT equal
//to the first entry of KeServiceDescriptorTable
if (!MmIsAddressValid (rc) || (rc == KeServiceDescriptorTable)
|| (memcmp (rc, KeServiceDescriptorTable, sizeof (*rc)) != 0)) {
// Proceed with the next address
check++;
// don't forget to reset the old address
rc = 0;
}
} __except (EXCEPTION_EXECUTE_HANDLER) { rc = 0; }
// when the loop is completed, check if it produced a valid address
if (rc)
// because if it didn't, we failed to find the address of KeServiceDescriptorTableShadow
break;
}
// otherwise, there is a valid address! So return it!
return rc;
}
ntStatus = IoCreateDevice(
DriverObject, // Our Driver Object
0, // We don't use a device extension
&DeviceName,
FILE_DEVICE_NULL, // Device type
0, // Device characteristics //此处应该用FILE_DEVICE_SECURE_OPEN吧?
FALSE, // Not an exclusive device
&DeviceObject ); // Returned ptr to Device Object