⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 krnldataclient.cpp

📁 该代码为我学习winnt内核时所写
💻 CPP
字号:
// KrnlDataClient.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

const char DEVICE_NAME[] = "\\\\.\\dvKrnlDataDevice";
const int LOG_BIN_NUM = 16;

char *GetFileName(char *szPath)
{
    if(strchr(szPath, '\\') == NULL)
    {
        return szPath;
    }

    char *szTemp = szPath;
    char *szRet;
    while( szTemp != NULL )
    {
        szRet = szTemp + 1;
        szTemp = strchr(szRet, '\\');
    }
    
    return szRet;
}

void PrintUsage(char *szExe)
{
    printf( 
        "=========================Usage=========================\n"
        "%s <option> <address> <number>\n"
        "option:    \t-b\tin BYTE  order\n"
        "           \t-s\tin SHORT order\n"
        "           \t-d\tin DWORD order\n"
        "address:   \tthe address u want to get data in hex\n"
        "number:    \thow many number u want to get according to option\n"
        "=======================================================\n",
        GetFileName(szExe));
}

bool IsValidAscii(char s)
{
    if((BYTE)s < 33 || (BYTE)s > 128)
    {
        return false;
    }
    return true;
}

void PrintDataInbyte(BYTE *pData, DWORD dwBase, DWORD dwLen)
{
    int nTime = dwLen / LOG_BIN_NUM;
    CHAR cAscii[LOG_BIN_NUM + 1] = {0};
    int i = 0;
    int j = 0;
    int n = 0;
    int temp = 0;

    for(n = 0; n < nTime; n++)
    {
        printf( "[%08X]: ", LOG_BIN_NUM * n + dwBase);
        for(i = (LOG_BIN_NUM * n); i < LOG_BIN_NUM * (n + 1); i++)
        {
            printf( "%.2X ", pData[i] );
        }
        memcpy(cAscii, &pData[LOG_BIN_NUM * n], LOG_BIN_NUM);
        for(j = 0; j < LOG_BIN_NUM; j++)
        {
            cAscii[j] = (IsValidAscii(cAscii[j])?cAscii[j]:0x20);
        }
        printf("    %s\n", cAscii);
    }

    temp = i;
    memset(cAscii, 0, LOG_BIN_NUM + 1);
    if( i < dwLen )
    {
        printf("[%08X]: ", LOG_BIN_NUM * n + dwBase);
        for(; i < dwLen; i++)
        {
            printf("%.2X ", pData[i] );
        }
        for(; i < LOG_BIN_NUM * (n + 1); i++)
        {
            printf("   ");
        }
        memcpy(cAscii, &pData[temp], dwLen - temp);
        for(j = 0; j < dwLen - temp; j++)
        {
            cAscii[j] = (IsValidAscii(cAscii[j])?cAscii[j]:0x20);
        }
        printf("    %s\n", cAscii);
    }
    printf("\n");
}

void PrintDataIndword(BYTE *pData, DWORD dwBase, DWORD dwLen)
{
    int nTime = dwLen / LOG_BIN_NUM;
    int nLineNum = LOG_BIN_NUM / sizeof(DWORD);
    int i = 0;
    int n = 0;
    int temp = 0;
    DWORD *pdwData = (DWORD *)pData;

    for(n = 0; n < nTime; n++)
    {
        printf( "[%08X]: ", LOG_BIN_NUM * n + dwBase);
        for(i = (nLineNum * n); i < nLineNum * (n + 1); i++)
        {
            printf( "%08X ", pdwData[i] );
        }
        printf("\n");
    }

    temp = i;
    if( i < (dwLen / sizeof(DWORD)) )
    {
        printf("[%08X]: ", LOG_BIN_NUM * n + dwBase);
        for(; i < (dwLen / sizeof(DWORD)); i++)
        {
            printf( "%08X ", pdwData[i] );
        }
        printf("\n");
    }
    printf("\n");
}

void PrintMemData(int nType, BYTE *pData, DWORD dwBase, DWORD dwLen)
{
    switch(nType)
    {
    case 1: //byte
        PrintDataInbyte(pData, dwBase, dwLen);
        break;
    case 2: //short
    case 3: //dowrd
        PrintDataIndword(pData, dwBase, dwLen);
        break;
    }
}

