驱动之路_遍历ShaDowSSDT函数

#include "stdafx.h"
#ifdef __cplusplus
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);
#endif

extern "C" __declspec(dllimport) BOOLEAN KeRemoveSystemServiceTable (IN ULONG Index);
PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorShadowTable;

void DDK_UnLoad(IN PDRIVER_OBJECT DriverObject)
{
    DbgPrint("Goodbye from DDK_UnLoad!\n");
}


extern "C" UCHAR *PsGetProcessImageFileName(__in PEPROCESS eprocess);


PSERVICE_DESCRIPTOR_TABLE GetKeServiceDescriptorShadowTableAddress()
{
    PCHAR address = (PCHAR)KeRemoveSystemServiceTable;//赋值
    ULONG add;
    for (int i = 0; i < 0x1024;i++)//遍历第一页内存
    {
        add = *((PULONG)(address+i));//访问函数的每个字节,转换为Ulong指针类型

        if (MmIsAddressValid((PVOID)add))//检查内存是否可以访问
        {
            if (memcmp((void *)add,KeServiceDescriptorTable,16) == 0)//如果前面16个字节相同的话
            {
                if (add == (DWORD)KeServiceDescriptorTable)
                {
                    //如果相等的话,就返回
                    continue;
                }else
                {
                    return (PSERVICE_DESCRIPTOR_TABLE)(*((DWORD*)(address+i)));
                }
            }
        }
    }
    return NULL;
}




typedef enum WIN_VER_DETAIL {
    WINDOWS_VERSION_NONE,       //  0
    WINDOWS_VERSION_2K,
    WINDOWS_VERSION_XP,
    WINDOWS_VERSION_2K3,
    WINDOWS_VERSION_2K3_SP1_SP2,
    WINDOWS_VERSION_VISTA_2008,
    WINDOWS_VERSION_7_7600_UP,
    WINDOWS_VERSION_7_7000
} WIN_VER_DETAIL;

WIN_VER_DETAIL WinVersion;

WIN_VER_DETAIL GetWindowsVersion()
{
    RTL_OSVERSIONINFOEXW    osverinfo;

    if (WinVersion)
        return WinVersion;


    memset(&osverinfo,0,sizeof(RTL_OSVERSIONINFOEXW));
    osverinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); 
    if (RtlGetVersion((RTL_OSVERSIONINFOW*)&osverinfo) != STATUS_SUCCESS){
        return WINDOWS_VERSION_NONE;
    }

    //     KdPrint(("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n", 
    //         osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber, 
    //         osverinfo.wServicePackMajor, osverinfo.wServicePackMinor));

    if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0){
        WinVersion = WINDOWS_VERSION_2K;
    } 
    else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1){
        WinVersion = WINDOWS_VERSION_XP;
    } 
    else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2){
        if (osverinfo.wServicePackMajor==0){ 
            WinVersion = WINDOWS_VERSION_2K3;
        } 
        else{
            WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
        }
    } 
    else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0){
        WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;
    }
    else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber == 7000){
        WinVersion = WINDOWS_VERSION_7_7000;
    }
    else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1 && osverinfo.dwBuildNumber >= 7600){
        WinVersion = WINDOWS_VERSION_7_7600_UP;
    }
    return WinVersion;
}


