Simples JIT (just in time) em C

Publicado por ??? (última atualização em 08/07/2013)

[ Hits: 3.536 ]

Download 5824.asm.c




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.

  



Esconder código-fonte

//-------------------------------------------------------------------
//
// 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;
}

Scripts recomendados

ToUpperCase em Assembler 8086

"Clear Screen" para Linux x86 em Assembly Puro (GNU Assembly)

Soma dois números lidos da memória

Inverter uma string, Assembly8086

Retorna o maior e menor elemento de um vetor em Assembly


  

Comentários
[1] Comentário enviado por CalistoW em 24/08/2019 - 21:57h

Que maneiro


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts