News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

More Advanced Prologue and Epilogue MACROses for PROCs

Started by Antariy, June 07, 2013, 11:00:04 PM

Previous topic - Next topic

jj2007

Quote from: ToutEnMasm on June 08, 2013, 03:01:50 PM
I don't see where is the problem to have a proc who use more than one page of stack memory ?

See also reply #2. For XP, you need crash=3990.

sinsi

Quote from: MichaelW on June 08, 2013, 04:47:57 PM
If I change the LOCAL allocation to 4096*2 then the app crashes because the second access skips over the new guard page and accesses uncommitted stack space.
Looks like Windows 8 guards against that, there is no crash.


eax=00000022 ebx=0018e004 ecx=7572c196 edx=004f2438 esi=00000000 edi=00000000
eip=00401009 esp=0018bffc ebp=0018dffc iopl=0         nv up ei pl nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000207
image00400000+0x1009:
00401009 8a8500e0ffff    mov     al,byte ptr [ebp-2000h]    ss:002b:0018bffc=??
0:000> t
eax=00000000 ebx=0018e004 ecx=7572c196 edx=004f2438 esi=00000000 edi=00000000
eip=0040100f esp=0018bffc ebp=0018dffc iopl=0         nv up ei pl nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000207
image00400000+0x100f:
0040100f c9              leave
0:000> r eip=401009
0:000> r
eax=00000000 ebx=0018e004 ecx=7572c196 edx=004f2438 esi=00000000 edi=00000000
eip=00401009 esp=0018bffc ebp=0018dffc iopl=0         nv up ei pl nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000207
image00400000+0x1009:
00401009 8a8500e0ffff    mov     al,byte ptr [ebp-2000h]    ss:002b:0018bffc=00

Notice after "ss:002b:0018bffc=??" we get "ss:002b:0018bffc=00"

sinsi

Upon further tests:
     LOCAL array[4096*3-3]:BYTE will crash
     LOCAL array[4096*3-4]:BYTE will work

Current bottom of stack: 18E000h
Current bottom of stack: 18B000h




TouEnMasm


I see nothing that couldn't be solved by a link option.
Except when the reserved stack is fully used.
Perhaps the system is not abble to add more than one page in the same time.
Fa is a musical note to play with CL

Antariy

Here is the info & crash testing proggie.

It's quite clear - read the code.

At least on XP the design is the same - see the results.

Short explanation on how to treat results.

First two tables are for the same page - bottom of the stack, just reffered with ESP and the bottom line.
Here you should look on the State and Protect fields, the memory is commited (1000h) and has PAGE_READWRITE access (4), so, this is normal stack location - ready for use to store the data.

Third table is a next page below the bottom of stack.
Here you may see that it is commited, and has PAGE_READWRITE + PAGE_GUARD access (104h). This is a guard page hitting of which tells the system there is need to grow the stack.

Fourth and fifth table are next two pages below the guard page, they show that this memory location is not commited - it is reserved, and it has no  protect what is, shortly speaking, equal to no access protect (causes a crash if code accesses it with any kind of read/write).


There are 3 steps - you can change the value in the top of the code - that show in real time how the stack is growing, and for every step there will be five (or more - you may at the top of the code change how much pages below the bottom are acessed to show their state). And for my system each step shows the same result - bottom (and upper, of course) of the stack is a normal data location, page below of bottom - is the guard, and the next pages are no access memory location.



After these steps the code will cause a crash - intentionally - to show in which circumstances the crash of this type will occur. Also this code consequently increases the page-step (shortly speaking, the "buffer size" required to crash the program if the locals after entry in the proc will point below the guard page), so it will show the smallest required buffer size to get a crash in a suitable circumstance. In real world this will be random thing - on some machines real prog will crash with the minimal buffer size that there will be shown, on some it will not crash, but for clearness the code produces the enviroment of the worst-case layout - we are on the bottom page, and pointing beyound guard page, the step is starting from 4096 bytes - i.e. one page - plus 4 bytes - to access beyound the guard page.
For me it crashes from first iteration - with 4096 bytes step - just like it should do and was expected (at least for my system).

As for "real world program" note: even if on some systems the program with the locals a bit larger than 4096 bytes is not crashes, this means nothing, really. That's just because the locals were placed NOT in the last page of the stack. That's why it is required to write the proggie like posted one is, to show how this crash works. "Real program" with big locals and no probing code will be real "random crash generator" which will be absolutely unpredictable when and where it will crash.


