blob: 7070ecc73667a63c52cae416042dae93176d4cdc [file] [log] [blame]
#include <stdio.h>
#include <string.h>
#include <sys/ptrace.h>
#include <stdlib.h>
#include <ctype.h>
#include "functions.h"
#include "output.h"
static int current_pid;
struct function * list_of_functions = NULL;
struct function functions_list[] = {
{"atexit", _T_INT, 1, {_T_ADDR}},
{"close", _T_INT, 1, {_T_INT}},
{"exit", _T_INT, 1, {_T_INT}},
{"fclose", _T_INT, 1, {_T_FILE}},
{"fprintf", _T_INT, 2, {_T_FILE, _T_FORMAT}},
{"free", _T_INT, 1, {_T_ADDR}},
{"gethostname", _T_INT, 2, {_T_STRING, _T_INT}},
{"getopt_long", _T_INT, 5, {_T_INT, _T_ADDR, _T_STRING, _T_ADDR, _T_ADDR}},
{"malloc", _T_ADDR, 1, {_T_UINT}},
{"memset", _T_ADDR, 3, {_T_ADDR, _T_CHAR, _T_UINT}},
{"mkdir", _T_INT, 2, {_T_STRING, _T_OCTAL}},
{"open", _T_INT, 3, {_T_STRING, _T_INT, _T_INT}},
{"printf", _T_INT, 1, {_T_FORMAT}},
{"rindex", _T_STRING, 2, {_T_STRING, _T_CHAR}},
{"strcmp", _T_INT, 2, {_T_STRING, _T_STRING}},
{"strncmp", _T_INT, 3, {_T_STRING, _T_STRING, _T_INT}},
{"time", _T_UINT, 1, {_T_ADDR}},
{NULL, _T_UNKNOWN, 5, {_T_UNKNOWN, _T_UNKNOWN, _T_UNKNOWN, _T_UNKNOWN, _T_UNKNOWN}},
};
static char * process_string(unsigned char * str)
{
static char tmp[256];
tmp[0] = '\0';
while(*str) {
switch(*str) {
case '\r': strcat(tmp,"\\r"); break;
case '\n': strcat(tmp,"\\n"); break;
case '\t': strcat(tmp,"\\t"); break;
case '\\': strcat(tmp,"\\"); break;
default:
if ((*str<32) || (*str>126)) {
sprintf(tmp,"%s\\%03o", tmp, *str);
} else {
sprintf(tmp, "%s%c", tmp, *str);
}
}
str++;
}
return tmp;
}
static char * print_string(int addr)
{
static char tmp[256];
int a;
int i=0;
tmp[0] = '\0';
while(1) {
a = ptrace(PTRACE_PEEKTEXT, current_pid, addr+i, 0);
*(int *)&tmp[i] = a;
if (!tmp[i] || !tmp[i+1] || !tmp[i+2] || !tmp[i+3] || i>100) {
break;
}
i += 4;
}
return process_string(tmp);
}
static char * print_param(int type, int esp)
{
static char tmp[256];
int a;
a = ptrace(PTRACE_PEEKTEXT, current_pid, esp, 0);
switch(type) {
case _T_STRING:
case _T_FORMAT:
sprintf(tmp,"\"%s\"",print_string(a));
break;
default:
if (a<1000000 && a>-1000000) {
sprintf(tmp, "%d", a);
} else {
sprintf(tmp, "0x%08x", a);
}
}
return tmp;
}
void print_function(const char *name, int pid, int esp)
{
struct function * tmp;
char message[1024];
int i;
current_pid = pid;
tmp = list_of_functions;
while(tmp) {
if (!strcmp(name, tmp->function_name)) {
break;
}
}
if (!tmp) {
tmp = &functions_list[0];
while(tmp->function_name) {
if (!strcmp(name, tmp->function_name)) {
break;
}
tmp++;
}
}
sprintf(message, "%s(", name);
if (tmp->num_params>0) {
sprintf(message, "%s%s", message, print_param(tmp->params_type[0], esp+4));
}
for(i=1; i<tmp->num_params; i++) {
sprintf(message, "%s,%s", message, print_param(tmp->params_type[i], esp+4*(i+1)));
}
send_left("%s", message);
send_right(") = ???");
}
static int func_type(char ** buf)
{
int returned_value = 0;
if (**buf == '+') {
returned_value |= _T_OUTPUT;
(*buf)++;
}
if (!strcmp(*buf, "int")) {
returned_value |= _T_INT;
*buf += 3;
} else if (!strcmp(*buf, "addr")) {
returned_value |= _T_ADDR;
*buf += 4;
} else {
return -1;
}
return returned_value;
}
static int fill_fields(struct function * fun, char * buf)
{
char * tmp = buf;
for(; (*tmp==' '); tmp++);
if ((fun->return_type = func_type(&buf)) == -1) {
return 0;
}
for(; (*tmp==' '); tmp++);
return 0;
}
void read_config_file(const char * filename)
{
char buf[1024];
FILE * stream;
struct function tmp;
stream = fopen(filename, "r");
if (!stream) {
return;
}
while (fgets(buf, 1024, stream)) {
if (fill_fields(&tmp, buf)) {
tmp.next = list_of_functions;
list_of_functions = malloc(sizeof(struct function));
bcopy(&tmp, list_of_functions, sizeof(struct function));
}
}
}