- 注册时间
- 2011-8-8
- 最后登录
- 1970-1-1
该用户从未签到
|
发表于 2011-8-16 13:16:44
|
显示全部楼层
搜内存原理是这样的。
在DriverEntry内取得返回地址。
(为什么可以取返回地址,想一想驱动的加载过程具体说就nt!IopLoadDriver内那句Call dword ptr [edi+2c])而这个返回地址就在内核文件内部。然后以返回地址为起点,按页对齐(对齐只是为了加快搜索速度,不对齐也行)向前搜。直到匹配了PE特征。而第一个匹配PE特征的地址就是内核文件基地址。
明白了原理相信C代码就很容易了。我顺带贴一个。
BOOLEAN
FindBaseAndSize(
IN PVOID SomePtr,
OUT PVOID *BaseAddress OPTIONAL,
OUT ULONG *ImageSize OPTIONAL
)
{
ULONG SomeAddress = (ULONG) SomePtr;
for ( SomeAddress &= 0xFFFFF000 ; ; SomeAddress -= PAGE_SIZE )
{
if(MmIsAddressValid ((PVOID)SomeAddress) && *(USHORT*)SomeAddress == IMAGE_DOS_SIGNATURE ) // MZ signature?
{
PVOID NtHeader = RtlImageNtHeader ((PVOID)SomeAddress);// + ((IMAGE_DOS_HEADER*)SomeAddress)->e_lfanew;
if (MmIsAddressValid ((PVOID)NtHeader) && *(ULONG*)NtHeader == IMAGE_NT_SIGNATURE) // PE signature?
{
if (ARGUMENT_PRESENT (BaseAddress))
*BaseAddress = (PVOID)SomeAddress;
if (ARGUMENT_PRESENT (ImageSize))
*ImageSize = ((IMAGE_NT_HEADERS*)NtHeader)->OptionalHeader.SizeOfImage;
return TRUE;
}
}
}
return FALSE;
}
在DriverEntry内调用的时候FindBaseAndSize(DriverEntry返回地址,XXX,XXX)。
备注:
一、实际上也不一定非取得返回地址,内核内任意一个函数的地址都可以作为起点。
二、我顺手贴的这个代码不支持X64. |
|