Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C (or asm): how to execute c code stored in memory (copied from labels)

Tags:

c

memory

assembly

I try to "inline" my VM by copying code segments from C code between labels to memory allocated by malloc. So I have Ops defined with start and end labels, and I want to copy the instruction defined by the following code to a buffer and then get executed (Im not sure if this is even possible)

OP_PUSH0_START:
    sp += 4; *sp = 0; // I WANT THE INSTRUCTIONS OF THIS LINE COPIED TO THE BUFFER
OP_PUSH0_END:

to do so I thought the following code snippet will work

void * ptr0 = &&OP_PUSH0_START;
void * ptr1 = &&OP_PUSH0_END;
while(ptr0 < ptr1)
{
    buf[c++] = *ptr0;
    ptr0++;
}
goto buf; //jump to start of buffer

but I cant eaven read it out without getting a memory error

I would be happy about any links or any suggestions how to achieve this

like image 653
Moritz Schöfl Avatar asked Jul 12 '12 08:07

Moritz Schöfl


People also ask

What is asm function in C?

The asm statement allows you to include assembly instructions directly within C code. This may help you to maximize performance in time-sensitive code or to access assembly instructions that are not readily available to C programs. Note that extended asm statements must be inside a function.

What is __ asm __ in C?

The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself. It must be followed by an assembly instruction, a group of instructions enclosed in braces, or, at the very least, an empty pair of braces.


2 Answers

The only legal way to transfer execution to an arbitrary location is to use a function pointer. goto only jumps to labels, not arrays or anything else.

Also you cannot take the address of a label. A label is not an object or a function.

It is rightly pointed out that data areas are often placed in memory whose content cannot be executed as CPU instructions. There are, however, often workarounds for that. Windows and Linux provide functions to change the permissions/rights/privileges/whatever-you-call-it of a region of the memory.

For example, here's an example of doing the kind of thing you're trying to do on Windows.

like image 196
Alexey Frunze Avatar answered Oct 06 '22 00:10

Alexey Frunze


Just an addition to Alexey's answer I would link my own sample of creating the jit-executor.

How to make a C program that can run x86 hex codes

The AsmJIT library is a fine x86/x64 "one line" assembler which actually creates a complete executable chunk of memory.

The portable version of jit engine is the LuaJIT. It supports the creation of function trampolines for the ARM/x86/PowerPC/MIPS architectures.

The thing about "pointer to the label" cannot be standard in C, because there are hardware architectures in which data and code do not share the same memory.

like image 26
Viktor Latypov Avatar answered Oct 05 '22 22:10

Viktor Latypov