Hi everybody,
I have been programming with Windows and assembly for a while now, but I don't know the limitations of Windows. Is it possible to execute code from memory that I have allocated by a GlobalAlloc call? for example,

GlobalAlloc .... (etc.)
mov memadr, eax
GlobalLock memadr
LoadProgram memadr ; loads program into memory
jmp memadr

If this isn't possible, is there any other way to dynamically load some code into memory with Windows and then execute it (it would have been easier in DOS!) Thanks.
Posted on 2004-08-16 09:07:40 by StefanD
You must use VirtualAlloc to allocate the memory, since recent CPUs support NX/DEP (No eXecute / Date Execution Protection) in hardware. This means that, finally, no-execute can be enforced on IA-32 systems.

It's pretty easy - invoke VirtualAlloc, NULL, datasize, MEM_COMMIT, PAGE_EXECUTE_READWRITE. You could also use VirtualProtect on a "normally allocated" block, but I would prefer VirtualAlloc myself... And if you're going to only write to the memory region once, you should use VirtualProtect to change permissions to PAGE_EXECUTE_READ after write is done.

PS: it's easy enough to just load&execute some code, if you want to load a full program, that takes some more work.
Posted on 2004-08-16 09:22:32 by f0dder
Thanks for the suggestion fodder. I have got a program to work that loads a routine into memory and then executes it, but it will generate an error and crash when I try and do a Windows API call. Here is the code:

; ?????????????????????????????????????????????????????????????????????????

.model flat, stdcall
option casemap :none ; case sensitive

; ?????????????????????????????????????????????????????????????????????????

include masm32includewindows.inc
include masm32includeuser32.inc
include masm32includekernel32.inc
include masm32includegdi32.inc
include masm32includemasm32.inc

includelib masm32libuser32.lib
includelib masm32libkernel32.lib
includelib masm32libgdi32.lib
includelib masm32libmasm32.lib

include masm32includedebug.inc
includelib masm32libdebug.lib

main PROTO
copy PROTO

; ---------------------
; literal string MACRO
; ---------------------
literal MACRO quoted_text:VARARG
LOCAL local_text
local_text db quoted_text,0
EXITM <local_text>
; --------------------------------
; string address in INVOKE format
; --------------------------------
EXITM <ADDR literal(quoted_text)>

; ?????????????????????????????????????????????????????????????????????????

pMem dd ?



call main

invoke ExitProcess,0

; ?????????????????????????????????????????????????????????????????????????

MyFunc proc
invoke Beep, 500, 100
invoke MessageBox, NULL, SADD("Code executing from memory"), SADD("appropriate title"),MB_OK
mov eax, 1
MyFunc endp
MyFunc_Len equ $ - MyFunc

main proc

mov pMem, eax

;Copy the procedure into the reserved memory
mov edi, pMem
mov esi, MyFunc
mov ecx, MyFunc_Len
rep movsb

;Call the memory
lea eax,pMem

;If the routine worked then eax should be equal to 1. use debug routines to test this
PrintHex eax

;Free up memory
invoke VirtualFree,pMem,0,MEM_RELEASE

main endp

; ?????????????????????????????????????????????????????????????????????????

end start

I was wondering if I could get it to perform the Win32 API calls in the executing memory? It works fine if you comment those two lines in MyFunc. Thanks
Posted on 2004-08-17 07:55:18 by StefanD
The calls to api are calls to jump table (Since you are using masm), hence the way it is encoded is relative to its location. I guess that is why your code crash. You can get it to work if you call the imports directly. I think there are some examples on this board, though I cannot remember where.
Posted on 2004-08-17 08:17:56 by roticv
Well, if you want to do API calls, then things get a bit complicated :). Do you ultimately want to use this technique to load larger pieces of code from disk? If so, I would recommend you to write a PE->your_own_format converter, and handle relocations and imports...
Posted on 2004-08-17 08:34:12 by f0dder
I don't want to load a larger piece of code from disk. I want to use this technique to create a dynamic recompiler emulator. Is there some way I could convert the offsets for it to work?
Posted on 2004-08-18 07:24:02 by StefanD
push address


But of course it means that you cannot use invoke.
Posted on 2004-08-18 07:31:35 by roticv
...or you could implement a disassembler, and have it fix up all references to outside of the code block you're moving :-)
Posted on 2004-08-18 08:16:48 by f0dder
"recent CPUs support NX/DEP"

could you tell us exactly what this instuction does and when it was implimented (what ptocessor).

A link is fine too
Posted on 2004-08-24 10:02:33 by mrgone
NX = Non-eXecutable, DEP = Data Execution Protection (microsoft term).

The NX is a per-page protection, just like supervisor-only or writable. Introduced for x86 with the 64bit athlon and P4 prescott. Can be emulated in software, sorta efficient when CPU has split code/data caches (google for PaX, find old docs. Or perhaps docs on plex86 virtualization.)
Posted on 2004-08-24 12:33:45 by f0dder

This article--and the link included--give a rough idea:



Posted on 2004-08-24 21:35:14 by farrier