It will be very interesting to see how it behaves on different systems, especially WinVista/7/8.
Please, since the program dumps much of info, redirect its output to the textual file from the command line, and copy contents of the file here.



=== Dump info for growing stack, 3 steps ===


============== Step #1 ==============

In printinfo1, ESP: 0012DFC8, stack bottom: 0012D000
VirtualQuery for ESP:
        BaseAddress:            0012D000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00003000
        State:                  00001000
        Protect:                00000004
        Type:                   00020000

In printinfo1, ESP: 0012DFC8, stack bottom: 0012D000
VirtualQuery for the stack bottom:
        BaseAddress:            0012D000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00003000
        State:                  00001000
        Protect:                00000004
        Type:                   00020000

In printinfo1, ESP: 0012DFC8, stack bottom: 0012D000
VirtualQuery for page step below bottom...:
        BaseAddress:            0012C000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00001000
        State:                  00001000
        Protect:                00000104
        Type:                   00020000

In printinfo1, ESP: 0012DFC8, stack bottom: 0012D000
VirtualQuery for page step below bottom...:
        BaseAddress:            0012B000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00001000
        State:                  00002000
        Protect:                00000000
        Type:                   00020000

In printinfo1, ESP: 0012DFC8, stack bottom: 0012D000
VirtualQuery for page step below bottom...:
        BaseAddress:            0012A000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00002000
        State:                  00002000
        Protect:                00000000
        Type:                   00020000


============== Step #2 ==============

In printinfo1, ESP: 0012CFC8, stack bottom: 0012C000
VirtualQuery for ESP:
        BaseAddress:            0012C000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00004000
        State:                  00001000
        Protect:                00000004
        Type:                   00020000

In printinfo1, ESP: 0012CFC8, stack bottom: 0012C000
VirtualQuery for the stack bottom:
        BaseAddress:            0012C000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00004000
        State:                  00001000
        Protect:                00000004
        Type:                   00020000

In printinfo1, ESP: 0012CFC8, stack bottom: 0012C000
VirtualQuery for page step below bottom...:
        BaseAddress:            0012B000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00001000
        State:                  00001000
        Protect:                00000104
        Type:                   00020000

In printinfo1, ESP: 0012CFC8, stack bottom: 0012C000
VirtualQuery for page step below bottom...:
        BaseAddress:            0012A000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00001000
        State:                  00002000
        Protect:                00000000
        Type:                   00020000

In printinfo1, ESP: 0012CFC8, stack bottom: 0012C000
VirtualQuery for page step below bottom...:
        BaseAddress:            00129000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00002000
        State:                  00002000
        Protect:                00000000
        Type:                   00020000


============== Step #3 ==============

In printinfo1, ESP: 0012BFC8, stack bottom: 0012B000
VirtualQuery for ESP:
        BaseAddress:            0012B000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00005000
        State:                  00001000
        Protect:                00000004
        Type:                   00020000

In printinfo1, ESP: 0012BFC8, stack bottom: 0012B000
VirtualQuery for the stack bottom:
        BaseAddress:            0012B000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00005000
        State:                  00001000
        Protect:                00000004
        Type:                   00020000

In printinfo1, ESP: 0012BFC8, stack bottom: 0012B000
VirtualQuery for page step below bottom...:
        BaseAddress:            0012A000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00001000
        State:                  00001000
        Protect:                00000104
        Type:                   00020000

In printinfo1, ESP: 0012BFC8, stack bottom: 0012B000
VirtualQuery for page step below bottom...:
        BaseAddress:            00129000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00001000
        State:                  00002000
        Protect:                00000000
        Type:                   00020000

In printinfo1, ESP: 0012BFC8, stack bottom: 0012B000
VirtualQuery for page step below bottom...:
        BaseAddress:            00128000
        AllocationBase:         00030000
        AllocationProtect:      00000004
        RegionSize:             00002000
        State:                  00002000
        Protect:                00000000
        Type:                   00020000



=== Crash - continuously access below guard page with increasing the step ===

Step size: -4096, ESP: 0012BFFC, Stack bottom: 0012B000

TouEnMasm


