#define SEC_IMAGE 0x1000000
#define PROCESSNAME_OFFSET 0x174
UNICODE_STRING DrvName;
typedef struct _USER_STACK {
PVOID FixedStackBase;
PVOID FixedStackLimit;
PVOID ExpandableStackBase;
PVOID ExpandableStackLimit;
PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG SerivceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
extern "C" PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
#ifdef __cplusplus
extern "C"
{
#endif
_declspec(dllexport) NTSTATUS
NTAPI
ZwCreateSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PLARGE_INTEGER SectionSize OPTIONAL,
IN ULONG Protect,
IN ULONG Attributes,
IN HANDLE FileHandle) ;
NTSTATUS PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread);
PCHAR PsGetProcessImageFileName(IN PEPROCESS process);
#ifdef __cplusplus
}
#endif
//=========================================================================
//函数名:GetNativeApiAddress
//功能 :在驱动内遍历指定Dll的PE文件,
// 找出指定函数名在内存中的地址位置
//参数:
// IN pszFunctionName 指定函数名
// IN pszDllName 指定Dll名
//返回值:
// 0 失败
// 其它 成功
//
//=========================================================================
ULONG GetNativeApiAddress(PCHAR pszFunctionName, PUNICODE_STRING pszDllName)
{
NTSTATUS ntStatus ;
HANDLE hfile = NULL;
HANDLE hsection = NULL;
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK IoStatus;
PVOID BaseAddress = NULL;
SIZE_T size = 0;
IMAGE_DOS_HEADER *dos_head = NULL;
IMAGE_OPTIONAL_HEADER *option_head = NULL;
IMAGE_EXPORT_DIRECTORY *export = NULL;
ULONG *arrayOfFunctionAddress = NULL;
ULONG *arrayOfFunctionName = NULL;
USHORT *arrayOfFunctionOrdinal = NULL;
ULONG ulFunctionOrdinal = 0;
ULONG ulBase = 0;
STRING FunctionNameSearch, NtFunctionName;
PCHAR pszAllFunctionName;
ULONG ulCount = 0;
ULONG ulFunctionAddress = 0;
::RtlZeroMemory(&oa, sizeof(OBJECT_ATTRIBUTES));
InitializeObjectAttributes(&oa,
pszDllName,
OBJ_CASE_INSENSITIVE,
0,
NULL);
ntStatus = ::ZwOpenFile(&hfile,
FILE_EXECUTE | SYNCHRONIZE,
&oa,
&IoStatus,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
if(!NT_SUCCESS(ntStatus))
{
KdPrint(("ZwOpenFile is error\n"));
return 0;
}
oa.ObjectName = 0;
ntStatus = ZwCreateSection(&hsection,
SECTION_ALL_ACCESS,
&oa,
0,
PAGE_EXECUTE,
SEC_IMAGE,
hfile);
if(!NT_SUCCESS(ntStatus))
{
KdPrint(("ZwCreateSection is error\n"));
return 0;
}
ntStatus = ZwMapViewOfSection(hsection,
NtCurrentProcess(),
&BaseAddress,
0,
1000,
0,
&size,
(SECTION_INHERIT)1,
MEM_TOP_DOWN,
PAGE_READWRITE);
if(!NT_SUCCESS(ntStatus))
{
KdPrint(("%x\n",ntStatus));
KdPrint(("ZwMapViewOfSection is error\n"));
return 0;
}
::ZwClose(hfile);
dos_head = (IMAGE_DOS_HEADER *)BaseAddress;
option_head = (IMAGE_OPTIONAL_HEADER *)((ULONG)BaseAddress + dos_head->e_lfanew + 24);
export = (IMAGE_EXPORT_DIRECTORY *)((ULONG)BaseAddress + option_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
arrayOfFunctionAddress = (ULONG *)((ULONG)BaseAddress + export->AddressOfFunctions);
arrayOfFunctionName = (ULONG *)((ULONG)BaseAddress + export->AddressOfNames);
arrayOfFunctionOrdinal = (USHORT *)((ULONG)BaseAddress + export->AddressOfNameOrdinals);
ulBase = export->ulBase;
::RtlInitString(&FunctionNameSearch, pszFunctionName);
for(ulCount = 0; ulCount < export->NumberOfFunctions; ulCount++)
{
pszAllFunctionName = (PCHAR)((ULONG)BaseAddress + arrayOfFunctionName[ulCount]);
::RtlInitString(&NtFunctionName, pszAllFunctionName);
ulFunctionOrdinal = arrayOfFunctionOrdinal[ulCount] + ulBase - 1;
ulFunctionAddress = (ULONG)((ULONG)BaseAddress + arrayOfFunctionAddress[ulFunctionOrdinal]);
if(::RtlCompareString(&NtFunctionName, &FunctionNameSearch, TRUE) == 0) //对名字进行比较
{
return ulFunctionAddress;
}
}
ZwClose(hsection);
return 0;
}
//=========================================================================
//函数名:GetSSDTAddress
//功能 : 取得指定函数在SSDT表中的地址
//参数:
// IN pszFunName 指定函数名
//返回值:
// 0 失败
// 其它 函数在SSDT中的地址
//=========================================================================
ULONG GetSSDTAddress(PCHAR pszFunName)
{
UNICODE_STRING usDllName;
ULONG ulAddress = 0;
ULONG ulNum = 0;
RtlInitUnicodeString(&usDllName, L"\\SystemRoot\\System32\\ntdll.dll");
ulAddress = ::GetNativeApiAddress(pszFunName, &usDllName);
if(0 == ulAddress)
{
return 0;
}
ulNum = *(ULONG *)(ulAddress + 1);
if (0 == ulNum)
{
return 0;
}
ulAddress = (ULONG)KeServiceDescriptorTable->ServiceTableBase;
return ulAddress +ulNum * 4;
}