﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-textbox-随笔分类-调试/壳</title><link>http://www.cnitblog.com/textbox/category/8650.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 14:39:12 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 14:39:12 GMT</pubDate><ttl>60</ttl><item><title>用户模式的调试原理</title><link>http://www.cnitblog.com/textbox/archive/2010/11/03/70852.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 03 Nov 2010 14:07:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2010/11/03/70852.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/70852.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2010/11/03/70852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/70852.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/70852.html</trackback:ping><description><![CDATA[用户模式的调试原理和过程.<br />主要对象: <br />    1.调试进程 (用户界面的输入\输出与被调试进程的桥梁)<br />    2.被调试进程<br /><br />调试器一般会用两个线程(也有用单线程的)来完成调试与用户界面的交互.UI线程与调试线程(DWT Debuger's Work Thread)<br />这样的原因是界面不会因为调试的等待而停止输入输出.<br /><br />  DWT的主要内容是<br />    1.建立会话.调用CreateProcess或DebugActiveProcess <br />    2.循环调用WaitForDebugEvent,ContinueDebugEvent 来接收被调试进程的调试的event<br />  类似window的消息循环.<br /> <br />  DWT的TEP与普通TEP的不同地方在于DbgSsReserved 数组主要用于保存(DebugObject)在xp中数组的每一个元素都是指向DBGSS_THREAD_DATA结构 该结构主要用于保存被调试的进程/句柄调用WaitForDebugEvent,ContinueDebugEvent,dbgUIGetThreadDebugObject,dbgUISetThreadDebugObject 会维护这个数组<br /><br />  被调试进程与普通进程的差别.<br />  EPB的DebugPort  不为空<br />  PEB的BeginDebugged 不为0<br /><br /><br /><br /><br />  CreateProcess<br />  CreateProcessInternalW<br />  ZwCeateProcessEx<br />   -DbgConnectToDbg<br />    -NtConnectPort<br />     设置DbgSsReserved[0]/DbgSsReserved[1] 调试端口句柄/Semaphore信号对象 很多API调试通讯都是通过该调试端口来传递.<br />   -NtCreateProcess<br />    -PspCreateProcess<br />     设置EPROCESS和DebugPort=1<br />  把普通的进程晋升为调试子系统"眼里"的被调试进程.<br /><br />   <br /><img src ="http://www.cnitblog.com/textbox/aggbug/70852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2010-11-03 22:07 <a href="http://www.cnitblog.com/textbox/archive/2010/11/03/70852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>脱壳的艺术(转)</title><link>http://www.cnitblog.com/textbox/archive/2010/04/06/65102.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Tue, 06 Apr 2010 01:14:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2010/04/06/65102.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/65102.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2010/04/06/65102.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/65102.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/65102.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: v\:* {behavior:url(#default#VML);}o\:* {behavior:url(#default#VML);}w\:* {behavior:url(#default#VML);}.shape {behavior:url(#default#VML);}														   Normal  0  ...&nbsp;&nbsp;<a href='http://www.cnitblog.com/textbox/archive/2010/04/06/65102.html'>阅读全文</a><img src ="http://www.cnitblog.com/textbox/aggbug/65102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2010-04-06 09:14 <a href="http://www.cnitblog.com/textbox/archive/2010/04/06/65102.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ollydbg常用断点函数</title><link>http://www.cnitblog.com/textbox/archive/2008/12/03/52183.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 03 Dec 2008 12:41:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2008/12/03/52183.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/52183.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2008/12/03/52183.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/52183.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/52183.html</trackback:ping><description><![CDATA[1、限制程序功能函数<br /><div id="postmessage_16488" class="t_msgfont"><br />
EnableMenuItem 允许、禁止或变灰指定的菜单条目<br />
EnableWindow 允许或禁止鼠标和键盘控制指定窗口和条目（禁止时菜单变灰）<br />
　<br />
2、对话框函数<br /><br />
CreateDialog 从资源模板建立一非模态对话窗<br />
CreateDialogParam 从资源模板建立一非模态对话窗 <br />
CreateDialogIndirect 从内存模板建立一非模态对话窗 <br />
CreateDialogIndirectParam 从内存模板建立一非模态对话窗 <br /><br />
DialogBox 从资源模板建立一模态对话窗 <br />
DialogBoxParam 从资源模板建立一模态对话窗 <br />
DialogBoxIndirect 从内存模板建立一模态对话窗 <br />
DialogBoxIndirectParam 从内存模板建立一模态对话窗 <br />
EndDialog 结束一模态对话窗 <br /><br />
MessageBox 显示一信息对话框 <br />
MessageBoxEx 显示一信息对话框 <br />
MessageBoxIndirect 显示一定制信息对话框 <br /><br />
GetDlgItemInt 得指定输入框整数值 <br />
GetDlgItemText 得指定输入框输入字符串 <br />
GetDlgItemTextA 得指定输入框输入字符串 <br />
Hmemcpy 内存复制 （非应用程序直接调用）<br /><br />
3、磁盘处理函数1273?GAMEHK所有--admin?11326　<br /><br />
GetDiskFreeSpaceA 获取与一个磁盘的组织有关的信息，以及了解剩余空间的容量 <br />
GetDiskFreeSpaceExA 获取与一个磁盘的组织以及剩余空间容量有关的信息<br />
GetDriveTypeA 判断一个磁盘驱动器的类型 <br />
GetLogicalDrives 判断系统中存在哪些逻辑驱动器字母<br />
GetFullPathNameA 获取指定文件的详细路径 <br />
GetVolumeInformationA 获取与一个磁盘卷有关的信息 　<br />
GetWindowsDirectoryA 获取Windows目录的完整路径名 <br />
GetSystemDirectoryA 取得Windows系统目录（即System目录）的完整路径名<br /><br />
4、文件处理函数　<br /><br />
CreateFileA 打开和创建文件、管道、邮槽、通信服务、设备以及控制台 <br />
OpenFile 这个函数能执行大量不同的文件操作 <br />
ReadFile 从文件中读出数据 <br />
ReadFileEx 与ReadFile相似，只是它只能用于异步读操作，并包含了一个完整的回调 <br />
WriteFile 将数据写入一个文件　<br />
WriteFileEx 与WriteFile类似，只是它只能用于异步写操作，并包括了一个完整的回调 <br />
SetFilePointer 在一个文件中设置当前的读写位置 　<br />
SetEndOfFile 针对一个打开的文件，将当前文件位置设为文件末尾 <br />
CloseHandle 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等<br />
　<br />
_lcreat 创建一个文件 <br />
_lopen 以二进制模式打开指定的文件 <br />
_lread 将文件中的数据读入内存缓冲区<br />
_lwrite 将数据从内存缓冲区写入一个文件 <br />
_llseek 设置文件中进行读写的当前位置 <br />
_lclose 关闭指定的文件 <br />
_hread 将文件中的数据读入内存缓冲区 　<br />
_hwrite 将数据从内存缓冲区写入一个文件<br /><br />
OpenFileMappingA 打开一个现成的文件映射对象<br />
CreateFileMappingA 创建一个新的文件映射对象 <br />
MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间 <br />
MapViewOfFileEx （内容同上） <br /><br />
CreateDirectoryA 创建一个新目录 <br />
CreateDirectoryExA 创建一个新目录 <br />
RemoveDirectoryA 删除指定目录 <br />
SetCurrentDirectoryA 设置当前目录<br /><br />
MoveFileA 移动文件<br />
DeleteFileA 删除指定文件<br />
CopyFileA 复制文件 <br />
CompareFileTime 对比两个文件的时间<br />
SetFileAttributesA 设置文件属性 <br />
SetFileTime 设置文件的创建、访问及上次修改时间 <br />
FindFirstFileA 根据文件名查找文件 <br />
FindNextFileA 根据调用FindFirstFile函数时指定的一个文件名查找下一个文件<br />
FindClose 关闭由FindFirstFile函数创建的一个搜索句柄 <br />
SearchPathA 查找指定文件 <br /><br />
GetBinaryTypeA 判断文件是否可以执行 <br />
GetFileAttributesA 判断指定文件的属性<br />
GetFileSize 判断文件长度 <br />
GetFileTime 取得指定文件的时间信息<br />
GetFileType 在给出文件句柄的前提下，判断文件类型 <br /><br />
5、注册表处理函数<br /><br />
RegOpenKeyA 打开一个现有的注册表项<br />
RegOpenKeyExA 打开一个现有的注册表项 <br />
RegCreateKeyA 在指定的项下创建或打开一个项<br />
RegCreateKeyExA 在指定项下创建新项的更复杂的方式<br />
RegDeleteKeyA 删除现有项下方一个指定的子项 <br />
RegDeleteValueA 删除指定项下方的一个值 <br />
RegQueryValueA 获取一个项的设置值 <br />
RegQueryValueExA 获取一个项的设置值<br />
RegSetValueA 设置指定项或子项的值 <br />
RegSetValueExA 设置指定项的值 <br />
RegCloseKey 关闭系统注册表中的一个项（或键）<br /><br />
6、时间处理函数<br /><br />
CompareFileTime 比较两文件时间<br />
GetFileTime 得文件建立，最后访问，修改时间<br />
GetLocalTime 得当前本地时间<br />
GetSystemTime 得当前系统时间　<br />
GetTickCount 得windows启动至现时毫秒　<br />
SetFileTime 设置文件时间<br />
SetLocalTime 设置本地时间 <br />
SetSystemTime 设置系统时间<br /><br />
7、进程函数<br /><br />
CreateProcessA 创建一个新进程 <br />
ExitProcess 以干净的方式关闭一个进程<br />
FindExecutableA 查找与一个指定文件关联在一起的程序的文件名 <br />
FreeLibray 释放指定的动态链库 <br />
GetCurrentProcess 获取当前进程的一个伪句柄<br />
GetCurrentProcessId 获取当前进程一个唯一的标识符 <br />
GetCurrentThread 获取当前线程的一个伪句柄<br />
GetExitCodeProces 获取一个已结束进程的退出代码<br />
GetExitCodeThread 获取一个已结束线程的退出代码 <br />
GetModuleHandleA 获取一个应用程序或动态链接库的模块句柄<br />
GetPriorityClassA 获取特定进程的优先级别<br /><br />
LoadLibraryA 载入指定的动态链接库，并将它映射到当前进程使用的地址空间<br />
LoadLibraryExA 装载指定的动态链接库，并为当前进程把它映射到地址空间<br />
LoadModule 载入一个windows应用程序，并在指定的环境中运行<br /><br />
TerminateProcess 结束一个进程 <br /><br />
-----------------------------------------------------------------------7433?GAMEHK所有--admin?19214　<br />
8、断点设置列表<br /><br />
一般处理<br />
bpx hmemcpy<br />
bpx MessageBox<br />
bpx MessageBoxExA<br />
bpx MessageBeep<br />
bpx SendMessage<br /><br />
bpx GetDlgItemText<br />
bpx GetDlgItemInt<br />
bpx GetWindowText<br />
bpx GetWindowWord<br />
bpx GetWindowInt<br />
bpx DialogBoxParamA<br />
bpx CreateWindow<br />
bpx CreateWindowEx<br />
bpx ShowWindow<br />
bpx UpdateWindow<br /><br />
bmsg xxxx wm_move<br />
bmsg xxxx wm_gettext　<br />
bmsg xxxx wm_command　<br />
bmsg xxxx wm_activate<br /><br />
时间相关<br /><br />
bpint 21 if ah==2A (DOS)<br />
bpx GetLocalTime<br />
bpx GetFileTime<br />
bpx GetSystemtime<br /><br />
CD-ROM 或 磁盘相关<br /><br />
bpint 13 if ah==2 (DOS)<br />
bpint 13 if ah==3 (DOS)<br />
bpint 13 if ah==4 (DOS)　<br />
bpx GetFileAttributesA<br />
bpx GetFileSize<br />
bpx GetDriveType<br />
bpx GetLastError<br />
bpx ReadFile<br />
bpio -h (Your CD-ROM Port Address) R <br /><br />
软件狗相关 <br /><br />
bpio -h 278 R<br />
bpio -h 378 R　<br /><br />
键盘输入相关 <br /><br />
bpint 16 if ah==0 (DOS)<br />
bpint 21 if ah==0xA (DOS) <br /><br />
文件访问相关 <br /><br />
bpint 21 if ah==3dh (DOS)<br />
bpint 31 if ah==3fh (DOS)<br />
bpint 21 if ah==3dh (DOS)<br />
bpx ReadFile<br />
bpx WriteFile<br />
bpx CreateFile<br />
bpx SetFilePointer<br />
bpx GetSystemDirectory　<br /><br />
INI 初始化文件相关<br /><br />
bpx GetPrivateProfileString<br />
bpx GetPrivateProfileInt<br />
bpx WritePrivateProfileString<br />
bpx WritePrivateProfileInt<br /><br />
注册表相关 <br /><br />
bpx RegCreateKey<br />
bpx RegDeleteKey<br />
bpx RegQueryValue<br />
bpx RegCloseKey<br />
bpx RegOpenKey<br /><br />
注册标志相关 <br /><br />
bpx cs:eip if EAX==0 <br /><br />
内存标准相关<br /><br />
bpmb cs:eip rw if 0x30:0x45AA==0<br /><br />
显示相关<br /><br />
bpx 0x30:0x45AA do "d 0x30:0x44BB"<br />
bpx CS:0x66CC do "? EAX"<br /><br />
转自：<a href="http://www.jjjbbs.com/" target="_blank">http://www.jjjbbs.com/</a></div><img src ="http://www.cnitblog.com/textbox/aggbug/52183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2008-12-03 20:41 <a href="http://www.cnitblog.com/textbox/archive/2008/12/03/52183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转Draren总结的ollydbg v1.09d 中文版使用说明</title><link>http://www.cnitblog.com/textbox/archive/2008/11/30/52105.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Sun, 30 Nov 2008 14:03:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2008/11/30/52105.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/52105.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2008/11/30/52105.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/52105.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/52105.html</trackback:ping><description><![CDATA[
		<h2>OllyDbg知识专题</h2>
		<div id="postmessage_1119" class="t_msgfont"> 转Draren总结的ollydbg v1.09d 中文版使用说明<br /><br />
