首页
社区
课程
招聘
[求助]堆践使用的问题.移动堆践指针为什么一些堆践中数据会变动?
发表于: 2006-4-17 17:13 6214

[求助]堆践使用的问题.移动堆践指针为什么一些堆践中数据会变动?

2006-4-17 17:13
6214

看到Dwing~GG写的那个自删除代码后
决定从新写一下.
但是发现一点点问题..堆践数据会变动??
Google搜了一下可是没有找到任何资料..不得已来这里问一下


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
试验过,确实如此
理论上栈指针上方的空间是自由空间, 它的内容是不确定的, 尽管之前已经对它进行了修改, 它的值还是会不断变化
猜想原因可能是:
1.栈指针上方的空间被映射到内存中的另一个页面上了(可能性不大)
2.系统API也会使用堆栈, 可能它们占用了栈指针上方的空间(用于局部变量保存等),导致栈内容发生改变

楼主碰到的情况应该是第2种, 就是调用系统API改变了堆栈自由空间的内容
2006-4-18 15:16
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
写了一个小程序测试了一下, MASM编写
其中$CTA0是定义字符串的一个宏, 这里不列出了

;Compile:ml /c /coff /Cp Test.asm
;Link:link /subsystem:windows Test.obj

.386
.model flat, stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc

includelib kernel32.lib
includelib user32.lib

.code
Start:
        push        ebp
        mov        ebp, esp
       
        sub        esp, 1000h                ;保留1K字节的空间
        mov        ebx, esp
       
        mov        eax, 0CCCCCCCCh                ;全填入0CCh
        mov        ecx, 1000h / 4h
        mov        edi, ebx
        cld
        rep        stosd
       
        add        esp, 1000h                ;还原保留的1K字节空间
       
        call        GetCommandLine                ;这里随便调用一个函数
       
        mov        eax, 0CCCCCCCCh
        mov        edi, ebx
        mov        ecx, 1000h / 4h               
        repz        scasd                        ;检查堆栈数据是否发生变化
        jz        Exit
       
        ;结果这句执行了, 证明堆栈数据发生了变化
        invoke        MessageBox, NULL, $CTA0("Data on stack has changed."), $CTA0("Test"), MB_OK
       
Exit:
        leave
        ret

END        Start
2006-4-18 15:41
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
VC的优化也不错:
00401000  />push    ebp
00401001  |>mov     ebp,esp
00401003  |>sub     esp,400
00401009  |>push    400                                     ; /BufSize = 400 (1024.)
0040100E  |>lea     eax,[ebp-400]                           ; |
00401014  |>push    eax                                     ; |Buffer
00401015  |>push    0040301C                                ; |VarName = "ComSpec"
0040101A  |>call    [<&KERNEL32.GetEnvironmentVariableA>]   ; \GetEnvironmentVariableA
00401020  |>push    200                                     ; /BufSize = 200 (512.)
00401025  |>push    00403010                                ; |/StringToAdd = " /c del \""
0040102A  |>lea     eax,[ebp-400]                           ; ||
00401030  |>push    eax                                     ; ||ConcatString
00401031  |>call    [<&KERNEL32.lstrcatA>]                  ; |\lstrcatA
00401037  |>push    eax                                     ; |/String
00401038  |>call    [<&KERNEL32.lstrlenA>]                  ; |\lstrlenA
0040103E  |>lea     eax,[ebp+eax-400]                       ; |
00401045  |>push    eax                                     ; |PathBuffer
00401046  |>push    0                                       ; |/pModule = NULL
00401048  |>call    [<&KERNEL32.GetModuleHandleA>]          ; |\GetModuleHandleA
0040104E  |>push    eax                                     ; |hModule
0040104F  |>call    [<&KERNEL32.GetModuleFileNameA>]        ; \GetModuleFileNameA
00401055  |>push    0                                       ; /ShowState = SW_HIDE
00401057  |>lea     eax,[ebp-400]                           ; |
0040105D  |>push    eax                                     ; |CmdLine
0040105E  |>call    [<&KERNEL32.WinExec>]                   ; \WinExec
00401064  |>xor     eax,eax
00401066  |>leave
00401067  \>retn

再手工优化一下:
sub     esp,400
push    400
push    esp
push    0040301C        ;"ComSpec"
call    GetEnvironmentVariableA
push    200
push    00403010        ;" /c del \""
push    esp
call    lstrcatA
push    eax
call    lstrlenA
add     eax,esp
push    eax
push    0
call    GetModuleHandleA
push    eax
call    GetModuleFileNameA
push    0
push    esp
call    WinExec
add     esp,400
retn
2006-4-20 09:30
0
雪    币: 159
活跃值: (339)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
自由空间当然是会改变的...举个简单的例子来说。
系统要用到很多的SEH...这样就需要使用堆栈...我们一般能确定的可能只能是在api返回以后,esp指向原来的值(经管现在对于类似strcpy之类的函数也不能确定它一定能返回-_-b),所以对于系统来说低esp的地址空间里面就是他想怎么着就怎么着的地方咯..
2006-4-20 18:08
0
雪    币: 1272
活跃值: (746)
能力值: ( LV13,RANK:810 )
在线值:
发帖
回帖
粉丝
6
To thebutterfly :Thank~~Boy

To Dwing:我是准备在已经获取长度的后面直接再次连接..字符串..
原来ASM不可以这么直接操作堆践..
最近VC坏了~~被"某人"删除了.不让阿拉写代码了..
只能用ASm直接写..原来不能这么直接操作堆践..

To Lenus:谢谢~~为什么再次sub esp,150就不会被覆盖??
这个如何解释?究竟有多少自由空间??~

谢谢楼上三位GG的~指教
2006-4-21 19:49
0
雪    币: 222
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
因为esp永远指向当前堆栈地址,你要用一段堆栈的空间,就应该将esp往前划一些,比如子程序中的局域变量区间。sub esp,150后这150个字节的空间都让你程序占了,其中的内容自然不会再被API改变
2006-4-27 08:10
0
游客
登录 | 注册 方可回帖
返回
//