void PrintIDTData(BYTE *pData, DWORD dwLen)
{
    int n = 0;
    PIDTR pIdt = NULL;
    PIDT_ENTRY pIdtEntry = NULL;

    pIdt = (PIDTR)pData;
    printf("IDTBase: %08X   IDTLimit: %X\n", pIdt->IDTBase, pIdt->IDTLimit);

    if((dwLen - sizeof(IDTR)) % sizeof(IDT_ENTRY) != 0)
    {
        printf("wrong len\n");
        return;
    }
    n = (dwLen - sizeof(IDTR)) / sizeof(IDT_ENTRY);

    pIdtEntry = (PIDT_ENTRY)(pData + sizeof(IDTR));
    printf("Number        Address        Selector\n");
    for(int i = 0; i < n; i++)
    {
        DWORD dwOffset = (DWORD)(pIdtEntry->OffsetLow) | ((DWORD)(pIdtEntry->OffsetHigh) << 16);
        printf("%03X    %08X    %08X\n", i, dwOffset, pIdtEntry->Selector);
    }
}

void PrintSSTData(BYTE *pData, DWORD dwLen)
{
    PSYSTEM_SERVICE_TABLE pSST = NULL;
    DWORD *pServiceEntry = NULL;
    BYTE *pArgument = NULL;

    pSST = (PSYSTEM_SERVICE_TABLE)pData;
    printf("ServiceTable: %08X    ArgumentTable: %08X    Limit: %X\n", 
        pSST->ServiceTable,
        pSST->ArgumentTable,
        pSST->ServiceLimit);

    if(dwLen < sizeof(SYSTEM_SERVICE_TABLE) + pSST->ServiceLimit * (sizeof(DWORD) + 1))
    {
        printf("wrong len\n");
        return;
    }

    pServiceEntry = (DWORD *)(pData + sizeof(SYSTEM_SERVICE_TABLE));
    pArgument = pData + sizeof(SYSTEM_SERVICE_TABLE) + pSST->ServiceLimit * sizeof(DWORD);
    printf("Number        Address        Argument\n");
    for(int i = 0; i < pSST->ServiceLimit; i++)
    {
        printf("%03X    %08X    %X\n", i, pServiceEntry[i], pArgument[i]);
    }
}