一点一滴的积累,也就会了. <br /><br />
之所以选择ollydbg <br /><br />
1.我的os是winXP,无法使用trw2000,而softice装了多次均未成功,还蓝屏死机多次.郁闷. <br /><br />
2.友好的gui界面,不像softice.可以边干活边听歌,不像softice,把整个os都挂起了.多用两次,连时间都不知道了. <br /><br />
3.强大的内存查看功能,再不用什么-d了,而且跳转方便,爽!一目了然. <br /><br />
4.强大的右键菜单功能 <br /><br />
ollydbg的界面: <br /><br />
菜单: <br /><br />
文件: <br />
    1.其中包括该菜单的下部有上次打开的纪录,该纪录保存有上次未清除的断点. <br />
    2.附加.对付那些Anti-Debug程序.先运行程序,再运行od,文件--&gt;附加. <br />
查看: <br />
    1.执行模块(Alt+E),查看程序使用的动态链接库 <br />
    2.查看断点.Alt+B <br />
调试: <br />
    1.运行(F9)加载程序后,运行! <br />
    2.暂停(F12) <br />
    3.单步进入(F7)遇见CALL进入!进入该子程序. <br />
    4.单步跳过(F8)遇见CALL不进去! <br />
    5.执行到返回(ALT+F9)就是执行到该子程的返回语句 <br /><br />
