admin 管理员组

文章数量: 887021

用windbg双机调试的话,因为是命令行类似于以编程来代替手工跟踪的方式。习惯了用OD+ida分析的,肯定会不适应,于是就有ida的调试方式可以代替它,我使用的是ida 5.5,可能有一些区别,希望碰到问题的朋友能够一起解决,交流才能进步。

把配置文件配置好的话,会轻松很多。
第一个问题,IDA的windbg插件不读取pdb.cfg里的pdb目录设置,而是固执的放到temp目录去,很让人生气、不过windbg.plw中会判断系统环境变量_NT_SYMBOL_PATH,存在的话,就会照此设置来了。如果以前没用过_NT_SYMBOL_PATH这个环境变量,可以用set创建成系统级别的环境变量:
Set _NT_SYMBOL_PATH = symsrv*symsrv.dll*f:\localsymbols*http://msdl.microsoft/download/symbols
不过我建议不要用在线的symbols,毕竟挂上去然后等几分钟,接着因为不匹配的pdb .sym noisy, .reload /f一番挺多余的。可以下载一个确定是配套版本的symbols到本地来,再给解压出来的symbols目录里添个flat.txt (achooollllls大侠对symbols里的flat.txt和pingme.txt等写过一个很精彩的说明),这样一个Set就完全让符号问题解决了。用注册表方式设置系统环境变量,不然_NT_SYMBOL_PATH存在时set只会设置目标命令行进程树里的环境变量。

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v _NT_SYMBOL_PATH /d "D:\xpoy\tools\调试器\win symbol\symbol xp sp3" /f

在模块基地址0x19C1000,windbg.plw中的代码位置是:
.text:019D0892                 call    sub_19C2468 ;//读取环境变量_NT_SYMBOL_PATH
.text:019D0897                 test    al, al
.text:019D0899                 jnz     short loc_19D08BB//
.text:019D089B                 push    400h
.text:019D08A0                 lea     edx, [ebp+var_400]
.text:019D08A6                 push    edx
.text:019D08A7                 call    sub_19C249C//没的话得到temp目录。
.text:019D08AC                 push    0
.text:019D08AE                 lea     ecx, [ebp+var_400]
.text:019D08B4                 push    ecx
.text:019D08B5                 push    ebx
.text:019D08B6                 call    sub_19D08C8

接着在ida的配置文件中,ida.cfg中配置调试器的目录
//      Processor specific parameters
之后可以设置dbgeng.dll windbg调试插件使用到的DLL的目录,
格式类似于
DBGTOOLS = "D:\\xpoy\\tools\\调试器\\X86 win32 windbger\\";
然后还可以到dbg_windbg.cfg中,把kernel-mode直接选上
KERNELMODE = YES
这样attack时候直接下一步就可以了。

要是觉得debug->attack中的没用项目太多的话,可以到plugin\plugin.cfg中把不用的都注释掉,前面加";"
只留一个
Windbg_debugger             windbg_user 0       0  DEBUG
便好了。

attack的命令行的话,就是给windbg的命令行参数。先一路配置好windbg可以远程调试了,然后windbg->view->windbg command line就弹出来所使用的完整命令行了,MessageBox弹出的对话框是可以直接ctrl+C复制里面的内容出来的。
比如我的:

com:pipe,resets=0,reconnect,port=\\.\pipe\kd_xp_sp3_深度_unknow

然后提一些IDA调试时的小经验,其实我只是用了一会儿,就兴冲冲来发帖了,有错误的话,见谅,也请大牛能指正下。 :P
执行起来时,要强制中断执行的话,需要按弹出来窗口的那个大大的suspend。
Ctrl+ALt+S打开的strack trace windows很有用,用windbg就一定会喜欢它的堆栈显示方式,Ida 的这个也可以显示类似的格式。
在最下方有一小行windbg的命令行显示,这个命令行不支持"!"开头的由ext等插件提供的功能,但原windbg的命令行, "."开头的命令行都支持,非常方便。但是普通命令不能用"g"/"t"/"p"等会让被调试对象执行起来的命令,必须用IDA的 F7、F8、F4等,这几个和OD中的意义一样,另外,用windbg的断点命令设置的断点,ida也不能检测到而不会在它自己的断点列表中显示,虽然这些也可以工作。比方我要查看当前调试目标user进程的模块,就可以很正常的这样来lm u,和windbg中的command line效果一样。最大的缺陷就是,ida不能用扩充命令后,在内核方式调试单个目标进程挺麻烦,!process等导出的函数模块不能用了。要解决此问题,需要手动用.load载入对应的ext们:
.load D:\xpoy\tools\调试器\X86 win32 windbger\winext\ext.dll;
...

