主题:Od中F2断点深入解析
语言:C,内联asm
平台:win32
工具:vc6.0 od 计算器
*******附件83 85,加不上去,楼下有。。真是做的稀烂。。。自卑。。
哈哈,自我申明,没有什么高深的技术,只是想逼自己做什么都需要动手,高手请过。。(纸上谈来终觉浅,绝知此事要躬行)。。
首先我们知道,在od中下 F2(或vc中F9)断点通常是在运行前编译器,将断点的位置写入int 3(机器码即0xcc),.当被调试的进程执行int3 指令时导致一个异常时,调试器会捕捉这个异常从而停在断点处,然后将断点处的指令恢复原来的指令。就是这样么?我们接下来具体操作操作,由于实际在od中下断处,我们观察内存根本看不见有cc出现(对像我这样的新手来说,其实通过其他方法是可以看到的),让我用小code来证明一下:两个问题
1.是否0xcc被插入。。
2.插入后是否一直恢复了原指令?答案:不是,它还有一个执行完后,继续写回的操作。
证1:code
#include "windows.h"
void Sample()
{
int sum=0;
sum+=2;
MessageBox(NULL,"SampleSelf!","Sample",MB_OK);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
byte *PointA;
PointA=(byte *)Sample; //Sample处下断
if (*PointA==0xcc) //检测
MessageBoxA(0,"CC exist!","Debugger",0);
Sample();
if (*PointA==0xcc)
MessageBoxA(0,"CC exist!","Debugger",0);
}
代码很简单,呵呵。。。我们来看看载入od的结果
1证明成立确实是int 3 插入,这个来论坛没人不知道呵呵。。。
第二条证明,可能有很多像我这样的新手会认为F2断点的原理早已掌握,其实不然。。我可能是个特殊。。
证2代码:
#include<windows.h>
#include<stdio.h>
DWORD Calculation(DWORD StartAddr,DWORD dwCodeLength)
{
_asm
{
xor eax,eax
xor ebx,ebx
mov esi,StartAddr
mov ecx,dwCodeLength
Label1:
mov bl,byte ptr [esi]
add eax,ebx
inc esi
loop Label1
}
}
DWORD CheckSelf(DWORD StartAddr,DWORD dwCodeLength)
{
_asm
{
xor eax,eax
xor ebx,ebx
mov esi,StartAddr
mov ecx,dwCodeLength
Label1:
mov bl,byte ptr [esi]
add eax,ebx
inc esi
loop Label1
sub eax, 3763//3763是由dwSumbyte提前提供
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DWORD dwStartAddr=0;
DWORD dwEndAddr=0;
DWORD dwCodeLength=0;
DWORD dwChecksum=0;
DWORD dwSumbyte=0;
DWORD dwOdd=0;
char temp[200]={0};
_asm
{
Start:
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
add ebx,ecx
add edx,ebx
add ebx,eax
add eax,ebx
mov dwStartAddr,offset Start
mov dwEndAddr,offset End
End:
}
dwCodeLength=dwEndAddr-dwStartAddr;
dwSumbyte=Calculation(dwStartAddr,dwCodeLength);
dwOdd = CheckSelf(dwStartAddr,dwCodeLength);
wsprintf(temp,"the Deviation is %d",dwOdd);
MessageBox(NULL,temp,"OK",MB_OK); //显示差值,od是否作用过。。。
}
代码也很简单,了解代码校验的估计都会。。所以也不多说。。
我测试的断点是 Start和End标签直接。。。
好我们来看结果:
1.不下断点:
结果正常!
2.下断点:
------1,下在此处:
为什么是这个值呢?
答:应该是0xcc,代替了图中的0x33,算算就知道 0xcc-0x33=153 正确
------2.那你来猜猜第二次应该是多少呢?
0xcc+0xcc-0x33-0x03应该等于354.。。
哈哈都对了。。。
确实是机器码cc起了作用。。
但==,看看我的代码2,发现了什么异常吗?不是说过它执行完了就回把源代码还原吗,
我的Start和End 之间的代码可在计算函数之前执行的哦!!为什么它还会存在int 3(0xcc),
我想,它在之后又还是将int 3 写入进程text一次,只要不结束,它就存在,是这样吗,实际确实是这样滴!(想想我们在断F2时,如果你不清除,断点是始终存在的,恩就是这个道理!)
我来实际操作看看,还是执行code1,Sample处下F2断点:
操作结果是:依次显示3副图
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!