Ever try using one of the PAGE_EXECUTE_... flags for VirtualAlloc? It makes it possible to execute a block of memory (only on Win2000).

Imagine the possibilities. It's too late at night for me to try, so why don't you tell me...

; Example...

.data

szMsg DB "Hello, World!", 0

.code


CopyMemory PROC Dest:DWORD, Source:DWORD, mLength:DWORD

cld ; Work upwards

mov esi, Source ; Source address
mov edi, Dest ; Destination address
mov ecx, mLength ; Get size in bytes
shr ecx, 1 ; Convert to words

rep movsw ; repeat copy util all done
ret

CopyMemory ENDP



AppEntry PROC
LOCAL pCodeMem;

jmp CodeEnd

CodeStart:

push edi
push 0
push 0
push OFFSET szMsg
push 0
call ebx
pop edi
jmp edi

CodeEnd:


invoke VirtualAlloc, 0, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE
mov pCodeMem, eax

invoke CopyMemory, pCodeMem, CodeStart, (CodeEnd - CodeStart)

mov ebx, MessageBox
mov edi, Return

jmp pCodeMem

Return:


invoke VirtualFree, pCodeMem, 0, MEM_RELEASE

invoke ExitProcess, 0

AppEntry ENDP
Posted on 2003-06-13 02:58:02 by Paulicles the Philosopher
Er... all pages can always be executed. The flag does nothing on the PC versions of Windows.
Posted on 2003-06-13 05:55:54 by Sephiroth3
In fact if I remember correctly someone mentioned that the .DATA segment can actually be executed... You could put code in the .data section and JMP or CALL it.

However I haven't really checked this. ;) :) :tongue:
Posted on 2003-06-13 11:22:20 by AmkG
Well it is possible to have excute code in .data section. One of the smc methods I think.
Posted on 2003-06-13 12:06:21 by roticv
If I could find a way to get the address of a label in C++ I could code the same thing in that language. I could probably get the pointer to a function that is __declspec(naked), and for the size I would add another naked sentinel function to point to the memory directly after the end of the function, similar to label CodeEnd.

I also believe that you could using pointer arithmetic to do calls and jmps (such as the jump to Return), using the base addresses of the memory block and the original program itself. Of course, that would be the basis of a system for running code in virtual memory, instead of something slapped together like I just did.

(EDIT)

Runnning this in copied code fails...

push 0
call ExitProcess

...but this succeeds...

push 0
mov ebx, ExitProcess
call ebx

That's because calls and jumps with a register holding the address is absolue. Calling or jumping with a constant memory address (call ExitProcess or jmp Return) is relative (as in, "call the function that is 1031 bytes from the address of the next intruction").
Posted on 2003-06-13 12:44:50 by Paulicles the Philosopher
It's always possible to get the address of a non-member function.

For example:

extern int f(...);

int (*pfunc)(...) = f;

Then you can use the function pointer:

int i = (*pfunc)(a, b, c);

I believe the recent C and C++ standards allow you to use the pointer directly.

int i = pfunc(a, b, c);

It's a little extra work to bypass the C++ type checking.
Posted on 2003-06-13 17:48:26 by tenkey

Er... all pages can always be executed. The flag does nothing on the PC versions of Windows.

that's exactly what i would have said ;)
Posted on 2003-06-13 18:57:40 by Tola
I was talking about a label, the kind you use with goto. You also can't really "get" the length of a function in C++
Posted on 2003-06-13 19:00:39 by Paulicles the Philosopher
It's not standard (and VC doesn't support it), but I believe gcc has an indirect goto. So there probably is a way to get a label address with that compiler.
Posted on 2003-06-13 19:11:30 by tenkey