Machine code: Difference between revisions

m
Reverted edits by LVrOk6FqRY (talk) to last revision by Thundergnat
m (Updated whitespace, removed comments as language is explanatory enough.)
m (Reverted edits by LVrOk6FqRY (talk) to last revision by Thundergnat)
Line 68:
#include <sys/mman.h>
#include <string.h>
 
int test (int a, int b) {
char code[] = {0x8B, 0x44, 0x24, 0x4, 0x3, 0x44, 0x24, 0x8, 0xC3};
{
void * buf;
/*
int c;
mov EAX, [ESP+4]
buf = mmap (0, sizeof(code), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
add EAX, [ESP+8]
memcpy (buf, code, sizeof(code));
ret
c = ((int (*) (int, int)) buf) (a, b);
*/
munmap (buf, sizeof(code));
char code[] = {0x8B, 0x44, 0x24, 0x4, 0x3, 0x44, 0x24, 0x8, 0xC3};
return c;
void * buf;
int c;
/* copy code to executable buffer */
buf = mmap (0, sizeof(code), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
MAP_PRIVATE|MAP_ANON,-1,0);
 
memcpy (buf, code, sizeof(code));
/* run code */
c = ((int (*) (int, int)) buf) (a, b);
/* free buffer */
munmap (buf, sizeof(code));
return c;
}
 
int main () {
printf("%d\n", test(7,12));
{
return 0;
printf("%d\n", test(7,12));
return 0;
}</lang>
 
Line 773 ⟶ 787:
 
=={{header|Python}}==
 
{{works with|CPython|3.x}}
 
The ctypes module is meant for calling existing native code from Python, but you can get it to execute your own bytes with some tricks. The bulk of the code is spent establishing an executable memory area - once that's done, the actual execution takes just a few lines.
 
<lang Python>import ctypes
import os
from ctypes import c_ubyte, c_int
 
code = bytes([0x8b, 0x44, 0x24, 0x04, 0x03, 0x44, 0x24, 0x08, 0xc3])
 
code_size = len(code)
# copy code into an executable buffer
if (os.name == 'posix'):
import mmap
executable_map = mmap.mmap(-1, code_size, mmap.MAP_PRIVATE | mmap.MAP_ANON, mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)
# we must keep a reference to executable_map until the call, to avoid freeing the mapped memory
executable_map.write(code)
# the mmap object won't tell us the actual address of the mapping, but we can fish it out by allocating
# some ctypes object over its buffer, then asking the address of that
func_address = ctypes.addressof(c_ubyte.from_buffer(executable_map))
elif (os.name == 'nt'):
# the mmap module doesn't support protection flags on Windows, so execute VirtualAlloc instead
code_buffer = ctypes.create_string_buffer(code)
PAGE_EXECUTE_READWRITE = 0x40 # Windows constants that would usually come from header files
MEM_COMMIT = 0x1000
executable_buffer_address = ctypes.windll.kernel32.VirtualAlloc(0, code_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
Line 796 ⟶ 821:
func_address = executable_buffer_address
else:
# for other platforms, we just hope DEP isn't enabled
code_buffer = ctypes.create_string_buffer(code)
func_address = ctypes.addressof(code_buffer)
 
prototype = ctypes.CFUNCTYPE(c_int, c_ubyte, c_ubyte) # build a function prototype from return type and argument types
func = prototype(func_address)
func = prototype(func_address) # build an actual function from the prototype by specifying the address
res = func(7, 12)
print(res)</lang>
</lang>
 
=={{header|Racket}}==
10,327

edits