Running machine code

Here's a code:
http://codepad.org/sQoF6kR8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>

typedef unsigned char byte;

int arg1;
int arg2;
int res1;

byte buf[1<<16];

typedef void (*pfunc)(void);

union funcptr {
  pfunc x;
  byte* y;
};

int main( void ) {

  byte* p = buf;

  *p++ = 0x60; // pusha

  *p++ = 0xA1; // mov eax, [arg1]
  (int*&)p[0] = &arg1; p+=sizeof(int);

  // 0FAF05 34120000  imul eax,[arg2]
  *p++ = 0x0F;
  *p++ = 0xAF;
  *p++ = 0x05;
  (int*&)p[0] = &arg2; p+=sizeof(int);

  *p++ = 0xA3; // mov [res1],eax
  (int*&)p[0] = &res1; p+=sizeof(int);

  *p++ = 0x61; // popa
  *p++ = 0xC3; // ret

  funcptr func;
  func.y = buf;

  arg1 = 123; arg2 = 321; res1 = 0;

  func.x(); // call generated code

  printf( "arg1=%i arg2=%i arg1*arg2=%i func(arg1,arg2)=%i\n", arg1,arg2,arg1*arg2,res1 );

}


output should be:
arg1=123 arg2=321 arg1*arg2=39483 func(arg1,arg2)=39483


When I run it on windows ( compiled visual studio 2015 default settings for debug 64bit ), I'm getting access violation on the printf line.

linux(64):
g++ test.cpp -o test
./test

Segmentation fault

what went wrong here?
Last edited on
how old is that code?
I am not sure you can do this anymore. I could be wrong. Could also be the wrong instruction sizes for your current execution mode (64 bit vs 32 bit mode or something).
I seem to recall having to do the above this way, and that was some time ago..

__asm //the visual studio version of assembler blocks, or it once was
{
emit(opcode) //I forget the exact syntax but the emit function was direct cpu instruction in integer format as you seem to be doing here.
}

you are jumping into the middle of YOUR program, and attempting to execute code. What about the call stack for your code? Is that being damaged? What about what was in the registers for YOUR code? There are several things that could go wrong here.

think in assembly like a CPU.
its sitting there
move something to ax
move something to bx
do some operation
do some memory addressing
about to write back to memory or process something else and BAM
jack something else into ax, do some other operations, do more stuff,
resume where you left off but the data is changed, the side effects and flags are changed...
kablooie.

your code comments claim to have cleaned up and done this correctly, but I am not convinced. I seem to vaguely recall having to push and pop flag registers, multiple registers, all kinds of stuff when doing this kind of activity.







Last edited on
Here I am seeing some mistakes in coding such as given below:-

*p++ = 0xA1; // mov eax, [arg1]
(int*&)p[0] = &arg1; p+=sizeof(int);

// 0FAF05 34120000 imul eax,[arg2]
*p++ = 0x0F;
*p++ = 0xAF;
*p++ = 0x05;
(int*&)p[0] = &arg2; p+=sizeof(int);

*p++ = 0xA3; // mov [res1],eax
(int*&)p[0] = &res1; p+=sizeof(int);

In the place of P++= 0xA1:// mov eax, [arg1]
(int*&)p[0] = &arg1; p+=sizeof(int);

you can not use P+ and also P++, imul eax[arg2], in given coding.

http://www.traininginlucknow.in/best-c-language-training-in-Lucknow.html
Last edited on
You're right!
Also I had to give 'execute' permission for that memory block.
Here's a working one for windows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
	typedef unsigned char byte;
	int arg1, arg2, res1; 
	byte*buf = (byte*)VirtualAllocEx(GetCurrentProcess(), 0, 1 << 16, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	byte* p = buf;

	*p++ = 0x50; // push eax
	*p++ = 0x52; // push edx

	*p++ = 0xA1; // mov eax, [arg2]
	(int*&)p[0] = &arg2; p += sizeof(int*);

	*p++ = 0x92; // xchg edx,eax

	*p++ = 0xA1; // mov eax, [arg1]
	(int*&)p[0] = &arg1; p += sizeof(int*);

	*p++ = 0xF7; *p++ = 0xEA; // imul edx

	*p++ = 0xA3; // mov [res1],eax
	(int*&)p[0] = &res1; p += sizeof(int*);

	*p++ = 0x5A; // pop edx
	*p++ = 0x58; // pop eax
	*p++ = 0xC3; // ret

	arg1 = 123; arg2 = 321; res1 = 0;
	((void(*)(void))buf)(); // call generated code
	printf("arg1=%i arg2=%i arg1*arg2=%i func(arg1,arg2)=%i\n", arg1, arg2, arg1*arg2, res1);


and for linux:
1
2
byte*buf = (byte *)valloc(1 << 16);
mprotect(buf, 1<<16, (PROT_READ | PROT_WRITE |PROT_EXEC));


I'm guessing there is no standard way to set memory permissions.
Topic archived. No new replies allowed.