windbg调试心得

来源:互联网 发布:文件服务器软件 编辑:程序博客网 时间:2024/05/18 00:01
题记:积点滴之水,纵难成沧海,亦能得一洼。

作者:A1Pass [www.hackav.com / a1pass.blog.163.com](转载请注明版权)

       有些朋友建议我多写一些心得与笔记,也好便于其他人学习进步,其实这些朋友高看我了,我的心得也是很有限的,简单的东西不成系统,复杂的东西一句两句的也说不清楚,抖出来有装X之嫌。我之所以最近几年少有技术文章发表,主要因为精力有限,且本身就在写书,由于做过的一些项目都过于复杂,因此很多东西也难得总结。

       我写文章的原则就是独到、有用,如果我想写一篇文章来阐述一个技术问题,那么势必要做到简单易懂、观点独到,否则重复别人做过的工作我认为意义不大。对于写技术文章而言,我比较欣赏国外的一些技术团队与国内的罗聪,他们的特点就是能非常认真的对待自己发表的作品,从排版、示例再到章节段落的组织,只需稍稍一看就能知道他们在认真对待自己的作品。

       而最近随着圈内各大论坛的逐渐落寞,各个领域的前辈或牛人们都已经鲜有新技术发表,这种风气从04年的入侵渗透领域开始,各个牛人们都开始蛰居地下,不消几年光景,一个个摇身一变都成了老板了。虽然他们利用技术成为了老板,虽然做老板并不需要技术,但是他们还是没能抽出些时间来公布一下他们的“存货”,那些东西随着时间的流逝,也就都烂到硬盘里了,甚是可惜。

       而我一人之力有限,为了生存亦难以独善其身,因此一些吃饭的东西也很难做到公布出来与大家众乐乐,但是我尝试从点滴做起,以求尽我所能记录并公布一些我的心得体会,也好使得朋友们能有个方向、有所启发。

       这个帖子我将置顶一年,然后归纳到《置顶导航》中,此贴子的内容我将常年更新,一般来讲每条心得不会超过200字,暂定分为“技术感悟”、“环境搭建”、“编程心得”、“调试心得”这几个类别,如果有什么不足还请各位朋友们指出,我会尽量完善。

【从 2012-12-21 到 2013-02-08 ,共收集了 15 个心得】

【技术感悟】(共计04个心得)
2012-12-21  x64位下汇编变化之一
1 所有指针都是64位(8字节);
2 常用寄存器由32位的eax、ebx等变成64位的rax、rbx;
3 新增了r8、r9 ~ r15这8个通用寄存器;
4 原先的eax,ax,al,ah仍然可以使用。


2012-12-22  x64位下汇编变化之二
       函数传递参数的方式发生变化,64位下将不再使用栈传递参数,而改用通用寄存器加内存地址的方式,其规则如下:
第1个参数:rcx
第2个参数:rdx
第3个参数:r8
第4个参数:r9
第5个参数:rdi+0x08
第6个参数:rdi+0x10
第7个参数:rdi+0x18
第8个参数:rdi+0x20
……
       因此在编写x64位下的程序时,函数的参数不超过4个将有利于程序的执行效率。


2012-12-25  x64位下远程注入的注意事项
       随着x64系统的不断普及,向x64进程注入代码也越来越成为我们不得不面对的一个问题,以下是A1Pass总结出的一些注意事项:
1. 不能将x32的代码注入到x64的进程中,反之亦然;
2. 不能将x32的DLL加载到x64的进程中,反之亦然;
3. 在目标进程做PE解析相关的操作时,要着重注意x64的PE结构与x32是不完全相同的;
4. 由于远程注入不可避免的会涉及到大量的指针操作,因此要时刻注意x64下的指针长度问题。


2013-01-01  建立ipc$时遇到带"号密码该如何处理
       比如密码为123"abc时,那么建立ipc$时应当使用如下格式的命令:

net use \\127.0.0.1 "123\"abc" /u:administrator

       也就是在“ " ”号前加转义符“ \ ”即可解决问题,这点与C语言有些类似。





【环境搭建】(共计05个心得)

2012-12-21  解决WinDBG符号(Symbol)加载不正常的情况
       我们都知道WinDBG在使用之前需要配置Symbol信息,这样你在查看系统结构时,会得到非常详尽的信息,我们一般情况下会这样配置。
1. 运行WinDBG后,按快捷键【Ctrl】+【S】调出符号信息配置对话框(或依次点击菜单栏上的“File”>“Symbol File Path...”);
2. 输入如下配置信息:C:\Symbols;SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols  ;
       至此我们已经完成了对WinDBG的符号配置问题,但是有时我们这样配置完成后由于某种原因并未生效,如果你遇到这样的问题,那么你或许可以试试如下方法。
1. 输入命令设置WinDBG符号;

kd>.sympath SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols

2. 用!sym noisy命令使得WinDBG在获得符号的时候取得更多的信息,然后使用!lmi命令让WinDBG查看Windows的ntoskrnl模块,最后然后使用.reload /f尝试获取ntoskrnl的符号。

kd>!sym noisy
kd>!lmi
kd>.reload /f
 [注意:以上的“kd>”是提示符,不要将其误当成命令中的一部分]
        现在,你可以尝试输入一下例如“dt _teb”等命令查看是否成功了。
        如果仍然不成功,你可以检查一下你是否安装了Symbol,如果安装了,则检查一下Symbol的版本是否正确(与当前操作系统版本比对),如果版本不正确,请卸载此Symbol,并重新安装正确版本的Symbol,或干脆不安装。


