驱动之路_通过ntdll.dll获取SSDT函数名与服务号

// EunmNtdll.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>



/*******************************************************************************
*
*  函 数 名 : GetServiceID
*  功能描述 : 取得SSDT函数索引号
*  参数列表 : 
*  说    明 : 
*  返回结果 : 如果成功返回索引号,失败返回-1
*
*******************************************************************************/
int GetServiceID(int nFunctionAddress)
{
#define MOV (0xb8)
    try
    {
        // 这里要是unsigned char ,要不然会符号扩展
        // 谨记
        unsigned char *pInstruction = (unsigned char *)nFunctionAddress ;
        if (MOV != *pInstruction)
        {
            return 0 ;
        }
        int nResult = *(int*)(pInstruction + 1) ;
        return nResult ;
    }
    catch (...)
    {
        return 0 ;
    }
}

//列举导出表的函数,参数就是dll模块的地址
BOOLEAN EunmEATTable(PVOID ulModuleBase)
{
    //这里大家都知道是变量的声明
    PIMAGE_DOS_HEADER pDosHeader; //dos头结构体
    PIMAGE_NT_HEADERS NtDllHeader;//nt结构体
    IMAGE_OPTIONAL_HEADER opthdr; //可选镜像头部
    ULONG_PTR* arrayOfFunctionAddresses;
    ULONG_PTR* arrayOfFunctionNames;
    WORD* arrayOfFunctionOrdinals;
    ULONG_PTR functionOrdinal;
    ULONG_PTR Base, x, functionAddress;
    IMAGE_EXPORT_DIRECTORY *pExportTable;
    char *functionName;

    __try
    {
        //得到dos头
        pDosHeader=(PIMAGE_DOS_HEADER)ulModuleBase;
        if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
        {
            printf("IMAGE_DOS_SIGNATURE failed\r\n");
            return FALSE;
        }
        //得到NT文件头 NT结构体
        NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG_PTR)((ULONG_PTR)pDosHeader+pDosHeader->e_lfanew);
        if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)
        {
            printf("IMAGE_NT_SIGNATURE failed\r\n");
            return FALSE;
        }
        //得到可选镜像结构体
        opthdr = NtDllHeader->OptionalHeader;

        //得到内存的导出表结构
        pExportTable =(IMAGE_EXPORT_DIRECTORY*)((ULONG_PTR)ulModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表

        //地址
        arrayOfFunctionAddresses = (ULONG_PTR*)((ULONG_PTR)ulModuleBase + pExportTable->AddressOfFunctions);  //地址表
        arrayOfFunctionNames = (ULONG_PTR*)((BYTE*)ulModuleBase + pExportTable->AddressOfNames);         //函数名表
        arrayOfFunctionOrdinals = (WORD*)( (BYTE*)ulModuleBase + pExportTable->AddressOfNameOrdinals);

        //得到导出表的起始地址
        Base = pExportTable->Base;

        //然后我们开始搜索整个导出表
        for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描
        {
            functionName = (char*)((BYTE*)ulModuleBase + arrayOfFunctionNames[x]);
            functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; 
            functionAddress = (ULONG_PTR)((BYTE*)ulModuleBase + arrayOfFunctionAddresses[functionOrdinal]);

            if (functionName[0] == (char)'N' && functionName[1] == (char)'t')
            {
                int ServerNumNo;
                if(ServerNumNo = GetServiceID(functionAddress))
                {
                    printf("%d,%s:0x%08X\r\n",ServerNumNo,functionName,functionAddress);
                }

                
            }
            
        }

    }__except(EXCEPTION_EXECUTE_HANDLER){
    }
    return FALSE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    EunmEATTable(GetModuleHandle(L"ntdll.dll"));
    getchar();
    return 0 ;
}

 

posted @ 2013-10-23 17:42  宝贝,我永远都在  阅读(792)  评论(0)    收藏  举报