Przykład dotyczy windowsa, testowałem go na wine oraz windows 7. Identyczne działanie można uzyskać na linuxie, lecz kod będzie wyglądał inaczej.
#include <windows.h>
void print_string(char *string){
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD count_written;
WriteConsole(screen, string,strlen(string),&count_written,NULL);
}
void print_int(int value){
char str_number[20];
_itoa(value,str_number,10);
print_string((char *)str_number);
}
int main(){
unsigned char bytes[] = {
0x55,
0x89, 0xe5,
0x83, 0xec, 0x10,
0x8b, 0x55, 0x08,
0x8b, 0x45, 0x0c,
0x01, 0xd0,
0x89, 0x45, 0xfc,
0x8b, 0x45, 0xfc,
0xc9,
0xc3
};
HANDLE mem_handle = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(bytes), NULL);
void* mem_map = MapViewOfFile( mem_handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0x0, 0x0, sizeof(bytes));
memcpy(mem_map, bytes, sizeof(bytes));
print_string("Wartość argumentu to:\n");
int result = (( int(*)(int,int) )mem_map)(20,13);
print_int(result);
print_string("\n");
return 0;
}
Wywołuję tutaj binaria funkcji która wygląda tak:
int function(int a,int b){
int c = a+b;
return c;
}
Wyciągnięte z objdumpa (komilowane na 32 bity bez optymalizacji "-O0"):
Czyli to co masz w tablicy [unsigned char bytes].
00401570 <_function>:
401570: 55 push %ebp
401571: 89 e5 mov %esp,%ebp
401573: 83 ec 10 sub $0x10,%esp
401576: 8b 55 08 mov 0x8(%ebp),%edx
401579: 8b 45 0c mov 0xc(%ebp),%eax
40157c: 01 d0 add %edx,%eax
40157e: 89 45 fc mov %eax,-0x4(%ebp)
401581: 8b 45 fc mov -0x4(%ebp),%eax
401584: c9 leave
401585: c3 ret
Jak użytkownicy forum, zauważyli, musisz sobie zadać jedno bardzo ważne pytanie.
O ile w ogóle ten przykład będzie działał u Ciebie to czy jest sens?