For me the question is how to avoid these:
Conditions to have a crash in XP is when the proc need more than one page of stack memory.In XP one page is 1000h.
If the stack memory is not allowed,the system do it at the first write.
If the system need to allocate two pages,there is a crash.
This one could be avoid with LInk /STACK option.
If max stack PROC > 1 page Need LInk /STACK   else       no risk
Fa is a musical note to play with CL

Antariy

Quote from: ToutEnMasm on June 08, 2013, 09:51:32 PM

I see nothing that couldn't be solved by a link option.
Except when the reserved stack is fully used.
Perhaps the system is not abble to add more than one page in the same time.


Michael has already shortly and well described when the problem will occur.
And increasing the commited stack size (and/or stack size at all) is not the real solution - in the system there is not only one program running, so the solution like "Let's set our app's stack size to a half of a gigabyte and commit it all!" will a bit surprise the Windows, especially if there will be couple of such programs to run. Or one program but with couple threads (since default thread stack size is equal to the main thread stack size). The growable stack mechanism was intended not to be overcomed with such ways.

TouEnMasm


I was writing the results of my test when your post had been write
try to put this rules in fault
If max stack PROC > 1 page Need LInk /STACK   else       no risk
Fa is a musical note to play with CL

Antariy

Quote from: ToutEnMasm on June 08, 2013, 11:12:09 PM

For me the question is how to avoid these:
Conditions to have a crash in XP is when the proc need more than one page of stack memory.In XP one page is 1000h.
If the stack memory is not allowed,the system do it at the first write.
If the system need to allocate two pages,there is a crash.
This one could be avoid with LInk /STACK option.
If max stack PROC > 1 page Need LInk /STACK   else       no risk


The point is: in link time you do not know when and where your program will go to the last page and will at this moment in the proc with huge locals. If such proc does not use probing code, the only "solution" is to make commited stack size = full stack size, but this is not proper thing to do in multitasking environment. And if you commit some other stack size - there is not guarantee that in some system, especially with each new one version, the program will not crash. It will be random crash generator, even if this behaviour will be masked first.

TouEnMasm

To antarity,I had have a look on on your CrashStack.zip,here is the result

Windbg answer:[quote][/quote]
004011b5 8b443efc        mov     eax,dword ptr [esi+edi-] :0023:00129ffc=????????
source code:
invoke crt_printf,CTXT("Step size: %d, ESP: %p, Stack bottom: %p",10),esi,ecx,edi
    mov eax,[edi+esi-4]       <<<<<<<<<<<< JUST A BUG

Use a debugger before anything.
Fa is a musical note to play with CL


jj2007

Quote from: ToutEnMasm on June 08, 2013, 11:38:26 PM
    mov eax,[edi+esi-4]       <<<<<<<<<<<< JUST A BUG

Yves,

Since you certainly don't understand why Alex writes LOOOOL, just a simple question:

Do you occasionally read comments?


    mov eax,[edi+esi-4]
    ; edi is a stack bottom
    ; esi - is a page sized step
    ; 4 is a displacement to access beyond (lower) than next page (guard)

TouEnMasm


The debugger made an enough comment


BAD ADRESS

Perhaps are you able to see this one ?
Fa is a musical note to play with CL

jj2007

Yves, no need to shout. "Bad address" is the whole point of this thread. The "bad" address is slightly below the current stack, and that's what we are discussing here.

TouEnMasm

I made it you more simple,i dont show the calcul.

take a proc at start who call just this proc:

;################################################################
Big_stack_proc PROC
Local bigone[0ff2h]:DWORD
Local retour:DWORD
mov retour,1         <<<< bug here
invoke StackSize

FindeBig_stack_proc:
         mov eax,retour
         ret
Big_stack_proc endp

The debugger show the bad adress:
00401082 c78534c0ffff01000000 mov dword ptr [ebp-3FCCh],1 ss:0023:0012bff0=????????
For what ? The proc just need more than one page of stack and the system failed to allow this two pages and the memory is not allowed,even if there is enough memory reserved (1Mo).

The calcul  of Local bigone[0ff2h]:DWORD is just made to need more than one page with  the start position of esp.

The question stay how to avoid this.Answer

If max stack PROC > 1 page Need LInk /STACK   else       no risk

Reply to the question and you win.
Fa is a musical note to play with CL