-
-
[分享]驱动中取NT API函数在SSDT中的服务号
-
发表于:
2011-12-29 01:24
5024
-
[分享]驱动中取NT API函数在SSDT中的服务号
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;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)