首页
社区
课程
招聘
[分享]驱动中取NT API函数在SSDT中的服务号
发表于: 2011-12-29 01:24 5013

[分享]驱动中取NT API函数在SSDT中的服务号

2011-12-29 01:24
5013
static HANDLE hModuleOfNtdll=NULL;
PVOID GetFunctionAddress(HMODULE hModule,PCSTR funcName);
HANDLE	GetNtDllBaseAddr(IN	PCWSTR lpModuleName=L"ntdll.dll");
ULONG GetFunctionIndexOfSSDT(PCSTR lpFunctionName);

PVOID GetFunctionAddress(HMODULE hModule,PCSTR funcName)
{
	if(hModule==NULL){
		GetNtDllBaseAddr();
		hModule=hModuleOfNtdll;
	}
	if(hModule ==NULL )return NULL;
	PIMAGE_DOS_HEADER pimDH = (PIMAGE_DOS_HEADER)hModule;
	PIMAGE_NT_HEADERS pimNH = (PIMAGE_NT_HEADERS)((UCHAR*)hModule+pimDH->e_lfanew);
	if(pimNH==NULL )return NULL ;

	PIMAGE_EXPORT_DIRECTORY pimExD = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)hModule+pimNH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

	ULONG*  pFuntionAddr =(ULONG*)((ULONG)hModule+(ULONG)(pimExD->AddressOfFunctions));
	ULONG*  pName        =(ULONG *)((ULONG)hModule+(ULONG)(  pimExD->AddressOfNames));
	ULONG NumberOfFunction = pimExD->NumberOfFunctions;
	USHORT uBase=pimExD->Base;
	ULONG i=0;
	USHORT* uFuntAddrOrdinals=(USHORT*)((ULONG)hModule+(ULONG)(pimExD->AddressOfNameOrdinals));
	USHORT  uAddrOrdinals=0;
	for(i=0;i<NumberOfFunction;i++)
	{
		uAddrOrdinals=uFuntAddrOrdinals[i]+uBase-1;
		ULONG_PTR name_addr=(pName[i])+(ULONG_PTR)hModule;		
		ULONG_PTR func_addr=pFuntionAddr[uAddrOrdinals]+(ULONG_PTR)hModule;		

		if(strcmp((char*)name_addr ,funcName)==0)
		{		 
			dprintf("\"%s\" address = %#x\r\n",(char*)name_addr,func_addr);
			return (PVOID)func_addr ;
		}
	}	
	return NULL ;
}



HANDLE	GetNtDllBaseAddr(IN	PCWSTR lpModuleName/*=L"ntdll.dll"*/)
{		
	HANDLE hModule = NULL;
	RTL_OSVERSIONINFOW os={0};
	ULONG_PTR uPebPtr;
	ULONG_PTR uLdr=NULL ;
	ULONG uPebOffset=0;
	ULONG uLdrOffset=0xc;
	RtlGetVersion (&os);
	
	if(KeGetCurrentIrql() != PASSIVE_LEVEL)
		return NULL;

	if(os.dwMajorVersion==5)
	{
		switch(os.dwMinorVersion)
		{
		case 1://xp sp3
			uPebOffset=0x1b0;
			break;
		case 2://2003 sp2
			uPebOffset=0x1a0;
			break;
		}
	}
	else if(os.dwMajorVersion==6)
	{
		switch(os.dwMinorVersion)
		{
		case 0://2008
			break;
		case 1:
#ifdef _WIN64
			//win7x64 sp1, 2008R2x64 sp1
			uPebOffset=0x338;
			uLdrOffset=0x18;
#else
			//win7x32 sp1
			uPebOffset=0x1a8;
#endif
		}
	}	
	if(uPebOffset==0)
	{
		dprintf ("this function do not supported current os.\r\n");
		return NULL ;
	}	

	__try{
		uPebPtr =(ULONG_PTR)((UCHAR *)PsGetCurrentProcess()+uPebOffset);
		if((uLdr=*(ULONG_PTR*)uPebPtr)==NULL )
		{
			return NULL;
		}
		uLdr +=uLdrOffset;
		PEB_LDR_DATA *pld=(PEB_LDR_DATA*)(*(ULONG_PTR*)uLdr);	
		LIST_ENTRY *pList=pld->InLoadOrderModuleList.Flink;	
		LIST_ENTRY *p=pList;

		do{
			PLDR_MODULE pModule=(PLDR_MODULE)p;			
			if(_wcsicmp (lpModuleName ,pModule->BaseDllName.Buffer)==0)
			{
				hModule=pModule->BaseAddress;
				dprintf("\"%ws\" base address = %#x\r\n",pModule->BaseDllName.Buffer,hModule);
				break; 
			}
			p=p->Flink;

		}while(p!=pList);
	}__except (1){
		dprintf ("get ntdll base addr exception....\r\n");
	}
	hModuleOfNtdll=hModule;
	return hModule;

}

ULONG GetFunctionIndexOfSSDT(PCSTR lpFunctionName)
{
	ULONG  idx =-1;	
	if(hModuleOfNtdll ==NULL)
	{
		GetNtDllBaseAddr();
	}		
	if(hModuleOfNtdll ==NULL)
	{
		dprintf ("=== Get \"ntdll.dll\" base addr failed. ===\r\n");
		return -1;
	}
	PVOID pFuncAddr=NULL;
	pFuncAddr=GetFunctionAddress(hModuleOfNtdll,lpFunctionName);
	if(pFuncAddr ==NULL)
	{
		dprintf ("GetFunctionAddress((HANDLE)%#x,(const char* %s) Failed.\r\n",
			hModuleOfNtdll,lpFunctionName );
		return -1;
	}
#ifdef _WIN64
	idx =*(ULONG*)((UCHAR*)pFuncAddr +4);
#else
	idx=*(ULONG*)((UCHAR*)pFuncAddr +1);
#endif
	dprintf ("\"%s\"\ index = %#x\r\n" ,lpFunctionName,idx );
	return idx;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
什么也不懂的菜鸟崇拜一下
SSDT的东西值得学习
2011-12-29 12:02
0
游客
登录 | 注册 方可回帖
返回
//