2012-12-23  解决Windows 7下编写驱动时DbgPrint / KDPrint不能打印的问题
       造成这个问题的原因主要是因为Windows 7为了避免不必要的系统开销而默认关闭了调试信息过滤,因此导致我们无法正常打印出调试字符串。开启的方法非常简单,我们只需要操作注册表就可以建立一个调试打印过滤器,将以下内容保存为*.reg文件后,双击执行后即可完成设置工作。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
"DEFAULT"=dword:0000000f



2012-12-24  在Windows Vista/7/8下关闭系统PAE功能
       计算机物理地址扩展(Physical Address Extension,PAE)技术最初是为了弥补32位地址在PC服务器应用上的不足而推出的,我们在执行一些试验的时候可能要求系统处于未开启PAE的状态,这样内存分页相对来说更简单、更可控,因此我们就需要通过以下两条CMD命令关闭系统的PAE功能,执行完以下两条命令后,重启系统即可完成操作。

BCDEdit /set PAE ForceDisable
BCDEdit /set NX  AlwaysOff



2012-12-26  解决WinDBG在Windows 7下不能使用Local kernel(调试本机内核)模式的问题
        由于Windows 7系统默认不允许进行本地内核调试,因此你需要执行以下步骤来开启它。
        (1)以管理员权限运行CMD,并输入“bcdedit -debug on”命令;
        (2)重启计算机;
        (3)以管理员权限运行WinDBG,执行本地内核调试。


2013-01-07  怎样使用VMware提供的Visual Studio远程调试插件
       如果我们安装VMware之前已经安装了Visual Studio,那么VMware就会为Visual Studio提供一个远程调试插件,并默认显示在工具栏中。总体来说,VMware提供的这个插件还是非常贴心的,现在的内存越来越大,我们为了使用大内存基本上都已经开始使用x64的系统了,这样在进行x86程序开发时就会有些不便,或者我们为了测试程序在不同系统下的兼容性等等,但是不管怎么说,你总会用到的,不是吗?
    总体而言,VMware提供的远程调试插件还是比较简单的,我们只需要注意以下几点即可:
    (1)在VMware在Visual Studio的插件设置中,不要忘记设置Shared Folders(共享目录)项;
    (2)虚拟机本身的Shared Folders(共享目录)也必须为启用状态;
    (3)作为被调试机的虚拟机用户名与用户密码一定要与宿主机的一样,且必须为管理员权限;
    (4)宿主机与虚拟机要保证在网上邻居中可以互相访问;
    (5)最好关闭虚拟机的系统防火墙,或配置相应的规则;
    (6)将本地安全策略中的“网络访问:本地帐户的共享和安全模型”修改为“经典 - 对本地用户进行身份验证,不改变其本来身份”。
    [:在“控制面板>管理工具>本地安全策略>本地策略>安全选项”中可以找到设置以上选项的地方]
    [:以上设置方法适用于VMware Workstation的6.0至8.0版本,理论上也适用于8.0以后的版本]
    做好以上这些后,你就可以进行畅快的双机调试了,那种感觉很爽,真的!





【编程心得】(共计04个心得 新!)

2012-12-21  C/C++ system函数用法
原型:

int system( const char *command );
int _wsystem( const wchar_t *command );
system函数可以调用一些DOS命令,比如“system("cls");”是清屏,“system("pause");”是暂停。


2012-12-23  善用#pragma comment以增加工程的编译兼容性
1. 包含某个库
#pragma comment(lib, "xxxxxx.lib")
2. 忽略某个库
#pragma comment(linker, "/NODEFAULTLIB:\"xxxxxx.lib\"")
3. 忽略某个错误
#pragma warning(disable: 9999) // 9999错误标号
更多资料请参见MSDN:http://msdn.microsoft.com/zh-cn/library/d9x1s805(v=vs.90).aspx


2012-12-27  Visual Studio中,用宏来区分平台类型(32位/64位)
       用于区分编译环境的宏有_M_AMD64/_M_X64/_WIN64/_IA64_/_AMD64_这几个,一般情况下使用_M_AMD64,示例如下:

#ifdef _M_AMD64
#pragma message ("This is Win64")
#else
#pragma message("This is Win32")
#endif

       更多相关信息请参见MSDN:http://msdn.microsoft.com/zh-cn/library/b0084kay(v=vs.90).aspx


2013-02-08  用宏封装变参函数的方法
    以下示例演示的是将变长参数printf()用宏封装为自己的my_printf()。

#define my_printf(lpstrDst,strFormat, ...) \
    printf(lpstrDst,_T(strFormat), __VA_ARGS__);






【调试心得】(共计02个心得)

2012-12-21 Visual Studio调试出现莫名其妙的问题,实在无法解决时
1. 尝试重新生成工程;
2. 尝试重启Visual Studio;
3. 尝试重启Windows。
(虽然看起来很弱,但是作为我来讲,凡是搞不明白的错误基本上都是通过以上3个方法之一解决的-_-! )


2012-12-24  迭代器报“vector iterators incompatible”错的几种可能
       以下3中可能会导致此种错误发生,但也并不排除会有其他可能。
1. 类型不匹配,例如用int型的向量迭代器与char型的向量迭代器进行比对操作;
2. 比对时向量结构发生变化(比如对向量进行了增删等操作);
3. 结构体内的某个元素是向量类型,但在使用前对整个结构体进行了清零操作,从而导致向量被破坏。
      更多详细信息请参见我为此专门写的一篇文章:http://a1pass.blog.163.com/blog/static/2971373220119242245951/
原创粉丝点击