代码:
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; }