开发者

C preprocessor variable constant?

I'm writing a program where a constant is needed but the value for the constant will be determined during run time. I have an array of op codes from which I want to randomly select one and _emit it into the program's code. Here is an example:

unsigned char opcodes[] = { 
  0x60, // pushad
  0x61, // popad
  0x90  // nop
}

int random_byte = rand() % sizeof(opcodes);
__asm _emit opcodes[random_byte]; // optimal goal, but invalid

However, it seems _emit can only take a constant value. E.g, this is valid:

switch(random_byte) {
  case 2:
    __asm _em开发者_开发百科it 0x90
    break;
}

But this becomes unwieldy if the opcodes array grows to any considerable length, and also essentially eliminates the worth of the array since it would have to be expressed in a less attractive manner.

Is there any way to neatly code this to facilitate the growth of the opcodes array? I've tried other approaches like:

#define OP_0 0x60
#define OP_1 0x61
#define OP_2 0x90

#define DO_EMIT(n) __asm _emit OP_##n

// ...

unsigned char abyte = opcodes[random_byte];
DO_EMIT(abyte)

In this case, the translation comes out as OP_abyte, so it would need a call like DO_EMIT(2), which forces me back to the switch statement and enumerating every element in the array.

It is also quite possible that I have an entirely invalid approach here. Helpful feedback is appreciated.


I'm not sure what compiler/assembler you are using, but you could do what you're after in GCC using a label. At the asm site, you'd write it as:

asm (
    "target_opcode: \n"
    ".byte 0x90\n" );    /* Placeholder byte */

...and at the place where you want to modify that code, you'd use:

extern volatile unsigned char target_opcode[];
int random_byte = rand() % sizeof(opcodes);
target_opcode[0] = random_byte;

Perhaps you can translate this into your compiler's dialect of asm.

Note that all the usual caveats about self-modifying code apply: the code segment might not be writeable, and you may have to flush the I-cache before executing the modified code.


You won't be able to do any randomness in the C preprocessor AFAIK. The closest you could get is generating the random value outside. For instance:

cpp -DRND_VAL=$RANDOM ...

(possibly with a modulus to maintain the value within a range), at least in UNIX-based systems. Then, you can use the definition value, that will be essentially random.


How about

char operation[4]; // is it really only 1 byte all the time?
operation[0] = random_whatever();
operation[1] = 0xC3; // RET
void (*func)() = &operation[0];
func();

Note that in this example you'd need to add a RET instruction to the buffer, so that in the end you end up at the right instruction after calling func().


Using an _emit at runtime into your program code is kind of like compiling the program you're running while the program is running.

You should describe your end-goal rather than just your idea of using _emit at runtime- there might be abetter way to accomplish what you want. Maybe you can write your opcodes to a regular data array and somehow make that bit of memory executable. That might be a little tricky due to security considerations, but it can be done.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