1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
/* radare 2008-2013 LGPL -- pancake */
#include <r_types.h>
#include <r_util.h>
#include <r_db.h>
#include <r_syscall.h>
#include <stdio.h>
#include <string.h>
#include "fastcall.h"
R_LIB_VERSION (r_syscall);
extern RSyscallPort sysport_x86[];
R_API RSyscall* r_syscall_new() {
RSyscall *rs = R_NEW (RSyscall);
if (rs) {
rs->fd = NULL;
rs->sysptr = NULL; //syscalls_linux_x86;
rs->sysport = sysport_x86;
rs->syspair = NULL;
rs->printf = (PrintfCallback)printf;
rs->regs = fastcall_x86_32;
}
return rs;
}
R_API void r_syscall_free(RSyscall *ctx) {
free (ctx);
}
/* return fastcall register argument 'idx' for a syscall with 'num' args */
R_API const char *r_syscall_reg(RSyscall *s, int idx, int num) {
if (num<0 || num>=R_SYSCALL_ARGS || idx<0 || idx>=R_SYSCALL_ARGS)
return NULL;
return s->regs[num].arg[idx];
}
R_API int r_syscall_setup(RSyscall *ctx, const char *arch, const char *os, int bits) {
char file[256];
if (os == NULL)
os = R_SYS_OS;
if (arch == NULL)
arch = R_SYS_ARCH;
if (!strcmp (os, "any")) // ignored
return R_TRUE;
if (!strcmp (arch, "mips"))
ctx->regs = fastcall_mips;
else if (!strcmp (arch, "arm"))
ctx->regs = fastcall_arm;
else if (!strcmp (arch, "x86")) {
switch (bits) {
case 8: ctx->regs = fastcall_x86_8;
case 32: ctx->regs = fastcall_x86_32;
case 64: ctx->regs = fastcall_x86_64;
}
} else if (!strcmp (arch,"sh")) {
ctx->regs = fastcall_sh;
}
#define SYSCALLPATH R2_LIBDIR"/radare2/"R2_VERSION"/syscall"
snprintf (file, sizeof (file), "%s/%s-%s-%d.sdb",
SYSCALLPATH, os, arch, bits);
if (!r_file_exists (file)) {
//eprintf ("r_syscall_setup: Cannot find '%s'\n", file);
return R_FALSE;
}
r_pair_free (ctx->syspair);
ctx->syspair = r_pair_new_from_file (file);
if (ctx->fd)
fclose (ctx->fd);
ctx->fd = NULL;
return R_TRUE;
}
R_API int r_syscall_setup_file(RSyscall *ctx, const char *path) {
if (ctx->fd)
fclose (ctx->fd);
ctx->fd = r_sandbox_fopen (path, "r");
if (ctx->fd == NULL)
return 1;
/* TODO: load info from file */
return 0;
}
R_API RSyscallItem *r_syscall_item_new_from_string(const char *name, const char *s) {
RSyscallItem *si;
char *o;
if (!s) return NULL;
si = R_NEW0 (RSyscallItem);
o = strdup (s);
r_str_split (o, ',');
/*
return r_syscall_item_new (name,
r_num_get (NULL, r_str_word_get0 (o, 0)),
r_num_get (NULL, r_str_word_get0 (o, 1)),
r_num_get (NULL, r_str_word_get0 (o, 2)),
r_str_word_get0 (o, 3));
*/
si->name = strdup (name);
si->swi = r_num_get (NULL, r_str_word_get0 (o, 0));
si->num = r_num_get (NULL, r_str_word_get0 (o, 1));
si->args = r_num_get (NULL, r_str_word_get0 (o, 2));
si->sargs = strdup (r_str_word_get0 (o, 3));
free (o);
return si;
}
R_API void r_syscall_item_free(RSyscallItem *si) {
free (si->name);
free (si->sargs);
free (si);
}
static int getswi(RPair *p, int swi) {
char *def;
if (swi == -1) {
def = r_pair_get (p, "_");
if (def && *def) {
swi = r_num_get (NULL, def);
free (def);
} else swi = 0x80; // XXX hardcoded
}
return swi;
}
R_API RSyscallItem *r_syscall_get(RSyscall *ctx, int num, int swi) {
char *ret, *ret2, foo[32];
RSyscallItem *si;
if (!ctx->syspair)
return NULL;
swi = getswi (ctx->syspair, swi);
snprintf (foo, sizeof (foo), "0x%02x.%d", swi, num);
ret = r_pair_get (ctx->syspair, foo);
if (ret == NULL)
return NULL;
ret2 = r_pair_get (ctx->syspair, ret);
if (ret2 == NULL)
return NULL;
si = r_syscall_item_new_from_string (ret, ret2);
free (ret);
free (ret2);
return si;
}
R_API int r_syscall_get_num(RSyscall *ctx, const char *str) {
char *o;
int i = 0;
if (!ctx->syspair)
return 0;
o = r_pair_get (ctx->syspair, str);
if (o && *o) {
r_str_split (o, ',');
i = r_num_get (NULL, r_str_word_get0 (o, 1));
}
free (o);
return i;
}
R_API char *r_syscall_get_i(RSyscall *ctx, int num, int swi) {
char *ret, foo[32];
if (!ctx->syspair)
return NULL;
swi = getswi (ctx->syspair, swi);
snprintf (foo, sizeof (foo), "0x%x.%d", swi, num);
ret = r_pair_get (ctx->syspair, foo);
return ret;
}
R_API const char *r_syscall_get_io(RSyscall *ctx, int ioport) {
int i;
for (i=0; ctx->sysport[i].name; i++) {
if (ioport == ctx->sysport[i].port)
return ctx->sysport[i].name;
}
return NULL;
}
R_API RList *r_syscall_list(RSyscall *ctx) {
RListIter *iter;
RPairItem *o;
RList *list = r_pair_list (ctx->syspair, NULL);
RList *olist = r_list_new ();
olist->free = (RListFree)r_syscall_item_free;
r_list_foreach (list, iter, o) {
RSyscallItem *si = r_syscall_item_new_from_string (o->k, o->v);
if (!strchr (si->name, '.'))
r_list_append (olist, si);
}
r_list_free (list);
return olist;
}
|