ollydbg的16进制编辑功能.类似与hiew,hex workshop <br /><br />
查看--&gt;文件 <br /><br />
二进制文件编辑功能.查看--&gt;文件,打开的文件是二进制显示.选中要改变的机器指令,空格,修改,右击--&gt;保存. <br /><br />
ollydbg的四个区域 <br /><br />
左上角是cpu窗口,分别是地址,机器码,汇编代码,注释;注释添加方便,而且还能即时显示函数的调用结果,返回值. <br />
右上角是寄存器窗口,但不仅仅反映寄存器的状况,还有好多东东;双击即可改变Eflag的值,对于寄存器,指令执行后发生改变的寄存器会用红色显示. <br />
cpu窗口下面还有一个小窗口,显示当前操作改变的寄存器状态.  不错; <br />
左下角是内存窗口.可以ascii或者unicode两种方式显示内存信息; <br />
右下角的是当前堆栈情况,还有注释啊. <br /><br />
F3选择打开程序. <br /><br />
使用 <br /><br />
F9执行程序. <br /><br />
下断点: <br /><br />
1.对函数下下断点 <br /><br />
在代码区右击--&gt;搜索--&gt;当前模块中的名称(ctrl+N),在跳出来的对话框中选择需要下的断点函数.-&gt;右击-&gt;查找导入参考(enter),按F2下断点.如果有多个地方调用了该函数就这样操作。 <br /><br />
2.在需要的地方下断点  F2 <br /><br />
添加注释: <br /><br />
在代码区第四列,右击--&gt;注释 <br /><br />
查看内存地址 <br /><br />
右击内存地址列--&gt;前往--&gt;输入要查看的内存地址 <br /><br />
在函数lstrlen的注释的上方,有一个变量string,当执行到该函数的时候,string后面会出现lstrlen函数的参数字符串.在实际使用中一般是输入的字符串.(很好用哦) <br /><br />
类似的还有lstrcmp,上面有string1,string2能够显示将要比较的两个字符串. <br /><br />
另外,一般在执行getwindowtext等函数后,右边寄存器列,eax会显示函数的返回值,即取到的内容.同时内存中也会有显示. <br /><br />
在反汇编中选中一条命令，如果其中有用到内存中的地址,右击--&gt;在转存中跟随--&gt;直接常数 <br />
此时内存地址会显示指令中引用到的内存字符 <br /><br />
拷贝功能十分强大.直接选择要拷贝的内容.右击--&gt;复制--&gt;文件or剪贴板 <br /><br />
ollydbg的条件断点可以按寄存器，存储器，消息（必须是消息的数字，如wm_command就是111）等等设断，非常强大，一旦设了之后记录到文件中，下次restart程序还能用，不用拿笔记，很方便。 <br /><br />
显示跳转路进: <br />
选项--&gt;调试设置--&gt;cpu页--&gt;显示跳转的方向,显示跳转的路径,如果跳转没有实现则显示灰色路径。在cpu窗口中,机器码的
前面显示"&gt;"符号.同时,在cpu窗口下的小缝中会显示跳转路径,从何跳转而来.右击--&gt;前往...一般都是条件跳转，上面的内容就是比
较的地方啦。：） <br /><br />
跟踪功能: <br />
选项--&gt;调试跟踪--&gt;跟踪:设置运行跟踪的缓存大小.越大越好. <br />
调试--&gt;打开或清除运行跟踪 <br />
然后我们就可以用CTRL+F11或CTRL+F12开启“跟踪进入”和“ 跟踪跳过”了。当我们暂停程序的时候，可以用小键盘上的“+”，“-”，“*”来控制跟踪功能了。 <br />
其中,“跟踪进入”和运行类似，但是记录所有指令以及寄存器变化。并且会自动进入所有的CALL中。 <br />
“ 跟踪跳过”和“跟踪进入”类似，但是不进入CALL <br />
“+”用来显示跟踪缓冲区中的下一条指令 <br />
“-”用来显示跟踪缓冲区中的上一条指令 <br />
“*”用来发返回当前指令 <br /><br />
让OD显示MFC42.DLL中的函数 <br />
打开调试--&gt;选择导入库--&gt;添加--&gt;选择MFC43.LIB加入.重新载入MFC程序，就可以看到call后面的api函数了. <br /><br />
动态暂停以messagebox为例) <br />
先运行目标程序,再运行od,选择文件--&gt;附加.在目标程序运行出现对话框时,切换至od,F12暂停. <br /><br />
字符串参考: <br />
在汇编代码区,右击--&gt;搜索--&gt;字符参考 <br /><br />
更改二进制文件: <br /><br />
方法1.查看--&gt;文件,打开文件,找到欲修改的偏移,使用机器码修改,然后右击保存文件.缺点是需要使用其他软件来获取偏移地址. <br /><br />
方法2.直接在反汇编代码区更改,这时可以使用汇编代码更改,不用记机器码.完了.右击--&gt;复制到可执行文件--&gt;保存文件.很是方便哪! <br /><br />
关于虚拟地址和偏移地址: <br />
ollydbg果然强大,太强大了,在欲修改的指令处右击--&gt;复制到可执行文件,弹出窗口中光标所在行即是欲修改的指令所在的偏移地址,右击--&gt;汇编,直接修改汇编指令,不用记机器码,又不用虚拟地址到偏移地址的转换.改完后保存文件.爽丫!<br />
olldbg 下怎么下消息断点？<br /><br />
如在softice 中下 BMSG 0084 WM_DESTROY，在olldbg下该怎么做？<br /><br />
不如下断 SendMessage，PostMessage，程序中的消息不一定都经过消息循环。<br /><br />
Ollydbg下消息断点的一个方法<br /><br />
原文：<br />
SoftIce can trace application messages. And Olly? <br />
by FuZzYBiT<br /><br />
SoftIce can trace application messages. And Olly?<br />
And so does OllyDbg. That’s a very “hidden feature”. I guess it is sooo useful.<br />
1. Open program<br />
2. Names window [CTRL+N in CPU Window]<br />
3. Find User32.TranslateMessage API<br />
4. right click/FindReferences<br />
5. conditional breakpoint [SHIFT+F4]<br />
6. expression: MSG<br />
7. Log function arguments: Always<br />
If you cannot find it, try right click SEARCH FOR-&gt; ALL INTERMODULAR CALLS.<br />
But if I want to trap a specific message like WM_COMMAND?<br />
To Log Only WM_COMMAND<br />
Do it in this fashion:<br />
1. Open program<br />
2. Names window [CTRL+N in CPU Window]<br />
3. Find User32.TranslateMessage API<br />
4. right click/FindReferences<br />
5. conditional breakpoint [SHIFT+F4]<br />
6. Condtion box: MSG==WM_COMMAND<br />
7. Log function arguments: On Condition<br />
If you can’t find User32.TranslateMessage API, do the same as above.<br /><br />
翻译:<br /><br />
SoftIce 能够跟踪应用程序的消息，那么OllyDbg呢？<br />
by FuZzYBiT<br /><br />
OllyDbg也是可以的，那是一个非常"隐蔽的功能"。它是如此的有用。<br />
1. 打开程序<br />
2. 名字窗口[ 在CPU窗口中按CTRL+N ]<br />
3. 查找 User32.TranslateMessage API<br />
4. 右击/FindReferences(查找参考)<br />
5. 下条件断点 [SHIFT+F4]<br />
6. 表达式: MSG<br />
7. 记录函数参数:永远<br /><br />
如果你不能找到它，试试右击鼠标，然后搜索全部模块中的名称。<br />
但是如果我想要捕捉一个特定的消息如WM_COMMAND呢?<br />
只对WM_COMMAND记录<br />
用这个方法做:<br />
1. 打开一个程序<br />
2. 名字窗口[ 在CPU窗口中按CTRL+N ]<br />
3. 查找 User32.TranslateMessage API<br />
4. 右击/FindReferences(查找参考)<br />
5. 下条件断点 [SHIFT+F4]<br />
6. 条件框:MSG==WM_COMMAND<br />
7. 记录函数参数: 条件满足时<br />
如果你不能找到User32.TranslateMessage API，象上面那样做。<br />
以下命令适用于 OllyDbg 的命令行插件 Cmdline.dll（显示于程序的插件菜单中）<br />
聆风听雨整理<br />
===============================================================<br />
命令行插件支持的命令<br /><br />
CALC<br />
判断表达式<br /><br />
WATCH<br />
添加监视表达式<br /><br />
AT<br />
在指定地址进行反汇编<br /><br />
FOLLOW<br />
跟随命令<br /><br />
ORIG<br />
反汇编于 EIP<br /><br />
DUMP<br />
在指定地址进行转存<br /><br />
DA<br />
转存为反汇编代码<br /><br />
DB<br />
使用十六进制字节格式转存<br /><br />
DC<br />
使用 ASCII 格式转存<br /><br />
DD<br />
转存在堆栈格式<br /><br />
DU<br />
转存在 UNICODE 格式<br /><br />
DW<br />
使用十六进制字词格式转存<br /><br />
STK<br />
前往堆栈中的地址<br /><br />
AS<br />
（AS + 地址 + 字符串）<br />
在指定地址进行汇编<br /><br />
BP<br />
进行条件中断（有条件的断点）<br /><br />
BPX<br />
中断在全部调用 （Call）<br /><br />
BPD<br />
清除全部调用中的断点<br /><br />
BC<br />
清除断点<br /><br />
MR<br />
内存断点于访问时<br /><br />
MW<br />
内存断点于写入时<br /><br />
MD<br />
清除内存断点<br /><br />
HR<br />
访问时进行硬件中断<br /><br />
HW<br />
写入时进行硬件中断<br /><br />
HE<br />
执行时进行硬件中断<br /><br />
HD<br />
清除硬件断点<br /><br />
STOP<br />
停止运行程序调试<br /><br />
PAUSE<br />
暂停执行程序调试<br /><br />
RUN<br />
运行程序进行调试<br /><br />
GE<br />
运行和通过例外<br /><br />
SI<br />
单步进入 Call 中<br /><br />
SO<br />
步过 Call<br /><br />
TI<br />
跟踪进入直到地址<br /><br />
TO<br />
跟踪步过直到地址<br /><br />
TC<br />
跟踪进入直到满足条件<br /><br />
TOC<br />
跟踪步过直到满足条件<br /><br />
TR<br />
运行直到返回<br /><br />
TU<br />
运行直到用户代码<br /><br />
LOG<br />
查看记录窗口<br /><br />
MOD<br />
查看模块窗口<br /><br />
MEM<br />
查看内存窗口<br /><br />
CPU<br />
查看 CPU 窗口<br /><br />
CS<br />
查看 Call 堆栈<br /><br />
BRK<br />
查看断点窗口<br /><br />
OPT<br />
打开选项设置窗口<br /><br />
EXIT<br />
退出 OllyDbg<br /><br />
QUIT<br />
退出 OllyDbg<br /><br />
OPEN<br />
打开一个可执行文件<br /><br />
CLOSE<br />
关闭可执行文件<br /><br />
RST<br />
重新运行当前程序<br /><br />
HELP<br />
查看 API 函数的帮助<br /><br />
OllyDbg应用方法大全--请补充！<br /><br />
所有文章均为散落在DFCG论坛各处或其他网络文集的经典。<br />
雪很冷搜集整理于学习笔记或与朋友讨论之中<br /><br /><br />
Ollydbg 中断方法<br /><br /><br />
  Quote: <br />
