flat assembler
Message board for the users of flat assembler.

Index > Main > Swapping the stack

Author
Thread Post new topic Reply to topic
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 15:35
Hi,

I wonder if anyone can help. I've been trying to get my head around stack usage. I set up a simple example (see code below) to try swapping stacks - but didn't get the results I expected. Basically the second string prints but the first doesn't. Yet nothing seems to break and the program exits normally.

I've watched the C call and printf routine using my new stack (with Ollydbg)
- why doesn't it actually output anything?!?

Any ideas?

Thanks for any help,

Kas.

Code:
format PE CONSOLE 4.0 
entry start 

        include 'win32a.inc'  

section ".code" code readable writeable executable

start:
        ; Stash default stack pointers
        mov [SYSTEM_EBP], ebp
        mov [SYSTEM_ESP], esp

        ; Substitute new stack pointers
        lea ebp, [stack_top-4]
        lea esp, [stack_top-8]

        ; Attempt C call (1)
        cinvoke printf, PFORMAT, test_string    ;THIS DOES *NOT* PRINT

        ; Return stack pointers to default
        mov ebp, [SYSTEM_EBP]
        mov esp, [SYSTEM_ESP]

        ; Attempt C call (2)
        cinvoke printf, PFORMAT, test_string2   ;THIS PRINTS OK

        ; Wait and exit
        cinvoke getchar 
        invoke ExitProcess,0 


section '.data' data readable writeable

PFORMAT         db "%s",0
test_string     db "I'm using the NEW stack!",13,10,0
test_string2    db "I'm using the OLD stack!",13,10,0

SYSTEM_EBP      dd 0
SYSTEM_ESP      dd 0

a_stack         dd 4096 dup 0 
stack_top:


section '.idata' import data readable writeable   

library kernel32,'kernel32.dll',\   
        msvcrt,'msvcrt.dll'   

 import kernel32,\   
        ExitProcess,'ExitProcess'   

 import msvcrt,\   
        getchar,'getchar',\   
        printf,'printf' 
    
Post 09 Nov 2008, 15:35
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 09 Nov 2008, 15:43
esp must always be in a stack page else the system exception handling code will fail your function call due to (what it thinks is) a corrupt stack pointer.
Post 09 Nov 2008, 15:43
View user's profile Send private message Visit poster's website Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 15:57
Ah!... thanks revolution.

So the os checks where esp is actually pointing. Damn.

Which begs a second question... how does one allocate a 'stack page' from the system?

I've looked through my win32 api ref and googled but I don't seem to be able to find any help on stack page allocation.

Do you or anyone else have any information (or even code example) about this?
Post 09 Nov 2008, 15:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 09 Nov 2008, 16:01
kas wrote:
how does one allocate a 'stack page' from the system?
Code:
sub esp,4092 ;but not more. Since we need to activate the page guard exception
push eax
;and repeat until you have the desired stack space    
Post 09 Nov 2008, 16:01
View user's profile Send private message Visit poster's website Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 16:03
Thanks again for a very fast answer. I'll try using your suggestion.

Kas.
Post 09 Nov 2008, 16:03
View user's profile Send private message Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 16:22
Hi again,

Ok I've tried using that strategy in the example and the c call works.

However, am I right in understanding that (say for a simple user threading scheme) where one has multiple stacks - all user threads must share an (extended) system default stack?

In other words - is there no way to allocate separate and continuous user thread structures - like any other kind of data definition/allocation?

Thanks,

Kas
Post 09 Nov 2008, 16:22
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 20:20
revolution,

Do you mean that default #PF handler commits guard pages only in thread's stack range? May be custom SE handler will do the trick, I'll try to write an example.
Post 09 Nov 2008, 20:20
View user's profile Send private message Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 21:13
Hi revolution,

Thanks for replying again.

I wasn't thinking about full OS threads - just a cooperative psuedo-threading setup. i.e. where 2 or more procedures (in the same process/thread) swapped control between each other.

Ideally I'd want each psuedo-thread would have its own little stack- defined in it's own structure. So the question I was asking was whether - in order to do this - we had to partition the OS's default stack or whether there was some way to ask the OS "hey now use this bit of memory I've allocated over here as your stack".

Kas. Smile
Post 09 Nov 2008, 21:13
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 21:33
kas,

There is some code with non-system-allocated stack: Weird code and programming style Wink
Post 09 Nov 2008, 21:33
View user's profile Send private message Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 21:53
baldr, it's a fascinating demo... though I just can't understand why the calls you make (in that demo) don't result in the same problem as my earlier posted example?

Why doesn't the OS (as revolution explained) notice that you're not using the OS defined stack and treat it as a possible corrupt stack access - instead of just working Wink !?
Post 09 Nov 2008, 21:53
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 22:35
kas,

OS doesn't. And doesn't have to. It just provide you growing stack, no matter how are you using it (or don't use at all).

Your code is failed because of alignment.
Code:
test_string2    db "I'm using the OLD stack!",13,10,0
                align 4; here goes the important part Wink
SYSTEM_EBP      dd 0    
will fix it. Don't you notice odd esp/ebp values? Wink
Post 09 Nov 2008, 22:35
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder 09 Nov 2008, 22:58
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:55; edited 1 time in total
Post 09 Nov 2008, 22:58
View user's profile Send private message Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 09 Nov 2008, 22:59
Oh my god... I thought I knew what I was doing... and that 'align' was just useful to improve CPU read/throughput speed i.e. performance.

It never occured to me that it (or rather the lack of...) might directly cause a fault!!! Shocked Embarassed

Thanks again baldr for your help,

Kas.
Post 09 Nov 2008, 22:59
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 23:07
kas,

Probably not fault (CPU-wise) at all, may be msvcrt does something strange.

asmcoder,

The same as above. Luckily your strings align new_stack, ret misaligns it. Wink
Post 09 Nov 2008, 23:07
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 10 Nov 2008, 01:35
Each thread has only one stack allocated by the OS. The OS will expand the stack downwards, as it is used, by 4096 bytes at a time using the guard page mechanism of the CPU.

The reason that you should use the OS stack (and not your own piece of memory) is because of the exception handling. Many (not all) OS functions will allocate a new SEH frame before doing the operations. The SEH allocation code will check that ESP is within the proper OS allocated stack and fail the call if it finds otherwise. If you are lucky to call a function that does not make an SEH frame then you can use your own stack anywhere in memory, but your code could easily break without warning on another OS version or after the next patch Tuesday or service pack update.

And yes, of course you should always align your memory access no matter if they are on the stack or not.
Post 10 Nov 2008, 01:35
View user's profile Send private message Visit poster's website Reply with quote
kas



Joined: 16 Jan 2008
Posts: 36
Location: UK
kas 10 Nov 2008, 02:31
Thanks for the info revolution about how OS functions and stack interdepend.

The align advice fixed the code - but I guess it was just a matter of time before this issue bit me too! Smile
Post 10 Nov 2008, 02:31
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder 10 Nov 2008, 09:57
[content deleted]
Post 10 Nov 2008, 09:57
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.