先祝福大家端午节快乐

Windbg 的工作实质是连接windows的内核调试,windows已经把内核调试的机制集成进了内核,只需要连接windows的内核调试接口,完全不需要想softice一样挂接很多中断处理过程就能实现内核调试,
关于这个的详细介绍请参考 Windows内核调试器原理浅析
http://www.xfocus.net/articles/200412/765.html

曾经听说过themida大牛说.windbg不过是一个demo,完全能够自己写出更好的,偶不是大牛,不可能写出好东西,只能先努力做个仿制品,.,还没有能力做复制品,更不用谈超越了

windbg的内核调试部分主要功能封装在dbgeng.dll之中
通过debugcreate创建一个clsid的com+接口来实现调试控制
我们可以拿出ida分析windbg.exe
signed int __stdcall CreateUiInterfaces(int a2, PCWSTR RemoteOptions)
{
............

  ReleaseUiInterfaces();
  if ( a2 )
  {
    v3 = DebugConnectWide(RemoteOptions, &_GUID_27fe5639_8407_4f47_8364_ee118fb08ac8, &g_UiClientBase);

..............
  }
  else
  {
    v6 = DebugCreate(&_GUID_27fe5639_8407_4f47_8364_ee118fb08ac8, &g_UiClientBase);
 
如同所示,DebugConnectWide连接远程的调试模块

事实上,我们直接利用dbgeng.h+dbgeng.lib,已经可以完成windbg的所有功能了
dbgeng.h文件在C:\Program Files\Debugging Tools for Windows (x86)\sdk\inc
这个文件大小为521kb,包括了一切windbg所用的debugapi
安装windbg的时候一定要选择安装sdk,不然可能没有这个文件

// RemoteOptions specifies connection types and
// their parameters.  Supported strings are:
//    npipe:Server=<Machine>,Pipe=<Pipe name>
//    tcp:Server=<Machine>,Port=<IP port>
STDAPI
DebugConnect(
    __in PCSTR RemoteOptions,
    __in REFIID InterfaceId,
    __out PVOID* Interface
    );

STDAPI
DebugConnectWide(
    __in PCWSTR RemoteOptions,
    __in REFIID InterfaceId,
    __out PVOID* Interface
    );

STDAPI
DebugCreate(
    __in REFIID InterfaceId,
    __out PVOID* Interface
    );

    STDMETHOD(GetThreadContext)(
        THIS_
        __out_bcount(ContextSize) /* align_is(16) */ PVOID Context,
        __in ULONG ContextSize
        ) PURE;
    STDMETHOD(SetThreadContext)(
        THIS_
        __in_bcount(ContextSize) /* align_is(16) */ PVOID Context,
        __in ULONG ContextSize
        ) PURE;

如上api声明,我们可以直接使用这些api完成调试工作

虽然我们可以这样实现自己的debugger,但是还是有一些麻烦
有一个开源的PyDbgEng,
http://sourceforge.net/projects/pydbgeng/

从上面的站点里面可以获取很多资料
我们看看介绍
PyDbgEng is a Python Wrapper For Microsoft Debug Engine.
kernel mode debugging 
x86, x64 support 
Wrapper for DebugCreate() API which creates IDebugClient COM interface. 
Easy access to IDebugClient COM interface 
Easy access to all other DbgEng COM interfaces via IDebugClient.QueryInterface() 
Easy access to all DbgEng structs and enums. 
Receive DbgEng events. Currently supported: IDebugEventCallbacks, IDebugOutputCallbacks 

很好.完全封装了IDebugClient COM interface. 从而我们可以直接使用
py的代码有个好处就是可以用最快的速度写出测试程序

我们随便选取一段代码
event_handler = DbgEventHandler()
dbg = PyDbgEng.KernelAttacher(  connection_string = connection_string, \
                                set_initial_bp = True, \
                                event_callbacks_sink = event_handler, \
                                output_callbacks_sink = event_handler, \
                                symbols_path = "SRV*http://msdl.microsoft.com/download/symbols")
---------------------------
class DbgEventHandler(PyDbgEng.IDebugOutputCallbacksSink, PyDbgEng.IDebugEventCallbacksSink):

    def LoadModule(self, dbg, ImageFileHandle, BaseOffset, ModuleSize, ModuleName, ImageName, CheckSum, TimeDateStamp):
        sys.stdout.write("LoadModule: ImageName = \"%s\"\n" % ImageName)
        return PyDbgEng.DbgEng.DEBUG_STATUS_NO_CHANGE
----------------------------
KernelAttacher连接上,设置event,然后就可以直接处理事件了,是不是很方便呢

我们再来看一个r3debuger
event_handler = DbgEventHandler()
dbg = PyDbgEng.ProcessCreator(  command_line = filename, \
                                follow_forks = True, \
                                event_callbacks_sink = event_handler, \
                                output_callbacks_sink = event_handler, \
                                symbols_path = "SRV*http://msdl.microsoft.com/download/symbols")

def NtCreateThread_at_entry(dbg, args):
    sys.stdout.write("NtCreateThread() called with following call stack:\n")
    stack_frames = dbg.get_stack_trace(FRAMES_COUNT)
    for i in range(FRAMES_COUNT):
        eip = stack_frames[i].InstructionOffset
        if (eip == 0):
            break
        func_symbol = dbg.get_symbol(eip)
        sys.stdout.write("[%d] %s\n" % (i, func_symbol))
    sys.stdout.write("\n")

代码基本是类似的,ProcessCreator选出进程,然后进行各种工作

我们可以发现,利用PyDbgEng +dbgeng.dll能够让我们自己编写debugger
的工作变得异常容易,只需要完成eventhandle的事件处理,,而无需对于复杂的
处理机制进行任何更改就可以实现我们想要的功能了

文中提到的工具
1.windbg
   Install Debugging Tools for Windows 32-bit Version
http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
   Install Debugging Tools for Windows 64-bit Versions
http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx

2.PyDbgEng 
http://sourceforge.net/projects/pydbgeng/
http://bbs.pediy.com/showthread.php?t=41440
lin斑推荐的工具太强大了