首页
社区
课程
招聘
[旧帖] [求助]获取原始SSDT表在Win7下为什么有问题 0.00雪花
发表于: 2014-4-20 18:58 3032

[旧帖] [求助]获取原始SSDT表在Win7下为什么有问题 0.00雪花

2014-4-20 18:58
3032
这段代码我在Xp下测试很成功,
在Win7取出的地址是错误的。
第一个参数索引号,第二个参数是在内存中的SSDT表地址
ULONG GetReallySSDTFunctionAddress(ULONG index,ULONG _SSDT)
{
// 获取步骤
// 获取SSDT表基址
// 获取ntkrnlpa.exe载入基址
// SSDT表基址-ntkrnlpa.exe载入基址 = SSDT表RVA
// 计算RVA在ntkrnlpa.exe文件中的 FileOffet
// 读入保存在硬盘上的SSDT表
	ULONG needlen;
	ULONG i;
	PVOID buf;
	ULONG ntkrnlpaBase=0;
	ULONG MemorySSDT; // 内存中SSDT表基址
	ULONG SSDT_RVA=0;
	PSYSTEM_MODULE_INFORMATION pModules;
	HANDLE handle=NULL;
	UNICODE_STRING FileName;
	OBJECT_ATTRIBUTES fileInfo={0};
	NTSTATUS status;
	IO_STATUS_BLOCK ioStatus;
	FILE_STANDARD_INFORMATION fsi={0};
	unsigned char *pFileBuff=NULL;
	ULONG NumberOfSection=0; //区块数目
	PIMAGE_DOS_HEADER pDosHead=NULL;
	PIMAGE_NT_HEADERS pNtHead=NULL;
	PIMAGE_SECTION_HEADER pSection=NULL; //所有区段
	ULONG addr2=0;
	ULONG addr1=0;
	ULONG ret_address;
	ULONG ssa;
	PWCHAR kernelName;
	ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&needlen);
	buf=(PVOID)ExAllocatePoolWithTag(NonPagedPool,needlen,1448);
	if (buf==NULL){ DbgPrint("分配内存失败!!\n");return STATUS_UNSUCCESSFUL;}
	ZwQuerySystemInformation(SystemModuleInformation,(PVOID)buf,needlen,&needlen);
	pModules=(PSYSTEM_MODULE_INFORMATION)buf;
	ntkrnlpaBase=(ULONG)pModules->Module[0].Base;
	if (ntkrnlpaBase==0)
	{
		DbgPrint("内核基址获取失败!\n");
		return STATUS_UNSUCCESSFUL;
	}
	//DbgPrint("ntkrnlpaBase:%x",ntkrnlpaBase);
	MemorySSDT=*(ULONG*)_SSDT;
	if (MemorySSDT==0)
	{
		DbgPrint("获取SSDT表地址失败。\n");
		return STATUS_UNSUCCESSFUL;
	}else if (MemorySSDT<ntkrnlpaBase || MemorySSDT>(ntkrnlpaBase+pModules->Module[0].Size)) //SSDT表不再ntkrnlpa模块中
	{
		DbgPrint("SSDT表地址无效!\n");
		return STATUS_UNSUCCESSFUL;
	}
	
	SSDT_RVA = MemorySSDT-ntkrnlpaBase;
	if (SSDT_RVA==0)
	{
		DbgPrint("SSDT RVA未取到!\n");
		return STATUS_UNSUCCESSFUL;
	}
	//DbgPrint("SSDT RVA:%x",SSDT_RVA);
	__asm
	{
		pushad
			_emit 0x0f
			_emit 0x20
			_emit 0xe0    //mov eax,cr4
			shr eax,4
			and eax,1
			mov ssa,eax
			popad
	}
	kernelName = ssa?L"\\SystemRoot\\system32\\ntkrnlpa.exe" : L"\\SystemRoot\\system32\\ntoskrnl.exe";
	DbgPrint("内核文件 : %S",kernelName);
	RtlInitUnicodeString(&FileName,kernelName);
	InitializeObjectAttributes(&fileInfo,&FileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
	status=ZwCreateFile(&handle,GENERIC_READ,&fileInfo,&ioStatus,NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
	if (ioStatus.Information!=1)
	{
		DbgPrint("文件打开失败!\n");
		return STATUS_UNSUCCESSFUL;
	}
	ZwQueryInformationFile(handle,&ioStatus,&fsi,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);
	if ((LONG)fsi.EndOfFile.QuadPart==0)
	{
		DbgPrint("获取文件大小失败!\n");
		return STATUS_UNSUCCESSFUL;
	}
	pFileBuff=(unsigned char *)ExAllocatePoolWithTag(NonPagedPool,(size_t)fsi.EndOfFile.QuadPart,1449);
	if (pFileBuff==NULL)
	{
		DbgPrint("为文件分配缓冲区失败!!\n");
		return STATUS_UNSUCCESSFUL;
	}

	ZwReadFile(handle,NULL,NULL,NULL,&ioStatus,pFileBuff,(size_t)fsi.EndOfFile.QuadPart,0,NULL);

	pDosHead=(PIMAGE_DOS_HEADER)pFileBuff;
	pNtHead=(PIMAGE_NT_HEADERS)((ULONG)pDosHead+(ULONG)(pDosHead->e_lfanew));
	NumberOfSection=pNtHead->FileHeader.NumberOfSections;
	//DbgPrint("区块数目:%d",NumberOfSection);
	pSection=(PIMAGE_SECTION_HEADER)((ULONG)pNtHead+sizeof(IMAGE_NT_HEADERS));
	for(i=0;i<NumberOfSection;i++)
	{
		if ((SSDT_RVA>pSection[i].VirtualAddress) && (SSDT_RVA<(pSection[i].VirtualAddress+pSection[i].SizeOfRawData)))  //判断是否位于某个区块之简
		{
			//数据的文件偏移=(数据RVA - 节RVA) + 节的文件偏移
			//DbgPrint("RVA :%x   %d ",SSDT_RVA,i);
			//DbgPrint("RVA %d",pSection[i].VirtualAddress);
			addr2=SSDT_RVA-pSection[i].VirtualAddress;
			addr1=addr2+pSection[i].PointerToRawData;
			break;
		}
	}
	//DbgPrint("File Offset:%x",addr1);
	ret_address=addr1+index*4;
	_asm
	{
		pushad
			mov ecx,pFileBuff
			mov ebx,ret_address
			mov eax,[ebx+ecx]
			mov ret_address,eax 
		popad

	}
	// 重定位
	ret_address-=pNtHead->OptionalHeader.ImageBase;
	ret_address+=ntkrnlpaBase;
	//释放资源
	ExFreePool(pFileBuff);
	ExFreePool(buf);
	ZwClose(handle);
return ret_address;
}

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 52
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不知道,帮你顶贴
2014-4-20 19:32
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你是64位系统还是32位,64位系统的PE文件格式有点变化。
2014-4-22 09:45
0
雪    币: 6890
活跃值: (8944)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
4
不是,都是32位的,对了,我一直使用的是DDK里面的Xp版,会不会是这个原因?
2014-4-24 18:01
0
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
当然有错,系统不同偏移都不同
2014-4-24 18:05
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我在xp win7下均调试成功,用hook xp createprocess同样的方法在win7下行不通,有知道原因的么?
2014-4-25 09:38
0
雪    币: 6890
活跃值: (8944)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
7
高兴,找到原因了,是那个索引号传错了,真是太粗心了
2014-4-26 21:34
0
游客
登录 | 注册 方可回帖
返回
//