Enviado em 06/10/2018 - 11:51h
Olá Pessoal !!!
//-------------------------------------------------------------------
//
// Jit com chamada dinamica ( .so ) ... usa SDL1.x como exemplo.
//
// Testado somente em 64 BITS.
//
// A Funcao ( emit_call_direct(ASM *a)) eh baseado neste projeto:
//
// https://github.com/skeeto/dynamic-function-benchmark
//
// ARQUIVO:
// jit64.c
//
// COMPILE:
// gcc jit64.c -o jit64 -ldl -Wall
//
// BY: Francisco - gokernel@hotmail.com
//
//-------------------------------------------------------------------
#ifdef WIN32
#include <windows.h>
#endif
#ifdef __linux__
#include <unistd.h>
#include <sys/mman.h> // to: mprotect()
#include <dlfcn.h> // to: dlopen(), dlsym(), ... in file: cs_library.c
#endif
#include <stdio.h>
#include <stdlib.h>
#define MMAP_ANON 0x20
#define UCHAR unsigned char
typedef struct {
UCHAR *p;
UCHAR *code;
}ASM;
void *init = NULL;
void *delay = NULL;
void *quit = NULL;
void libopen (void) {
#ifdef __linux__
void *lib = dlopen ("libSDL.so", RTLD_NOW);
if (lib) {
printf ("Library SDL Loaded\n");
init = dlsym (lib, "SDL_Init");
delay = dlsym (lib, "SDL_Delay");
quit = dlsym (lib, "SDL_Quit");
if (init) {
printf ("SDL_Init loaded ...\n");
}
if (delay) {
printf ("SDL_Delay loaded ...\n");
}
if (quit) {
printf ("SDL_Quit loaded ...\n");
}
}
else printf ("libSDL.so Not Found\n");
#endif
}
ASM * asm_new (unsigned int size) {
ASM *a = (ASM*)malloc(sizeof(ASM));
#ifdef WIN32
if (a && (a->code=(UCHAR*)malloc(size)) != NULL) {
a->p = a->code;
return a;
}
#endif
#ifdef __linux__
if (a && (a->code = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MMAP_ANON, -1, 0)) != MAP_FAILED) {
a->p = a->code;
return a;
}
#endif
return NULL;
}
int set_executable (void *ptr, unsigned int size) {
#ifdef WIN32
unsigned long old_protect;
if (!VirtualProtect(ptr, size, PAGE_EXECUTE_READWRITE, &old_protect)) {
printf ("ERROR: asm_set_executable() ... NOT FOUND - VirtualProtect()\n");
return 1; // erro
}
#endif
#ifdef __linux__
unsigned long start, end, PageSize;
PageSize = sysconf (_SC_PAGESIZE);
start = (unsigned long)ptr & ~(PageSize - 1);
end = (unsigned long)ptr + size;
end = (end + PageSize - 1) & ~(PageSize - 1);
if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC) == -1) {
printf ("ERROR: asm_set_executable() ... NOT FOUND - mprotec()\n");
return 1; // erro
}
#endif
return 0; // no erro
}
void asm_get_addr (ASM *a, void *ptr) { ///: 32/64 BITS OK
*(void**)a->p = ptr;
a->p += 4; // ! OK
}
void g2 (ASM *a, UCHAR c1, UCHAR c2) {
a->p[0] = c1;
a->p[1] = c2;
a->p += 2;
}
void g3 (ASM *a, UCHAR c1, UCHAR c2, UCHAR c3) {
a->p[0] = c1;
a->p[1] = c2;
a->p[2] = c3;
a->p += 3;
}
void g4 (ASM *a, UCHAR c1, UCHAR c2, UCHAR c3, UCHAR c4) {
a->p[0] = c1;
a->p[1] = c2;
a->p[2] = c3;
a->p[3] = c4;
a->p += 4;
}
void emit_sub_esp (ASM *a, char c) { // 32/64 BITS OK
#if defined(__x86_64__)
g4(a,0x48,0x83,0xec,(char)c); // 48 83 ec 08 sub $0x8,%rsp
#else
g3(a,0x83,0xec,(char)c); // 83 ec 08 sub $0x8,%esp
#endif
}
void emit_begin (ASM *a) { //: 32/64 BITS OK
#if defined(__x86_64__)
// 55 : push %rbp
// 48 89 e5 : mov %rsp,%rbp
//-----------------------------
a->p[0] = 0x55;
a->p[1] = 0x48;
a->p[2] = 0x89;
a->p[3] = 0xe5;
a->p += 4;
emit_sub_esp (a,16);
#else
// 55 : push %ebp
// 89 e5 : mov %esp,%ebp
//-----------------------------
a->p[0] = 0x55;
a->p[1] = 0x89;
a->p[2] = 0xe5;
a->p += 3;
emit_sub_esp (a,100);
#endif
}
void emit_end (ASM *a) { ///: 32/64 BITS OK
#if defined(__x86_64__)
a->p[0] = 0xc9; // c9 : leaveq
a->p[1] = 0xc3; // c3 : retq
a->p += 2;
#else
a->p[0] = 0xc9; // c9 : leave
a->p[1] = 0xc3; // c3 : ret
a->p += 2;
#endif
}
void emit_call (ASM *a, void *func) {
//
// b8 7a 13 40 00 mov $0x40137a,%eax
// ff d0 call *%eax
//
*a->p++ = 0xb8; asm_get_addr(a, func); // %eax
g2(a,0xff,0xd0); // %eax
}
void emit_call_direct (ASM *a, void *func) {
#ifdef __linux__
#if defined(__x86_64__)
//
// Codigo baseado neste projeto:
//
// https://github.com/skeeto/dynamic-function-benchmark
//
//uintptr_t rel = (uintptr_t)func - (uintptr_t)a->p - 5;
*a->p++ = 0xe8;
*(long*)a->p = (void*)func - (void*)a->p - 4;
a->p += 4;
#endif
#endif
}
void hello (int i) {
printf ("\nFunction Hello World: %d\n\n", i);
}
void execute (void) {
ASM *a;
if ((a = asm_new (1000)) != NULL) {
libopen ();
if (init && delay && quit) {
emit_begin(a);
// funcao argumento 1:
// mov $32 %edi
g2(a,0xbf,0x20); g3(a,0x00,0x00,0x00);
emit_call_direct (a, init);
// funcao argumento 1:
// mov $32 %edi
g2 (a,0xbf,0x20); g3(a,0x00,0x00,0x00);
emit_call (a, hello);
// funcao argumento 1:
// bf b8 0b 00 00 mov $3000,%edi
g2(a,0xbf,0xb8); g3(a,0x0b,0x00,0x00);
emit_call_direct (a, delay);
emit_call_direct (a, quit);
emit_end(a);
if (set_executable(a, (a->p - a->code))==0) {
( (void(*)(void)) a->code ) ();
printf ("\nExiting Whith Sucess !!!\n");
}
}
}
}
int main (void) {
execute ();
return 0;
}
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
É cada coisa que me aparece! - não é só 3% (3)
Melhorando a precisão de valores flutuantes em python[AJUDA] (5)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta