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.
Stefan.
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.
Stefan.
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.
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.
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:
; ?????????????????????????????????????????????????????????????????????????
.486
.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
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
; --------------------------------
; string address in INVOKE format
; --------------------------------
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
; ?????????????????????????????????????????????????????????????????????????
.data?
pMem dd ?
.code
start:
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
ret
MyFunc endp
MyFunc_Len equ $ - MyFunc
main proc
;
invoke VirtualAlloc,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE
mov pMem, eax
;Copy the procedure into the reserved memory
cld
mov edi, pMem
mov esi, MyFunc
mov ecx, MyFunc_Len
rep movsb
;Call the memory
lea eax,pMem
call DWORD PTR
;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
ret
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
; ?????????????????????????????????????????????????????????????????????????
.486
.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
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
; --------------------------------
; string address in INVOKE format
; --------------------------------
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
; ?????????????????????????????????????????????????????????????????????????
.data?
pMem dd ?
.code
start:
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
ret
MyFunc endp
MyFunc_Len equ $ - MyFunc
main proc
;
invoke VirtualAlloc,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE
mov pMem, eax
;Copy the procedure into the reserved memory
cld
mov edi, pMem
mov esi, MyFunc
mov ecx, MyFunc_Len
rep movsb
;Call the memory
lea eax,pMem
call DWORD PTR
;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
ret
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
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.
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...
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?
push address
retn
But of course it means that you cannot use invoke.
...or you could implement a disassembler, and have it fix up all references to outside of the code block you're moving :-)
"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
could you tell us exactly what this instuction does and when it was implimented (what ptocessor).
A link is fine too
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.)
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.)
mrgone,
This article--and the link included--give a rough idea:
http://ct.com.com/click?q=f1-Mt_uQpslWZEIoOfyFTWcmMUKm9RR
hth
farrier
This article--and the link included--give a rough idea:
http://ct.com.com/click?q=f1-Mt_uQpslWZEIoOfyFTWcmMUKm9RR
hth
farrier