.load D:\xpoy\tools\调试器\X86 win32 windbger\winxp\acpikd.dll;
...
我为了自己方便用,写了一个很简陋的脚本,也一并放上来,实在是找不到idc怎么查找一个目录里面的所有文件.改成读取配置文件其实也很方便。
原版的这个脚本里,我只是固定的写着WinSendCommand自己机器上面windbg目录的那些ext文件,同时#softinclude在了idc\userload.idc里面,这样每次打开ida都会试着执行下。
windbg的sx?选项在debug option->edit exception中可以做类似的设置。也可以提前在cfg\exceptions.cfg中更改,但是没windbg那么方便。
ida的trace比od的还强大,在定位目标的时候很牛, 比方write trace, read trace用来定位全操作目标内存范围的代码们。 :)!!!!!
另外ida还可以用来调试其他平台(arm、iphone)等

用ida在逆向时跟踪内核实在是太爽了,至少在没源代码和调试非windows内核模块(需要双机调试的用户模块)的时候比windbg的插件们好用多了。

另外,如果重启被调试机时,没有在开机时候挂一个调试器上去过,在系统运行途中需要先运行vmkdmon,然后再运行调试器以挂上去。

用了几天发现,虽然IDA的命令行窗口只能按照行来选,不过反汇编和点来点去跟踪函数流程实在是超爽。而命令行窗口的问题,可以通过.logopen 这个命令,把windbg的命令行输出到一个log文件,这样把log文件拖到记事本打开,然后ida里还可以非常舒服的看汇编,

IDA6.1很奇怪的在查找dbgeng.dll的时候,不会按照cfg中设置的windbg目录去查找,而是直觉在ida的目录,再到windows目录查找下,似乎是因为环境变量的问题。但我把dbgeng.dll复制到ida6.1目录下也可以解决问题。感谢落幕CC公开的6.1。

 

附ida原作者宣传这个功能的视频:

http://hex-rays/video/windbg_video_1.htm

 

附2,脚本

 

#include <idc.idc>

static SendLoadSpecExtWithPath (Path, Ext)
{
     auto CurrentExtPath, EvalStr;
     CurrentExtPath= ".load "+ Path+  Ext;
     Message ( CurrentExtPath+ "\r\n");
     WinDbgCommand (CurrentExtPath) ;
}
 
static strrchr (In_str, In_chr)
{
    auto Len_str, temp_chr;
    Len_str= strlen (In_str);
    while (0<Len_str)
    {
        temp_chr= substr(In_str, Len_str, Len_str+ 1);
        if (temp_chr==In_chr)
        {
            break;
        }
        Len_str= Len_str- 1;
    }

    return Len_str;
}

static main ()
{
    auto ExtPath;
    ExtPath= AskFile ( 0, "ext.dll", "选择你的windbg目录的winext\\ext.dll");
    ExtPath= substr ( ExtPath, 0, strrchr (ExtPath, "\\")+ 1);
   
    if (""!=strlen(ExtPath))
    {
        SendLoadSpecExtWithPath ( ExtPath, "kext.dll");
        SendLoadSpecExtWithPath ( ExtPath, "logexts.dll");
        SendLoadSpecExtWithPath ( ExtPath, "uext.dll");
        SendLoadSpecExtWithPath ( ExtPath, "wdfkd.dll");
        SendLoadSpecExtWithPath ( ExtPath, "ext.dll");
    }

    ExtPath= AskFile ( 0, "ext.dll", "选择你的windbg目录的winxp\\exts.dll");
    ExtPath= substr ( ExtPath, 0, strrchr (ExtPath, "\\")+ 1);
    if (""!=strlen(ExtPath))
    {
        SendLoadSpecExtWithPath (ExtPath,"acpikd.dll");
        SendLoadSpecExtWithPath (ExtPath,"exts.dll");
        SendLoadSpecExtWithPath (ExtPath,"fltkd.dll");
        SendLoadSpecExtWithPath (ExtPath,"kdexts.dll");
        SendLoadSpecExtWithPath (ExtPath,"ks.dll");
        SendLoadSpecExtWithPath (ExtPath,"minipkd.dll");
        SendLoadSpecExtWithPath (ExtPath,"ndiskd.dll");
        SendLoadSpecExtWithPath (ExtPath,"ntsdexts.dll");
        SendLoadSpecExtWithPath (ExtPath,"rpcexts.dll");
        SendLoadSpecExtWithPath (ExtPath,"scsikd.dll");
        SendLoadSpecExtWithPath (ExtPath,"traceprt.dll");
        SendLoadSpecExtWithPath (ExtPath,"vdmexts.dll");
        SendLoadSpecExtWithPath (ExtPath,"wmitrace.dll");
        SendLoadSpecExtWithPath (ExtPath,"wow64exts.dll");
        SendLoadSpecExtWithPath (ExtPath,"Wudfext.dll");
    }
}

本文标签: 双机 内核 IDA winDbg