The task requires poking machine code directly into memory and executing it. The machine code is the architecture-specific opcodes which have the simple task of adding two unsigned bytes together and making the result available to the high-level language.

For example, the following assembly language program is given for x86 (32 bit) architectures:

mov EAX, [ESP+4]
add EAX, [ESP+8]
ret
This would translate into the following opcode bytes:

139 68 36 4 3 68 36 8 195
Or in hexadecimal:

8B 44 24 04 03 44 24 08 C3
Task

If different than 32-bit x86, specify the target architecture of the machine code for your example. It may be helpful to also include an assembly version of the machine code for others to reference and understand what is being executed. Then, implement the following in your favorite programming language:

 Poke the necessary opcodes into a memory location.
 Provide a means to pass two values to the machine code.
 Execute the machine code with the following arguments: unsigned-byte argument of value 7; unsigned-byte argument of value 12; The result would be 19.
 Perform any clean up actions that are appropriate for your chosen language (free the pointer or memory allocations, etc.)


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)
    if (executable_buffer_address == 0):
        print('Warning: Failed to enable code execution, call will likely cause a protection fault.')
        func_address = ctypes.addressof(code_buffer)
    else:
        ctypes.memmove(executable_buffer_address, code_buffer, code_size)
        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)                        # build an actual function from the prototype by specifying the address
res = func(7,12)
print(res)
 