内核上项目【获取模块】

目的

在Win7 64位系统编写驱动获取目标进程的模块地址

操作步骤

1.打开目标进程
2.附加到目标进程
3.根据PsGetProcessWow64Process获取目标进程版本
3.根据不同的位数遍历相应的进程链表结构LDR寻找目标模块,匹配成功则返回模块地址

注意事项

在64位很多宏默认为64位需要进行调整修改为特定长度,这样寻找到的LDR等值才能与32位程序适配

实现代码

代码如下:
头文件“GetModule.h”

#pragma once
#include<ntifs.h>
HANDLE GetObjectModule(HANDLE pid,CHAR* ModuleName);
EXTERN_C PVOID NTAPI PsGetProcessWow64Process(PEPROCESS Process);
typedef PPEB(__stdcall* PFNPsGetProcessPeb)(PEPROCESS pEProcess);

typedef struct _PEB32 {
    UCHAR InheritedAddressSpace;
    UCHAR ReadImageFileExecOptions;
    UCHAR BeingDebugged;
    UCHAR Spare;
    ULONG Mutant;
    ULONG ImageBaseAddress;
    ULONG/*PPEB_LDR_DATA32*/ Ldr;
} PEB32, * PPEB32;

typedef struct _PEB64
{
    UCHAR InheritedAddressSpace;                                            //0x0
    UCHAR ReadImageFileExecOptions;                                         //0x1
    UCHAR BeingDebugged;                                                    //0x2
    union
    {
        UCHAR BitField;                                                     //0x3
        struct
        {
            UCHAR ImageUsesLargePages : 1;                                    //0x3
            UCHAR IsProtectedProcess : 1;                                     //0x3
            UCHAR IsLegacyProcess : 1;                                        //0x3
            UCHAR IsImageDynamicallyRelocated : 1;                            //0x3
            UCHAR SkipPatchingUser32Forwarders : 1;                           //0x3
            UCHAR SpareBits : 3;                                              //0x3
        };
    };
    ULONGLONG Mutant;                                                       //0x8
    ULONGLONG ImageBaseAddress;                                             //0x10
    ULONGLONG Ldr;                                                          //0x18
}PEB64, * PPEB64;

//0x58 bytes (sizeof)
typedef struct _PEB_LDR_DATA64
{
    ULONG Length;                                                           //0x0
    UCHAR Initialized;                                                      //0x4
    VOID* SsHandle;                                                         //0x8
    struct _LIST_ENTRY InLoadOrderModuleList;                               //0x10
    struct _LIST_ENTRY InMemoryOrderModuleList;                             //0x20
    struct _LIST_ENTRY InInitializationOrderModuleList;                     //0x30
    VOID* EntryInProgress;                                                  //0x40
    UCHAR ShutdownInProgress;                                               //0x48
    VOID* ShutdownThreadId;                                                 //0x50
}PEB_LDR_DATA64,*PPEB_LDR_DATA64;

typedef struct _PEB_LDR_DATA32
{
    ULONG Length;                                                           //0x0
    UCHAR Initialized;                                                      //0x4
    ULONG SsHandle;                                                         //0x8
    LIST_ENTRY32 InLoadOrderModuleList;                               //0xc
    LIST_ENTRY32 InMemoryOrderModuleList;                             //0x14
    LIST_ENTRY32 InInitializationOrderModuleList;                     //0x1c
    ULONG EntryInProgress;                                                  //0x24
    UCHAR ShutdownInProgress;                                               //0x28
    ULONG ShutdownThreadId;                                                 //0x2c
}PEB_LDR_DATA32,*PPEB_LDR_DATA32;

//0x78 bytes (sizeof)
typedef struct _LDR_DATA_TABLE_ENTRY32
{
    LIST_ENTRY32 InLoadOrderLinks;                                    //0x0
    LIST_ENTRY32 InMemoryOrderLinks;                                  //0x8
    LIST_ENTRY32 InInitializationOrderLinks;                          //0x10
    ULONG DllBase;                                                          //0x18
    ULONG EntryPoint;                                                       //0x1c
    ULONG SizeOfImage;                                                      //0x20
    UNICODE_STRING32 FullDllName;                                     //0x24
    UNICODE_STRING32 BaseDllName;                                     //0x2c
    ULONG Flags;                                                            //0x34
    USHORT LoadCount;                                                       //0x38
    USHORT TlsIndex;                                                        //0x3a
}LDR_DATA_TABLE_ENTRY32,* PLDR_DATA_TABLE_ENTRY32;

