Is it possible to execute code from stack?


invoke VirtualProtect, NULL, ESP, SIZE, PAGE_EXECUTE, ADDR lpflOldProtect


Just out of curiosity  ;)
Posted on 2009-09-24 10:54:10 by karthikeyanck
No.
Posted on 2009-09-24 11:55:52 by Scali
I just read somewhere in the forum that BitRake referred to as stack execution, Did I misunderstand the terminology :shy:
Posted on 2009-09-25 01:53:25 by karthikeyanck
Back in the 60s it was possible, but these days x86 processors have no-execute privileges (which broke a lot of software which DID execute code on the stack).
Posted on 2009-09-25 01:59:08 by Scali
60s?

!!!

You can do it on all pre-NT windows systems, and most NT systems except for Vista and upwards.
And you can do it on most Linux systems, including those protected by StackGuard et al.
And outside the x86 world, its generally possible too.
But you should not do it.
Your application will be identified as malicious by most heuristic based malware scanners.
The reason is that this is seen as a buffer overflow variant.
If you really need to, use heap memory, or a Shared Memory Object (SMO).
Posted on 2009-09-25 06:58:13 by Homer
"in the 60s" is a figure-of-speech for "a long time ago". Obviously Windows and x86 didn't even exist in the 60s.
By the way, XP Service Pack 2 also introduced DEP, which meant that stack was now protected by default on CPUs with no-execute bit. This is why software broke. So it hasn't been possible on most Windows/x86 systems since about 2004 or so, which for me classifies as 'the 60s'.

There is never, ever, any need to execute code on stack, and even if it is possible on some systems, it's considered poor coding practice. The proper way to handle runtime-generated code is to use VirtualAlloc() to allocate a buffer, with execute privileges, and then drop the code into that buffer.
Posted on 2009-09-25 07:31:34 by Scali
VirtualAlloc calls GlobalAlloc which calls HeapAlloc (ProcessHeap) if I recall correctly.
It then sets the page permissions and such.
Heap memory is, if I recall correctly, executable by default.
It's much quicker to do it yourself.
Posted on 2009-09-25 08:49:05 by Homer

VirtualAlloc calls GlobalAlloc which calls HeapAlloc (ProcessHeap) if I recall correctly.
It then sets the page permissions and such.
Heap memory is, if I recall correctly, executable by default.
It's much quicker to do it yourself.



VirtualAlloc() is the 'native' allocation method of Windows NT (works on page-level). GlobalAlloc()/LocalAlloc() are 16-bit legacy functions. In a 32-bit application, there are no separate global and local heaps. Hence there is now HeapAlloc(). HeapAlloc() is implemented on top of VirtualAlloc() with finer granularity (so recommended for normal application usage). I don't know if the Heap memory can be set to executable in a normal way, and I doubt that it is executable by default (shouldn't be). Only VirtualAlloc() officially supports altering the permissions through VirtualProtect(). Which is why I said that using VirtualAlloc() is the recommended way to allocate executable memory.
Posted on 2009-09-25 09:02:59 by Scali
Of course you can VirtualProtect the stack, but you shouldn't do this - as others have mentioned, either do VirtualAlloc (keep in mind it has 64kb granularity!), or reserve heap memory and VirtualProtect (and keep in mind you mark entire pages as executable!).

Global/LocalAlloc internally call HeapAlloc on NT, but they pass some magic undocumented flags - so they're not entirely the same as a normal HeapAlloc call. This is also why you should use Global/LocalAlloc in those few APIs that MSDN says expect G/LAlloc memory... and use HeapAlloc for everything else.

HeapAlloc sucked under Win9x, but has a decent implementation under NT... XP introduced low-fragmentation heap, and on Vista (or is it Win7?) LFH is used by default. Also, Win7 introduces a whole bunch of anti-exploit and diagnostics features to Heap memory, while still being superfast, so unless you have pretty darn specific needs... go heap.
Posted on 2009-09-25 09:59:32 by f0dder
Are you sure about using HeapAlloc and then calling VirtualProtect?
http://msdn.microsoft.com/en-us/library/aa366898(VS.85).aspx
Says:
A pointer to the base address of the region of pages whose access protection attributes are to be changed.

All pages in the specified region must be within the same reserved region allocated when calling the VirtualAlloc or VirtualAllocEx function using MEM_RESERVE. The pages cannot span adjacent reserved regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx using MEM_RESERVE.
===
It quite specifically says the memory has to be allocated through VirtualAlloc, and you need the base address of the allocated region.
I think with HeapAlloc() you can't know the real base address (in fact, you shouldn't even assume it actually uses VirtualAlloc(), even though it most probably does), you can at best guess it from the page-size your OS reports.
So I would say, HeapAlloc() is not a good idea, only use VirtualAlloc() when you want to use any of the Virtual*()-functionality, such as VirtualProtect().
Posted on 2009-09-25 10:18:01 by Scali
Yeah ok, I'll go with "this all gets handed to the heap manager on nt systems" and "theres some undocumented funky flags and other secret squirrel stuff".
Posted on 2009-09-25 10:31:28 by Homer
Yeah Scali, that's what MSDN says - and so, theoretically, VirtualProtect could start failling for HeapAlloc memory any day; I doubt it's going to happen, especially since HA internally uses VirtualAlloc (can't remember if it calls that function, or if HeapAlloc ends as a kernel mode call that ends calling the kernel mode variant - irrelevant, anyway), but I do think it's good advice only use VP on stuff you directly allocated with VA... nobody thought the stack would end up being NX'ed, and see what happened :)

Thing to keep in mind with VA is that you shouldn't do a VA call for each JIT function you want to create, since that's a big waste of memory - 64kb granularity, ugh. And there's no guarantee that granularity won't end up larger some day (you have to query systeminfo for the granularity to be safe).


Yeah ok, I'll go with "this all gets handed to the heap manager on nt systems" and "theres some undocumented funky flags and other secret squirrel stuff".
I haven't traced the calls since... pre-SP2 XP, I think it was, but that was definitely what happened back then (Local/GlobalAlloc calls allocated some 4 or 8 bytes extra than HeapAlloc which stored... "stuff"), and I had some weird errors on some Windows versions when trying to use HeapAlloc memory for clipboard functions and CreateStreamOnHGlobal().
Posted on 2009-09-25 10:34:20 by f0dder