Originally posted by dong at 2004-6-1 10:29 PM:<br />
我问个问题<br />
在od中怎么下断点呢??<br />
现在有的程序一点注册就没反映了<br />
这样的怎么下断点呢??<br />
能介绍下什么情况下什么断点吗?  <br />
在转存中下硬件访问－&gt;Word"断点，下断之后，怎么取消！ <br />
9398944(老菜鸟) 11:09:59<br />
alt+D  按H  然后删除 <br /><br /><br />
这个没有万能的方法，只能视具体情况而定，就我的经验而言：<br />
第一步，反汇编找有用信息，有时候虽然点击注册按钮后，没有任何反映，但软件也许包含了可用的信息，比如“未注册”，“已注册”等等之类的，都可用做断点的。<br />
第二步，如果反汇编也找不到有用信息，如果用OD可以下HMEMECPY断点，在每个调用的函数上下断，虽然这个法子太笨，但我试过，几乎有70%以上的机会可找到断点，找到断点后再慢慢跟吧!这只是个人的看法，关键只要找到断点，有什么办法都无所谓。<br />
在命令行下bpx hmemcpy断点，然后回车，在每个调用的函数上下断。<br />
有的程序甚至无法用API中断，可以在OD载入程序后上下翻动反汇编窗口查看字符串参考下断，在反汇编窗口里直接找到的，右键查找那里找不到<br /><br /><br />
转发Ollydbg 中断方法浅探-各种断点常识知识<br /><br />
Ollydbg 中断方法浅探 <br />
                                   ――国庆节小礼 <br /><br />
Ollydbg是一个新的32位的汇编层调试软件。适应于windows98、me、2000、xp和2003操作系统。由于他具有图形窗口界面，所以操作方便、直观，是cracker的好工具。 <br />
由于Ollydbg没有了TRW2000的万能断点，所以许多的新手感觉到用Ollydbg断点不好找。现在我来的说说Ollydbg下中断的几种方法。本人是个菜鸟，水平有限，可能不能完整的写出来，也可能存在错误。请大家指正。 <br />
我所表述的是Ollydbg v1.09d中文版，其他版本和英文版下自己参考。 <br /><br />
第一 寻常断点 <br />
Ollydbg中一般下中断的方法，就是在程序的地址处用鼠标选择这一行。然后按F2键，这时被选择的那一行的地址会变成别的颜色，就表示这个地址处下了中断。然后运行程序时只有到这个地址处就会被Ollydbg中断。 <br />
这个方法用的比较多，所以把他称作寻常断点。 <br />
如果有命令行插件，就可以在命令窗口中输入BPX xxxxxxxx 下断点。 <br />
优点：只要自己怀疑是重要的代码处都可以下这种下断点，不受条件的限制，所以方便实用。 <br />
缺点：如果不知道代码功能下断点具有盲目性。 <br /><br />
第二 API断点 <br />
Ollydbg中一般下API中断的方法，有二种。 <br />
1.  在代码窗口中点鼠标右键，出现功能菜单。在[搜索]选择项下有〔当前模块的名称〕和〔全部模块的名称〕俩项，选择其中的一项就打开了程序调用
API的窗口，在这个窗口中选择你要跟踪的API函数名。双击这个函数就能到程序的调用地址处。然后用F2下中断。也可以在API窗口中选择需要跟踪的函
数点鼠标右键出现功能菜单，选择〔在每个参考设置断点〕。同样下了断点。                                      <br />
快捷方式：Ctrl+N <br />
2.  在命令行窗口中输入BPX  API函数名或者BP  API函数名 后回车。这时出现了所有调用这个函数的地址的窗口，在这个窗口中可以看到调用这个API函数的地址已改变了颜色。说明下好了断点。 <br />
说明一下：BPX一般中断在程序调用API的地址处。BP会中断在API的写入地址处。二这有所不同，根据需要选择。 <br />
   优点：这种方法下的断点是针对每一个API函数的，所以具有明确的目的。 <br />
   缺点：关键的API函数不容易找到。所以有时下的断点没有作用。 <br /><br />
   第三  内存断点（跟踪关键数据的断点） <br />
   Ollydbg中的内存断点相当于TRW中的bpm 断点。 <br />
下断点的方法是：在程序运行中断时选择界面中的转存窗口，用光标选择内存中的一段关键数据（颜色会改变），然后右击鼠标出现功能菜单。选择〔断点〕项，其中有二个选择〔内存访问〕和〔内存写入〕。 <br />
〔内存访问〕断点是程序运行时要调用被选择的内存数据时就会被Ollydbg中断，根据这个特点在破解跟踪时只要在关键数据内存中下中断就可以知道程序在
什么地方和什么时候用到了跟踪的数据。对于一些复杂算法和流程变态的算法跟踪有很大的帮助。从破解上讲，一个注册码的生成一定是由一些关键数据或者原始数
据计算来的。所以在内存中一定要用到这些关键数据。那么〔内存访问〕断点就是最好的中断方法。 <br />
〔内存写入〕断点是程序运行时向被选择的内存地址写入数据时就会被Ollydbg中断。根据这个特点在破解时可以跟踪一个关键数据是什么时候生成的，生成的代码段在那个地方。所以一个关键的数据如果不知道他的由来就可以用〔内存访问〕断点查找计算的核心。 <br />
内存中断的下断点还有另外的一种方法：程序运行时如果知道关键的数据，比如我们输入的试验码、程序生成的序列号等。这时在内存中一定存在这些数据。用
Alt+M打开内存窗口，在这个窗口中搜索知道的关键数据。用光标选择这些数据同样下内存中断，这种方法更容易找的关键的数据。 <br />
优点：断点是直接面向关键数据的，所以比较容易到核心部分。 <br />
缺点：内存断点重新运行后会消失，干扰比较多。 <br /><br />
第四  硬件断点（跟踪关键标志的断点） <br />
硬件断点是Olldbg所特有的断点，他不会因为重新运行就销毁，只要不删除。跟踪这个程序时就有效。但他在98系统下会不起作用。 <br />
硬件断点是根据关键标志回逆到关键代码的好方法。下中断的方法和内存断点的方法相同，有三个方式〔硬件访问〕、〔硬件写入〕、〔硬件执行〕。一般用前2
个。他也同样有内存断点的特性，所以可以用内存断点的地方也可以用硬件断点。这里介绍利用他来跟踪注册标志的使用方法，一般软件的注册都用到了标志比较。
即在内存地址中有一个标志，在判断是不是注册时比较标志的值。不同的值表示不同的注册状态。这个标志的地址一般比较固定。根据这个特点可以下硬件断点来跟
踪标志位是什么地方被标志的。 <br />
方法：在转存窗口中选择到标志存放的内存地址处，然后选择标志值。下〔硬件写入〕中断（根据标志的字节下不同的长度）。重新运行程序你会发现
Ollydbg会不断的中断在这个标志的内存地址处。在功能菜单的〔调试〕选项下选择〔硬件断点〕就打开了硬件断点的窗口，在这个窗口中选择〔跟踪〕，这
时转存窗口就会来到被下中断的内存地址处。运行程序跟踪内存地址中的值就会知道被赋标志的代码，跟踪到计算的核心。〔硬件访问〕的使用可以知道程序在运行
时多少地方用到了这个注册标志。对于破解复杂效验的程序十分的有效。 <br />
直接在命令栏里下bh ****硬件断点<br /><br />
以上只是我的总结，本想每个方法用一段例子，无奈时间有限，请大家原谅了。 <br />
当然，还是许多的下中断的方法，本人水平有限，不能一一尽述。只当抛砖引玉，请大侠们赐教。</div>
<img src ="http://www.cnitblog.com/textbox/aggbug/52105.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2008-11-30 22:03 <a href="http://www.cnitblog.com/textbox/archive/2008/11/30/52105.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OD资料（转自看雪论坛）</title><link>http://www.cnitblog.com/textbox/archive/2008/11/30/52089.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Sun, 30 Nov 2008 05:45:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2008/11/30/52089.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/52089.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2008/11/30/52089.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/52089.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/52089.html</trackback:ping><description><![CDATA[
		<br />
 OllyDBG 入门系列（一）－认识OllyDBG<br /><br />
作者：CCDebuger<br /><br />
一、OllyDBG 的安装与配置<br /><br />
OllyDBG 1.10 版的发布版本是个 ZIP 压缩包，只要解压到一个目录下，运行 OllyDBG.exe 就可以了。汉化版的发布版本是个 RAR 压缩包，同样只需解压到一个目录下运行 OllyDBG.exe 即可：<br /><img style="cursor: pointer;" title="http://bbs.pediy.com/upload/2006/4/image/od_window.gif_950.gif" src="http://bbs.pediy.com/upload/2006/4/image/od_window.gif_950.gif" alt="此图已经缩小，点击察看原图。" onload="if(this.width&gt;screen.width*0.6) {this.width=screen.width*0.6;this.alt='此图已经缩小，点击察看原图。';}" onmouseover="this.style.cursor='pointer';" onclick="window.open('http://bbs.pediy.com/upload/2006/4/image/od_window.gif_950.gif');" border="0" width="614" /><br />
OllyDBG 中各个窗口的功能如上图。简单解释一下各个窗口的功能，更详细的内容可以参考 TT 小组翻译的中文帮助：<br /><br />
反汇编窗口：显示被调试程序的反汇编代码，标题栏上的地址、HEX 数据、反汇编、注释可以通过在窗口中右击出现的菜单 界面选项-&gt;隐藏标题 或 显示标题 来进行切换是否显示。用鼠标左键点击注释标签可以切换注释显示的方式。<br /><br />
寄存器窗口：显示当前所选线程的 CPU 寄存器内容。同样点击标签 寄存器 (FPU) 可以切换显示寄存器的方式。<br /><br />
信息窗口：显示反汇编窗口中选中的第一个命令的参数及一些跳转目标地址、字串等。<br /><br />
数据窗口：显示内存或文件的内容。右键菜单可用于切换显示方式。<br /><br />
堆栈窗口：显示当前线程的堆栈。<br /><br />
要调整上面各个窗口的大小的话，只需左键按住边框拖动，等调整好了，重新启动一下 OllyDBG 就可以生效了。<br /><br />
启动后我们要把插件及 UDD 的目录配置为绝对路径，点击菜单上的 选项-&gt;界面，将会出来一个界面选项的对话框，我们点击其中的目录标签：<br /><img style="cursor: pointer;" title="http://bbs.pediy.com/upload/2006/4/image/od_dir.gif" src="http://bbs.pediy.com/upload/2006/4/image/od_dir.gif" alt="http://bbs.pediy.com/upload/2006/4/image/od_dir.gif" onload="if(this.width&gt;screen.width*0.6) {this.width=screen.width*0.6;this.alt='此图已经缩小，点击察看原图。';}" onmouseover="this.style.cursor='pointer';" onclick="window.open('http://bbs.pediy.com/upload/2006/4/image/od_dir.gif');" border="0" /> <br />
因为我这里是把 OllyDBG 解压在 F:\OllyDBG 目录下，所以相应的 UDD 目录及插件目录按图上配置。还有一个常用到的标签就是上图
后面那个字体，在这里你可以更改 OllyDBG 中显示的字体。上图中其它的选项可以保留为默认，若有需要也可以自己修改。修改完以后点击确定，弹出一
个对话框，说我们更改了插件路径，要重新启动 OllyDBG。在这个对话框上点确定，重新启动一下 OllyDBG，我们再到界面选项中看一下，会发现
我们原先设置好的路径都已保存了。有人可能知道插件的作用，但对那个 UDD 目录不清楚。我这简单解释一下：这个 UDD 目录的作用是保存你调试的工
作。比如你调试一个软件，设置了断点，添加了注释，一次没做完，这时 OllyDBG 就会把你所做的工作保存到这个 UDD 目录，以便你下次调试时可
以继续以前的工作。如果不设置这个 UDD 目录，OllyDBG 默认是在其安装目录下保存这些后缀名为 udd 的文件，时间长了就会显的很乱，所以
还是建议专门设置一个目录来保存这些文件。<br /><br />
另外一个重要的选项就是调试选项，可通过菜单 选项-&gt;调试设置 来配置：<br /><img style="cursor: pointer;" title="http://bbs.pediy.com/upload/2006/4/image/od_debug_op.gif" src="http://bbs.pediy.com/upload/2006/4/image/od_debug_op.gif" alt="http://bbs.pediy.com/upload/2006/4/image/od_debug_op.gif" onload="if(this.width&gt;screen.width*0.6) {this.width=screen.width*0.6;this.alt='此图已经缩小，点击察看原图。';}" onmouseover="this.style.cursor='pointer';" onclick="window.open('http://bbs.pediy.com/upload/2006/4/image/od_debug_op.gif');" border="0" /> <br />
新手一般不需更改这里的选项，默认已配置好，可以直接使用。建议在对 OllyDBG 已比较熟的情况下再来进行配置。上面那个异常标签中的选项经常会在脱壳中用到，建议在有一定调试基础后学脱壳时再配置这里。<br /><br />
除了直接启动 OllyDBG 来调试外，我们还可以把 OllyDBG 添加到资源管理器右键菜单，这样我们就可以直接在 .exe 及 .dll 文
件上点右键选择“用Ollydbg打开”菜单来进行调试。要把 OllyDBG 添加到资源管理器右键菜单，只需点菜单 选项-&gt;添加到浏览器，将
会出现一个对话框，先点击“添加 Ollydbg 到系统资源管理器菜单”，再点击“完成”按钮即可。要从右键菜单中删除也很简单，还是这个对话框，点击
“从系统资源管理器菜单删除 Ollydbg”，再点击“完成”就行了。<br /><br />
OllyDBG 支持插件功能，插件的安装也很简单，只要把下载的插件（一般是个 DLL 文件）复制到 OllyDBG 安装目录下的 PLUGIN 
目录中就可以了，OllyDBG 启动时会自动识别。要注意的是 OllyDBG 1.10 对插件的个数有限制，最多不能超过 32 个，否则会出错。
建议插件不要添加的太多。<br /><br />
到这里基本配置就完成了，OllyDBG 把所有配置都放在安装目录下的 ollydbg.ini 文件中。<br /><br />
二、基本调试方法<br /><br />
OllyDBG 有三种方式来载入程序进行调试，一种是点击菜单 文件-&gt;打开 （快捷键是 F3）来打开一个可执行文件进行调试，另一种是点击菜
单 文件-&gt;附加 来附加到一个已运行的进程上进行调试。注意这里要附加的程序必须已运行。第三种就是用右键菜单来载入程序（不知这种算不算）。一
般情况下我们选第一种方式。比如我们选择一个 test.exe 来调试，通过菜单 文件-&gt;打开 来载入这个程序，OllyDBG 中显示的内容
将会是这样：<br /><img style="cursor: pointer;" title="http://bbs.pediy.com/upload/2006/4/image/od_debug_test.gif_029.gif" src="http://bbs.pediy.com/upload/2006/4/image/od_debug_test.gif_029.gif" alt="此图已经缩小，点击察看原图。" onload="if(this.width&gt;screen.width*0.6) {this.width=screen.width*0.6;this.alt='此图已经缩小，点击察看原图。';}" onmouseover="this.style.cursor='pointer';" onclick="window.open('http://bbs.pediy.com/upload/2006/4/image/od_debug_test.gif_029.gif');" border="0" width="614" /> <br />
调试中我们经常要用到的快捷键有这些：<br /><br />
F2：设置断点，只要在光标定位的位置（上图中灰色条）按F2键即可，再按一次F2键则会删除断点。（相当于 SoftICE 中的 F9）<br /><br />
F8：单步步过。每按一次这个键执行一条反汇编窗口中的一条指令，遇到 CALL 等子程序不进入其代码。（相当于 SoftICE 中的 F10）<br /><br />
F7：单步步入。功能同单步步过(F8)类似，区别是遇到 CALL 等子程序时会进入其中，进入后首先会停留在子程序的第一条指令上。（相当于 SoftICE 中的 F8）<br /><br />
F4：运行到选定位置。作用就是直接运行到光标所在位置处暂停。（相当于 SoftICE 中的 F7）<br /><br />
F9：运行。按下这个键如果没有设置相应断点的话，被调试的程序将直接开始运行。（相当于 SoftICE 中的 F5）<br /><br />
CTR+F9：执行到返回。此命令在执行到一个 ret (返回指令)指令时暂停，常用于从系统领空返回到我们调试的程序领空。（相当于 SoftICE 中的 F12）<br /><br />
ALT+F9：执行到用户代码。可用于从系统领空快速返回到我们调试的程序领空。（相当于 SoftICE 中的 F11）<br /><br />
上面提到的几个快捷键对于一般的调试基本上已够用了。要开始调试只需设置好断点，找到你感兴趣的代码段再按 F8 或 F7 键来一条条分析指令功能就可以了。就写到这了，改天有空再接着灌。<br /><span class="pediy"><br /><br /><b>命令</b>：<br />以下命令适用于 OllyDbg 的快捷命令栏插件（显示于程序的状态栏上方） <br /><br /> CALC <br /> 判断表达式 
<br /><br /> WATCH <br /> 添加监视表达式 <br /><br /> AT / FOLLOW <br /> Disassemble at address 
<br /> 在地址进行反汇编 <br /><br /> ORIG <br /> Disassemble at EIP <br /> 反汇编于 EIP <br /><br /> DUMP 
<br /> Dump at address <br /> 在地址转存 <br /><br /> DA <br /> Dump as disassembly <br /> 转存为反汇编代码 
<br /><br /> DB <br /> Dump in hex byte format <br /> 转存在十六进制字节格式 <br /><br /> DC <br /> Dump 
in ASCII format <br /> 转存在 ASCII 格式 <br /><br /> DD <br /> Dump in stack format <br /> 
转存在堆栈格式 <br /><br /> DU <br /> Dump in UNICODE format <br /> 转存在 UNICODE 格式 <br /><br /> 
DW <br /> Dump in hex word format <br /> 转存在十六进制字词格式 <br /><br /> STK <br /> Go to address 
in stack <br /> 前往堆栈中的地址 <br /><br /> AS + 地址 + 字符串 <br /> Assemble at address <br /> 在地址进行汇编 
<br /><br /> L + 地址 + 字符串 <br /> Label at address <br /> 在地址进行标号 <br /><br /> C + 地址 + 字符串 
<br /> Comment at address <br /> 在地址进行注释 <br /><br /> BP <br /> Break with condition <br /> 
使用条件中断 <br /><br /> BPX <br /> Break on all calls <br /> 中断在全部调用 <br /><br /> BPD <br /> Delete 
break on all calls <br /> 清除位于全部调用的断点 <br /><br /> BC <br /> Delete breakpoint <br /> 清除断点 
<br /><br /> MR <br /> Memory breakpt on access <br /> 内存断点于访问时 <br /><br /> MW <br /> Memory 
breakpt on write <br /> 内存断点于写入时 <br /><br /> MD <br /> Remove memory breakpoint <br /> 
清除内存断点 <br /><br /> HR <br /> HW break on access <br /> 硬件中断在访问 <br /><br /> HW <br /> HW 
break on write <br /> 硬件中断在写入 <br /><br /> HE <br /> HW break on execution <br /> 硬件中断在执行 
<br /><br /> HD <br /> Remove HW breakpoint <br /> 清除硬件断点 <br /><br /> STOP <br /> Pause execution 
<br /> 暂停执行 <br /> PAUSE <br /> PAUSE <br /><br /> RUN <br /> Run program <br /> 运行程序 <br /> 
Run till address <br /> 运行到地址 <br /><br /> GE <br /> Run and pass exception <br /> 运行和通过例外 
<br /><br /> SI <br /> Step into <br /> 步入 <br /><br /><br /> SO <br /> Step over <br /> 步过 <br /><br /> TI <br /> Trace in till address <br /> 跟踪进入直到地址 <br /><br /> TO <br /> Trace over 
till address <br /> 跟踪步过直到地址 <br /><br /> TC <br /> Trace in till condition <br /> 跟踪进入直到条件 
<br /><br /> TOC <br /> Trace over till condition <br /> 跟踪步过直到条件 <br /><br /> TR <br /> Till 
return <br /> 直到返回 <br /><br /> TU <br /> Till user code <br /> 直到用户代码 <br /><br /> LOG <br /> 
View Log window <br /> 查看记录窗口 <br /><br /> MOD <br /> View Modules window <br /> 查看模块窗口 
<br /><br /> MEM <br /> View Memory window <br /> 查看内存窗口 <br /><br /> CPU <br /> View CPU 
window <br /> 查看 CPU 窗口 <br /><br /> CS <br /> View Call Stack <br /> 查看 Call 堆栈 <br /><br /> 
BRK <br /> View Breakpoints window <br /> 查看断点窗口 <br /><br /> OPT <br /> Open Options <br /> 
打开选项 <br /><br /> EXIT / QUIT <br /> Quit OllyDbg <br /> 退出 OllyDbg <br /><br /> OPEN <br /> 
Open executable file <br /> 打开可执行文件 <br /><br /> CLOSE <br /> Close executable <br /> 关闭程序 
<br /><br /> RST <br /> Restart current program <br /> 恢复当前程序 <br /><br /> HELP <br /> Help 
on API function <br /> API 函数的帮助 <br /><br /> ASM <br /> Assemble (if command needs it's 
own addres, \"ASM COMMAND;ADDRESS\") <br /> 汇编 (如果命令需要自身的地址 \"ASM COMMAND;ADDRESS\") 
<br /><br /> DASM <br /> Disassemble immediate opcode <br /> 反汇编直接的机器码 <br /><br /> FR <br /> 
Find reference to selected command/address <br /> 查找参考到选定的命令/地址 <br /><br /> AC <br /> 
Analyse code <br /> 分析代码 <br /><br /> SN <br /> Search for Name(label) in current module 
<br /> 在当前模块中搜索名称(标号) <br /><br /> SOB <br /> Scan object files <br /> 扫描项目文件<br /><br /><b>断点</b><br /></span>在代码窗口中点鼠标右键，出现功能菜单。在[搜索]选择项下有〔当前模块的名称〕和〔全部模块的名称〕俩项，选择其中的一项就打开了程序调用API的窗
口，在这个窗口中选择你要跟踪的API函数名。双击这个函数就能到程序的调用地址处。然后用F2下中断。也可以在API窗口中选择需要跟踪的函数点鼠标右
键出现功能菜单，选择〔在每个参考设置断点〕。同样下了断点。                                      <br />
快捷方式：Ctrl+N <br />
2.  在命令行窗口中输入BPX  API函数名或者BP  API函数名 后回车。这时出现了所有调用这个函数的地址的窗口，在这个窗口中可以看到调用这个API函数的地址已改变了颜色。说明下好了断点。 <br />
说明一下：BPX一般中断在程序调用API的地址处。BP会中断在API的写入地址处。二这有所不同，根据需要选择。 <br />
   优点：这种方法下的断点是针对每一个API函数的，所以具有明确的目的。 <br />
   缺点：关键的API函数不容易找到。所以有时下的断点没有作用。<br /> <br /><b>内存断点（跟踪关键数据的断点） </b><br />
   Ollydbg中的内存断点相当于TRW中的bpm 断点。 <br />
下断点的方法是：在程序运行中断时选择界面中的转存窗口，用光标选择内存中的一段关键数据（颜色会改变），然后右击鼠标出现功能菜单。选择〔断点〕项，其中有二个选择〔内存访问〕和〔内存写入〕。 <br />
〔内存访问〕断点是程序运行时要调用被选择的内存数据时就会被Ollydbg中断，根据这个特点在破解跟踪时只要在关键数据内存中下中断就可以知道程序在
什么地方和什么时候用到了跟踪的数据。对于一些复杂算法和流程变态的算法跟踪有很大的帮助。从破解上讲，一个注册码的生成一定是由一些关键数据或者原始数
据计算来的。所以在内存中一定要用到这些关键数据。那么〔内存访问〕断点就是最好的中断方法。 <br />
〔内存写入〕断点是程序运行时向被选择的内存地址写入数据时就会被Ollydbg中断。根据这个特点在破解时可以跟踪一个关键数据是什么时候生成的，生成的代码段在那个地方。所以一个关键的数据如果不知道他的由来就可以用〔内存访问〕断点查找计算的核心。 <br />
内存中断的下断点还有另外的一种方法：程序运行时如果知道关键的数据，比如我们输入的试验码、程序生成的序列号等。这时在内存中一定存在这些数据。用
Alt+M打开内存窗口，在这个窗口中搜索知道的关键数据。用光标选择这些数据同样下内存中断，这种方法更容易找的关键的数据。 <br />
优点：断点是直接面向关键数据的，所以比较容易到核心部分。 <br />
缺点：内存断点重新运行后会消失，干扰比较多。 <br /><br /><b> 硬件断点（跟踪关键标志的断点） </b><br />
硬件断点是Olldbg所特有的断点，他不会因为重新运行就销毁，只要不删除。跟踪这个程序时就有效。但他在98系统下会不起作用。 <br />
硬件断点是根据关键标志回逆到关键代码的好方法。下中断的方法和内存断点的方法相同，有三个方式〔硬件访问〕、〔硬件写入〕、〔硬件执行〕。一般用前2
个。他也同样有内存断点的特性，所以可以用内存断点的地方也可以用硬件断点。这里介绍利用他来跟踪注册标志的使用方法，一般软件的注册都用到了标志比较。
即在内存地址中有一个标志，在判断是不是注册时比较标志的值。不同的值表示不同的注册状态。这个标志的地址一般比较固定。根据这个特点可以下硬件断点来跟
踪标志位是什么地方被标志的。 <br />
方法：在转存窗口中选择到标志存放的内存地址处，然后选择标志值。下〔硬件写入〕中断（根据标志的字节下不同的长度）。重新运行程序你会发现
Ollydbg会不断的中断在这个标志的内存地址处。在功能菜单的〔调试〕选项下选择〔硬件断点〕就打开了硬件断点的窗口，在这个窗口中选择〔跟踪〕，这
时转存窗口就会来到被下中断的内存地址处。运行程序跟踪内存地址中的值就会知道被赋标志的代码，跟踪到计算的核心。〔硬件访问〕的使用可以知道程序在运行
时多少地方用到了这个注册标志。对于破解复杂效验的程序十分的有效。 <br />
直接在命令栏里下bh ****硬件断点<br /><span class="pediy"><br /><br /></span><img src ="http://www.cnitblog.com/textbox/aggbug/52089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2008-11-30 13:45 <a href="http://www.cnitblog.com/textbox/archive/2008/11/30/52089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Cracker 笔记1</title><link>http://www.cnitblog.com/textbox/archive/2008/11/30/52077.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Sun, 30 Nov 2008 03:46:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2008/11/30/52077.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/52077.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2008/11/30/52077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/52077.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/52077.html</trackback:ping><description><![CDATA[
		<b>逆向分析基础知识</b>
		<br />
 <br /><b>1.1 调用约定</b> <br />
 <br />
在分析汇编代码时总是要遇到无数的Call，对于这些Call，尽量要根据Call之前传递的参数和Call的返回值来判断Call的功能。传递参数的工作必须由函数调用者和函数本身来协调，计算机提供了一种被称为栈的数据结构来支持参数传递。<br />
 <br />
当参数个数多于一个时，按照什么顺序把参数压入堆栈。函数调用后，由谁来把堆栈恢复。在高级语言中，通过函数调用约定来说明这两个问题。常见的调用约定有：<br />
 <br /><img style="cursor: pointer;" title="http://bbs.pediy.com/upload/bbs/faq/call.gif" src="http://bbs.pediy.com/upload/bbs/faq/call.gif" alt="此图已经缩小，点击察看原图。" onload="if(this.width&gt;screen.width*0.6) {this.width=screen.width*0.6;this.alt='此图已经缩小，点击察看原图。';}" onmouseover="this.style.cursor='pointer';" onclick="window.open('http://bbs.pediy.com/upload/bbs/faq/call.gif');" border="0" width="614" /> <br />
 <br />
 <br />
【例】按__stdcall约定调用函数test2(Par1, Par2) <br />
 <br />
 <br />
push par2 ; 参数2<br />
push par1 ; 参数1<br />
call test2;<br />
{<br />
push ebp ; 保护现场原先的EBP指针<br />
mov ebp, esp ; 设置新的EBP指针，指向栈顶<br />
mov eax, [ebp+0C] ; 调用参数2<br />
mov ebx, [ebp+08] ; 调用参数1<br />
sub esp, 8 ; 若函数要用局部变量，则要在堆栈中留出点空间<br />
…<br />
add esp, 8 ; 释放局部变量占用的堆栈<br />
pop ebp ; 恢复现场的ebp指针<br />
ret 8 ; 返回（相当于ret; add esp,8）<br />
}<br />
 <br />
 <br />
其堆栈调用示意图：<br />
 <br /><img style="cursor: pointer;" title="http://bbs.pediy.com/upload/bbs/faq/callesp.gif" src="http://bbs.pediy.com/upload/bbs/faq/callesp.gif" alt="http://bbs.pediy.com/upload/bbs/faq/callesp.gif" onload="if(this.width&gt;screen.width*0.6) {this.width=screen.width*0.6;this.alt='此图已经缩小，点击察看原图。';}" onmouseover="this.style.cursor='pointer';" onclick="window.open('http://bbs.pediy.com/upload/bbs/faq/callesp.gif');" border="0" /> <br />
 <br />
 <br /><div style="margin: 10px 20px 20px;"><fieldset><legend><smallfont><strong>资料</strong></smallfont></legend>  <br /><b><a href="http://bbs.pediy.com/showthread.php?t=38234" target="_blank"><font color="darkblue">函数调用堆栈变化分析</font></a></b><br /></fieldset></div><br /><b>1.2 局部变量</b> <br />
 <br />
在子程序内部说明的变量称为局部变量，局部变量的作用域是其所在的子程序。从汇编角度来看，局部变量就是一个临时堆栈缓存，用完释放。<br />
例如这个实例：<a href="http://bbs.pediy.com/upload/bbs/faq/local.zip" target="_blank"><font color="darkblue">附件:local.zip</font></a> <br />
 <br />
其反汇编代码如下（红体字为局部变量）：<br />
 <br />
00401000 &gt;/$ 6A 04 push 4 ; /Arg2 = 00000004<br />
00401002 |. 6A 03 push 3 ; |Arg1 = 00000003<br />
00401004 |. E8 16000000 call 0040101F ; \Add.0040101F<br />
00401009 |. 8BD8 mov ebx, eax<br />
0040100B |. 6A 00 push 0 ; /ExitCode = 0<br />
0040100D \. FF15 00204000 call [&lt;&amp;KERNEL32.ExitProcess&gt;] ; \ExitProcess<br />
 <br />
 <br />
0040101F /$ 55 push ebp ; 保护现场原先的EBP指针<br />
00401020 |. 8BEC mov ebp, esp ; 设置新的EBP指针，指向栈顶<br />
00401022 |. 83EC 04 sub esp, 4 ; 分配局部变量所有空间<br />
00401025 |. 8B45 0C mov eax, [ebp+C] ; 调用参数2<br />
00401028 |. 8B5D 08 mov ebx, [ebp+8] ; 调用参数1<br />
0040102B |. 895D FC mov <font color="red">[ebp-4]</font> , ebx ; 参数1放局部变量里<br />
0040102E |. 0345 FC add eax,<font color="red">[ebp-4]</font> ; 参数2与局部变量相加<br />
00401031 |. 83C4 04 add esp, 4 ; 释放局部变量所有空间<br />
00401034 |. 5D pop ebp ; 恢复现场的ebp指针<br />
00401035 \. C2 0800 retn 8<br />
 <br />
 <br /><b>1.3 返回值</b> <br />
 <br />
在调试程序时，不要见Call就跟进，在Call之前所做的所有PUSH动作以及对寄存器的操作都可能是在给函数传递参数，而函数的返回值一般都放在EAX里面，当然这个值可能是一个指针，指向一个数据结构。从汇编角度来看，主要有如下形式：<br />
 <br />
1)通过寄存器返回函数值；<br />
2)通过参数按引用方式返回函数值；<br />
3)通过全局变量返回函数值；<br />
4)通过处理器标志返回函数值；<br />
一般情况下，由retrun操作符返回的值放在EAX寄存器之中，如果结果超过这个寄存器的位容量，那么该结果的高32位会加载到EDX寄存器中。 如果
返回一个含有几百个字节的结构或者一个近似大小的对象，编译器会在不告诉程序的情况下，给函数传递一个隐式参数，这个指针指向保存的返回结果。<br />
 <br />
 <br /><b>1.4 启动函数</b> <br />
 <br />
