Baixe o app para aproveitar ainda mais
Prévia do material em texto
/* Ingrid Caldas Pereira 0910912 */ /* Rafaela Vieira de Freitas 0911343 */ /* As funções foram testadas em uma plataforna little endian de 32 bits*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "dyncall.h" char buffEntr[4] = {0x55, 0x89, 0xe5, 0x53}; /* push %ebp mov %esp,%ebp push %ebx */ char buffParm[3] = {0x8b, 0x5d, 0x08}; /* mov 0x08(%ebp), %ebx */ char buffIncPtr[3] = {0x83, 0xc3, 0x08}; /* add $0x08, %ebx */ char buffDecPtr[3] = {0x83, 0xeb, 0x08}; /* sub $0x08, %ebx */ char buffEmpilha[2] = {0xff, 0x33}; /* push (%ebx) */ char buffDesempilha[2] = {0x8f, 0x03}; /* pop (%ebx) */ char buffDesempilhaF[2] = { 0xd9, 0x1b}; /* fstps (%ebx) */ char buffDesempilhaD[2] = {0xdd, 0x1b}; /* fstpl (%ebx) */ char buffRet[2] = {0x89, 0x03}; /* mov %eax, (%ebx) */ char buffRetF[2] = {0xd9, 0x1b}; /* fstps (%ebx) */ char buffRetD[2] = {0xdd, 0x1b}; /* fstsl (%ebx) */ char buffSaida[5] = {0x5b, 0x89, 0xec, 0x5d, 0xc3}; /* pop %ebx mov %ebp, %esp pop %ebp ret */ unsigned char * Inicializa(unsigned char * buff) { memcpy(buff, buffEntr, 4); return buff + 4; } unsigned char * GuardaParm(unsigned char * buff) { memcpy(buff, buffParm, 3); return buff + 3; } unsigned char * IncrementaPtr(unsigned char * buff, int i) { if(i == 0) return buff; buffIncPtr[2] = 8 * i; memcpy(buff, buffIncPtr, 3); return buff + 3; } unsigned char * DecrementaPtr(unsigned char * buff, int i) { if(i == 0) return buff; buffDecPtr[2] = i * 8; memcpy(buff, buffDecPtr, 3); return buff + 3; } unsigned char * EmpilhaParms(unsigned char * buff, const char * tpParm) { if(tpParm[0] == '>' || tpParm[0] == '\0') return buff; buff = EmpilhaParms(buff, tpParm + 1); if(tpParm[0] == 'i' || tpParm[0] == 'p' || tpParm[0] == 'c' || tpParm[0] == 'f') { memcpy(buff, buffEmpilha, 2); buff += 2; buff = DecrementaPtr(buff, 1); } else if(tpParm[0] == 'd') { buffIncPtr[2] = 0x04; memcpy(buff, buffIncPtr, 3); buff += 3; memcpy(buff, buffEmpilha, 2); buff += 2; buffDecPtr[2] = 0x04; memcpy(buff, buffDecPtr, 3); buff += 3; memcpy(buff, buffEmpilha, 2); buff += 2; buff = DecrementaPtr(buff, 1); } return buff; } unsigned char * ChamaFunc(unsigned char * buff, void * f) { unsigned int end, corrente, fInt; fInt = (int) f; corrente = (int) buff + 5; end = fInt - corrente; buff[0] = 0xe8; memcpy(buff+1, &end, 4); return buff + 5; } unsigned char * GuardaRet(unsigned char * buff, const char * signature ) { if(signature[0] == '>') { if(signature[1] == 'f') { memcpy(buff, buffRetF, 2); buff += 2; return IncrementaPtr(buff, 1); } else if(signature[1] == 'd') { memcpy(buff, buffRetD, 2); buff += 2; return IncrementaPtr(buff, 1); } else if(signature[1] == 'i' || signature[1] == 'p' || signature[1] == 'c') { memcpy(buff, buffRet, 2); buff += 2; return IncrementaPtr(buff, 1); } } return buff; } unsigned char * DesempilhaParms(unsigned char * buff, const char * tpParm) { if(tpParm[0] == '>' || tpParm[0] == '\0') return buff; if(tpParm[0] == 'i' || tpParm[0] == 'p' || tpParm[0] == 'c' || tpParm[0] == 'f') { memcpy(buff, buffDesempilha,2); buff += 2; buff = IncrementaPtr(buff, 1); } else if(tpParm[0] == 'd') { memcpy(buff, buffDesempilha, 2); buff += 2; buffIncPtr[2] = 0x04; memcpy(buff, buffIncPtr, 3); buff += 3; memcpy(buff, buffDesempilha, 2); buff += 2; buffIncPtr[2] = 0x04; memcpy(buff, buffIncPtr, 3); buff += 3; } buff = DesempilhaParms(buff, tpParm + 1); return buff; } unsigned char * Finaliza(unsigned char * buff) { memcpy(buff, buffSaida, 5); return buff + 5; } DynCall create_func (void* f, const char* signature) { int i; unsigned char * temp; DynCall dynCall; temp = (unsigned char *) malloc(500 * sizeof(char)); dynCall = (DynCall) temp; for(i=0; signature[i] != '>' && signature[i] != '\0'; i++) { } temp = Inicializa(temp); temp = GuardaParm(temp); temp = IncrementaPtr(temp, i); temp = EmpilhaParms(temp, signature); temp = ChamaFunc(temp, f); temp = GuardaRet(temp, signature + i); temp = DesempilhaParms(temp, signature); temp = Finaliza(temp); return dynCall; } void free_func (DynCall func) { free(func); }
Compartilhar