Simples JIT (just in time) em C
Publicado por ??? (última atualização em 08/07/2013)
[ Hits: 3.863 ]
Este é um simples exemplo de um JIT (just in time) escrito em puro C para Windows e GNU/Linux em 32 bits.
Este exemplo gera uma simples função que chama outra função (hello)...
Espero que seja útil para alguém.
//-------------------------------------------------------------------
//
// THANKS TO:
// The only GOD, creator of heaven and earth, in the name of JESUS CHRIST.
//
// DESCRIPTION:
// A simples JIT (32 bits) x86.
//
// FILE:
// asm.c
//
// COMPILE:
// gcc asm.c -o asm -m32 -O2 -Wall
//
// BY: gokernel - gokernel@hotmail.com
//
//-------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#ifdef __linux__
#include <unistd.h>
#include <sys/mman.h> // for: mprotect
#endif
typedef struct ASM
{
unsigned char *code;
int len;
}ASM;
ASM *asm_new (int size)
{
ASM *a = (ASM*) malloc (sizeof(ASM));
a->code = (unsigned char*) malloc (size);
a->len = 0;
return a;
}
//-------------------------------------------------------------------
// This function use the code of Fabrice Bellard:
//
// LIB: tcc-0.9.25
// FILE: libtcc.c
// FUNC: void set_pages_executable (void *ptr, unsigned long length);
// LINE: 400
//
// Set executable: a->code
//
//-------------------------------------------------------------------
void asm_set_executable (ASM *a)
{
#ifdef __linux__
unsigned long start, end, PageSize;
PageSize = sysconf (_SC_PAGESIZE);
start = (unsigned long)a->code & ~(PageSize - 1);
end = (unsigned long)a->code + a->len;
end = (end + PageSize - 1) & ~(PageSize - 1);
mprotect ((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
}
// 1 byte
void asm_gen (ASM *a, unsigned char c)
{
*(unsigned char*)(a->code + a->len) = c;
a->len++;
}
// 4 bytes
void asm_get_addr (ASM *a, void *ptr)
{
*(void**)(a->code + a->len) = ptr;
a->len += sizeof (void*);
}
// 7 bytes
void asm_op_call (ASM *a, void *func)
{
// b8 7a 13 40 00 mov $0x40137a,%eax
// ff d0 call *%eax
//
asm_gen (a, 0xb8); asm_get_addr (a, func);
asm_gen (a, 0xff); asm_gen(a, 0xd0);
}
void hello (void)
{
printf ("\ncall function: Hello World\n\n");
}
void execute (void)
{
ASM *a = asm_new (1000);
if (a && a->code)
{
//-----------------------------------------------------------
asm_gen(a, 0x55); // push %ebp
asm_gen(a, 0x89); asm_gen(a, 0xe5); // mov %esp,%ebp
asm_op_call (a, hello);
asm_gen(a, 0xc9); // leave
asm_gen(a, 0xc3); // ret
//-----------------------------------------------------------
asm_set_executable (a);
// execute here
//
( (void(*)())a->code ) ();
free (a->code);
free (a);
}
}
int main (void)
{
execute ();
printf ("Exiting with sucess !!!\n");
return 0;
}
Soma dois números lidos da memória
Escrita de um número em hexadecimal na tela em Assembly Puro para Linux 64 bits (GNU Assembly
Inverter uma string, Assembly8086
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Jogar games da Battle.net no Linux com Faugus Launcher
Como fazer a Instalação de aplicativos para acesso remoto ao Linux
Como fazer a instalação do Samba
Como fazer a conversão binária e aplicar as restrições no Linux
Assisti Avatar 3: Fogo e Cinzas (0)
Duas Pasta Pessoal Aparecendo no Ubuntu 24.04.3 LTS (40)









