OllyDbg常用断点
- 格式:doc
- 大小:17.08 KB
- 文档页数:17
od 加密函数断点
OD加密函数断点是指在使用OD(OllyDbg)调试工具时,针对
特定的加密函数设置断点以便分析其加密算法和过程。
在进行OD加
密函数断点时,我们通常需要考虑以下几个方面:
1. 加密函数的位置,首先需要在程序中定位到需要分析的加密
函数的位置,可以通过静态分析或动态调试的方式找到函数的入口点。
2. 加密算法分析,一旦设置了断点,当程序执行到加密函数时,我们可以逐步跟踪代码的执行过程,观察寄存器和内存的变化,以
便分析加密算法的具体实现方式。
3. 输入输出数据分析,通过断点可以观察到加密函数的输入和
输出数据,我们可以分析这些数据的结构和变化规律,以便理解加
密过程中数据的转换和变换。
4. 调试技巧,在设置加密函数断点时,需要灵活运用OD调试
工具提供的功能,比如条件断点、内存监视等,以便更好地分析加
密函数的执行过程。
总之,在进行OD加密函数断点时,我们需要综合运用静态分析和动态调试的方法,结合加密算法分析和输入输出数据分析,以便全面深入地理解加密函数的实现原理和运行过程。
这样能够帮助我们更好地理解程序的加密机制,为安全分析和逆向工程提供有力支持。
OD下断点的方法OD下断点的方法寻常断点Ollydbg中一般下中断的方法,就是在程序的地址处用鼠标选择这一行。
然后按F2键,这时被选择的那一行的地址会变成别的颜色,就表示这个地址处下了中断。
然后运行程序时只有到这个地址处就会被Ollydbg中断。
这个方法用的比较多,所以把他称作寻常断点。
如果有命令行插件,就可以在命令窗口中输入BPX xxxxxxxx 下断点。
优点:只要自己怀疑是重要的代码处都可以下这种下断点,不受条件的限制,所以方便实用。
缺点:如果不知道代码功能下断点具有盲目性。
API断点Ollydbg中一般下API中断的方法,有二种。
1. 在代码窗口中点鼠标右键,出现功能菜单。
在[搜索]选择项下有〔当前模块的名称〕和〔全部模块的名称〕俩项,选择其中的一项就打开了程序调用API的窗口,在这个窗口中选择你要跟踪的API函数名。
双击这个函数就能到程序的调用地址处。
然后用F2下中断。
也可以在API窗口中选择需要跟踪的函数点鼠标右键出现功能菜单,选择〔在每个参考设置断点〕。
同样下了断点。
快捷方式:Ctrl+N2. 在命令行窗口中输入BPX API函数名或者BP API函数名后回车。
这时出现了所有调用这个函数的地址的窗口,在这个窗口中可以看到调用这个API函数的地址已改变了颜色。
说明下好了断点。
说明一下:BPX一般中断在程序调用API的地址处。
BP会中断在API的写入地址处。
二这有所不同,根据需要选择。
优点:这种方法下的断点是针对每一个API函数的,所以具有明确的目的。
缺点:关键的API函数不容易找到。
所以有时下的断点没有作用。
内存断点(跟踪关键数据的断点)Ollydbg中的内存断点相当于TRW中的bpm 断点。
下断点的方法是:在程序运行中断时选择界面中的转存窗口,用光标选择内存中的一段关键数据(颜色会改变),然后右击鼠标出现功能菜单。
选择〔断点〕项,其中有二个选择〔内存访问〕和〔内存写入〕。
〔内存访问〕断点是程序运行时要调用被选择的内存数据时就会被Ollydbg中断,根据这个特点在破解跟踪时只要在关键数据内存中下中断就可以知道程序在什么地方和什么时候用到了跟踪的数据。
Ollydbg破解教学之万能断点篇(共5篇)第一篇:Ollydbg破解教学之万能断点篇Ollydbg破解教学之万能断点篇(图)安全中国*********************************.ar时间:22.Dec.2oo2 内容: 在Windows XP里用OllyDbg 学习使用与WIN98功效相似的万能断点法POINT H。
附件:感谢Crackslatinos List的所有成员。
第二篇:破解习作教学之“难”破解习作教学之“难”在有些小学语文教师眼中,习作教学之“难”,堪称“难于上青天”。
一是拿到一篇习作教材,不知道该教什么,更不明白该从什么地方教起;二是每次教学唯恐不够,“教”了很多,但是儿童却“无动于衷”;三是难以把握“教”的尺度,如果指导过细便千篇一律,如果不指导,不少学生又会无从下笔。
习作教学到底难不难?作为写作教学的起步阶段,由国家提供优质的课程教材来实施,有丰富的教学资源来支持,答案应当是肯定的――不难!可是为什么会变“难”呢?通过一次校本教研习作教学活动,可以透视出藏在“难”背后的深层原因。
这次活动的主题是“习作教学内容‘阶梯型’建构”,主要从苏教版教材中选定习作内容――“我的发现”,在三年级、四年级、五年级分别进行教学内容的建构和设计。
执教前,我和执教的三位教师,通过研读教材共同确定了一个拾级而上的教学内容:在专题活动操作过程中,我们越来越清楚地感觉到,解决习作教学之“难”其实就在教学过程本身的操作细节上。
一、教学内容做到“步步为营”习作教学要走“小步子”,要保持一种“慢慢走,欣赏啊”的姿态,切不可贪多求全。
关于“观察”的教学内容,可以切分成许多前后勾连、全程贯通的小“格子”:方位观察、时间观察、动静观察、联想观察、整体与局部观察、体验式观察等等,将每一项内容排成一个循序渐进的阶梯,逐层分布在几个年级里“教”,步步为营,可能效果会更好。
推而广之,将各类文体写作知识进行梳理,结合教材,精心细分,每一次教学“弱水三千只取一瓢饮”,这样才会教得深入、透彻,让每个儿童得到扎实的训练。
方的韩国Ollydbg(以下均简称为OD)中的硬件断点的主要原理是:将要下断点的内存地址放入调试寄存器对应的选项中,由调试寄存器将其断下,并报异常给OD,等待调试人员操作。
硬件断点的长度有3种情况:1个字节(1)、2个字节(2)、4个字节(4)硬件标识有8种情况:未知(0)、执行断点(1)、访问断点(2)、写入断点(3)、未知(4)、临时断点(5)、未知(6)、未知(7)临时断点主要用于单步跳过OD在以下结构体中存放了以下硬件断点的信息:第一个4字节:硬件断点的首地址第二个4字节:硬件断点的长度第三个4字节:硬件断点的标识下面三个4字节:未知004D8D70 7A 06 40 00 01 00 00 00 02 00 00 00 00 00 00 00 z @. ... .......004D8D80 00 00 00 00 00 00 00 00 00 00 00 00 ............通过分析,硬件断点表的设置、断点表的添加以及断点表的删除都是由不同的函数来完成的,一共有三个函数。
这里硬件断点表的添加和删除要特别说明一下,函数中会在添加断点表时检查调试线程是否是运行状态,如果是运行状态就会进入一个判断函数,并查看是否需要断下。
写完断点表后,断点的处理就不需要由这两个函数来完成了。
这里先概括的介绍其流程,下面再详细分析代码:添加硬件断点表(Sethardwarebreakpoint):该函数有三个参数:断点首地址、断点长度、断点标识(访问、写入、执行断点等等)1、判断是何种类型的断点,若是可执行断点的话,下断的内存长度只能是1,而且会强制设为1;2、若为断点类型不为4(这个还没有逆向出来)的话,要判断下断的内存长度是否是4的倍数,如果不是则退出;3、判断下断的内存长度是否为1、2、4,如果都不符合,则退出;4、读取硬件断点表数据,用于下面的比较;5、循环判断当前断点是否已经存在在硬件断点表中,判断的方法如下:a) 判断断点类型是否相同,不同则判断表中的下一个元素;b) 断点地址是否相同,相同则继续,不同则判断原先的断点是否命中在当前断点地址之中,若在其中,则修改原先的断点地址和长度,若不在其范围内,则判断下一个元素;c) 断点长度是否相同,相同则继续,不同则如同b的处理;d) 判断4个硬件调试寄存器是否已经用完,若用完了,则弹出硬件断点对话框,传入参数为1,要求用户必须删掉一个断点,若不删除,则退出;e) 若为类型为5、6、7的话,直接退出;f) 若有空余的寄存器元素,则把当前的断点信息赋值;6、检查线程是否运行,线程信息结构体是否存在,若没有运行则跳过下面的处理,直接退出;7、暂停所有活动线程;8、遍历所有线程,查询硬件断点表,EIP的地址是否等于断点表中的地址,判断方法如下:a) 设置调试寄存器属性为CONTEXT_DEBUG_REGISTERS,并得到线程环境,若得到线程环境失败则查询下一个线程;b) 根据硬件断点表中的数据修改线程环境结构体数据;c) 遍历整个硬件断点表,判断表中是否有值,若无则继续检查下一个;d) 根据硬件断点的不同做相应的处理,主要是设置调试寄存器的dr7;e) 遍历完硬件断点表后,使用SetThreadContext函数将线程环境设置回去;f) 继续遍历线程9、重启线程并退出函数00451CE3 . 6A 03 push 3 ; BreakPoint_Flag00451CE5 . 6A 01 push 1 ; BreakPoint_Len00451CE7 . 8B4D B0 mov ecx, dword ptr [ebp-50] ; |00451CEA . 51 push ecx ; | BreakPoint_Addr00451CEB . E8 A069FBFF call _Sethardwarebreakpoint ; \_Sethardwarebreakpoint该函数主要有三个参数:断点首地址、断点长度、断点标识(访问、写入、执行断点)00408690 >/$ 55 push ebp00408691 |. 8BEC mov ebp, esp00408693 |. 81C4 24FDFFFF add esp, -2DC00408699 |. 53 push ebx0040869A |. 56 push esi0040869B |. 57 push edi0040869C |. 8B75 10 mov esi, dword ptr [ebp+10] ;断点标识0040869F |. 8B7D 08 mov edi, dword ptr [ebp+8] ;断点首地址004086A2 |. 833D 5C374D00>cmp dword ptr [4D375C], 0004086A9 |. 75 08 jnz short 004086B3004086AB |. 83C8 FF or eax, FFFFFFFF004086AE |. E9 2F030000 jmp 004089E2一个switch…case循环体,用来判断要设置什么类型的硬件断点:004086B3 |> 83FE 01 cmp esi, 1 ;比较是否是执行断点004086B6 |. 74 0F je short 004086C7 ;跳转到处理函数004086B8 |. 83FE 05 cmp esi, 5004086BB |. 74 0A je short 004086C7004086BD |. 83FE 06 cmp esi, 6004086C0 |. 74 05 je short 004086C7004086C2 |. 83FE 07 cmp esi, 7004086C5 |. 75 09 jnz short 004086D0 ;如果都不是,跳到下面处理处理执行断点:004086C7 |> C745 0C 01000>mov dword ptr [ebp+C], 1 ;设置断点长度为1 004086CE |. EB 21 jmp short 004086F1 ;跳转到长度处理比较该断点标识是不是4004086D0 |> 83FE 04 cmp esi, 4004086D3 |. 75 08 jnz short 004086DD004086D5 |. 81E7 FFFF0000 and edi, 0FFFF ; Case 4004086DB |. EB 14 jmp short 004086F1 ;跳转到长度处理比较该断点标识是不是0004086DD |> 85F6 test esi, esi004086DF |. 74 10 je short 004086F1 ;跳转到长度处理断点标识为1、2、3时检查断点的长度及地址是否按内存对齐:004086E1 |. 8B55 0C mov edx, dword ptr [ebp+C] ; Default004086E4 |. 4A dec edx004086E5 |. 85FA test edx, edi004086E7 |. 74 08 je short 004086F1 ;跳转到长度处理004086E9 |. 83C8 FF or eax, FFFFFFFF ;内存不对齐则返回错误004086EC |. E9 F1020000 jmp 004089E2断点长度检查处理:004086F1 |> 837D 0C 01 cmp dword ptr [ebp+C], 1 ; Case 0004086F5 |. 74 14 je short 0040870B ;长度为一跳转004086F7 |. 837D 0C 02 cmp dword ptr [ebp+C], 2004086FB |. 74 0E je short 0040870B ;长度为二跳转004086FD |. 837D 0C 04 cmp dword ptr [ebp+C], 400408701 |. 74 08 je short 0040870B ;长度为四跳转00408703 |. 83C8 FF or eax, FFFFFFFF ;长度不为1 / 2 / 4时,返回错误00408706 |. E9 D7020000 jmp 004089E2查询断点表,要下的断点是否在表中,如果是则直接返回:0040870B |> B8 708D4D00 mov eax, 004D8D70 ;004D8070是断点表的首地址00408710 |. 33D2 xor edx, edx00408712 |. 8955 F8 mov dword ptr [ebp-8], edx00408715 |. 33DB xor ebx, ebx00408717 |> 8B50 08 /mov edx, dword ptr [eax+8]0040871A |. 85D2 |test edx, edx ;查询表是否有记录0040871C |. 74 3E |je short 0040875C ;没有则跳转到下一个记录结构体0040871E |. 3BF2 |cmp esi, edx ;比较断点类型是否相同00408720 |. 75 3A |jnz short 0040875C ;不同则跳转到下一个记录结构体如果要下的断点在断点表某个断点的范围内,则直接返回:00408722 |. 3B38 |cmp edi, dword ptr [eax] ;比较断点首地址与断点表地址00408724 |. 72 15 |jb short 0040873B ;断点首地址小则跳转00408726 |. 8B08 |mov ecx, dword ptr [eax]00408728 |. 8B55 0C |mov edx, dword ptr [ebp+C]0040872B |. 0348 04 |add ecx, dword ptr [eax+4]0040872E |. 03D7 |add edx, edi00408730 |. 3BCA |cmp ecx, edx ;比较断点尾地址与断点表尾地址00408732 |. 72 07 |jb short 0040873B ;断点尾地址大则跳转00408734 |. 33C0 |xor eax, eax00408736 |. E9 A7020000 |jmp 004089E2 ;跳转到结束处如果要下的断点在断点表中存在,则直接返回:0040873B |> 3B38 |cmp edi, dword ptr [eax] ;比较断点首地址与断点表地址0040873D |. 77 1D |ja short 0040875C ;断点首地址大则跳转0040873F |. 8B08 |mov ecx, dword ptr [eax]00408741 |. 8B55 0C |mov edx, dword ptr [ebp+C]00408744 |. 0348 04 |add ecx, dword ptr [eax+4]00408747 |. 03D7 |add edx, edi00408749 |. 3BCA |cmp ecx, edx ;比较断点尾地址与断点表尾地址0040874B |. 77 0F |ja short 0040875C ;断点尾地址小则跳转0040874D |. 8938 |mov dword ptr [eax], edi0040874F |. 8B4D 0C |mov ecx, dword ptr [ebp+C]00408752 |. 8948 04 |mov dword ptr [eax+4], ecx00408755 |. C745 F8 01000>|mov dword ptr [ebp-8], 1跳转到下一个结构体中:0040875C |> 43 |inc ebx0040875D |. 83C0 1C |add eax, 1C00408760 |. 83FB 04 |cmp ebx, 400408763 |.^ 7C B2 \jl short 00408717 如果断点表没访问完,继续比较查询断点是否包含在断点表中,包含则跳转到标识检查:00408765 |. 837D F8 00 cmp dword ptr [ebp-8], 000408769 |. 0F85 91000000 jnz 00408800通过检查断点表中的标识,判断断点表是否已满:0040876F |. 33DB xor ebx, ebx00408771 |. B8 788D4D00 mov eax, 004D8D7800408776 |> 8338 00 /cmp dword ptr [eax], 000408779 |. 74 09 |je short 00408784 ;如果有空位,跳转到下面处理0040877B |. 43 |inc ebx0040877C |. 83C0 1C |add eax, 1C0040877F |. 83FB 04 |cmp ebx, 400408782 |.^ 7C F2 \jl short 00408776 ;若断点表没访问完,继续比较如果断点表未满,则跳转到设置断点表代码中去:00408784 |> 83FB 04 cmp ebx, 400408787 |. 7C 40 jl short 004087C9如果断点表已满,比较断点标识,如果小于5则跳转到处理函数:00408789 |. 83FE 05 cmp esi, 5 ;标识为5,返回-10040878C |. 74 0A je short 004087980040878E |. 83FE 06 cmp esi, 6 ;标识为6,返回-100408791 |. 74 05 je short 0040879800408793 |. 83FE 07 cmp esi, 7 ;标识为7,返回-100408796 |. 75 08 jnz short 004087A000408798 |> 83C8 FF or eax, FFFFFFFF0040879B |. E9 42020000 jmp 004089E2 ;跳转到函数结束处断点表已满处理函数(弹出对话框选择在断点表中删除一个断点来放置现在的断点):004087A0 |> 6A 01 push 1 ; /Arg1 = 00000001004087A2 |. E8 AD070000 call _Hardbreakpoints ; \_Hardbreakpoints004087A7 |. 59 pop ecx004087A8 |. 85C0 test eax, eax ;查看是否有删除断点表中的值004087AA |. 74 08 je short 004087B4 ;如果有删除则跳转到下面检查空位004087AC |. 83C8 FF or eax, FFFFFFFF004087AF |. E9 2E020000 jmp 004089E2 ;如果选择取消,则返回-1这里检查断点表中是否有空位,没有则报错,并返回-1:004087B4 |> 33DB xor ebx, ebx004087B6 |. B8 788D4D00 mov eax, 004D8D78004087BB |> 8338 00 /cmp dword ptr [eax], 0 ;比较断点表的标识变量004087BE |. 74 09 |je short 004087C9 ;如果为0则跳转004087C0 |. 43 |inc ebx ;比较下一个表中的值004087C1 |. 83C0 1C |add eax, 1C004087C4 |. 83FB 04 |cmp ebx, 4004087C7 |.^ 7C F2 \jl short 004087BB ;如果没有比较完,继续比较004087C9 |> 83FB 04 cmp ebx, 4 ;查看断点表中有多少个值004087CC |. 7C 13 jl short 004087E1 ;如果断点表不满则跳转到下面004087CE |. 68 040D4B00 push 004B0D04; /当前没有空闲的位置进行新的硬件中断。
OllyDBG 入门系列(五)-消息断点及 RUN 跟踪作者:CCDebuger找了几十个不同语言编写的 crackme,发现只用消息断点的话有很多并不能真正到达我们要找的关键位置,想想还是把消息断点和 RUN 跟踪结合在一起讲,更有效一点。
关于消息断点的更多内容大家可以参考 jingulong 兄的那篇《几种典型程序Button处理代码的定位》的文章,堪称经典之作。
今天仍然选择 镜像打包中的一个名称为 cycle 的 crackme。
按照惯例,我们先运行一下这个程序看看:我们输入用户名 CCDebuger,序列号 78787878,点上面那个“Check”按钮,呵,没反应!看来是要注册码正确才有动静。
现在关掉这个 crackme,用 PEiD 查一下壳,原来是 MASM32 / TASM32 [Overlay]。
启动 OllyDBG 载入这个程序,F9让它运行。
这个程序按我们前面讲的采用字串参考或函数参考的方法都很容易断下来。
但我们今天主要学习的是消息断点及 RUN 跟踪,就先用消息断点来断这个程序吧。
在设消息断点前,有两个内容我们要简单了解一下:首先我们要了解的是消息。
Windows 的中文翻译就是“窗口”,而 Windows 上面的应用程序也都是通过窗口来与用户交互的。
现在就有一个问题,应用程序是如何知道用户作了什么样的操作的?这里就要用到消息了。
Windows 是个基于消息的系统,它在应用程序开始执行后,为该程序创建一个“消息队列”,用来存放该程序可能创建的各种不同窗口的信息。
比如你创建窗口、点击按钮、移动鼠标等等,都是通过消息来完成的。
通俗的说,Windows 就像一个中间人,你要干什么事是先通知它,然后它才通过传递消息的方式通知应用程序作出相应的操作。
说到这,又有个问题了,在 Windows 下有多个程序都在运行,那我点了某个按钮,或把某个窗口最大化,Windows 知道我是点的哪个吗?这里就要说到另一个内容:句柄(handle)了。
Ollydbg常用快捷键,各类断点Ollydbg常用快捷键:Alt+E →Modules窗口,查找输入函数Ctrl+N →查找名称标志,选择你要下断的内容Shift+F9 →强制继续执行跟踪或称拦截信息步进跟踪F12 →暂时停止F10 →打开反汇编选项菜单F9 →运行键F8 →单步跟踪结束F7 →单步跟踪F3 →打开快捷键F2 →下断点快捷键Ctrl+F9 →返回到跟踪Ctrl+F8 →自动步进扫描,按F12可停止Ctrl+F7 →同上,功能略有不同Ctrl+F6 →回到OL主窗口Ctrl+F2 →重新开始Art+F2 →结束跟踪Enter →进制转换计算Art+L →打开日志窗口Art+C →快速回到程序入口Ctrl+S →打开查找命令次序窗口Shift+F2 →打开附加选项窗口Shift+F4 →打开条件对话窗Ctrl+E →编辑机器码Ctrl+G →输入跟随地址Space →填充或修改汇编内容(NOP修改)断点设置列表一般处理bpx hmemcpybpx MessageBoxbpx MessageBoxExAbpx MessageBeepbpx SendMessagebpx GetDlgItemTextbpx GetDlgItemIntbpx GetWindowTextbpx GetWindowWordbpx GetWindowIntbpx DialogBoxParamAbpx CreateWindowbpx CreateWindowExbpx ShowWindowbpx UpdateWindowbmsg xxxx wm_movebmsg xxxx wm_gettextbmsg xxxx wm_commandbmsg xxxx wm_activate时间相关bpint 21 if ah==2A (DOS)bpx GetLocalTimebpx GetFileTimebpx GetSystemtimeCD-ROM 或磁盘相关bpint 13 if ah==2 (DOS) bpint 13 if ah==3 (DOS)bpint 13 if ah==4 (DOS)bpx GetFileAttributesAbpx GetFileSizebpx GetDriveTypebpx GetLastErrorbpx ReadFilebpio -h (Your CD-ROM Port Address) R软件狗相关bpio -h 278 Rbpio -h 378 R键盘输入相关bpint 16 if ah==0 (DOS)bpint 21 if ah==0xA (DOS)文件访问相关bpint 21 if ah==3dh (DOS) bpint 31 if ah==3fh (DOS)bpint 21 if ah==3dh (DOS)bpx ReadFilebpx WriteFilebpx CreateFilebpx SetFilePointerbpx GetSystemDirectoryINI 初始化文件相关bpx GetPrivateProfileStringbpx GetPrivateProfileIntbpx WritePrivateProfileStringbpx WritePrivateProfileInt注册表相关bpx RegCreateKeybpx RegDeleteKeybpx RegQueryValuebpx RegCloseKeybpx RegOpenKey注册标志相关bpx cs:eip if EAX==0内存标准相关bpmb cs:eip rw if 0x30:0x45AA==0显示相关bpx 0x30:0x45AA do "d 0x30:0x44BB"bpx CS:0x66CC do "? EAX"密码常用中断Hmemcpy (win9x专用)GetDlgItemTextAGetDlgItemIntvb:getvolumeinFORMationavbastrcomp (trw)Bpx __vbaStrComp (记得是两个'_')MSVBVM60!_vbastrcomp|soficeMSVBVM50! |VBAI4STRCtrl+Dbpx msvbvm60!__vbastrcomp do "d *(esp+0c)"(softice)按几次F5出册码出来了。
od 硬件条件断点
OD (OllyDbg) 是一款用于调试二进制应用程序的工具,它可
以在执行程序时设置断点并检查程序的状态。
要在OD中设置硬件条件断点,你需要遵循以下步骤:
1. 打开OllyDbg,并加载要调试的二进制程序。
2. 找到你想要设置断点的位置。
这可以是一个特定的内存地址,也可以是程序中的某个函数。
3. 在OllyDbg的菜单栏上选择 "Breakpoints" > "Hardware breakpoints"。
4. 在 "Hardware breakpoints" 窗口中,点击 "New" 按钮。
5. 在弹出的窗口中,选择 "Condition" 选项卡。
6. 在 "Condition" 选项卡中,输入你想要设置的条件,例如要
求寄存器的值等于某个特定值。
7. 点击 "OK" 按钮保存设置。
8. 回到主OllyDbg窗口,你将看到硬件条件断点已添加到"Browse breakpoints" 窗口中。
9. 启动程序,并当程序执行到设置的断点位置时,程序会停止执行并等待你进一步调试。
请注意,硬件条件断点只在特定条件满足时触发断点,因此你需要确保设置的条件是合适的,并且可以满足在期望的情况下触发断点。
此外,硬件断点通常会影响程序的执行速度,因此在调试大型程序时,设置过多的硬件条件断点可能会导致性能下降。
第十一章:硬件断点与条件断点下面我们将把剩下的类型的断点介绍完,本章先介绍硬件断点和条件断点。
硬件断点硬件断点(简称:HBP)是处理器的特性之一,它的工作原理我不是很了解,但是我们会用就行了,我们可以设置硬件断点使程序中断下来。
在OD中我们最多可以设置4个硬件断点,如果想设置第5个的话,你需要删除已经设置了的4个中的其中一个。
跟之前一样,我们还是拿CrueHead'a的CrackMe来做实验。
硬件断点分为:硬件执行断点(ON EXECUTION),硬件写入断点(ON WRITE),硬件访问断点(ON ACCESS)3种。
硬件执行断点与普通的CC断点作用一样,但硬件执行断点并不会将指令首字节修改为CC,所以更难检测。
但是有些程序会使用一些技巧来清除硬件断点,应对方法我们会在后面的章节介绍。
如果你想在401013处设置硬件执行断点的话,请在401013这一行单击鼠标右键选择-Breakpoint-Hardware,on execution。
也可以在命令栏中输入:这样可以设置硬件执行断点。
OD中有个特殊的窗口,通过它我们可以查看和管理硬件断点。
我们选择菜单栏中的Debug-Hardware breakpoints就可以打开这个窗口。
在硬件断点窗口中,如果我们单击Follow按钮,反汇编窗口中该硬件断点所对应的那一行指令就会灰色高亮显示。
如果我们单击Delete按钮,那么相应的硬件断点就会被清除。
现在按F9键运行程序。
中断在401013处。
正如你所看到的,起到的效果跟普通的CC断点有点像,如果你像对CC断点做的测试-MOV EAX,DWORD PTR DS:[401013]一样的话,你会发现机器码并没有改变。
在401000这一行单击鼠标右键选择-New origin here将EIP修改为401000,接着按F7键单步。
可以看到EAX的值为0004A6E8,内存的形式为E8 A60400,机器码并没有发生变化。
OllyDBG断点INT3 断点INT3 断点是在汇编指中向下断地址写⼊0xCC指令,当被调试进程执⾏INT3指令时产⽣异常,调试器就会捕获这个异常,从⽽停在断点处。
在OllyDBG中使⽤快捷键F2来设置或取消断点。
硬件断点硬件断点和DRx调试寄存器有关。
DRx调试寄存器共有8个(DR0-DR7),硬件断点的原理是使⽤DR0-DR7设置地址,并使⽤DR7设置状态,所以最多设置4个断点。
设置硬件断点的快捷键是F4内存断点OD可以设置内存访问或写⼊断点,原理是对所设置的地址赋予不可访问/不可写属性,这样当访问/写⼊的时候就会产⽣异常。
OD捕获异常后,⽐较异常地址是不是断点地址,如果是中断。
OllyDBG设置内存断点的⽅式:点击View -> Memory调出内存窗⼝,在需要下断点的地⽅右击选择set memory breakpoint on write内存访问⼀次性断点windows对内存使⽤段页式的管理⽅式。
在OD⾥按“Alt+M”快捷键显⽰内存,可以看到许多个段,每个段都有不可访问、读、写、执⾏属性。
在相应的段上点击右键,会在快捷菜单中发现⼀个命令“set memory breakpoint on access”,⽤于对整个内存块设置断点。
这个断点是⼀次性的,当所在段被读取或执⾏时就会中断。
如果想捕获调⽤或返回某个模块,该类断点就⾮常有⽤。
消息断点Windows本⾝是由消息驱动的,如果调试时没有合适的断点,可以尝试使⽤消息断点,当某个特定窗⼝函数接受到某个指定消息时,消息断点将使程序中断。
消息断点与INT 3断点的区别在于:INT 3断点可以在程序启动之前设置,消息断点只有在窗⼝被创建之后才能被设置并拦截消息的断点设置⽅法:View -> Windows列出窗⼝中相关参数OD⽆法反汇编代码逆向脱ASPack壳找OEP时发现程序在跳转到OEP后OD⽆法分析出代码,如下图。
按Ctrl+A或者右键删除分析即可。
OllyDbg 常用断点完全教程断点[Breakpoints]OllyDbg支持数种不同类型的断点:- 一般断点[Ordinary breakpoint], 将您想中断的命令的第一个字节,用一个特殊命令INT3(调试器陷阱)来替代。
您可以在反汇编窗口中选中要设断点的指令行并按下F2 键就可以设定一个此类型的断点。
也可以在快捷菜单中设置。
再次按下F2 键时,断点将被删除。
注意,程序将在设断指令被执行之前中断下来。
INT3断点的设置数量是没有限制的。
当您关闭被调试程序或者调试器的时候,OllyDbg将自动把这些断点保存到硬盘中,永远不要试图在数据段或者指令的中间设置这种断点,如果您试图在代码段以外设置断点,OllyDbg将会警告。
您可以在安全选项[Security options]中永远关闭这个提示,在某些情况下调试器会插入自带的临时INT3断点。
- 条件断点[Conditional breakpoint](快捷键Shift+F2)是一个带有条件表达式的普通INT3断点。
当调试器遇到这类断点时,它将计算表达式的值,如果结果非零或者表达式无效,将暂停被调试程序,当然,由条件为假的断点引起的开销是非常高的(主要归因于操作系统的反应时间)。
在Windows NT、奔腾Ⅱ/450处理器环境下OllyDbg每秒最多处理2500个条件为假的断点。
条件断点的一个典型使用情况就是在Windows消息上设置断点(比如WM_PAINT)。
为此,您可以将伪变量MSG 同适当的参数说明联合使用。
如果窗口被激活,参考一下后面的消息断点描述。
- 条件记录断点[Conditional logging breakpoint](Shift+F4)是一种条件断点,每当遇到此类断点或者满足条件时,它将记录已知函数表达式或参数的值。
例如,您可以在一些窗口过程函数上设置记录断点并列出对该函数的所有调用。
或者只对接收到的WM_COMMAND消息标识符设断,或者对创建文件的函数(CreateFile)设断,并且记录以只读方式打开的文件名等,记录断点和条件断点速度相当,并且从记录窗口中浏览上百条消息要比按上百次F9轻松的多,您可以为表达式选择一个预先定义好的解释说明。
Ollydbg破解教学之万能断点篇(图)安全中国 更新时间:2008-9-6 0:30:57 责任编辑:流火热点:终于有一点时间总结一下OD破解的经验,有许多大侠们都认为OD不能下万能断点,可是有些软件的破解需要用到万能断点,以前一直没有这方面的资料,有的只是OD不能下万能断点的断言,一时心恢之极,可是我原来用TRW和SICE用的挺好,谁知系统又跟我闹矛盾,一用TRW和SICE就死机,没办法我现在只能用OD,我写的一些破解文章都是用OD破的,反复试验,我终于发现OD也能下万能断点,在我以前写的一些文章中好象有一篇简单提到过,但没有说的很详细,这次静下心,想写一点东西,送给我心爱的组织DFCG吧,我的破解是从DFCG组织起步的,很感谢DFCG的高手们的帮助,在此说声谢谢!为了更明确,这次破解所使用的调试器OD是从看雪论坛临时下载的OD1.09的汉化版,没有使用我自己手头经过改造的OD,在此也感谢看雪论坛,这里真的有很多高手,在这个论坛我也学到了很多.这次破解的对象是超级XX王,为保护国产软件我隐去了软件相关信息,我不想给自己带来麻烦,现在工作很忙,能少一点麻烦就尽量少一点吧.破解作者yzez[DFCG]破解工具ollydbg1.09汉化版,看雪论坛下载.破解目的本不为破解而破解,只因为技术而破解破解环境WINDOWS XP,这个我已经在98和XP下各做了两次,贴图和我这篇文章是在XP系统下完成的.破解过程1.检查了一下,该程序无壳,C++编译,用W32DSM反汇编一堆乱码,我倒!那就动态调试吧!用ollydbg1.09载入程序,这次我将教你们如何用OD下万能断点,过程我尽可能详细一点,下面请看.载入程序选OD菜单栏上的插件-----命令行(快捷键是ALT+F1),在弹出的窗口中输入万能断点命令:bpx hmemcpy,按ENTER键,结果又出现一个对话框:Intermodular calls00401164 CALL DWORD PTR DS:[<&USER32.GetWindowRect>] USER32.GetWindowRect0040118F CALL DWORD PTR DS:[<&USER32.GetClientRect>] USER32.GetClientRect00401279 CALL DWORD PTR DS:[<&USER32.GetClientRect>] USER32.GetClientRect004013E1 CALL DWORD PTR DS:[<&USER32.GetClientRect>] USER32.GetClientRect0040190A CALL DWORD PTR DS:[<&KERNEL32.GetThreadLocale>] kernel32.GetThreadLocale0040191C CALL DWORD PTR DS:[<&KERNEL32.GetLocaleInfoA>] kernel32.GetLocaleInfoA还有很多,我就省略了,在这个框里右键单击,出现一个对话框,选中在每个命令中设置断点(热键是S),单击,你看每一行都变成了红色吧,这表示全部设下断点了,后面的过程很烦燥,你要一边按F9,边按F2把一些无用的断点去掉,有一点耐心吧,当然也可以不这样做,但遇到断点跳不过的时候,你就得按F2把这个断点去掉.感觉在这一点上OD比不上TRW和SICE,到出现注册信息框后,你要输入注册信息,然后按确定,程序被断下来,我的序列号是:GK342QZ0C6RE03L,我输入试验码:123456789098765.程序中断在下面:00471F71 CALL DWORD PTR DS:[<&USER32.GetWindowTex>****按确定后回到OD程序中断在此,按F8走,在此还没有到关键处!*****************************************************注意这里会循环两次,分别处理序列号和试验码,按F8走00471F77 LEA ECX,DWORD PTR DS:[EAX+1]00471F7A PUSH ECX00471F7B MOV ECX,DWORD PTR SS:[EBP+10]00471F7E PUSH EAX00471F7F CALL SuperPIM.0043E15D00471F84 PUSH EAX00471F85 PUSH ESI00471F86 CALL DWORD PTR DS:[<&USER32.GetWindowTex>00471F8C MOV ECX,DWORD PTR SS:[EBP+10]00471F8F PUSH -100471F91 CALL SuperPIM.00401D6A00471F96 JMP SHORT SuperPIM.00471FA300471F98 MOV EAX,DWORD PTR SS:[EBP+10]00471F9B PUSH DWORD PTR DS:[EAX]00471F9D PUSH ESI00471F9E CALL SuperPIM.00470B6100471FA4 POP ESI00471FA5 POP EBP00471FA6 RETN 0C*************************************程序第二次循环后最后会返回到0040FE99下面看代码:----------------------------------------------------------------------------------------------------------0040FE99 LEA EAX,DWORD PTR SS:[EBP-14]****第二次循环后会返回到这里,注意这就是我们要找的关键地方,按F8往下!0040FE9C PUSH EAX0040FE9D CALL SuperPIM.00433D92***********这就是关键CALL,按F7追进,一定要进,因为算法就在这里面!0040FEA2 POP ECX0040FEA3 AND DWORD PTR SS:[EBP-4],00040FEA7 LEA ESI,DWORD PTR DS:[EDI+74]0040FEAA MOV EAX,DWORD PTR DS:[ESI]******试验码入EAX0040FEAC CMP DWORD PTR DS:[EAX-C],0******比较试验码输入了吗?0040FEB0 JE SHORT SuperPIM.0040FF2F******没有输入就跳走,一跳就失败!0040FEB2 PUSH 280040FEB4 LEA EAX,DWORD PTR SS:[EBP-18]0040FEB7 PUSH ESI0040FEB8 PUSH EAX0040FEB9 CALL SuperPIM.0042CEC8**********此CALL对输入的注册码进行处理,得到一个40位的长字符串,有兴趣自己跟,******************************************我已是头晕的很,不想跟进!0040FEBE LEA ECX,DWORD PTR SS:[EBP-14]0040FEC1 PUSH ECX0040FEC2 PUSH EAX0040FEC3 CALL SuperPIM.0040F9B7**********此CALL对序列号处理,也是得到一个40位的长字符串0040FEC8 MOV ECX,DWORD PTR SS:[EBP-18]0040FECB ADD ESP,140040FECE ADD ECX,-100040FED1 MOV BYTE PTR SS:[EBP-D],AL0040FED4 CALL SuperPIM.00401B5D**********此CALL进行比较,注册码不对,值为00040FED9 CMP BYTE PTR SS:[EBP-D],0*******比较是0吗?0040FEDD JE SHORT SuperPIM.0040FF2F******相等就跳,跳就失败,所以一定不能跳!0040FEDF PUSH 0**************************不跳往下你就成功了!下面代码省略!...............................................................省略若干代码!.........................=============================================================================================================************************************关键CALL的代码!*******************************************************00433D92 MOV EAX, SuperPIM.0049844E****追进关键CALL后我们来到这里!00433D97 CALL SuperPIM.0045090000433D9C PUSH ECX00433D9D PUSH ECX00433D9E AND [LOCAL.5], 000433DA2 LEA EAX, [LOCAL.5]00433DA5 PUSH EAX00433DA6 CALL SuperPIM.00433CA9********此CALL根据电脑硬件信息得到你的序列号,有兴趣跟吧!我是没有兴趣!00433DAB AND [LOCAL.1], 000433DAF PUSH 1400433DB1 LEA EAX, [LOCAL.5]00433DB4 PUSH EAX00433DB5 LEA EAX, [LOCAL.4]00433DB8 PUSH EAX00433DB9 CALL SuperPIM.0042CEC8*******算法CALL(1),按F7跟进!00433DBE PUSH 2800433DC0 LEA EAX, [LOCAL.4]00433DC3 PUSH EAX00433DC4 PUSH [ARG.1]00433DC7 MOV BYTE PTR SS:[EBP-4], 100433DCB CALL SuperPIM.0042CEC800433DD0 MOV ECX, [LOCAL.4]00433DD3 ADD ESP, 1C00433DD6 ADD ECX, -10*****************************省略N行代码!********************************************************0043454B RETN===========================================================================================================***********************************算法CALL!*********************************************************0042CEC8 MOV EAX, SuperPIM.00497B52********追进算法CALL我们在这里!0042CECD CALL SuperPIM.004509000042CED2 SUB ESP, 140042CED5 PUSH EBX0042CED6 PUSH ESI0042CED7 XOR EBX, EBX0042CED9 PUSH EDI0042CEDA MOV [LOCAL.8], EBX0042CEDD CALL SuperPIM.004639B50042CEE2 MOV EDX, DWORD PTR DS:[EAX]0042CEE4 MOV ECX, EAX0042CEE6 CALL DWORD PTR DS:[EDX+C]0042CEE9 LEA EDI, DWORD PTR DS:[EAX+10]0042CEEC MOV [LOCAL.4], EDI0042CEEF MOV EAX, [ARG.2]0042CEF2 MOV EAX, DWORD PTR DS:[EAX]*******序列号:GK342QZ0C6RE03L 移入EAX0042CEF4 MOV ESI, DWORD PTR DS:[EAX-C]*****序列号的位数15(十六进制值是F)送入ESI0042CEF7 CMP ESI, EBX**********************比较ESI和EBX,ESI的值是F即序列号位数,EBX的初始值是00042CEF9 MOV [LOCAL.1], EBX0042CEFC MOV [LOCAL.8], ESI0042CEFF JE SuperPIM.0042CFB2*************相等就跳,这里当然不相等,所以就不会跳!0042CF05 MOV EAX, [ARG.3]******************常数14(十进制值是20)送入EAX0042CF08 CMP EAX, ESI**********************比较EAX和ESI,即14和F 比较!0042CF0A MOV [LOCAL.6], EAX0042CF0D JG SHORT SuperPIM.0042CF12*******大于就跳!0042CF0F MOV [LOCAL.6], ESI0042CF12 CMP [LOCAL.6], EBX****************跳到这里!比较14和0 0042CF15 JLE SuperPIM.0042CFB2*************小于就跳,这里当然不会小!所以不跳!0042CF1B MOV EAX, EBX**********************0移入EAX0042CF1D CDQ***********************************EDX清0,准备计算!0042CF1E IDIV ESI***************************除,EAX/ESI ,EAX的值是0,ESI的值存放序列号的位数F0042CF20 MOV EAX, [ARG.2]******************赋EAX地址值0042CF23 MOV EAX, DWORD PTR DS:[EAX]*******序列号:GK342QZ0C6RE03L 移入EAX0042CF25 PUSH EBX***************************EBX入栈0042CF26 MOV AL, BYTE PTR DS:[EDX+EAX]*****序列号的第一位G(ASCII码值47)入AL0042CF29 MOV BYTE PTR SS:[EBP-1C], AL******保存值470042CF2C PUSH [LOCAL.7]0042CF2F CALL SuperPIM.0042CD8E***************************算法CALL(2)*****************************************************0042CD8E PUSH EBP0042CD8F MOV EBP, ESP0042CD91 PUSH ECX*************************G的ASCII码值47入ECX 0042CD92 MOVZX EAX, BYTE PTR SS:[EBP+8]****扩展成000000470042CD96 MOV ECX, [ARG.2]****************赋ECX的初始值为00042CD99 MOV [LOCAL.1], EAX0042CD9C MOV EAX, ECX********************ECX的值移入EAX0042CD9E IMUL EAX, ECX********************EAX=EAX*ECX=0*00042CDA1 LEA EAX, DWORD PTR DS:[EAX+EAX*2+7]**EAX+EAX*2+7的值7给EAX0042CDA5 IMUL EAX, ECX********************EAX=EAX*ECX=7*00042CDA8 ADD EAX, 0D*********************EAX=EAX+0D=D0042CDAB IMUL EAX, ECX********************EAX=EAX*ECX=D*0=00042CDAE PUSH ESI*************************序列号位数F入栈!0042CDAF LEA ESI, DWORD PTR DS:[ECX+5]0042CDB2 PUSH ESI0042CDB3 MOV [ARG.1], EAX0042CDB6 LEA EAX, [ARG.1]0042CDB9 PUSH 40042CDBB PUSH EAX0042CDBC CALL SuperPIM.0042CD2E***********这个CALL也在计算,我实在不想跟进!0042CDC1 PUSH ESI0042CDC2 LEA EAX, [LOCAL.1]0042CDC5 PUSH 40042CDC7 PUSH EAX0042CDC8 CALL SuperPIM.0042CD5E**********这个CALL也是计算CALL,烦!不跟了!0042CDCD MOV EAX, [ARG.1]0042CDD0 ADD ESP, 180042CDD3 XOR EAX, [LOCAL.1]*************这里赋EAX的值38000002 0042CDD6 POP ESI0042CDD7 LEAVE0042CDD8 RETN======================================================================= ==算法CALL(2)结束==================0042CF34 POP ECX0042CF35 POP ECX0042CF36 PUSH 2B***************************常数2B入栈!0042CF38 XOR EDX, EDX0042CF3A POP ECX**************************把常数2B赋给ECX0042CF3B DIV ECX**************************除,EAX/ECX=38000002/2B=014D6535,余数1B入EDX0042CF3D MOV ECX, EDX*********************结果1B入ECX0042CF3F ADD CL, 30***********************CL=CL+30=1B+30=4B(对应的字符串是K)0042CF42 CMP CL, 39***********************比较是不是数字90042CF45 MOV BYTE PTR SS:[EBP-14], CL*****保存字符串K0042CF48 JLE SHORT SuperPIM.0042CF55******小于就跳走!0042CF4A CMP CL, 41***********************比较是不是A0042CF4D JGE SHORT SuperPIM.0042CF55******大于就跳走0042CF4F ADD CL, 0F60042CF52 MOV BYTE PTR SS:[EBP-14], CL0042CF55 CMP EBX, [ARG.3]*****************跳到这里!比较0和140042CF58 JGE SHORT SuperPIM.0042CF67******大于等于就跳走!0042CF5A PUSH [LOCAL.5]0042CF5D LEA ECX, [LOCAL.4]0042CF60 CALL SuperPIM.00417EAF0042CF65 JMP SHORT SuperPIM.0042CFA5******无条件跳0042CF67 MOV EAX, EBX0042CF69 CDQ0042CF6A IDIV [ARG.3]0042CF6D MOVSX ECX, CL0042CF70 PUSH 2B0042CF72 MOV ESI, EDX0042CF74 MOVSX EAX, BYTE PTR DS:[ESI+EDI]0042CF78 LEA EAX, DWORD PTR DS:[EAX+ECX-60]0042CF7C CDQ0042CF7D POP ECX0042CF7E IDIV ECX0042CF80 ADD DL, 300042CF83 CMP DL, 390042CF86 MOV BYTE PTR SS:[EBP-14], DL0042CF89 JLE SHORT SuperPIM.0042CF960042CF8B CMP DL, 410042CF8E JGE SHORT SuperPIM.0042CF960042CF90 ADD DL, 0F60042CF93 MOV BYTE PTR SS:[EBP-14], DL0042CF96 PUSH [LOCAL.5]0042CF99 LEA ECX, [LOCAL.4]0042CF9C PUSH ESI0042CF9D CALL SuperPIM.0042CE4B0042CFA2 MOV ESI, [LOCAL.8]0042CFA5 MOV EDI, [LOCAL.4]***************上面跳到这里!0042CFA8 INC EBX*************************EBX加10042CFA9 CMP EBX, [LOCAL.6]**************比较1和14 0042CFAC JL SuperPIM.0042CF1B***********小于就跳,循环,序列号只有15位,这里循环20次,取完后又从第一位取出!************************************循环结束后得到的值是:K3L2LPBDW1F2H4B8S0UY这就是我们要的注册码!0042CFB2 MOV ECX, [ARG.1]0042CFB5 LEA EAX, [LOCAL.4]0042CFB8 PUSH EAX0042CFB9 CALL SuperPIM.00401F360042CFBE LEA ECX, DWORD PTR DS:[EDI-10]0042CFC1 CALL SuperPIM.00401B5D0042CFC6 MOV ECX, [LOCAL.3]0042CFC9 MOV EAX, [ARG.1]0042CFCC POP EDI0042CFCD POP ESI0042CFCE POP EBX0042CFCF MOV DWORD PTR FS:[0], ECX0042CFD6 LEAVE0042CFD7 RETN写这篇文章的目的是想说明如何在OD下万能断点,算法过程太烦琐,就不想多跟了!希望能对大家有点启发,如果觉得这篇破文还行帮我顶一下吧!也是希望有更多的人能看到,对更多的人有益,我也是一只菜鸟,请大家多多指点!我的序列号:GK342QZ0C6RE03L注册码:K3L2LPBDW1F2H4B8S0UYWinXP 关于POINT-H万能断点的教程________________________________________标题: 【翻译】WinXP 关于POINT-H万能断点的教程作者: nba2005时间: 2008-04-01,17:26:46链接: /showthread.php?t=62346WinXP 关于POINT-H万能断点的教程【文章标题】: WinXP 关于POINT-H万能断点的教程【文章译者】: NBA2005【作者邮箱】: stockfox1699@【作者QQ号】: 382309369创作《算法分析实战篇和应用篇之提高(一)我的常用断点系统》,顺手对该文进行了翻译,前后共三个小时。
OllyDbg常用断点以前收集的资料,不知道作者是谁了。
很抱歉!--liuyunagangOD常用断点常用断点(OD中)拦截窗口:bp CreateWindow 创建窗口bp CreateWindowEx(A) 创建窗口bp ShowWindow 显示窗口bp UpdateWindow 更新窗口bp GetWindowText(A) 获取窗口文本拦截消息框:bp MessageBox(A) 创建消息框bp MessageBoxExA 创建消息框bp MessageBoxIndirect(A) 创建定制消息框bp IsDialogMessageW拦截警告声:bp MessageBeep 发出系统警告声(如果没有声卡就直接驱动系统喇叭发声)拦截对话框:bp DialogBox 创建模态对话框bp DialogBoxParam(A) 创建模态对话框bp DialogBoxIndirect 创建模态对话框bp DialogBoxIndirectParam(A) 创建模态对话框bp CreateDialog 创建非模态对话框bp CreateDialogParam(A) 创建非模态对话框bp CreateDialogIndirect 创建非模态对话框bp CreateDialogIndirectParam(A) 创建非模态对话框bp GetDlgItemText(A) 获取对话框文本 作用是得指定输入框输入字符串 bp GetDlgItemInt 获取对话框整数值拦截剪贴板:bp GetClipboardData 获取剪贴板数据拦截注册表:bp RegOpenKey(A) 打开子健bp RegOpenKeyEx 打开子健bp RegQueryValue(A) 查找子健bp RegQueryValueEx 查找子健bp RegSetValue(A) 设置子健bp RegSetValueEx(A) 设置子健功能限制拦截断点:bp EnableMenuItem 禁止或允许菜单项bp EnableWindow 禁止或允许窗口拦截时间:bp GetLocalTime 获取本地时间bp GetSystemTime 获取系统时间bp GetFileTime 获取文件时间bp GetTickCount 获得自系统成功启动以来所经历的毫秒数bp GetCurrentTime 获取当前时间(16位)bp SetTimer 创建定时器bp TimerProc 定时器超时回调函数GetDlgItemInt 得指定输入框整数值GetDlgItemText 得指定输入框输入字符串GetDlgItemTextA 得指定输入框输入字符串拦截文件:bp CreateFileA 创建或打开文件 (32位)bp OpenFile 打开文件 (32位)bp ReadFile 读文件 (32位)bp WriteFile 写文件 (32位)GetModuleFileNameAGetFileSizeSetfilepointerfileopenFindFirstFileAReadFile拦截驱动器:bp GetDriveTypeA 获取磁盘驱动器类型bp GetLogicalDrives 获取逻辑驱动器符号bp GetLogicalDriveStringsA 获取当前所有逻辑驱动器的根驱动器路径 ★★VB程序专用断点★★文件长度:RtcFileLenbp __vbaFreeStr 对付VB程序重启验证bp __vbaStrCmp 比较字符串是否相等bp __vbaStrComp 比较字符串是否相等bp __vbaVarTstNe 比较变量是否不相等bp __vbaVarTstEq 比较变量是否相等bp __vbaStrCopy 复制字符串bp __vbaStrMove 移动字符串bp MultiByteToWideChar ANSI字符串转换成Unicode字符串bp WideCharToMultiByte Unicode字符串转换成ANSI字符串=============== ================密码常用中断Hmemcpy (win9x专用)GetDlgItemTextAGetDlgItemIntvb:getvolumeinformationavbastrcomp (trw)Bpx __vbaStrComp (记得是两个 ’_’)MSVBVM60!_vbastrcomp|soficeMSVBVM50! |VBAI4STRCtrl+Dbpx msvbvm60!__vbastrcomp do "d *(esp+0c)"(softice)按几次F5出册码出来了。
个有机会Ollydbg(以下均简称为OD)中的Int3断点的主要功能是:在需要下断点的执行代码处将原来的代码改成0xCC,程序执行到此处后会报一个Int3异常,由OD捕获并处理。
当要执行该行代码时,将原来的代码改回来并执行,然后再恢复断点,这样就不会影响程序的正常运行了。
这里仅描述最常见的功能,其它的有兴趣的话可以分析一把。
先说明一下OD中的两个结构体,在IDA中,声明为如下格式:t_bpoint用来保存Int断点的相关信息00000000 t_bpoint struc ; (sizeof=0x11)00000000 addr dd ? ; // Address of breakpoint00000004 dummy dd ? ; // Always 100000008 type dd ? ; // Type of breakpoint, TY_xxx0000000C cmd db ? ; // Old value of command0000000D passcount dd ? ; // Actual pass count00000011 t_bpoint ends其中:addr为断点的地址,dummy始终为1,type为断点的类型,cmd为要用0xCC替换的指令码,passcount为需要断下的次数,0表示每次都断下。
t_sorted结构体保存了一种有序的数据:00000000 ; Descriptor of sorted table00000000 t_sorted struc ; (sizeof=0x138)00000000 name[MAXPA TH] db 260 dup(?) ; char Name of table, as appears in error messages00000104 n dd ? ; int Actual number of entries00000108 nmax dd ? ; int Maximal number of entries0000010C selected dd ? ; int Index of selected entry or -100000110 seladdr dd ? ; ulong Base address of selected entry00000114 itemsize dd ? ; int Size of single entry00000118 version dd ? ; ulong Unique version of table0000011C data dd ? ; void* Elements, sorted by address00000120 sortfunc dd ? ; SORTFUNC Function which sorts data or NULL00000124 destfunc dd ? ; DESTFUNC Destructor function or NULL00000128 sort dd ? ; int Sorting criterium (column)0000012C sorted dd ? ; int Whether indexes are sorted00000130 index dd ? ; int Indexes, sorted by criterium00000134 suppresserr dd ? ; int Suppress multiple overflow errors00000138 t_sorted endsname是结构体的名称,用来区别不同类型的结构体n是数组元素的个数itemsize是数组元素的大小data 是指向各种数据结构数组的指针,这里使用的是int3断点,所以现在保存的是int3断点数据结构体数组的指针---------------------------------------------------------------------------------------------------------------------------------1)Int3断点的设置int3断点的设置是通过消息来处理的,对应右键点击菜单中的切换,其对应的消息为1E;此外还有热键F2、双击反汇编窗口等也能切换int3断点,转入的函数虽然不同,但是调用设置int3断点的函数都是同一个,就不再举例了。
第十章-断点本章将介绍各种类型的断点。
断点可以让你在程序代码执行到合适的时候暂停下来。
这次我们的实验的对象还是CrueHead’a的CrackMe。
普通断点这是一个很普通的断点,我们前面章节已经使用了。
在SoftIce中我们可以使用BPX命令来设置断点。
OD中可以使用BP命令或者F2快捷键来设置断点。
也可以再按一次F2快捷键来取消断点。
我们来到CrueHead’a的CrackMe的入口点处。
举个例子,拿401018这行来说吧,按F2键-这行就会以红色突出显示,在该地址处设置的断点就会加入了断点列表中。
我们来看看断点列表刚刚设置的断点,此时该断点是激活状态。
断点列表中Active栏显示的是Always。
在该行上单击鼠标右键会弹出一些操作断点的菜单项。
Remove:从列表中删除断点。
Disable:禁用断点但并不将断点从列表中删除。
禁用时,断点并不会触发。
Edit condition:给断点设置触发条件,我们后面再来讨论。
Follow in disassembler:在反汇编窗口中显示断点。
Disable all or enable all:禁用/启用列表中的全部断点。
这里没有启用的选项,因为列表中唯一的断点没有被禁用。
Copy to Clipboard:把选中断点的信息复制到剪贴板。
我们来实验一下。
我们选择Whole line拷贝整行,Whole Table可以拷贝整个列表的断点信息。
Breakpoints, item 0Address=00401018Module=CRACKMEActive=AlwaysDisassembly=OR EAX,EAX拷贝下来的信息显示了断点的地址,对应的指令以及激活状态。
按下F9键-CrackMe运行起来了。
然后正如猜想的一样中断了下来。
在状态栏显示暂停状态。
暂停的原因如下:我们来了解一下当设置一个断点以后,二进制代码会发生什么变化。
单击鼠标右键选择-Follow in Dump-Selection我们看看数据窗口中401018地址处的内容:我们初看一下数据窗口中的内容和反汇编代码中代码是一样的:数据窗口和反汇编代码中我们看到的都是0B C0,对应的是OR EAX,EAX。
风格Ollydbg(以下均简称为OD)中的内存断点的主要功能是:修改要下内存断点的内存页属性,如访问断点就设置禁止访问、执行断点就设置禁止执行。
这样当程序要用到这个内存页时就会报异常,由OD捕获,OD比较一下是否是下了断点的内存区域,如果不是就继续执行,否则就断下等待调试人员操作。
内存断点的添加、设置以及判断部分是由不同的函数处理的,先说一下这三个函数的关系,然后写出其流程,最后分析代码:内存断点添加函数一般只是设置内存断点信息表,并不修改内存访问属性,若是在运行状态时设置内存断点,则会修改内存页属性;内存断点设置函数是在按下F9时才会被调用的,并且每走一步调用一次,其主要作用就是根据内存断点信息表设置内存页属性;内存断点处理函数则是在一个大的异常处理函数中的一部分,OD通过异常事件结构体处理对应的各种异常,下面只提取有关的部分进行分析。
OD中用一个结构体来存储内存断点的信息,且只能下一个内存断点,下第二个断点会将前面的记录覆盖:第一个4字节 00000000 未知第二个4字节 00400654 标识内存断点首地址第三个4字节 00000004 内存断点字节的长度第四个4字节 00400000 内存断点首地址所在内存页的地址第五个4字节 00401000 内存断点尾地址所在内存页的地址第六个4字节 00000001 01-标识内存访问断点 20-标识内存写入断点第七个4字节 00000000 未知004D8138 00 00 00 00 33 05 40 00 02 00 00 00 00 00 40 00 ....3 @. .....@.004D8148 00 10 40 00 01 00 00 00 00 00 00 00 . @. .......此外还有一个存放内存信息的结构体:typedef struct t_memory { // Memory block descriptorulong base; // Base address of memory blockulong size; // Size of blockulong type; // Service information, TY_xxxulong owner; // Address of owner of the memoryulong initaccess; // Initial read/write accessulong access; // Actual status and read/write accessulong threadid; // Block belongs to this thread or 0char sect[SHORTLEN]; // Name of module sectionchar *copy; // Copy used in CPU window or NULLulong reserved[8]; // Reserved for plugin compatibility} t_memory;首先是添加部分的函数:1. 内存断点的添加是通过消息来处理的,而且反汇编窗口和数据窗口的消息还不一样,这样就有了两组对应的消息,数据窗口中:访问断点-7Eh、写入断点-7Fh、清除断点-80h;反汇编窗口中:访问断点-23h、写入断点-24h、清除断点-25h;2. 将Setmembreakpoint函数参数传入,让函数做相应的处理。
OllyDbg常用断点查找子健bp RegSetValue(A) 设置子健bp RegSetValueEx(A) 设置子健程序专用断点:BP __vbaObjSet (功能限制----灰色按钮中断)bp __vbaFreeObjListbp __vbaVarDupbp MessageBoxA 窗口断点bp __vbaStrMoveBP __vbaFreeVarListbpx hmemcpybp ShellExecuteA (弹出网页窗口断点)bp rtcMsgBox (杀窗专用)bp __vbaStrCmpbp __vbaVarMovebp VarBstrCmp(字符串比较真码!!)bp __vbaStrCmp 字符串比较文件长度:RtcFileLenbp __vbaFreeStr 对付VB程序重启验证bp __vbaStrCmp 比较字符串是否相等bp __vbaStrComp 比较字符串是否相等bp __vbaVarTstNe 比较变量是否不相等bp __vbaVarTstEq 比较变量是否相等bp __vbaStrCopy 复制字符串bp __vbaStrMove 移动字符串bp MultiByteToWideChar ANSI字符串转换成Unicode字符串bp WideCharToMultiByte Unicode字符串转换成ANSI字符串bp __vbaStrCompbp __vbaStrCompVarbp __vbaStrTextCmpbp __vbaFileOpenbp __vbaInputFilebp __vbaFileSeekbp __vbaWriteFilebp __vbaFileClosebp rtcFileAttributesbp rtcFileDateTimebp rtcFileLenbp rtcFileLengthbp __vbaVarIntbp __vbaVarCmpGebp __vbaVarCmpGtbp __vbaVarCmpLebp __vbaVarCmpLtbp __vbaVarCmpNebp __vbaVarTextCmpEqbp __vbaVarTextCmpGebp __vbaVarTextCmpGtbp __vbaVarTextCmpLebp __vbaVarTextCmpLtbp __vbaVarTextCmpNebp __vbaVarTextTstEqbp __vbaVarTextTstGebp __vbaVarTextTstGtbp __vbaVarTextTstLebp __vbaVarTextTstLtbp __vbaVarTextTstNebp __vbaVarTstEq (字符串比较)bp __vbaVarTstGebp __vbaVarTstGtbp __vbaVarTstLebp __vbaVarTstLtbp __vbaVarTstNe注意:VB程序仍然可以使用普通API函数,只要函数“最终”CALL了这个函数上面的断点对应VB6程序,如果是VB5程序则将msvbvm60改成msvbvm50即可bpx hmemcpy 破解万能断点,拦截内存拷贝动作 (注意:Win9x专用断点,XP无效) bpx Lockmytask 当你用其它断点都无效时可以试一下,这个断点拦截按键的动作实在找不到断点可以试下面的方法:bmsg handle wm_gettext 拦截注册码(handle为对应窗口的句柄)bmsg handle wm_command 拦截OK按钮(handle为对应窗口的句柄)拦截窗口:bpx CreateWindow 创建窗口bpx CreateWindowEx(A/W) 创建窗口bpx ShowWindow 显示窗口bpx UpdateWindow 更新窗口bpx GetWindowText(A/W) 获取窗口文本拦截消息框:bpx MessageBox(A) 创建消息框bpx MessageBoxExA 创建消息框bpx MessageBoxIndirect(A) 创建定制消息框拦截警告声:bpx MessageBeep 发出系统警告声(如果没有声卡就直接驱动系统喇叭发声)vbaStrMove 移动字符串__vbaVarCat 连接字符串rtcMidCharVar 在字符串中取字符或者字符串!__vbaLenBstr 取字符串的长度vbaVarTstNe 变量比较vbaVarTstEq 变量比较rtcMsgBox 显示对话框VarBstrCmp 比较字符串VarCyCmp 比较字符串用OD载入脱壳后的程序,在命令行输入:bpx hmemcpy,然后回车,会弹出程序运行调用的所有的函数,在每个函数上设置好断点!说明:我破VB程序喜欢用这个断点设置方法,通过一步步跟踪,基本可以把握程序保护的思路,所以我破VB程序基本用这个断点,当然你可以用其它的断点,只要能找到关键,任何断点都是用意义的。
关于VB的程序,注册没有提示的二个办法:第一(提示错误):用GetVBRes来替换里面的提示串,一般是以‘111111’,‘222222’之类的替换因为:VB,用的字来存放提示还有加了点东东,我们用的工具一般是字节分析。
换成‘22222’之类的就是字节了,用静态分析,就有你该的串了。
GetVBRes(网上很多,自己下吧)第二(没有提示):用vbde这个工具(不知道,有没有用过DEDE,是一样思路),主要是找出破解的按钮窗口的位置,来进行跟踪。
先给出修改能正确反编译VB程序的W32DASM的地址:======================offsets 0x16B6C-0x16B6D修改机器码为: 98 F4======================VB程序的跟踪断点:============MultiByteToWideChar,rtcR8ValFromBstr,WideCharToMultiByte,__vbaStrCmp__vbaStrComp__vbaStrCopy__vbaStrMove__vbaVarTstNertcBeeprtcGetPresentDate (时间API)rtcMsgBox=========时间限制断点:================CompareFileTimeGetLocalTimeGetSystemTimeGetTimeZoneInformationmsvcrt.diffTime()msvcrt.Time()================VB断点查找方法1,VB6.0编写,OD载入程序调出注册窗口,alt+e调出可执行模块窗口找到X:\WINDOWS\system32\MSVBVM60.DLL双击,在ctrl+n调出窗口找到,名称XXXXXXE区段=ENGINE 导出__vbaVarMove双击来到下面地址(可以直接在命令行 bp __vbaVarMove)回到程序注册窗口点注册被拦断在刚才下断的地址,断后在ctrl+F9,F8回2,OD载入程序,命令行下断点。
bp rtcMsgBox堆栈友好提示确定注册失败按钮返回。
接着向上找出点注册按钮执行的代码第一句,可以吗?当然行,根据我们知道程序员写一个事件执行的代码是如这种,各种语言都差不多。
3,OD载入程序,命令行下断点。
bp rtcMsgBox任意填入伪注册码 9999999999999999999确定后中断堆栈友好提示确定注册失败按钮返回。
W32Dasm反汇编程序,Shiht+F124,VB中的messagebox是一个消息框,汇编中用rtcMsgBox下断点.用olldbg载入程序,Alt+e,在可执行文件模块中找到Msvbvm60.dll,双击它,在代码窗口点右键-搜索-当前模块中的名称中的rtcMsgBox函数,双击它,在6A362F29 55 PUSH EBP这一句双击下断点,关掉多余的窗口,只留下cpu调试主窗口,F9运行程序,点?号按钮,随便输入987654321后,回车后立即中断,然后Ctrt+f9执行到返回地址,因为这是msvbvm60的领空,我们要回到程序领空.秘密记事本弹出message错误提示信息,点确定,向上看 ,再按F8就回到5,为Microsoft Visual Basic 6.0。
先用SmartCheck找到程序比较注册码点,6,用vb常用比较断点vbastrcmpvbastrcompvbavartsteq在od中设断点找注册码7,用Od载入程序,运行,填入上面的注册码和顺序号。
在Od中下断点,Alt+E,双击Msvbvm60运行库,右键-搜索当前模块中的名称,找到Vbastrcmp,双击下断点。
--------------------------注意:VB程序仍然可以使用普通API函数,只要函数“最终”CALL了这个函数上面的断点对应VB6程序,如果是VB5程序则将msvbvm60改成msvbvm50即可★注意:上面所列函数末尾有带“A”的,有带“W”的,有不带后缀的;一般说来,如果函数同时可以有后缀也可以没有后缀(形如:MessageBox(A/W)),则不带后缀的表示16位的函数(MessageBox),带后缀的(MessageBoxA、MessageBoxW)表示32位的函数;通常优先使用带后缀(A或W)的断点,带A后缀的一般用于WIN9X系统,而带W后缀的一般用于NT系统;如果函数没有任何后缀,则表示这是个通用的跨平台的API函数。
功能限制拦截断点:bp EnableMenuItem 禁止或允许菜单项bp EnableWindow 禁止或允许窗口拦截时间:bp GetLocalTime 获取本地时间bp GetSystemTime 获取系统时间bp GetFileTime 获取文件时间bp GetTickCount 获得自系统成功启动以来所经历的毫秒数bp GetCurrentTime 获取当前时间(16位)bp SetTimer 创建定时器bp TimerProc 定时器超时回调函数GetDlgItemInt 得指定输入框整数值GetDlgItemText 得指定输入框输入字符串GetDlgItemTextA 得指定输入框输入字符串拦截文件:bp CreateFileA 创建或打开文件 (32位)bp OpenFile 打开文件 (32位)bp ReadFile 读文件 (32位)bp WriteFile 写文件 (32位)GetModuleFileNameAGetFileSizeSetfilepointerfileopenFindFirstFileAReadFile拦截驱动器:bp GetDriveTypeA 获取磁盘驱动器类型bp GetLogicalDrives 获取逻辑驱动器符号bp GetLogicalDriveStringsA 获取当前所有逻辑驱动器的根驱动器路径★★VB程序专用断点★★=============== ================密码常用中断Hmemcpy (win9x专用)GetDlgItemTextAGetDlgItemIntvb:getvolumeinformationavbastrcomp (trw)Bpx __vbaStrComp (记得是两个’_’)MSVBVM60!_vbastrcomp|soficeMSVBVM50! |VBAI4STRCtrl+Dbpx msvbvm60!__vbastrcomp do "d *(esp+0c)"(softice)按几次F5出册码出来了。