在编写Win32应用程序时，都必须在源码里实现一个WinMain函数。但Windows程序执行并不是从WinMain函数开始的，首先被执行的是启
动函数相关代码，这段代码是编译器生成的。启动代码完成初始化进程，再调用WinMain。标准编译器通常包含启动代码在内的库文件源码，例如
Visual C++中，启动代码存放在CRT\SRC\crt0.c文件中。<br />
所有的C/C++运行时启动函数的作用基本都是相同的：检索指向新进程的命令行指针，检索指向新进程的环境变量指针，全局变量初始化，内存堆栈初始化等。当所有的初始化操作完毕后，启动函数就调用应用程序的进入点函数。<br />
调用WinMain如下所示：<br />
GetStartupInfo (&amp;StartupInfo);<br />
Int nMainRetVal = WinMain(GetModuleHandle(NULL),NULL,pszCommandLineAnsi,(StartupInfo.dwFlags&amp;STARTF_USESHOWWINDOW)?StartupInfo.wShowWindow:SW__SHOWDEFAULT);<br />
当进入点返回时，启动函数便调用C运行库期的exit函数，将返回值（nMainRetVal）传递给它，进行一些必要处理，最后调用系统函数ExitProcess退出。 其他一些编译器，如Delphi、BorLand C++开发包中都有相应的启动代码。<br />
在绝大数情况下，我们对启动代码并不需要关心。 对于逆向分析人员来说，首要的任务是找到Winmain函数。 <br />
 <br />
WinMain函数原型如下：<br />
int WINAPI WinMain(<br />
HINSTANCE hInstance, // 当前实例的句柄<br />
HINSTANCE hPrevInstance, // 前一个实例的句柄 <br />
LPSTR lpCmdLine, // 命令行的指针 <br />
int nCmdShow // 窗口的显示状态<br />
); <br />
其中参数hInstance一般通过GetModuleHandleA函数进行获取的，这对识别WinMain函数有些帮助。另外，对WinMain的调
用通常放在启动函数代码结尾部分，后面通常跟着诸如exit或XcptFilter之内的两、三个函数。例如下面这段代码：<br />
.text:004010DC push eax ; nShowCmd<br />
.text:004010DD push [ebp+lpCmdLine] ; lpCmdLine<br />
.text:004010E0 push esi ; hPrevInstance<br />
.text:004010E1 push esi ; lpModuleName<br />
.text:004010E2 call ds:GetModuleHandleA<br />
.text:004010E8 push eax ; hInstance<br />
.text:004010E9 call WinMain(x,x,x,x)<br />
.text:004010EE mov [ebp+var_60], eax<br />
.text:004010F1 push eax ; int<br />
.text:004010F2 call _exit<br />
 <br />
许多开发人员可以得到启动源代码的情况下对启动代码进行修改，这样，程序的执行可能不是从WinMain开始，而是从任何其他的函数开始<br /><br /><b>1.5 API函数</b> <br />
 <br />
现在很多讲Windows程序设计的书都是讲基于MFC库和OWL库的Windows设计，对Windows实现的细节都鲜有讨论，而调试程序都是和系统
底层打交道，所以有必要掌握一些Win32 API函数的知识，这样我们可快捷地找出程序调用错在哪？是哪个参数出了问题。<br />
Windows程序模块包括KERNEL、USER和GDI，其中KERNEL完成内存管理、程序的装人与执行和任务调度等功能，它需要调用原MS?
DOS中的文件管理、磁盘输入输出和程序执行等功能；USER是一个程序库，它用来对声音、时钟、鼠标器及键盘输入等操作进行管理；GDI是一功能十分丰
富的子程序库，它提供了图形与文字输出、图象操作和窗口管理等各种与显示和打印有关的功能。上述KERNEL、USER和GDI模块中的库函数可被应用程
序调用，也可被其他程序模块调用。把包含库函数的模块称为输出者（export）。你应明白为什么跟踪软件时经常在KERNEL32!.text和
USER32.text等系统领空转的问题吧。<br />
 <br />
这里列出几个经常碰到的Win 32 API函数，它们都是存在Windows系统核心文件KERNEL32.DLL中和视窗管理文件USER32.DLL中。<br />
Windows函数是区分字符集的：A表示ANSI，W表示Wide，即Unicode (Wide character-set)，前者就是通常使用的
单字节方式，但这种方式处理象中文这样的双字节字符不方便，容易出现半个汉字的情况。而后者是双字节方式，方便处理双字节字符。Windows的所有与字
符有关的函数都提供两种方式的版本。尽管你编程时使用GetWindowText，但实际上编译程序会根据设置自动调用GetWindowTextA或
GetWindowTextW。函数的最后一个字母告诉我们函数是使用单字节还是双字节字符串。<br />
 <br />
1、 Hmemcpy函数<br />
void hmemcpy(hpvDest, hpvSource, cbCopy) <br />
void _huge* hpvDest; // 目的数据地址 <br />
const void _huge* hpvSource; // 源数据地址 <br />
long cbCopy; // 数据大小 (Bytes) <br />
这个函数在KERNEL32.DLL中，它很常用，俗称万能断点，但一般的编程书籍上很少提到，原因它是底层的东西，没有特殊需要，一般不直接调用。但的确它是很有用的！有意思的是它执行的操作很简单，只是将内存中的一块数据拷贝到另一个地方。<br />
注意：此函数只在Windows 9x系统上有效，在Win NT/2K系统上相关的函数是memcpy，但在Win NT/2K上不同于Windows 9x上，很少再调用memcpy来处理数据了，用此函数设断基本上什么也拦不住。<br />
 <br />
2、 GetWindowText函数<br />
此函数在USER32.DLL用户模块中，它的作用是复制指定窗口中的字符到缓冲区。函数原型：<br />
int GetWindowText(<br />
HWND hWnd//欲获取文字的那个窗口的句柄 <br />
LPTSTR lpString //预定义的一个缓冲区，至少有cch+1个字符大小；随同窗口文字载入 <br />
int nMaxCount//lpString缓冲区的长度<br />
);<br />
16位：GetWindowText<br />
32位：GetWindowTextA，GetWindowTextW<br />
 <br />
3、 GetDlgItemText<br />
此函数在USER32.DLL用户模块中，它的作用是返回对话框中某一个窗口的标题或文字。函数原型：<br />
UINT GetDlgItemText(<br />
HWND hDlg, // 对话框句柄<br />
int nIDDlgItem, //控制标识符<br />
LPTSTR lpString, / 预定义的一个字符缓冲区<br />
int nMaxCount// 字符缓冲区的长度<br />
);<br />
16位：GetDlgItemText<br />
32位：GetDlgItemTextA，GetDlgItemTextW<br />
 <br />
4、 MessageBox函数<br />
此函数是在USER32.DLL用户模块中，它的作用创建、显示和操作信息框。函数原型：<br />
int MessageBox(<br />
HWND hWnd, //窗口句柄<br />
LPCTSTR lpText, // 信息框中文字的地址<br />
LPCTSTR lpCaption, // 信息框标题地址<br />
UINT uType // 信息框类型<br />
);<br />
16位：MessageBox<br />
32位：MessageBoxA，MessageBoxW<br />
 <br />
学习API函数最好的资料就是《Windows程序设计》这本书，下面列出其他一些参考资料：<br /><fieldset><legend><smallfont><strong>API函数资料</strong></smallfont></legend>  <br /><a href="http://spiff.tripnet.se/%7Eiczelion/files/win32api.zip" target="_blank"><font color="darkblue"><b>Win32 API reference（推荐）</b></font> </a><br /><a href="http://www.pediy.com/document/API32.CHM" target="_blank"><font color="darkblue"><b>Windows API 函数手册（774个Win32函数，中文） </b></font></a><br /><a href="http://www.pediy.com/tutorial/chap5/Chap5-1.htm" target="_blank"><font color="darkblue"><b>常见断点列表 </b></font></a></fieldset><br /><img src ="http://www.cnitblog.com/textbox/aggbug/52077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2008-11-30 11:46 <a href="http://www.cnitblog.com/textbox/archive/2008/11/30/52077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>