NTSTATUS LookupProcessByName(
                             IN PCHAR pcProcessName,
                             OUT PEPROCESS *pEprocess
                             )
{ 
    NTSTATUS    status;
    ULONG        uCount = 0;
    ULONG        uLength = 0;
    PLIST_ENTRY    pListActiveProcess;
    PEPROCESS    pCurrentEprocess = NULL;
    ULONG ulNextProcess = NULL;
    ULONG g_Offset_Eprocess_Flink;
    WIN_VER_DETAIL WinVer;
    char lpszProName[100];
    char *lpszAttackProName = NULL;


    if (!ARGUMENT_PRESENT(pcProcessName) || !ARGUMENT_PRESENT(pEprocess))
    {
        return STATUS_INVALID_PARAMETER;
    }
    if (KeGetCurrentIrql() > PASSIVE_LEVEL)
    {
        return STATUS_UNSUCCESSFUL;
    }
    uLength = strlen(pcProcessName);

    WinVer = GetWindowsVersion();
    switch(WinVer)
    {
    case WINDOWS_VERSION_XP:
        g_Offset_Eprocess_Flink = 0x88;
        break;
    case WINDOWS_VERSION_7_7600_UP:
    case WINDOWS_VERSION_7_7000:
        g_Offset_Eprocess_Flink = 0xb8;
        break;
    case WINDOWS_VERSION_VISTA_2008:
        g_Offset_Eprocess_Flink = 0x0a0;
        break;
    case WINDOWS_VERSION_2K3_SP1_SP2:
        g_Offset_Eprocess_Flink = 0x98;
        break;
    case WINDOWS_VERSION_2K3:
        g_Offset_Eprocess_Flink = 0x088;
        break;
    }
    if (!g_Offset_Eprocess_Flink){
        return STATUS_UNSUCCESSFUL;
    }

    pCurrentEprocess = PsGetCurrentProcess();
    ulNextProcess = (ULONG)pCurrentEprocess;

    __try
    {
        memset(lpszProName,0,sizeof(lpszProName));//填充0
        if (uLength > 15)//如果你传进来的字符串大于15
        {
            strncat(lpszProName,pcProcessName,15);//我就取前15个字符
            uLength = 15;
        }
        while(1)
        {
            lpszAttackProName = NULL;
            lpszAttackProName = (char *)PsGetProcessImageFileName(pCurrentEprocess);//取当前进程的EPROCESS

            DbgPrint("%s",lpszAttackProName);//打印进程名称,中文不会被打印出来,有BUG

                if (lpszAttackProName && strlen(lpszAttackProName) == uLength)
                {
                    if(_strnicmp(pcProcessName,lpszAttackProName, uLength) == 0)//如果lenth大于15,因为我们前面已经裁去了
                    {
                        *pEprocess = pCurrentEprocess;
                        status = STATUS_SUCCESS;
                        break;
                    }
                }
            if ((uCount >= 1) && (ulNextProcess == (ULONG)pCurrentEprocess))
            {
                *pEprocess = 0x00000000;
                status = STATUS_NOT_FOUND;
                break;
            }
            pListActiveProcess = (LIST_ENTRY *)((ULONG)pCurrentEprocess + g_Offset_Eprocess_Flink);
            pCurrentEprocess = (PEPROCESS)((ULONG(pListActiveProcess->Flink)) - g_Offset_Eprocess_Flink);
            uCount++;
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        KdPrint(("LookupProcessByName:%08x\r\n",GetExceptionCode()));
        status = STATUS_NOT_FOUND;
    }
    return status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)
{

    PEPROCESS eprocess_explorer;
    KdPrint(("驱动被加载!!!"));//调试的时候可以用这个函数调试
    DriverObject->DriverUnload=DDK_UnLoad;//设置卸载驱动函数
    KeServiceDescriptorShadowTable = GetKeServiceDescriptorShadowTableAddress();
    if (!KeServiceDescriptorShadowTable)
    {
        DbgPrint("获取影子地址失败");
        
    } 
    else
    {
        DbgPrint("影子的地址是:%x",KeServiceDescriptorShadowTable[1]);
        //我们得到一个gui进程的对象,因为我们切换进程的时候需要用到
        if (LookupProcessByName("explorer.exe",&eprocess_explorer) == STATUS_SUCCESS)
        {
            KeAttachProcess(eprocess_explorer);//附加到目标进程
            
            //遍历影子的地址
            for (int i = 0; i < KeServiceDescriptorShadowTable[1].TableSize;i++)
            {
                DbgPrint("%d : %x",i+1,KeServiceDescriptorShadowTable[1].ServiceTable[i]);
            }
            DbgPrint("影子的地址是:%x",KeServiceDescriptorShadowTable[1]);
            KeDetachProcess();//解除附加
        }else{
            DbgPrint("附加失败");
        }
    }
    
    return STATUS_SUCCESS;
}

 

posted @ 2013-09-20 17:49  宝贝,我永远都在  阅读(645)  评论(0)    收藏  举报