//0xe0 bytes (sizeof)
typedef struct _LDR_DATA_TABLE_ENTRY64
{
    struct _LIST_ENTRY InLoadOrderLinks;                                    //0x0
    struct _LIST_ENTRY InMemoryOrderLinks;                                  //0x10
    struct _LIST_ENTRY InInitializationOrderLinks;                          //0x20
    VOID* DllBase;                                                          //0x30
    VOID* EntryPoint;                                                       //0x38
    LONGLONG SizeOfImage;                                                      //0x40
    struct _UNICODE_STRING FullDllName;                                     //0x48
    struct _UNICODE_STRING BaseDllName;                                     //0x58
}LDR_DATA_TABLE_ENTRY64, * PLDR_DATA_TABLE_ENTRY64;

实现函数文件function.c

#include<ntifs.h>
#include<ntstrsafe.h>
#include"GetModule.h"

NTSTATUS ConvertCharToUnicodeString(char* charString, UNICODE_STRING* unicodeString)
{
	ANSI_STRING ansiString = {0};
	RtlInitAnsiString(&ansiString, charString);

	return RtlAnsiStringToUnicodeString(unicodeString, &ansiString, TRUE);
}

/*
功能:获取目标进程的模块的DllBase
参数一:目标进程的PID
参数二:需要寻找的模块名称
返回:寻找到的模块DllBase
*/
HANDLE GetObjectModule(HANDLE pid, CHAR* ModuleName)
{
	PEPROCESS Process = 0;
	PLDR_DATA_TABLE_ENTRY32 pBase32, pNext32;
	PLDR_DATA_TABLE_ENTRY64 pBase64, pNext64;
	UNICODE_STRING CompareModuleName = {0};
	BOOLEAN FindIs = FALSE;
	HANDLE return_handle = 0;
	UNICODE_STRING uniFunctionName;
	ConvertCharToUnicodeString(ModuleName,&CompareModuleName);
	PFNPsGetProcessPeb  PsGetProcessPeb = NULL;

	NTSTATUS is = PsLookupProcessByProcessId(pid, &Process);
	if (!NT_SUCCESS(is))
	{
		return 0;
	}
	KAPC_STATE stack = { 0 };
	KeStackAttachProcess(Process, &stack);

	PPEB32 peb32  = PsGetProcessWow64Process(Process);

	if (peb32 == NULL) //如果为64位进程
	{
		RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");
		PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);
		PPEB64 peb64 = PsGetProcessPeb(Process);

		PPEB_LDR_DATA64 peb64ldr = (PPEB_LDR_DATA64)peb64->Ldr;
		pBase64 = (PLDR_DATA_TABLE_ENTRY64)(peb64ldr->InLoadOrderModuleList.Flink);
		pNext64 = pBase64;

		do
		{
			UNICODE_STRING UnicodeString = { 0 };
			RtlUnicodeStringInit(&UnicodeString, pNext64->BaseDllName.Buffer);
			if (!RtlCompareUnicodeString(&UnicodeString, &CompareModuleName, TRUE))
			{
				FindIs = TRUE;
				return_handle = pNext64->DllBase;
				break;
			}
			else
			{
				pNext64 = pNext64->InLoadOrderLinks.Flink;
			}
		} while (pNext64 != pBase64);

		KeUnstackDetachProcess(&stack);
		ObDereferenceObject(Process);
		RtlFreeUnicodeString(&CompareModuleName);
	}
	else //如果为32位进程
	{
		PPEB_LDR_DATA32 peb32ldr = (PPEB_LDR_DATA32)peb32->Ldr;

		pBase32 = (PLDR_DATA_TABLE_ENTRY32)(peb32ldr->InLoadOrderModuleList.Flink);
		pNext32 = pBase32;

		do
		{
			UNICODE_STRING UnicodeString = { 0 };
			RtlUnicodeStringInit(&UnicodeString, (PWCH)pNext32->BaseDllName.Buffer);
			if (!RtlCompareUnicodeString(&UnicodeString, &CompareModuleName, TRUE))
			{
				FindIs = TRUE;
				return_handle = pNext32->DllBase;
				break;
			}
			else
			{
				pNext32 = pNext32->InLoadOrderLinks.Flink;
			}
		} while (pNext32 != pBase32);

		KeUnstackDetachProcess(&stack);
		ObDereferenceObject(Process);
		RtlFreeUnicodeString(&CompareModuleName);
	}
	
	if (FindIs == TRUE)
	{
		return return_handle;
	}
	return 0;
}

驱动主文件main.c

#include<ntifs.h>
#include"GetModule.h"

VOID DriverUnload(_In_ struct _DRIVER_OBJECT* DriverObject)
{
	DbgPrint("--------------DRIVER_UNLOAD-----------------");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
	HANDLE address;
	DbgBreakPoint();
	address = GetObjectModule(1140,"ntdll.dll");


	pDriverObject->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值