int 3是0cch还是0CCCCCCCCh
debug吧
全部回复
仅看楼主
level 1
int 3与0cch和0CCCCCCCCh是啥关系呀,很多资料是说int 3机器码0cch,这一点不难,但在那些资料上马上就出现了矛盾的地方,那就是下面
lea edi,[e
bp
-0c0h]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
几乎所有说int 3机器码0cch的资料,都会接着讲上面的代码,上面的代码大体意思是将一定的区域ebp-0c0h开始的区域初始化为0CCCCCCCCh,这是因为把它们全部初始化成0CCCCCCCCh后,运行到那里就会停止,这问题就出来了
上面不是说int 3机器码0cch是吗,所以填充那些区域的也应该是0cch呀,怎么会是0CCCCCCCCh?是我眼瞎还是作者眼瞎
高手快来帮帮我呀
2014年08月14日 14点08分 1
level 4
mark一下,回头回答你。下班了~~~
2014年09月18日 09点09分 2
为什么呀?
2014年09月20日 15点09分
level 4
如果你了解汇编,以下这个顺便给你提及以下。
1)INT3 指令 他的机器码是:(0xcc) 一个字节
2)软件中断指令INT 3,机器码是 (0xcd03),两个字节
--------------
你也许理解错了,一般用CCCCCC这个是申请一段栈空间时使用的。,你写一个简单的C程序,调试,然后看反汇编代码,在main函数开始部分就能够看到了。
CC/33 = 4
2014年09月20日 16点09分 3
感觉你说的不对,但还是谢谢了
2014年09月28日 13点09分
回复 反正你也没办法 :我没说全,抱歉;让你误解了。。。。CC/33 = 4这么一句不够
2014年09月29日 01点09分
level 1
我在别处也发过贴,获得的答案不一样
2014年09月22日 01点09分 4
level 4
这一段绝对是对的
1)INT3 指令 他的机器码是:(0xcc) 一个字节
2)软件中断指令INT 3,机器码是 (0xcd03),两个字节
2014年09月29日 01点09分 5
level 4
你是不是说如下的代码
2014年09月29日 01点09分 6
level 4
#include <stdio.h>
#include <conio.h>
int main(void)
{
55 push ebp
8B EC mov ebp,esp
81 EC D8 00 00 00 sub esp,0D8h
53 push ebx
56 push esi
57 push edi
8D BD 28 FF FF FF lea edi,[ebp-0D8h]
B9 36 00 00 00 mov ecx,36h
B8 CC CC CC CC mov eax,0CCCCCCCCh
F3 AB rep stos dword ptr es:[edi]
int a = 10;
C7 45 F8 0A 00 00 00 mov dword ptr [a],0Ah
int b = a + 3;
8B 45 F8 mov eax,dword ptr [a]
83 C0 03 add eax,3
89 45 EC mov dword ptr [b],eax
return 0;
33 C0 xor eax,eax
}
5F pop edi
5E pop esi
5B pop ebx
8B E5 mov esp,ebp
5D pop ebp
C3 ret
2014年09月29日 01点09分 7
level 4
看第一段:
反汇编的格式:机器码 汇编代码
int main(void)
{
55 push ebp ; 保存ebp
8B EC mov ebp,esp ; 设置ebp指向当前的esp地址
81 EC D8 00 00 00 sub esp,0D8h ; 申请0D8h的栈空间
;; 在当前的栈底(也就是之前的栈顶)压入以下三个寄存器的内容
53 push ebx
56 push esi
57 push edi
;; 将申请的栈空间大小存入变址寄存器 EDI
8D BD 28 FF FF FF lea edi,[ebp-0D8h]
;; 循环次数36h
B9 36 00 00 00 mov ecx,36h
;; eax <<<<= 0CCCCCCCCh,一个32位的数!
B8 CC CC CC CC mov eax,0CCCCCCCCh
;; 执行操作。。。
F3 AB rep stos dword ptr es:[edi]
==========================================
不知道你看懂没,等价的效果就是这样,对该栈空间的【每个字节】作如下设置
验证:【36h * 4h = D8h】
【伪代码】
int stack_new_space[36h];
_asm { mov ecx, 36h; }
for (int i = 0; i < ecx; i++)
{
stack_new_space[i] = 0xCCCCCCCC;
}
---------------------------------
现在知道为什么选CC了么,CC只有1个字节,这样保证该空间的每个字节的内容都是一样的,均为CC,then 如果栈结构被破坏会中断程序的执行。
2014年09月29日 01点09分 8
level 4
也就是对栈空间,以4个字节为操作单位,以0CCCCCCCCh 为操作数,循环赋值36h次,遍历下去。
最终效果是:36h * 4h = D8h 范围内的每个字节都是CCh
2014年09月29日 01点09分 9
level 4
看到大段的CC了没,不进可以用来预防错误,而且是调试时一种有效的硬编码的手段,可以用来调试很多难调试的问题。
2014年09月29日 01点09分 10
level 4
最后小结下,int3的作用
1.往分配好的局部变量空间放入int3中断,防止该空间里的东东被意外执行;一般在函数之间插入int 3,这样,如果有错误的jump(一般指栈结构被破坏了)产生,能够停止执行,且容易知道哪里错了。
2.遇到棘手问题的时候,可以人为故意地在特定地方插入int3,以达到调试的目的。
===================================
不过我记不清int 3 和 int3两个哪个是指令,哪个是软中断了,
记得好像前者是软中断,后者是指令。这样的话,我上面的2楼回复就是倒过来了。。。
抱歉!!!
2014年09月29日 01点09分 11
level 4
看了下Intel的手册,这下理清两个int 3的关系了。
INT n/INTO/INT 3—Call to Interrupt Procedure
Opcode Instruction Description
CC INT 3 A Valid Valid Interrupt 3 — trap to debugger.
CD ib INT imm8 Interrupt vector number specified by immediate byte.
【CC】
The INT 3 instruction generates a special one byte opcode (CC) that is intended for
calling the debug exception handler. (This one byte form is valuable because it can be
used to replace the first byte of any instruction with a breakpoint, including other one
byte instructions, without over-writing other code).
【CD 03】
Note that the “normal” 2-byte opcode for INT 3 (CD03) does not have these special
features. Intel and Microsoft assemblers will not generate the CD03 opcode from any
mnemonic, but this opcode can be created by direct numeric code definition or by
self-modifying code.
2014年09月29日 03点09分 12
level 4
也就是说,int 3 生成机器码CC是一个特殊的设计;
根据int + number的中断形式,理论上能够为int 3生成CD 03这样的机器码,但是它没有CC的那些特殊性质;所以,这也是个容易造成困扰的地方。
不过,Intel有所考虑,因为这些是他可以控制的,比如:
int + number中,number 介于[0, 255]区间内,但是前32个number为Intel所【预留】;
同时,Intel和微软约定,不会以任何形式生成CD 03这样的机器码,但是你可以手动修改代码,以插入CD 03这样的代码。
===============================
至此,一切应该清晰明了了。
楼主,你明白了没?[酷]
2014年09月29日 04点09分 13
啊,我明白了
2014年09月29日 08点09分
回复 反正你也没办法 :sorry, 之前让你误解了;上午打了半天酱油,总算给你回答完毕了、、、
2014年09月29日 08点09分
回复 icecoobe :lea edi,[ebp-0D8h] mov ecx,36h mov eax,0CCCCCCCCh rep stos dword ptr es:[edi] 是不是可以改成 lea edi,[ebp-0D8h] mov ecx,0D8h mov eax,0CCh rep stos db(dbyte) ptr es:[edi] 如果可能的话?
2014年09月29日 08点09分
回复 反正你也没办法 :可以!总之,大小数量什么的要对应就行了,没记错的话,使用rep stosb,它使用AL寄存器部分的内容,所以mov eax, xxx,这个数据要注意,只选取AL部分。
2014年09月29日 08点09分
level 1
lea edi,[ebp-0D8h]
mov ecx,36h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
是不是可以改成
lea edi,[ebp-0D8h]
mov ecx,0D8h
mov eax,0CCh
rep stos db(dbyte) ptr es:[edi]
如果可能的话?
2014年09月29日 08点09分 16
4字节操作比单字节快,循环次数只有1/4
2014年12月14日 15点12分
level 4
【题外话】
我记得寄存器的基本单元是一个字节,即使有ax,eax这种超多1个字节的寄存器,在进行某些单字节操作符运算的时候,进位之类的信息是不会保存到ax或者eax高位的部分。所以不要一直将ax、eax等当成一个整体。
所以,你在进行重要实验的时候,最好查看下Intel的手册。
2014年09月29日 08点09分 17
牛逼
2015年01月22日 15点01分
我大致明白为什么 VC单步运行的时候为什么会 烫烫烫烫烫烫...........[呵呵]
2015年01月22日 15点01分
回复 safezpa :可以跟我说说你的猜想
2015年01月22日 16点01分
level 1
0xcc和cd03功能是一样的,cc就是cd03的简写而已,为了方便调试。
一大堆cc就是为了能在越界时即刻触发中断。 和分配内存用的guard一样。
2014年12月14日 15点12分 20
level 1
很抱歉 挖坟 ,但是真的很谢谢老哥的解释,让我豁然开朗。
2019年03月21日 13点03分 21
我也要挖个坟 上面的都讲的有道理
2019年03月29日 16点03分
1