http://blog.fishc.com/698.html
让编程改变世界
Change the world by program
OD使用教程3
亲爱的鱼油们:当您看到这教程的时候,小甲鱼做了两个非常艰难的决定。
决定一,我们的OllyDBG使用教程将进一步给大家解释所以然,因为市面上几乎所有的教程都是告诉你应该怎么做,但是没有告诉你为什么要这么做。很简单,因为要把原理层面说清楚,需要有大量的知识积累和时间来准备。
决定二,我们的OllyDBG使用教程将大量使用实例来进行破解和逆向分析,不再停留于理论层面。
最后,从这节课开始,鸡冻吧?!
大家先一起来看看今天准备上我们“砧板”的程序吧:reverseMe.exe(reverse就是逆向的意思,一般程序用这样的名字意思就像美国西部故事片的女主角最喜欢的台词:fuck me的意思)
让我们废话少说,开刀吧!
这回我们边讲解会边给大家介绍一些必须必要掌握的内容,如果你听过小甲鱼的《零基础入门学习汇编语言》,那么你会觉得这些内容很熟悉,如果没有,我会大概快速讲讲。
关于寄存器
寄存器就好比是CPU身上的口袋,方便CPU随时从里边拿出需要的东西来使用。
今天的程序中我们涉及到九个寄存器:
EAX:扩展累加寄存器
EBX:扩展基址寄存器
ECX:扩展计数寄存器
EDX:扩展数据寄存器
ESI:扩展来源寄存器
EDI:扩展目标寄存器
EBP:扩展基址指针寄存器
ESP:扩展堆栈指针寄存器
EIP:扩展的指令指针寄存器
这些寄存器的大小是32位(4个字节),他们可以容纳数据从0-FFFFFFFF(无符号数),除了以下三个寄存器,其他我们都可以随意使用:
EBP:主要是用于栈和栈帧,由于刚开始接触,不用担心太多,小甲鱼会逐渐给你介绍的。
ESP:指向当前进程的栈空间地址。
EIP:总是指向下一条要被执行的指令。
关于栈
栈是在内存中的一部分,它有两个特殊的性质:
FILO(Fisrt In Last Out,先进后出)
地址反向增长(栈底为大地址,栈顶为小地址)
关于CALL指令
很多朋友都问过如何“找CALL”,但很遗憾,从没有朋友问过为什么要“找CALL”。
call XXX; 等于 push eip; 然后 jmp XXX;
call有以下几种方式:
call 404000h ;直接跳到函数或过程的地址
call eax ;函数或过程地址存放在eax
call dword ptr [eax]
call dword ptr [eax+5]
call dword ptr [<&API>] ;执行一个系统API
中
关于系统API
Windows应用程序运行在Ring3级别(包括我们的倚天剑:OllyDBG)
但有时候需要Ring0级别才能进行操作,那咋整?
我们可以通过系统为我们搭建的桥梁:API函数,我们也称之为系统提供给我们的接口。
因为系统只信任自己提供的函数,所以我们要通过API才能实现对内核的操作。
你可以这么想,假如小甲鱼送给你一辆法拉利跑车,恩,你没听错,是假如,不是真的!那你要怎么来驾驶她?
没错,要通过踩油门来加速,要通过打方向盘来转弯……而油门,方向盘
就是所谓的接口,对于法拉利来说,它们就是API函数。
关于mov指令
mov指令格式:mov dest, src
这是一个很容易理解的指令,mov指令将src的内容拷贝到dest,mov指令总共有以下几种扩展:
movs/movsb/movsw/movsd edi,esi:这些变体按串/字节/字/双字为单位将esi寄存器指向的数据复制到edi寄存器指向的空间。
movsx符号位扩展,byte->word,word->dword (扩展后高位全用符号位填充),然后实现mov。
movzx零扩展,byte->word,word->dword(扩展后高位全用0填充),然后实现mov。
关于cmp指令
cmp指令格式:cmp dest, src
cmp指令比较dest和src两个操作数,并通过比较结果设置C/?O/Z标志位。
cmp指令大概有以下几种格式:
cmp eax, ebx ;如果相等,Z标志位置1,否则0.
cmp eax, [404000] ;将eax和404000地址处的dword型数据相比较并同上置位。
cmp [404000], eax ;同上。
标志位
对于这个概念,建议鱼油以关注苍井空老师的热情去关注它,因为它在破解中起到的作用是至关重要的。
事实上所有的标志位归并与一个32位的标志位寄存器,也就是说有32个不同的标志位。
每个标志位有两个属性:置1或置0,就相当于我们平时说的OK或不OK,OK就买鱼C优盘支持小甲鱼,不OK就看着小甲鱼饿死街头酱紫啦~
哈哈,大家可能更加关注的是32个标志位都要记住?那不折腾死人才怪!
在逆向中,你真正需要关心的标志位只有三个,也就是cmp指令能修改的那三个:Z/O/C。
Z标志位(0标志),这个标志位是最常用的,运算结果为0时候,Z标志位置1,否则置0。
O标志位(溢出标志),在运行过程中,如操作数超出了机器能表示的范围则称为溢出,此时OF位置1,否则置0。
C标志位(进位标志),记录运算时从最高有效位产生的进位值。例如执行加法指令时,最高有效位有进位时置1,否则置0。
下/
逻辑运算
关于test指令
test指令格式:test dest, src
这个指令和and指令一样,对两个操作数进行按位的‘与’运算,唯一不同之处是不将‘与’的结果保存到dest。
即本指令对两个操作数的内容均不进行修改,仅是在逻辑与操作后,对标志位重新置位。
小甲鱼很负责任地告诉大家该指令的实战形态百分之九十九是酱紫:test eax, eax(如果eax的值为0,则Z标志位置1)
关于条件跳转指令
条件跳转指令,就是根据各种不同标志位的条件判断是否成立,条件成立则跳转。
No picture you say a j8…
patch
patch也就是我们平时所说的补丁。
所谓给程序打补丁就是我们对程序破解所进行的修改,就是说像我们衣服破了,如果没有打补丁,就会走光的意思。
OllyDBG的“/”可以查看所有打过的补丁