int main(int argc, char* argv[])
{
    BYTE temp[6];
    __asm
    {
        sidt temp
    }
    printf("idt base: %08x    limit: %X\n", *(DWORD *)&temp[2], *(SHORT *)temp);

    if(argc == 1)
    {
        PrintUsage(argv[0]);
        return 0;
    }

    //打开设备
    HANDLE hDevice = CreateFile( 
        DEVICE_NAME,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(hDevice == INVALID_HANDLE_VALUE)
    {
        printf("Error CreateFile:%08X\n", GetLastError());
        return 0;
    }
    
    //隐藏指定ID的进程
    if(strcmp(argv[1], "-hide") == 0)
    {
        if(argc != 3)
        {
            PrintUsage(argv[0]);
            goto out;
        }
        DWORD dwPID = strtoul(argv[2], NULL, 10);
        if(dwPID == 0)
        {
            PrintUsage(argv[0]);
            goto out;
        }

        DWORD dwWritten = 0;

        if( !DeviceIoControl(
            hDevice,
            KRNLDATA_IO_HIDE_PROC,
            &dwPID,
            sizeof(DWORD),
            NULL,
            0,
            &dwWritten,
            NULL))
        {
            printf("Error DeviceIoControl:%08X\n", GetLastError());
        }
    }
    //停止隐藏进城
    if(strcmp(argv[1], "-unhide") == 0)
    {
        DWORD dwWritten;
        if( !DeviceIoControl(
            hDevice,
            KRNLDATA_IO_STOP_HIDE,
            NULL,
            0,
            NULL,
            0,
            &dwWritten,
            NULL))
        {
            printf("Error DeviceIoControl:%08X\n", GetLastError());
        }
    }
    //获取线性地址对应的物理地址
    if(strcmp(argv[1], "-physical") == 0)
    {
        if(argc != 3)
        {
            PrintUsage(argv[0]);
            goto out;
        }
        DWORD dwAddress = strtoul(argv[2], NULL, 16);
        if(dwAddress == 0)
        {
            PrintUsage(argv[0]);
            goto out;
        }

        DWORD dwWritten = 0;
        ULARGE_INTEGER PhysicalAddr;

        if( !DeviceIoControl(
            hDevice,
            KRNLDATA_IO_PHYSICAL,
            &dwAddress,
            sizeof(DWORD),
            &PhysicalAddr,
            sizeof(ULARGE_INTEGER),
            &dwWritten,
            NULL))
        {
            printf("Error DeviceIoControl:%08X\n", GetLastError());
        }
        else
        {
            printf("Line Addr: %08X    Physical Addr: %08X-%08X\n", 
                dwAddress, 
                PhysicalAddr.u.HighPart,
                PhysicalAddr.u.LowPart);
        }
    }
    //读取中断表请求
    if(strcmp(argv[1], "-idt") == 0)
    {
        DWORD dwWritten = 0;
        DWORD dwLen = sizeof(IDTR) + sizeof(IDT_ENTRY) * 0xFF;
        BYTE *pDataBuf = new BYTE[dwLen];

        if( !DeviceIoControl(
            hDevice,
            KRNLDATA_IO_IDT,
            NULL,
            0,
            pDataBuf,
            dwLen,
            &dwWritten,
            NULL))
        {
            printf("Error DeviceIoControl:%08X\n", GetLastError());
        }
        else
        {
            PrintIDTData(pDataBuf, dwWritten);
        }

        delete []pDataBuf;
    }
    //读取服务表请求
    if(strcmp(argv[1], "-sst") == 0)
    {
        DWORD dwWritten = 0;
        DWORD dwLen = sizeof(SYSTEM_SERVICE_TABLE) + 5 * 2000;
        BYTE *pDataBuf = new BYTE[dwLen];

        if( !DeviceIoControl(
            hDevice,
            KRNLDATA_IO_SST,
            NULL,
            0,
            pDataBuf,
            dwLen,
            &dwWritten,
            NULL))
        {
            printf("Error DeviceIoControl:%08X\n", GetLastError());
        }
        else
        {
            PrintSSTData(pDataBuf, dwWritten);
        }

        delete []pDataBuf;
    }
    //读取内存请求
    if(strcmp(argv[1], "-memory") == 0)
    {
        if(argc != 5)
        {
            PrintUsage(argv[0]);
            goto out;
        }
        DWORD dwAddress = strtoul(argv[3], NULL, 16);
        if(dwAddress == 0)
        {
            PrintUsage(argv[0]);
            goto out;
        }

        DWORD dwLen = strtoul(argv[4], NULL, 10);
        if(dwLen == 0)
        {
            PrintUsage(argv[0]);
            goto out;
        }

        int nPrintType = 0;
        if( strcmp(argv[2], "-b") == 0)
        {
            nPrintType = 1;    //byte
        }
        if(strcmp(argv[2], "-s") == 0)
        {
            nPrintType = 2;    //short
            dwLen *= 2;
        }
        if(strcmp(argv[2], "-d") == 0)
        {
            nPrintType = 3;    //dword
            dwLen *= 4;
        }
        if(nPrintType == 0)
        {
            PrintUsage(argv[0]);
            goto out;
        }

        //读取内存制定位置的数据
        DVKRNLDATA_MEM_REQUEST MemReq;
        MemReq.pAddress = (LPVOID)dwAddress;
        MemReq.dwRequestLen = dwLen;

        BYTE *pDataBuf = new BYTE[dwLen];
        DWORD dwWritten = 0;

        if(dwAddress < 0x80000000)
        {
            //非内核区域
            __try
            {
                memcpy(pDataBuf, (LPVOID)dwAddress, dwLen);
                PrintMemData(nPrintType, pDataBuf, dwAddress, dwLen);
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                printf("Invalid Memory Address!\n");
            }
        
        }
        else
        {
            //内核区域通过驱动来获取
            if( !DeviceIoControl(
                hDevice,
                KRNLDATA_IO_READ_MEM,
                (LPVOID)&MemReq,
                sizeof(MemReq),
                pDataBuf,
                dwLen,
                &dwWritten,
                NULL))
            {
                printf("Error DeviceIoControl:%08X\n", GetLastError());
            }
            else
            {
                PrintMemData(nPrintType, pDataBuf, dwAddress, dwWritten);
            }
        }
        delete []pDataBuf;
    }

out:
	CloseHandle(hDevice);
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -