元始天尊 发表于 2015-7-19 14:37:24

监听windbg内核调试通信数据

本帖最后由 元始天尊 于 2015-7-19 22:30 编辑

很简单,hook住readfile writefile即可,代码:

// hook.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#include <windows.h>
#include <shlwapi.h>
#include "detours.h"
#include "common.h"
using namespace std;
#pragma comment(lib,"detours.lib")
#pragma comment(lib,"shlwapi.lib")
#include <string>
#include <fstream>
using namespace std;



#if defined(UNICODE) || defined(_UNICODE)
#define _T(X) L##X
#else
#define _T(X)
#endif

HANDLE WINAPI NEW_CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
BOOL WINAPI NEW_ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);
BOOL WINAPI NEW_WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);


#define G(X) GetProcAddress(GetModuleHandleW(L"kernel32.dll"),X)

FARPROC OLD_FUNCS =
{
        G("CreateFileW"),
        G("ReadFile"),
        G("WriteFile"),
};

FARPROC NEW_FUNCS =
{
        (FARPROC)NEW_CreateFileW,
        (FARPROC)NEW_ReadFile,
        (FARPROC)NEW_WriteFile,
};

HANDLE currentpipe=(HANDLE)-100;
HANDLE hOutputHandle;
HANDLE hLogFile=(HANDLE)-101;
HANDLE hDataFile=(HANDLE)-101;

CRITICAL_SECTION cs;

HANDLE WINAPI NEW_CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
{
        HANDLE hFile = ((HANDLE (WINAPI*)(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))OLD_FUNCS)
                (lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
        if(StrStrIW(lpFileName,L"pipe\\com_1") && hFile != INVALID_HANDLE_VALUE)
        {
                currentpipe=hFile;
        }
        return hFile;
}

BOOL WINAPI NEW_ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
{
        BOOL ret = ((BOOL (WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED))OLD_FUNCS)(hFile,lpBuffer,nNumberOfBytesToRead,
                lpNumberOfBytesRead,lpOverlapped);
        if(hFile == hLogFile)
                return ret;
        if(ret && currentpipe == hFile && nNumberOfBytesToRead)
        {
                EnterCriticalSection(&cs);
                __try
                {
                        char output={0};
                        sprintf(output,"接收数据%d:\r\n",nNumberOfBytesToRead);
                        char buf;
                        for(int i=0;i<nNumberOfBytesToRead;i++)
                        {
                                sprintf(buf,"%02X ",(int)((BYTE*)lpBuffer));
                                strcat(output,buf);
                                if((i%16) == 15)
                                        strcat(output,"\r\n");
                        }
                        strcat(output,"\r\n");

                        DWORD ret;
                        WriteFile(hDataFile,lpBuffer,nNumberOfBytesToRead,&ret,NULL);
                        WriteFile(hLogFile,output,strlen(output),&ret,NULL);
                        FlushFileBuffers(hLogFile);
                }
                __except(1)
                {
                        MessageBoxA(NULL,"","",0);
                }
                LeaveCriticalSection(&cs);
        }
        return ret;
}

BOOL WINAPI NEW_WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped)
{
        BOOL ret = ((BOOL (WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED))OLD_FUNCS)(hFile,lpBuffer,nNumberOfBytesToWrite,
                lpNumberOfBytesWritten,lpOverlapped);
        if(hFile == hLogFile)
                return ret;
        if(ret && currentpipe == hFile && nNumberOfBytesToWrite)
        {
                EnterCriticalSection(&cs);
                __try
                {
                        char output={0};
                        sprintf(output,"发送数据%d:\r\n",nNumberOfBytesToWrite);
                        char buf;
                        for(int i=0;i<nNumberOfBytesToWrite;i++)
                        {
                                sprintf(buf,"%02X ",(int)((BYTE*)lpBuffer));
                                strcat(output,buf);
                                if((i%16) == 15)
                                        strcat(output,"\r\n");
                        }
                        strcat(output,"\r\n");

                        DWORD ret;
                        WriteFile(hDataFile,lpBuffer,nNumberOfBytesToWrite,&ret,NULL);
                        WriteFile(hLogFile,output,strlen(output),&ret,NULL);
                        FlushFileBuffers(hLogFile);
                }
                __except(1)
                {
                        MessageBoxA(NULL,"","",0);
                }
                LeaveCriticalSection(&cs);
        }
        return ret;
}

extern "C" __declspec(dllexport) void __cdecl Hook()
{
        DetourRestoreAfterWith();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        for (int i = 0; i < HookMax; i++)
        {
                DetourAttach(&(PVOID&)OLD_FUNCS, NEW_FUNCS);
        }
        DetourTransactionCommit();
}

extern "C" __declspec(dllexport) void __cdecl UnHook()
{
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        for (int i = 0; i < HookMax; i++)
        {
                DetourDetach(&(PVOID&)OLD_FUNCS, NEW_FUNCS);
        }
        DetourTransactionCommit();
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
                {
                        hLogFile=CreateFileW(L"C:\\windbg_log.txt",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
                                NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
                        hDataFile=CreateFileW(L"C:\\windbg_data.txt",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
                                NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
                        Hook();
                        AllocConsole();
                        InitializeCriticalSection(&cs);
                        hOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
                }
                break;
        case DLL_THREAD_ATTACH:
                break;
        case DLL_THREAD_DETACH:
                break;
        case DLL_PROCESS_DETACH:
                {
                        UnHook();
                        FreeConsole();
                }
                break;
        }
        return TRUE;
}




得到的数据包:
Offset      01234567   89ABCDEF

00000000   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii            
00000010   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii            
00000020   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii            
00000030   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii            
00000040   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii            
00000050   30 30 30 07 00 0F 01 0008 80 80 44 33 00 00 31   000      €€D31
00000060   30 00 00 00 00 00 00 0100 00 00 00 00 00 00 40   0            @
00000070   37 55 80 FF FF FF FF C4F4 52 80 FF FF FF FF 1F   7U€聂R€
00000080   00 00 00 00 00 00 00 0080 4D 80 FF FF FF FF FF         €M€
00000090   FF FF FF 00 00 00 00 D350 20 00 80 84 1F 00 00       覲€?
000000A0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000B0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000C0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000D0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000E0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000F0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000100   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000110   00 00 00 00 00 00 00 1000 00 00 BC FA 05 00 F0            贱?
00000120   0F FF FF 00 04 00 00 1000 03 00 CC 5D C2 0C 00          蘛?
00000130   CC CC CC CC CC 8B FF 558B EC FF 08 00 23 00 23   烫烫虌U嬱# #
00000140   00 30 00 82 00 00 00 0000 00 00 00 00 00 00 5C    0 ?          \
00000150   57 49 4E 44 4F 57 53 5C73 79 73 74 65 6D 33 32   WINDOWS\system32
00000160   5C 6E 74 6B 72 6E 6C 7061 2E 65 78 65 00 AA 69   \ntkrnlpa.exe 猧
00000170   69 69 69 06 00 00 00 63F8 05 00 00 00 00 00 30   iii    c?   0
00000180   30 30 30 07 00 0F 01 0000 80 80 44 33 00 00 31   000      €€D31
00000190   30 00 00 00 00 00 00 0100 00 00 00 00 00 00 40   0            @
000001A0   37 55 80 FF FF FF FF C4F4 52 80 FF FF FF FF 1F   7U€聂R€
000001B0   00 00 00 00 00 00 00 0080 4D 80 FF FF FF FF FF         €M€
000001C0   FF FF FF 00 00 00 00 D350 20 00 80 84 1F 00 00       覲€?
000001D0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000001E0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000001F0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000200   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000210   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000220   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000230   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000240   00 00 00 00 00 00 00 1000 00 00 BC FA 05 00 F0            贱?
00000250   0F FF FF 00 04 00 00 1000 03 00 CC 5D C2 0C 00          蘛?
00000260   CC CC CC CC CC 8B FF 558B EC FF 08 00 23 00 23   烫烫虌U嬱# #
00000270   00 30 00 82 00 00 00 0000 00 00 00 00 00 00 5C    0 ?          \
00000280   57 49 4E 44 4F 57 53 5C73 79 73 74 65 6D 33 32   WINDOWS\system32
00000290   5C 6E 74 6B 72 6E 6C 7061 2E 65 78 65 00 AA 69   \ntkrnlpa.exe 猧
000002A0   69 69 69 04 00 00 00 0000 80 80 00 00 00 00 30   iii      €€    0
000002B0   30 30 30 02 00 38 00 0000 80 80 9C 0B 00 00 46   0008   €€?F
000002C0   31 00 00 80 F6 7D 07 0301 00 00 F4 F6 7D 07 02   1€鰙   赧}
000002D0   BE B7 52 01 5E AE 52 0700 00 00 01 00 00 00 00   痉R ^甊         
000002E0   00 00 00 02 00 00 00 11BF B7 52 2C F7 7D 07 00         糠R,鱹
000002F0   00 00 00 07 00 00 00 AA69 69 69 04 00 00 00 00          猧ii   
00000300   00 80 80 00 00 00 00 3030 30 30 02 00 38 00 01    €€    00008
00000310   00 80 80 3F 17 00 00 4631 00 00 80 F6 7D 07 00    €€?   F1€鰙
00000320   00 00 00 F4 F6 7D 07 0F00 28 0A 06 00 02 00 4C      赧}   (   L
00000330   01 0C 03 2D 00 00 00 0080 4D 80 FF FF FF FF C0      -    €M€?
00000340   4F 55 80 FF FF FF FF F48E 67 80 FF FF FF FF AA   OU€魩g€?
00000350   69 69 69 69 04 00 00 0001 00 80 80 00 00 00 00   iiii      €€   
00000360   30 30 30 30 02 00 38 0001 00 80 80 B1 13 00 00   00008   €€?
00000370   30 31 00 00 FE FF FF FF38 F6 7D 07 34 11 BC 77   01?8鰙 4 紈
00000380   F4 8E 67 80 FF FF FF FF04 00 00 00 D4 F5 7D 07   魩g€    怎}
00000390   18 11 8D 07 38 00 00 0038 00 00 00 03 00 00 00       8   8      
000003A0   E8 79 E1 00 03 00 00 00AA 69 69 69 04 00 00 00   鑩?    猧ii   
000003B0   01 00 80 80 00 00 00 0030 30 30 30 02 00 3C 00   €€    0000<
000003C0   00 00 80 80 D4 11 00 0030 31 00 00 FE FF FF FF   €€?01?
000003D0   00 00 00 00 34 11 BC 77F4 8E 67 80 FF FF FF FF       4 紈魩g€
000003E0   04 00 00 00 04 00 00 0018 11 8D 07 38 00 00 00               8   
000003F0   38 00 00 00 03 00 00 00E8 79 E1 00 03 00 00 00   8       鑩?   
00000400   E0 6A 54 80 AA 69 69 6969 04 00 00 00 00 00 80   鄇T€猧iii      €
00000410   80 00 00 00 00 30 30 3030 02 00 38 00 00 00 80   €    00008   €
00000420   80 E7 10 00 00 30 31 0000 BA 02 00 00 48 F7 7D   €?01?H鱹
00000430   07 A0 74 C1 77 E0 6A 5480 FF FF FF FF 18 00 00    爐羨鄇T€   
00000440   00 34 11 BC 77 20 00 0000 28 00 00 00 A8 02 E1    4 紈    (   ??
00000450   00 5C EE 7D 07 50 00 0000 20 00 00 00 AA 69 69    \題 P       猧i
00000460   69 04 00 00 00 00 00 8080 00 00 00 00 30 30 30   i      €€    000
00000470   30 02 00 50 00 01 00 8080 40 14 00 00 30 31 00   0P   €€@   01
00000480   00 BA 02 00 00 00 00 0000 A0 74 C1 77 E0 6A 54    ?      爐羨鄇T
00000490   80 FF FF FF FF 18 00 0000 18 00 00 00 20 00 00   €         
000004A0   00 28 00 00 00 A8 02 E100 5C EE 7D 07 50 00 00    (   ??\題 P
000004B0   00 20 00 00 00 F4 8E 6780 F4 8E 67 80 00 00 00      魩g€魩g€   
000004C0   00 00 00 00 00 4B 44 4247 90 02 00 00 AA 69 69      KDBG    猧i

分析过程:
windbg内核通信协议看起来比较复杂,常见的包为信息包和控制包、中断包
经过观察,有一些点需要注意:
1.管道读写,端口读写或者其他与内核通信的方式,有时候会缺失数据,比如本来是0x30303030的信息包,下面0x50处少一个0x30,现在的0x30是我后补上去的,编写通信模块需要注意这一部分
2.读写被调试主机传来的数据,用的是ReadFile/WriteFile,且很多时候是一个/若干个字节read/write一次,不明白为何这么低效!!!这样做就需要我们构建好数据包,再给数据包分析函数处理,主要是处理通信过程

API与结构体的映射:
DbgKdReadVirtualMemoryApi         0x00003130L      =>                ReadMemory
DbgKdWriteVirtualMemoryApi          0x00003131L      =>                WriteMemory
DbgKdGetContextApi                  0x00003132L      =>                null
DbgKdSetContextApi                  0x00003133L      =>                null
DbgKdWriteBreakPointApi             0x00003134L      =>                WriteBreakPoint
DbgKdRestoreBreakPointApi         0x00003135L      =>                RestoreBreakPoint
DbgKdContinueApi                  0x00003136L      =>                Continue
DbgKdReadControlSpaceApi            0x00003137L      =>                ReadMemory
DbgKdWriteControlSpaceApi         0x00003138L      =>                WriteMemory
DbgKdReadIoSpaceApi               0x00003139L      =>                ReadWriteIo
DbgKdWriteIoSpaceApi                0x0000313AL      =>                ReadWriteIo
DbgKdRebootApi                      0x0000313BL      =>                null
DbgKdContinueApi2                   0x0000313CL      =>                Continue2
DbgKdReadPhysicalMemoryApi          0x0000313DL      =>                ReadMemory
DbgKdWritePhysicalMemoryApi         0x0000313EL      =>                WriteMemory
DbgKdQuerySpecialCallsApi         0x0000313FL      =>                QuerySpecialCalls
DbgKdSetSpecialCallApi            0x00003140L      =>                SetSpecialCall
DbgKdClearSpecialCallsApi         0x00003141L      =>                null
DbgKdSetInternalBreakPointApi       0x00003142L      =>                SetInternalBreakpoint
DbgKdGetInternalBreakPointApi       0x00003143L      =>                GetInternalBreakpoint
DbgKdReadIoSpaceExtendedApi         0x00003144L      =>                ReadWriteIoExtended
DbgKdWriteIoSpaceExtendedApi      0x00003145L      =>                ReadWriteIoExtended
DbgKdGetVersionApi                  0x00003146L      =>                GetVersion32
DbgKdWriteBreakPointExApi         0x00003147L      =>                BreakPointEx
DbgKdRestoreBreakPointExApi         0x00003148L      =>                null
DbgKdCauseBugCheckApi               0x00003149L      =>                null
DbgKdSwitchProcessor                0x00003150L      =>                null
DbgKdPageInApi                      0x00003151L      =>                null
DbgKdReadMachineSpecificRegister    0x00003152L      =>                ReadWriteMsr
DbgKdWriteMachineSpecificRegister   0x00003153L      =>                ReadWriteMsr
OldVlm1                           0x00003154L      =>                null
OldVlm2                           0x00003155L      =>                null
DbgKdSearchMemoryApi                0x00003156L      =>                SearchMemory
DbgKdGetBusDataApi                  0x00003157L      =>                null
DbgKdSetBusDataApi                  0x00003158L      =>                null
DbgKdCheckLowMemoryApi            0x00003159L      =>                null
DbgKdClearAllInternalBreakpointsApi 0x0000315AL      =>                null
DbgKdFillMemoryApi                  0x0000315BL      =>                null
DbgKdQueryMemoryApi               0x0000315CL      =>                null
DbgKdSwitchPartition                0x0000315DL      =>                null       

typedef struct _DBGKD_ANY_WAIT_STATE_CHANGE
{
    ULONG NewState;
    USHORT ProcessorLevel;
    USHORT Processor;
    ULONG NumberProcessors;
    ULONG64 Thread;
    ULONG64 ProgramCounter;
    union
        {
      DBGKM_EXCEPTION64 Exception;
      DBGKD_LOAD_SYMBOLS64 LoadSymbols;
      DBGKD_COMMAND_STRING CommandString;
    } u;
    union
        {
      DBGKD_CONTROL_REPORT ControlReport;
      DBGKD_ANY_CONTROL_REPORT AnyControlReport;
    };
} DBGKD_ANY_WAIT_STATE_CHANGE, *PDBGKD_ANY_WAIT_STATE_CHANGE;

00000000   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii                    发送复位控制包
00000010   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii                    发送复位控制包
00000020   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii                    发送复位控制包
00000030   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii                    发送复位控制包
00000040   69 69 69 69 06 00 00 0000 00 00 00 00 00 00 00   iiii                    发送复位控制包
00000050   30 30 30 30 07 00 0F 0100 08 80 80 44 33 00 00   0000      €€D3        接收DBGKD_ANY_WAIT_STATE_CHANGE信息包,长度0x10F
00000060   31 30 00 00 00 00 00 0001 00 00 00 00 00 00 00   10                    包开始:NewState=DbgKdLoadSymbolsStateChange
00000070   40 37 55 80 FF FF FF FFC4 F4 52 80 FF FF FF FF   @7U€聂R€
00000080   1F 00 00 00 00 00 00 0000 80 4D 80 FF FF FF FF            €M€
00000090   FF FF FF FF 00 00 00 00D3 50 20 00 80 84 1F 00       覲€?
000000A0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000B0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000C0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000D0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000E0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000000F0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000100   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000110   00 00 00 00 00 00 00 0010 00 00 00 BC FA 05 00               贱
00000120   F0 0F FF FF 00 04 00 0010 00 03 00 CC 5D C2 0C   ?      蘛?
00000130   00 CC CC CC CC CC 8B FF55 8B EC FF 08 00 23 00    烫烫虌U嬱#
00000140   23 00 30 00 82 00 00 0000 00 00 00 00 00 00 00   # 0 ?         
00000150   5C 57 49 4E 44 4F 57 535C 73 79 73 74 65 6D 33   \WINDOWS\system3        包以0xAA结束,然而由于0x50处原先少一个0x30
00000160   32 5C 6E 74 6B 72 6E 6C70 61 2E 65 78 65 00 AA   2\ntkrnlpa.exe ?        (为了方便查看,我补上了缺少的0x30)
00000170   69 69 69 69 06 00 00 0063 F8 05 00 00 00 00 00   iiii    c?           接收请求重新连接信息包
00000180   30 30 30 30 07 00 0F 0100 00 80 80 44 33 00 00   0000      €€D3    接收PACKET_TYPE_KD_STATE_CHANGE64信息包,长度0x10F
00000190   31 30 00 00 00 00 00 0001 00 00 00 00 00 00 00   10                                包开始:NewState=DbgKdLoadSymbolsStateChange
000001A0   40 37 55 80 FF FF FF FFC4 F4 52 80 FF FF FF FF   @7U€聂R€ETHREAD=0xFFFFFFFF80553740 BaseAddr=0xFFFFFFFF8052F4C4
000001B0   1F 00 00 00 00 00 00 0000 80 4D 80 FF FF FF FF            €M€映像路径长度0x1F        Dll基址=0xFFFFFFFF804D8000
000001C0   FF FF FF FF 00 00 00 00D3 50 20 00 80 84 1F 00       覲€ 进程ID=-1        映像大小=0x1F8480
000001D0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000001E0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000001F0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00            

00000200   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000210   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000220   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000230   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000240   00 00 00 00 00 00 00 0010 00 00 00 BC FA 05 00               贱
00000250   F0 0F FF FF 00 04 00 0010 00 03 00 CC 5D C2 0C   ?      蘛?
00000260   00 CC CC CC CC CC 8B FF55 8B EC FF 08 00 23 00    烫烫虌U嬱#
00000270   23 00 30 00 82 00 00 0000 00 00 00 00 00 00 00   # 0 ?         
00000280   5C 57 49 4E 44 4F 57 535C 73 79 73 74 65 6D 33   \WINDOWS\system3
00000290   32 5C 6E 74 6B 72 6E 6C70 61 2E 65 78 65 00 AA   2\ntkrnlpa.exe ?        包结束
000002A0   69 69 69 69 04 00 00 0000 00 80 80 00 00 00 00   iiii      €€      发送上次接收信息的确认包
000002B0   30 30 30 30 02 00 38 0000 00 80 80 9C 0B 00 00   00008   €€?   发送读取版本控制信息包 DbgKdGetVersionApi,长度0x38
000002C0   46 31 00 00 80 F6 7D 0703 01 00 00 F4 F6 7D 07   F1€鰙   赧}   包开始
000002D0   02 BE B7 52 01 5E AE 5207 00 00 00 01 00 00 00    痉R ^甊      
000002E0   00 00 00 00 02 00 00 0011 BF B7 52 2C F7 7D 07            糠R,鱹
000002F0   00 00 00 00 07 00 00 00AA 00 00 00 00 00 00 00         ?              包结束
00000300   69 69 69 69 04 00 00 0000 00 80 80 00 00 00 00   iiii      €€            接收到服务器收到信息的确认包
00000310   30 30 30 30 02 00 38 0001 00 80 80 3F 17 00 00   00008   €€?           接收读取版本控制信息包 DbgKdGetVersionApi,长度0x38
00000320   46 31 00 00 80 F6 7D 0700 00 00 00 F4 F6 7D 07   F1€鰙   赧}         包开始
00000330   0F 00 28 0A 06 00 02 004C 01 0C 03 2D 00 00 00   (   L   -   
00000340   00 80 4D 80 FF FF FF FFC0 4F 55 80 FF FF FF FF    €M€繭U€PsLoadedModuleList=0xFFFFFFFF80554FC0        DebuggerDataList=0xFFFFFFFF80678EF4
00000350   F4 8E 67 80 FF FF FF FFAA 00 00 00 00 00 00 00   魩g€?   包结束
00000360   69 69 69 69 04 00 00 0001 00 80 80 00 00 00 00   iiii      €€            发送上次接收信息的确认包
00000370   30 30 30 30 02 00 38 0001 00 80 80 B1 13 00 00   00008   €€?        发送读取内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x38
00000380   30 31 00 00 FE FF FF FF38 F6 7D 07 34 11 BC 77   01?8鰙 4 紈        包开始
00000390   F4 8E 67 80 FF FF FF FF04 00 00 00 D4 F5 7D 07   魩g€      读取0x80678EF4处4字节
000003A0   18 11 8D 07 38 00 00 0038 00 00 00 03 00 00 00       8   8              
000003B0   E8 79 E1 00 03 00 00 00AA 00 00 00 00 00 00 00   鑩?    ?              包结束
000003C0   69 69 69 69 04 00 00 0001 00 80 80 00 00 00 00   iiii      €€            接收到服务器收到信息的确认包
000003D0   30 30 30 30 02 00 3C 0000 00 80 80 D4 11 00 00   0000<   €€?        接收内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x3C
000003E0   30 31 00 00 FE FF FF FF00 00 00 00 34 11 BC 77   01?    4 紈        包开始
000003F0   F4 8E 67 80 FF FF FF FF04 00 00 00 04 00 00 00   魩g€   

00000400   18 11 8D 07 38 00 00 0038 00 00 00 03 00 00 00       8   8      
00000410   E8 79 E1 00 03 00 00 00E0 6A 54 80 AA 00 00 00   鑩?    鄇T€?        包结束,读取得到E0 6A 54 80
00000420   69 69 69 69 04 00 00 0000 00 80 80 00 00 00 00   iiii      €€            发送上次接收信息的确认包
00000430   30 30 30 30 02 00 38 0000 00 80 80 E7 10 00 00   00008   €€?        发送读取内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x38
00000440   30 31 00 00 BA 02 00 0048 F7 7D 07 A0 74 C1 77   01?H鱹 爐羨        包开始
00000450   E0 6A 54 80 FF FF FF FF18 00 00 00 34 11 BC 77   鄇T€    4 读取0x80546AE0处0x18字节(DBGKD_DEBUG_DATA_HEADER64)
00000460   20 00 00 00 28 00 00 00A8 02 E1 00 5C EE 7D 07       (   ??\題
00000470   50 00 00 00 20 00 00 00AA 00 00 00 00 00 00 00   P       ?              包结束
00000480   69 69 69 69 04 00 00 0000 00 80 80 00 00 00 00   iiii      €€            接收到服务器收到信息的确认包
00000490   30 30 30 30 02 00 50 0001 00 80 80 40 14 00 00   0000P   €€@           接收内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x50
000004A0   30 31 00 00 BA 02 00 0000 00 00 00 A0 74 C1 77   01?      爐羨        包开始
000004B0   E0 6A 54 80 FF FF FF FF18 00 00 00 18 00 00 00   鄇T€      
000004C0   20 00 00 00 28 00 00 00A8 02 E1 00 5C EE 7D 07       (   ??\題
000004D0   50 00 00 00 20 00 00 00F4 8E 67 80 F4 8E 67 80   P       魩g€魩g€
000004E0   00 00 00 00 00 00 00 004B 44 42 47 90 02 00 00         KDBG            读取得到F4 8E 67 80 F4 8E 67 80 00 00 00 00 00 00 00 00 4B 44 42 47 90 02 00 00
000004F0   AA 00 00 00 00 00 00 0000 00 00 00 00 00 00 00   ?                    包结束
00000500   69 69 69 69 04 00 00 0001 00 80 80 00 00 00 00   iiii      €€            发送上次接收信息的确认包
00000510   30 30 30 30 02 00 38 0001 00 80 80 02 1A 00 00   00008   €€            发送读取内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x38
00000520   30 31 00 00 05 00 00 0000 EF 7D 07 34 11 BC 77   01       飣 4 紈        包开始
00000530   F8 6A 54 80 FF FF FF FF78 02 00 00 FE FF FF FF   鴍T€x   ?        读取0x80546AF8处0x278字节0x80546AE0整个是KDDEBUGGER_DATA64结构
00000540   D8 EE 7D 07 AA 1E BC 7700 00 00 00 E8 DE E1 00   仡} ?紈    柁?
00000550   B8 DE E1 00 E8 DE E1 00AA 00 00 00 00 00 00 00   皋?柁??                      包结束
00000560   69 69 69 69 04 00 00 0001 00 80 80 00 00 00 00   iiii      €€            接收到服务器收到信息的确认包
00000570   30 30 30 30 02 00 B0 0200 00 80 80 80 97 00 00   0000?€€€?         接收内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x2B0
00000580   30 31 00 00 05 00 00 0000 00 00 00 34 11 BC 77   01          4 紈        包开始
00000590   F8 6A 54 80 FF FF FF FF78 02 00 00 78 02 00 00   鴍T€x   x   
000005A0   D8 EE 7D 07 AA 1E BC 7700 00 00 00 E8 DE E1 00   仡} ?紈    柁?
000005B0   B8 DE E1 00 E8 DE E1 0000 80 4D 80 00 00 00 00   皋?柁? €M€            有效数据开始 00 80 4D 80 00 00 00 0
000005C0   DC 8B 52 80 00 00 00 0000 00 00 00 00 00 00 00   軏R€            
000005D0   2C 01 08 00 18 00 01 008C 06 50 80 00 00 00 00   ,       ?P€   
000005E0   00 00 00 00 00 00 00 00C0 4F 55 80 00 00 00 00         繭U€   
000005F0   58 B1 55 80 00 00 00 0060 B2 55 80 00 00 00 00   X盪€    `睻€      

00000600   88 D6 55 80 00 00 00 0020 C5 55 80 00 00 00 00   堉U€   臮€   
00000610   AC BA 54 80 00 00 00 001C 3F 55 80 00 00 00 00   T€   ?U€   
00000620   F8 3F 55 80 00 00 00 0040 49 55 80 00 00 00 00   ?U€    @IU€   
00000630   C0 28 FF FF 00 04 00 0010 00 03 00 CC 5D C2 0C   ?      蘛?
00000640   00 CC CC CC CC CC 8B FF55 8B EC FF 08 00 23 00    烫烫虌U嬱#
00000650   23 00 30 00 82 00 00 0000 00 00 00 00 00 00 00   # 0 ?         
00000660   5C 57 49 4E 44 4F 57 535C 73 79 73 74 65 6D 33   \WINDOWS\system3
00000670   32 5C 6E 74 6B 72 6E 6C70 61 2E 65 78 65 00 33   2\ntkrnlpa.exe 3
00000680   32 5C 6E 74 6B 72 6E 6C70 61 2E 65 78 65 00 00   2\ntkrnlpa.exe       
00000690   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000006A0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000006B0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000006C0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000006D0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000006E0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000006F0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000700   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000710   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000720   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000730   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000740   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000750   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000760   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000770   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000780   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000790   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000007A0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000007B0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000007C0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000007D0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000007E0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
000007F0   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00   
               
00000800   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000810   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00000820   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                           有效数据结束,然而没有遇到0xAA,所以一直等待
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
00002E60   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 AA                  ?        结束符0xAA
00002E70   69 69 69 69 04 00 00 0000 00 80 80 00 00 00 00   iiii      €€            发送上次接收信息的确认包
00002E80   30 30 30 30 02 00 38 0000 00 80 80 74 0E 00 00   00008   €€t           发送读取内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x38
00002E90   30 31 00 00 00 00 00 0048 F7 7D 07 A0 74 C1 77   01      H鱹 爐羨        包开始
00002EA0   5C 8C 4D 80 FF FF FF FF05 01 00 00 34 11 BC 77   \孧€    4        读取0x804D8C5C处0x105大小的数据
00002EB0   0D 01 00 00 18 01 00 0020 03 E1 00 24 EB 7D 07             ?$雧
00002EC0   05 04 00 00 0D 01 00 00AA 00 00 00 00 00 00 00         ?      
00002ED0   69 69 69 69 04 00 00 0000 00 80 80 00 00 00 00   iiii      €€            接收到服务器收到信息的确认包
00002EE0   30 30 30 30 02 00 3D 0101 00 80 80 A9 75 00 00   0000=   €€﹗        接收内存控制信息包 DbgKdReadVirutalMemoryApi,长度0x13D
00002EF0   30 31 00 00 00 00 00 0000 00 00 00 A0 74 C1 77   01          爐羨        包开始
00002F00   5C 8C 4D 80 FF FF FF FF05 01 00 00 05 01 00 00   \孧€      
00002F10   0D 01 00 00 18 01 00 0020 03 E1 00 24 EB 7D 07             ?$雧
00002F20   05 04 00 00 0D 01 00 0032 36 30 30 2E 78 70 73         2600.xps
00002F30   70 2E 30 38 30 34 31 332D 32 31 31 31 00 00 00   p.080413-2111   
00002F40   00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00                  
00002F50   28 73 2A C1 1F F8 D2 11BA 4B 00 A0 C9 3E C9 3B   (s*? 篕 犐>?
00002F60   16 E3 C9 E3 5C 0B B8 4D81 7D F9 2D F0 02 15 AE    闵鉢 窶 }?? ?
00002F70   A2 A0 D0 EB E5 B9 33 4487 C0 68 B6 B7 26 99 C7   须骞3D嚴h斗&櫱
00002F80   AA C8 08 58 8F 7E E0 4285 D2 E1 E9 04 34 CF B3    X ~郆呉衢 4铣
00002F90   A0 60 9B AF 31 14 62 0078 A7 55 80 00 00 00 00   燻洴1 b x€   
00002FA0   70 A7 55 80 00 00 00 0090 B1 54 80 00 00 00 00   p€   盩€   
00002FB0   68 97 55 80 00 00 00 0080 97 55 80 00 00 00 00   h桿€    €桿€   
00002FC0   68 99 55 80 00 00 00 00E8 4B 55 80 00 00 00 00   h橴€    鐺U€   
00002FD0   E0 4B 55 80 00 00 00 0078 4F 55 80 00 00 00 00   郖U€    xOU€   
00002FE0   00 95 55 80 00 00 00 00BC B0 54 80 00 00 00 00    昒€    及T€   
00002FF0   C4 99 55 80 00 00 00 00C8 99 55 80 00 00 00 00   臋U€    葯U€   

00003000   EC 97 55 80 00 00 00 0020 99 55 80 00 00 00 00   鞐U€   橴€   
00003010   38 4C 55 80 00 00 00 0078 B5 54 80 00 00 00 00   8LU€    x礣€   
00003020   7C B5 54 80 00 00 00 0034 4C 55 80 00 4F BC 68   |礣€    4LU€ O糷
00003030   33 11 71 4A 69 AD C1 1FDD 6B 00 00 00            3 qJi 輐                   包结束,然而等待0xAA标志
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
000034C0   00 2B AA 00 00 00 00 0000 00 00 00 00 00 00 00    +?                    0xAA标志
000034D0   69 69 69 69 04 00 00 0001 00 80 80 00 00 00 00   iiii      €€   
000034E0   30 30 30 30 02 00 38 0001 00 80 80 67 11 00 00   00008   €€g   
000034F0   30 31 00 00 58 A9 B1 5244 F4 7D 07 A0 74 C1 77   01X┍RD魙 爐羨

Golden Blonde 发表于 2015-7-20 08:36:08

非常佩服你的逆向能力。BAIDU给你那点钱真是低估你了。我觉得你在内核方面多修炼一年可以直接提出2X的工资。

元始天尊 发表于 2015-8-2 16:53:54

此代码不稳定,可以测得写入数据,读取数据应该是采用了异步方式因此数据不正确

// WinDbgSpyDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "WinDbgSpy.h"
#include "WinDbgSpyDlg.h"
#include "afxdialogex.h"

#include <tlhelp32.h>
#include <shlwapi.h>
#include <windows.h>
#pragma comment(lib,"shlwapi.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
        CAboutDlg();

// 对话框数据
        enum { IDD = IDD_ABOUTBOX };

        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
        DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CWinDbgSpyDlg 对话框




CWinDbgSpyDlg::CWinDbgSpyDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(CWinDbgSpyDlg::IDD, pParent)
        , m_content(_T(""))
{
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CWinDbgSpyDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialogEx::DoDataExchange(pDX);
        DDX_Text(pDX, IDC_CONTENT, m_content);
        DDX_Control(pDX, IDC_MSGLIST, m_msglist);
}

BEGIN_MESSAGE_MAP(CWinDbgSpyDlg, CDialogEx)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_WM_TIMER()
        ON_LBN_SELCHANGE(IDC_MSGLIST, &CWinDbgSpyDlg::OnLbnSelchangeMsglist)
END_MESSAGE_MAP()

// CWinDbgSpyDlg 消息处理程序



void CWinDbgSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
                CAboutDlg dlgAbout;
                dlgAbout.DoModal();
        }
        else
        {
                CDialogEx::OnSysCommand(nID, lParam);
        }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//这将由框架自动完成。

void CWinDbgSpyDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // 用于绘制的设备上下文

                SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

                // 使图标在工作区矩形中居中
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;

                // 绘制图标
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CDialogEx::OnPaint();
        }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CWinDbgSpyDlg::OnQueryDragIcon()
{
        return static_cast<HCURSOR>(m_hIcon);
}

char apiname[]=
{
        "DbgKdReadVirtualMemoryApi          ",
        "DbgKdWriteVirtualMemoryApi         ",
        "DbgKdGetContextApi               ",
        "DbgKdSetContextApi               ",
        "DbgKdWriteBreakPointApi            ",
        "DbgKdRestoreBreakPointApi          ",
        "DbgKdContinueApi                   ",
        "DbgKdReadControlSpaceApi         ",
        "DbgKdWriteControlSpaceApi          ",
        "DbgKdReadIoSpaceApi                ",
        "DbgKdWriteIoSpaceApi               ",
        "DbgKdRebootApi                     ",
        "DbgKdContinueApi2                  ",
        "DbgKdReadPhysicalMemoryApi         ",
        "DbgKdWritePhysicalMemoryApi      ",
        "DbgKdQuerySpecialCallsApi          ",
        "DbgKdSetSpecialCallApi             ",
        "DbgKdClearSpecialCallsApi          ",
        "DbgKdSetInternalBreakPointApi      ",
        "DbgKdGetInternalBreakPointApi      ",
        "DbgKdReadIoSpaceExtendedApi      ",
        "DbgKdWriteIoSpaceExtendedApi       ",
        "DbgKdGetVersionApi               ",
        "DbgKdWriteBreakPointExApi          ",
        "DbgKdRestoreBreakPointExApi      ",
        "DbgKdCauseBugCheckApi            ",
        "DbgKdSwitchProcessor               ",
        "DbgKdPageInApi                     ",
        "DbgKdReadMachineSpecificRegister   ",
        "DbgKdWriteMachineSpecificRegister",
        "OldVlm1                            ",
        "OldVlm2                            ",
        "DbgKdSearchMemoryApi               ",
        "DbgKdGetBusDataApi               ",
        "DbgKdSetBusDataApi               ",
        "DbgKdCheckLowMemoryApi             ",
        "DbgKdClearAllInternalBreakpointsApi",
        "DbgKdFillMemoryApi               ",
        "DbgKdQueryMemoryApi                ",
        "DbgKdSwitchPartition               ",
};


BOOL CWinDbgSpyDlg::OnInitDialog()
{
        CDialogEx::OnInitDialog();

        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);

        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
                BOOL bNameValid;
                CString strAboutMenu;
                bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
                ASSERT(bNameValid);
                if (!strAboutMenu.IsEmpty())
                {
                        pSysMenu->AppendMenu(MF_SEPARATOR);
                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                }
        }

        SetIcon(m_hIcon, TRUE);                        // 设置大图标
        SetIcon(m_hIcon, FALSE);                // 设置小图标

        InitOk = FALSE;
        SetTimer(0,100,NULL);
        int MapSize=0x1000000;
        do
        {
                hMapRead = CreateFileMappingA(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,MapSize,"WDBGMAPREAD");
                if(hMapRead == NULL)
                        break;
                lpBufRead = MapViewOfFile(hMapRead,FILE_MAP_READ|FILE_MAP_WRITE,0,0,MapSize);//预留16M容量满则清理
                if(lpBufRead == NULL)
                        break;
                hMapWrite = CreateFileMappingA(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,MapSize,"WDBGMAPWRITE");
                if(hMapWrite == NULL)
                        break;
                lpBufWrite = MapViewOfFile(hMapWrite,FILE_MAP_READ|FILE_MAP_WRITE,0,0,MapSize);//预留16M容量满则清理
                if(lpBufWrite == NULL)
                        break;
                hEvent = CreateEventA(NULL,FALSE,TRUE,"WDBGEVENT");
                memset(lpBufRead,0,MapSize);memset(lpBufWrite,0,MapSize);
                MAPOBJ* Ptr = (MAPOBJ*)lpBufRead;
                Ptr->ReadOffset = sizeof(MAPOBJ);
                Ptr->WriteOffset = sizeof(MAPOBJ);
                Ptr->MaxOffset = MapSize;
                Ptr = (MAPOBJ*)lpBufWrite;
                Ptr->ReadOffset = sizeof(MAPOBJ);
                Ptr->WriteOffset = sizeof(MAPOBJ);
                Ptr->MaxOffset = MapSize;
                InitOk = TRUE;

                //注入
                PROCESSENTRY32 pe32;
                HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                if(hProcessSnap != INVALID_HANDLE_VALUE)
                {
                        pe32.dwSize = sizeof(pe32);
                        if(Process32First(hProcessSnap,&pe32))
                        {
                                do
                                {
                                        if(StrStrIA(pe32.szExeFile,"windbg.exe"))
                                        {
                                                char str[]="e:\\Projects\\WinDbgSpy\\Debug\\WinDbgMon.dll";
                                                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
                                                LPVOID dllname = VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT, PAGE_READWRITE);
                                                WriteProcessMemory(hProcess, dllname, str, sizeof(str), NULL);
                                                HANDLE hthread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, dllname, 0, NULL);
                                                WaitForSingleObject(hthread, INFINITE);
                                                CloseHandle(hthread);
                                                CloseHandle(hProcess);
                                        }
                                } while (Process32Next(hProcessSnap,&pe32));
                        }
                        CloseHandle(hProcessSnap);
                }
        } while (0);

        return TRUE;// 除非将焦点设置到控件,否则返回 TRUE
}

BOOL CWinDbgSpyDlg::DestroyWindow()
{
        if(lpBufRead)
                UnmapViewOfFile(lpBufRead);
        if(lpBufWrite)
                UnmapViewOfFile(lpBufWrite);
        if(hMapRead)
                CloseHandle(hMapRead);
        if(hMapWrite)
                CloseHandle(hMapWrite);
        KillTimer(0);
        return CDialogEx::DestroyWindow();
}

void CWinDbgSpyDlg::OnTimer(UINT_PTR nIDEvent)
{
        if(!InitOk)
                return;
        if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent,100))
        {
                MAPOBJ* mapobj1 = (MAPOBJ*)lpBufRead;
                MAPOBJ* mapobj2 = (MAPOBJ*)lpBufWrite;
                volatile int end1 = mapobj1->WriteOffset;
                volatile int end2 = mapobj2->WriteOffset;
                if(mapobj1->ReadOffset + sizeof(KD_PACKET) < end1)
                {
                        FlushViewOfFile((BYTE*)mapobj1+mapobj1->ReadOffset,mapobj1->WriteOffset - mapobj1->ReadOffset);
                        int origin = mapobj1->ReadOffset;
                        if(!ProcessPacket(mapobj1, true, end1))
                                mapobj1->ReadOffset = origin;
                }
                if(mapobj2->ReadOffset + sizeof(KD_PACKET) < end2)
                {
                        int origin = mapobj2->ReadOffset;
                        if(!ProcessPacket(mapobj2, false, end2))
                                mapobj2->ReadOffset = origin;
                }
                SetEvent(hEvent);
        }


        CDialogEx::OnTimer(nIDEvent);
}

bool CWinDbgSpyDlg::ProcessPacket(MAPOBJ* mapobj, bool isreceive, int end)
{
        int curbyte=GetByte(mapobj);//尝试读取一个字节,同步导引包
        switch(curbyte)
        {
        case BREAKIN_PACKET_BYTE:
                return TryReceiveBreakInPacket(mapobj, isreceive);
                break;
        case PACKET_LEADER_BYTE:
                return TryReceiveInfoPacket(mapobj, isreceive);//尝试读取信息包
                break;
        case CONTROL_PACKET_LEADER_BYTE:
                return TryReceiveControlPacket(mapobj, isreceive);//尝试读取控制包
                break;
        default:
                {
                        while(mapobj->ReadOffset + sizeof(KD_PACKET) < end)
                        {
                                mapobj->ReadOffset++;
                                int curbyte = *((BYTE*)mapobj+mapobj->ReadOffset);
                                if(curbyte == BREAKIN_PACKET_BYTE || curbyte == PACKET_LEADER_BYTE || curbyte == CONTROL_PACKET_LEADER_BYTE)
                                {
                                        BYTE* begin = (BYTE*)mapobj+mapobj->ReadOffset;
                                        if(begin == begin && begin == begin)
                                                return true;
                                }
                        }
                        break;
                }
        }
        return false;
}

int CWinDbgSpyDlg::GetByte(MAPOBJ* mapobj)
{
        int curbyte = *((BYTE*)mapobj+mapobj->ReadOffset);
        mapobj->ReadOffset++;
        return curbyte;
}

bool CWinDbgSpyDlg::TryReceiveBreakInPacket(MAPOBJ* mapobj, bool isreceive)
{
        int count=0;
        while(count < 3)//之前GetByte已经经过一个leader byte
        {
                if(*((BYTE*)mapobj+mapobj->ReadOffset) != PACKET_LEADER_BYTE)
                        break;
                mapobj->ReadOffset++;
                count++;
        }
        if(count < 2)//无法同步,匹配下一个握手信号
                return true;
        if(isreceive)
                m_msglist.AddString("<=中断包");
        else
                m_msglist.AddString(">=中断包");
}

bool CWinDbgSpyDlg::TryReceiveInfoPacket(MAPOBJ* mapobj, bool isreceive)
{
        char buf;
        int count=0;
        while(true)//之前GetByte已经经过一个leader byte
        {
                if(*((BYTE*)mapobj+mapobj->ReadOffset) != PACKET_LEADER_BYTE)
                        break;
                mapobj->ReadOffset++;
                count++;
        }
        if(count < 2)//无法同步,匹配下一个握手信号
                return true;

        KD_PACKET* curpack = (KD_PACKET*)((BYTE*)mapobj+mapobj->ReadOffset - (int)&((KD_PACKET*)0)->PacketType);
        curpack->PacketLeader=PACKET_LEADER;
        KD_PACKET curpackr;
        memcpy(&curpackr,curpack,sizeof(curpackr));
        curpackr.PacketLeader = CONTROL_PACKET_LEADER;//重建头部
        mapobj->ReadOffset += sizeof(KD_PACKET) - (int)&((KD_PACKET*)0)->PacketType;
        if(mapobj->ReadOffset > mapobj->WriteOffset)
                return false;
        if(isreceive)
                strcpy(buf,"<=I-");
        else
                strcpy(buf,">=I-");
        switch(curpackr.PacketType)
        {
        case PACKET_TYPE_KD_STATE_CHANGE32://KD_PACKET后跟DBGKD_WAIT_STATE_CHANGE32
        case PACKET_TYPE_KD_STATE_CHANGE64:
                {//本该由第一次接收版本号决定所使用的结构体
                        DBGKD_WAIT_STATE_CHANGE32* info = (DBGKD_WAIT_STATE_CHANGE32*)((BYTE*)mapobj+mapobj->ReadOffset);
                        strcat(buf,"statechange32 ");
                        switch(info->NewState)
                        {
                        case DbgKdExceptionStateChange:
                                strcat(buf,"exc ");
                                break;
                        case DbgKdLoadSymbolsStateChange:
                                strcat(buf,"sym ");
                                break;
                        case DbgKdCommandStringStateChange:
                                strcat(buf,"str ");
                                break;
                        default:
                                sprintf(buf,"%s%d ",buf,info->NewState);
                                break;
                        }
                }
                break;
        case PACKET_TYPE_KD_STATE_MANIPULATE://KD_PACKET后跟DBGKD_MANIPULATE_STATE
                {
                        DBGKD_MANIPULATE_STATE32* info = (DBGKD_MANIPULATE_STATE32*)((BYTE*)mapobj+mapobj->ReadOffset);
                        strcat(buf,"api ");
                        int index=info->ApiNumber-DbgKdMin;
                        if(index>=0 && index<=45)
                                strcat(buf,apiname);
                        else
                                sprintf(buf,"%s%d",buf,index);
                }
                break;
        case PACKET_TYPE_KD_DEBUG_IO:
                {
                        strcat(buf,"debugio ");
                }
                break;
        case PACKET_TYPE_KD_POLL_BREAKIN:
                {
                        strcat(buf,"breakin ");
                }
                break;
        case PACKET_TYPE_KD_TRACE_IO:
                {
                        strcat(buf,"traceio ");
                }
                break;
        case PACKET_TYPE_KD_CONTROL_REQUEST:
                {
                        strcat(buf,"ctrlreq");
                }
                break;
        case PACKET_TYPE_KD_FILE_IO:
                {
                        strcat(buf,"fileio");
                }
                break;
        default:
                sprintf(buf,"%s%d",buf,curpackr.PacketType);
        }

        vector<BYTE> newdata;
        newdata.insert(newdata.end(),(BYTE*)&curpackr,(BYTE*)(&curpackr+1));
        newdata.insert(newdata.end(),(BYTE*)mapobj+mapobj->ReadOffset,(BYTE*)mapobj+mapobj->ReadOffset+curpackr.ByteCount);

        mapobj->ReadOffset += curpackr.ByteCount;
        if(mapobj->ReadOffset > mapobj->WriteOffset)
                return false;
        //等待0xAA
        bool waitsuccess = false;
        while(true)//终止条件待处理
        {
                if(*((BYTE*)mapobj+mapobj->ReadOffset) == 0xAA)
                {
                        waitsuccess = true;
                        break;
                }
                mapobj->ReadOffset++;
                if(mapobj->ReadOffset > mapobj->WriteOffset-1)
                        break;
        }
        mapobj->ReadOffset++;
        if(waitsuccess)
        {
                int index = dataarray.size();
                dataarray.push_back(newdata);
                int index2 = m_msglist.AddString(buf);
                m_msglist.SetItemData(index2,index);
                packetread.push_back(curpackr);
        }
        return waitsuccess;
}

bool CWinDbgSpyDlg::TryReceiveControlPacket(MAPOBJ* mapobj, bool isreceive)
{
        char buf;
        int count=0;
        while(true)//之前GetByte已经经过一个leader byte
        {
                if(*((BYTE*)mapobj+mapobj->ReadOffset) != CONTROL_PACKET_LEADER_BYTE)
                        break;
                mapobj->ReadOffset++;
                count++;
        }
        if(count < 2)//无法同步,匹配下一个握手信号
                return true;

        KD_PACKET* curpack = (KD_PACKET*)((BYTE*)mapobj+mapobj->ReadOffset - (int)&((KD_PACKET*)0)->PacketType);
        KD_PACKET curpackr;
        memcpy(&curpackr,curpack,sizeof(curpackr));
        curpackr.PacketLeader = CONTROL_PACKET_LEADER;//重建头部
        mapobj->ReadOffset += sizeof(KD_PACKET) - (int)&((KD_PACKET*)0)->PacketType;
        if(mapobj->ReadOffset > mapobj->WriteOffset)
                return false;
        if(isreceive)
                strcpy(buf,"<=C-");
        else
                strcpy(buf,">=C-");
        switch(curpackr.PacketType)
        {
        case PACKET_TYPE_KD_ACKNOWLEDGE:
                strcat(buf,"acknowledge");
                break;
        case PACKET_TYPE_KD_RESEND:
                strcat(buf,"resend");
                break;
        case PACKET_TYPE_KD_RESET:
                strcat(buf,"reset");
                break;
        default:
                sprintf(buf,"%s%d",buf,curpackr.PacketType);
                break;
        }
        vector<BYTE> newdata;
        newdata.insert(newdata.end(),(BYTE*)&curpackr,(BYTE*)(&curpackr+1));
        int index = dataarray.size();
        dataarray.push_back(newdata);
        int index2 = m_msglist.AddString(buf);
        m_msglist.SetItemData(index2,index);
        packetwrite.push_back(curpackr);
        return true;
}

void CWinDbgSpyDlg::OnLbnSelchangeMsglist()
{
        int cursel=m_msglist.GetCurSel();
        if(cursel>=0)
        {
                int index = m_msglist.GetItemData(cursel);
                vector<BYTE>& data = dataarray;
                char buf;
                UpdateData(TRUE);
                m_content="";
                for(int i=0;i<data.size();i++)
                {
                        sprintf(buf,"%02X ",data);
                        m_content += buf;
                        if((i%16)==15)
                        {
                                m_content += "\r\n";
                        }
                }
                UpdateData(FALSE);
        }
}


// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "detours.h"
#include "common.h"
#include <Shlwapi.h>
#include <stdio.h>
#pragma comment(lib,"detours.lib")
#pragma comment(lib,"shlwapi.lib")

HANDLE hMapRead;
HANDLE hMapWrite;
LPVOID lpBufRead;
LPVOID lpBufWrite;
CRITICAL_SECTION lock;
BOOL InitOk;
HANDLE hEvent;
HANDLE currentpipe=INVALID_HANDLE_VALUE;

HANDLE WINAPI NEW_CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
BOOL WINAPI NEW_ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);
BOOL WINAPI NEW_WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);

#define G(X) GetProcAddress(GetModuleHandleW(L"kernel32.dll"),X)

#define HookMax 3
FARPROC OLD_FUNCS =
{
        G("CreateFileW"),
        G("ReadFile"),
        G("WriteFile"),
};

FARPROC NEW_FUNCS =
{
        (FARPROC)NEW_CreateFileW,
        (FARPROC)NEW_ReadFile,
        (FARPROC)NEW_WriteFile,
};

enum
{
        ECreateFileW,
        EReadFile,
        EWriteFile,
};

void __cdecl Hook()
{
        DetourRestoreAfterWith();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        for (int i = 0; i < HookMax; i++)
        {
                DetourAttach(&(PVOID&)OLD_FUNCS, NEW_FUNCS);
        }
        DetourTransactionCommit();
}

void __cdecl UnHook()
{
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        for (int i = 0; i < HookMax; i++)
        {
                DetourDetach(&(PVOID&)OLD_FUNCS, NEW_FUNCS);
        }
        DetourTransactionCommit();
}

void Init()
{
        InitializeCriticalSection(&lock);
        int MapSize=0x1000000;
        hMapRead = OpenFileMappingA(FILE_MAP_READ|FILE_MAP_WRITE,FALSE,"WDBGMAPREAD");
        if(hMapRead == NULL)
                return;
        hMapWrite = OpenFileMappingA(FILE_MAP_READ|FILE_MAP_WRITE,FALSE,"WDBGMAPWRITE");
        if(hMapWrite == NULL)
                return;
        lpBufRead = MapViewOfFile(hMapRead,FILE_MAP_READ|FILE_MAP_WRITE,0,0,MapSize);//预留16M容量满则清理
        lpBufWrite = MapViewOfFile(hMapWrite,FILE_MAP_READ|FILE_MAP_WRITE,0,0,MapSize);//预留16M容量满则清理
        InitOk = TRUE;
        hEvent = OpenEventA(SYNCHRONIZE|EVENT_MODIFY_STATE,FALSE,"WDBGEVENT");
        Hook();
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORDul_reason_for_call, LPVOID lpReserved )
{
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
                Init();
                break;
        case DLL_THREAD_ATTACH:
                break;
        case DLL_THREAD_DETACH:
                break;
        case DLL_PROCESS_DETACH:
                UnHook();
                break;
        }
        return TRUE;
}

HANDLE WINAPI NEW_CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
{
        HANDLE hFile = ((HANDLE (WINAPI*)(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))OLD_FUNCS)
                (lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
        if(StrStrIW(lpFileName,L"pipe\\com_") && hFile != INVALID_HANDLE_VALUE)
        {
                currentpipe = hFile;
        }
        return hFile;
}

BOOL WINAPI NEW_ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
{
        BOOL ret = ((BOOL (WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED))OLD_FUNCS)(hFile,lpBuffer,nNumberOfBytesToRead,
                lpNumberOfBytesRead,lpOverlapped);
        if(ret && currentpipe == hFile)
        {
                if(InitOk && WAIT_OBJECT_0 == WaitForSingleObject(hEvent,INFINITE))
                {
                        MAPOBJ* mapobj = (MAPOBJ*)lpBufRead;
                        //memset((BYTE*)mapobj+mapobj->WriteOffset,0,*lpNumberOfBytesRead);
                        FlushViewOfFile((BYTE*)mapobj+mapobj->WriteOffset,*lpNumberOfBytesRead);
                        memcpy((BYTE*)mapobj+mapobj->WriteOffset,lpBuffer,*lpNumberOfBytesRead);
                        FlushViewOfFile((BYTE*)mapobj+mapobj->WriteOffset,*lpNumberOfBytesRead);
                        mapobj->WriteOffset += *lpNumberOfBytesRead;
                        SetEvent(hEvent);
                }
        }
        return ret;
}

BOOL WINAPI NEW_WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped)
{
        BOOL ret = ((BOOL (WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED))OLD_FUNCS)(hFile,lpBuffer,nNumberOfBytesToWrite,
                lpNumberOfBytesWritten,lpOverlapped);
        if(ret && currentpipe == hFile)
        {
                if(InitOk && WAIT_OBJECT_0 == WaitForSingleObject(hEvent,INFINITE))
                {
                        MAPOBJ* mapobj = (MAPOBJ*)lpBufWrite;
                        memset((BYTE*)mapobj+mapobj->WriteOffset,0,*lpNumberOfBytesWritten);
                        memcpy((BYTE*)mapobj+mapobj->WriteOffset,lpBuffer,*lpNumberOfBytesWritten);
                        mapobj->WriteOffset += *lpNumberOfBytesWritten;
                        SetEvent(hEvent);
                }
        }
        return ret;
}

页: [1]
查看完整版本: 监听windbg内核调试通信数据