| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2694 人关注过本帖
标题:对于不同的代码,VC中的栈偏移地址计算方法怎么不统一
只看楼主 加入收藏
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
结帖率:79.17%
收藏
 问题点数:0 回复次数:11 
对于不同的代码,VC中的栈偏移地址计算方法怎么不统一
模式一:
使用代码class my_class
{
public :
    my_class()
    {
        m_member = 1;
    }
    
    void method(int n)
    {
        m_member = n;
    }
    
    ~my_class()
    {
        m_member = 0;
    }
    
private :
    int m_member;
};

int main(char argc, char* argv[])
{
    my_class a_class;
    a_class.method(10);
    
    return 0;
}
做测试代码时,可以看到他的反汇编代码为(截取部分):
_main    PROC NEAR                    ; COMDAT

; 41   : {

    push    ebp
    mov    ebp, esp
    push    -1
    push    __ehhandler$_main
    mov    eax, DWORD PTR fs:__except_list
    push    eax
    mov    DWORD PTR fs:__except_list, esp
    sub    esp, 72                ; 00000048H
    push    ebx
    push    esi
    push    edi
    lea    edi, DWORD PTR [ebp-84]
    mov    ecx, 18                    ; 00000012H
    mov    eax, -858993460                ; ccccccccH
    rep stosd
也就是这里的 84 = 72 +3*4,这里的3 是因为考虑了 push ebx,push    esi, push edi这三个语句对于栈地址的影响,于是只将剩余的 18*4=72 部分地址进行初始化,而不是整个 84 个字节空间 (见模式一.jpg)

模式二:
使用代码:
#include <stdio.h>
int fun(int a, int b)
{
   char var[128] = "A";
   a = 0x4455;
   b = 0x6677;
   return a + b;
}
int main()
{
//     int i;
//     int p;
//     printf("0x%08x\n",i);
    fun(0x8899,0x1100);
    return 0;
}做测试代码时,
其反汇编代码 (截取部分代码)
_TEXT    SEGMENT
_main    PROC NEAR                    ; COMDAT

; 10   : {

    push    ebp
    mov    ebp, esp
    sub    esp, 64                    ; 00000040H
    push    ebx
    push    esi
    push    edi
    lea    edi, DWORD PTR [ebp-64]
    mov    ecx, 16                    ; 00000010H
    mov    eax, -858993460                ; ccccccccH
    rep stosd

; 11   : //     int i;
; 12   : //     int p;
; 13   : //     printf("0x%08x\n",i);
; 14   :     fun(0x8899,0x1100);

    push    4352                    ; 00001100H
也就是这里并没有考虑  push ebx,push    esi, push edi这三个语句对于栈地址的影响,而是直接将整个 64 个字节空间 进行赋默认 初值 ccccccccH (见模式二.jpg)

注意:以上两个代码均在  VC6.0 DEBUG 模式下编译得到的反汇编代码

模式一.JPG (48.47 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册


模式二.JPG (51.47 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册
收到的鲜花
  • cnhanxiao2008-11-03 12:45 送鲜花  30朵  
  • zklhp2008-11-03 12:51 送鲜花  50朵   附言:好文章
搜索更多相关主题的帖子: 栈偏移地址 初始化空间 差异 反汇编 
2008-11-02 17:46
cnhanxiao
Rank: 2
等 级:新手上路
威 望:4
帖 子:124
专家分:0
注 册:2008-10-17
收藏
得分:0 
路走偏锋,羡慕楼主在精通VC的情况下,执着地对反汇编很有研究

还有绑架成版主的?拒绝做版主——对不起啊!
2008-11-03 12:45
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]vfdff[/un] 在 2008-11-2 17:46 的发言:[/bo]

模式一:
使用代码class my_class
{
public :
    my_class()
    {
        m_member = 1;
    }
    
    void method(int n)
    {
        m_member = n;
    }
    
    ~my_class()
    {
        m ...



第一个和类的模型之类的东西有关 偶不懂

第二个填cccccccch 是debug模式下的代码 是防止他运行(cch就是int 3h)
2008-11-03 12:54
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 3# 的帖子
cch 是中断 向量  3h 入口地址 ,这个中断是VC编译器的模拟中断 还是操作系统也是用这个中断?

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008-11-05 02:52
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]vfdff[/un] 在 2008-11-5 02:52 的发言:[/bo]

cch 是中断 向量  3h 入口地址 ,这个中断是VC编译器的模拟中断 还是操作系统也是用这个中断?


下断不都用这个 应该是操作系统的吧 cpu就有这功能……
2008-11-05 08:46
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 5# 的帖子
现在保护模式下不是使用描述符,没有中断向量地址的概念了!

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008-11-14 19:45
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]vfdff[/un] 在 2008-11-14 19:45 的发言:[/bo]

现在保护模式下不是使用描述符,没有中断向量地址的概念了!


谁说的? 怎么没描述符了
2008-11-15 08:20
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
与8086/8088一样,在响应中断或者处理异常时,80386根据中断向量号转对应的处理程序。但是,在保护模式下,80386不使用实模式下的中断向量表,而是使用中断描述符表IDT。在保护模式下,80386把中断向量号作为中断描述符表IDT中描述符的索引,而不再是中断向量表中的中断向量的索引。
2008-11-15 08:31
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]zklhp[/un] 在 2008-11-15 08:31 的发言:[/bo]

与8086/8088一样,在响应中断或者处理异常时,80386根据中断向量号转对应的处理程序。但是,在保护模式下,80386不使用实模式下的中断向量表,而是使用中断描述符表IDT。在保护模式下,80386把中断向量号作为中断描述 ...


; *通过中断门进入ring0,像在Dos下一样,我们只要替换中断向量表的地址以指向我们
; *自己的程序就可以了,不过在win下中断向量表变为IDT(中断描述符表),其第0~1保存
; *中断处理程序偏移的低16位,6~7字节保存偏移的高16位,我们必须使用描述符具有DPL=3
; *的中断门以便在ring3下转入中断程序,而int 03h,04h,05h,10h,13h,30h等本来就是
; *DPL=3,我们可以方便地利用之,注意中断处理程序返回用iretd
    ;---------------------------
    ; 下面利用int 5进入ring0
    ;---------------------------
    invoke  MessageBoxA,0,addr CTEXTInt,addr sztit,MB_YESNO
    cmp  eax,IDNO
    jz   @xit000           ;继续演示?

    mov  esi,dword ptr [idtR+2]    ;esi->idt base
    push  dword ptr [esi+8*5+0]
    push  dword ptr [esi+8*5+4]    ;保存INT 5,中断描述符

    push  offset myring0_prc_Intgt   ;替换原来INT5的入口地址
    pop  word ptr [esi+8*5]
    pop  word ptr [esi+8*5+6]
    int  5              ;进入ring0!
    ;int  3              ;//可选择利用int 3
    ;db  0CCh            ;//则保存和恢复就改为8*3
    ;为了增强反跟踪效果
    ;当然也可以利用int 1,方法一致不过可能在某些处理器上冲突                    
    pop  dword ptr [esi+8*5+4]    ;恢复,int 5,中断描述符
    pop  dword ptr [esi+8*5+0]
2008-11-15 08:47
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
windows源码里找的
_KiTrap03       proc
        push    0                       ; push dummy error code
        ENTER_TRAP      kit3_a, kit3_t

        cmp     ds:_PoHiberInProgress, 0
        jnz     short kit03_01

   lock inc     ds:_KiHardwareTrigger   ; trip hardware analyzer

kit03_01:
        mov     eax, BREAKPOINT_BREAK

KiTrap03DebugService:
;
; If caller is user mode, we want interrupts back on.
;   . all relevent state has already been saved
;   . user mode code always runs with ints on
;
; If caller is kernel mode, we want them off!
;   . some state still in registers, must prevent races
;   . kernel mode code can run with ints off
;
;
; Arguments:
;     eax - ServiceClass - which call is to be performed
;     ecx - Arg1 - generic first argument
;     edx - Arg2 - generic second argument

        test    dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK
        jnz     kit03_30                ; fault occured in V86 mode => Usermode

        test    word ptr [ebp]+TsSegCs,MODE_MASK
        jz      kit03_10

        cmp     word ptr [ebp]+TsSegCs,KGDT_R3_CODE OR RPL_MASK
        jne     kit03_30

kit03_05:
        sti
kit03_10:


;
; Set up exception record and arguments for raising breakpoint exception
;

        mov     esi, ecx                ; ExceptionInfo 2
        mov     edi, edx                ; ExceptionInfo 3
        mov     edx, eax                ; ExceptionInfo 1

        mov     ebx, [ebp]+TsEip
        dec     ebx                     ; (ebx)-> int3 instruction
        mov     ecx, 3
        mov     eax, STATUS_BREAKPOINT
        call    CommonDispatchException ; Never return

kit03_30:
; Check to see if this process is a vdm

        mov     ebx,PCR[PcPrcbData+PbCurrentThread]
        mov     ebx,[ebx]+ThApcState+AsProcess
        test    byte ptr [ebx]+PrVdmFlag,0fh ; is this a vdm process?
        jz      kit03_05


        stdCall _Ki386VdmReflectException_A, <03h>
        test    ax,0FFFFh
        jz      Kit03_10

        jmp     _KiExceptionExit

_KiTrap03       endp
2008-11-15 08:59
快速回复:对于不同的代码,VC中的栈偏移地址计算方法怎么不统一
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018447 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved