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;
}
Passkeys: A Evolução da Autenticação Digital
Instalação de distro Linux em computadores, netbooks, etc, em rede com o Clonezilla
Título: Descobrindo o IP externo da VPN no Linux
Armazenando a senha de sua carteira Bitcoin de forma segura no Linux
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Instalando Brave Browser no Linux Mint 22
vídeo pra quem quer saber como funciona Proteção de Memória:
Encontre seus arquivos facilmente com o Drill
Mouse Logitech MX Ergo Advanced Wireless Trackball no Linux
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
VMs e Interfaces de Rede desapareceram (12)
Instalação do drive do adaptador wiffi (7)