mirror of
https://github.com/radareorg/r0.git
synced 2026-11-08 17:41:58 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
863df639f8 | ||
|
|
39bede8372 | ||
|
|
30709b9b1d | ||
|
|
b01e0d7b34 | ||
|
|
5a5b11ef98 | ||
|
|
b3551aa7a2 | ||
|
|
b0fa755b4b | ||
|
|
7139b88824 | ||
|
|
0fce443275 | ||
|
|
3bd7ce6beb | ||
|
|
ca297b60a0 | ||
|
|
1ac42e0af6 | ||
|
|
04187f5984 | ||
|
|
8e9a02fec4 | ||
|
|
c3f761ff94 | ||
|
|
8897ce01e8 | ||
|
|
c8771027c1 | ||
|
|
f35349f466 | ||
|
|
bed3edc0cd | ||
|
|
223a733c42 |
No files matched your search
@@ -1,20 +1,28 @@
|
||||
CC?=gcc
|
||||
VERSION=0.8
|
||||
VERSION=0.9
|
||||
CCw32?=i486-mingw32-gcc
|
||||
CFLAGS+=-O2 -Wall
|
||||
CFLAGS+=-O0 -Wall -g
|
||||
#CFLAGS+=-DVERSION=\"${VERSION}\"
|
||||
PREFIX?=/usr/local
|
||||
DESTDIR?=
|
||||
|
||||
ARCH=X32
|
||||
#ARCH=ARM
|
||||
#ARCH=NONE
|
||||
|
||||
all: r0 r0d
|
||||
|
||||
r0: r0.o
|
||||
${CC} ${CFLAGS} r0.o -o r0
|
||||
|
||||
r0.o: calc.c cmd.c io.c util.c hexparse.c
|
||||
$(CC) -c r0.c -DUSE_DISASM_$(ARCH)=1
|
||||
|
||||
r0d: r0d.o
|
||||
${CC} ${CFLAGS} r0d.o -o r0d
|
||||
|
||||
r0.o: calc.c cmd.c io.c util.c hexparse.c
|
||||
|
||||
r0.js:
|
||||
emcc -Os -o r0.js r0.c
|
||||
emcc -s FORCE_FILESYSTEM=1 -lnodefs.js -s EXPORTED_FUNCTIONS='["_r0_open", "_r0_cmd"]' -DUSE_DISASM_X32=1 -Os -o r0.js r0.c
|
||||
|
||||
r0.arm:
|
||||
$(CC) -DUSE_DISASM_ARM=1 r0.c -o r0.arm
|
||||
@@ -23,7 +31,7 @@ r0.8086:
|
||||
$(CC) -fsanitize=address -g -DUSE_DISASM_8086=1 r0.c -o r0.8086
|
||||
|
||||
r0.x86:
|
||||
$(CC) -fsanitize=address -g -DUSE_DISASM_X32=1 r0.c -o r0.x86
|
||||
$(CC) -DUSE_DISASM_X32=1 -Os r0.c -o r0.x86
|
||||
# $(CC) -fsanitize=address -g -DUSE_DISASM_X86=1 r0.c -o r0.x86
|
||||
|
||||
r0.com: # msdos
|
||||
@@ -32,11 +40,25 @@ r0.com: # msdos
|
||||
r0.wasm:
|
||||
emcc -Os -o r0.html r0.c
|
||||
|
||||
# https://github.com/bebbo/amiga-gcc
|
||||
AMICC=/opt/amiga/bin/m68k-amigaos-gcc
|
||||
AMICFLAGS=-O0
|
||||
r0.amiga ami:
|
||||
$(AMICC) $(AMICFLAGS) -mcrt=nix20 -o r0.run r0.c
|
||||
lha c r0-nix20.lha r0.run
|
||||
rm -f r0.run
|
||||
$(AMICC) $(AMICFLAGS) -DR0_NOENV=1 -DHAVE_FTRUNCATE=0 -mcrt=nix13 -o r0.run r0.c
|
||||
lha c r0-nix13.lha r0.run
|
||||
|
||||
r0.bc:
|
||||
clang -emit-llvm -o r0.bc -c r0.c
|
||||
|
||||
r0: r0.o
|
||||
${CC} ${CFLAGS} r0.o -o r0
|
||||
WASI_SDK=$(HOME)/Downloads/wasi/wasi-sdk-12.0
|
||||
WASI_SYSROOT=$(HOME)/Downloads/wasi/wasi-sysroot
|
||||
|
||||
wasi:
|
||||
export CC="$(WASI_SDK)/bin/clang --sysroot=$(WASI_SYSROOT) -DHAVE_SYSTEM=0" ; $(MAKE) clean ; $(MAKE)
|
||||
mv r0 r0.wasm
|
||||
|
||||
dist:
|
||||
@if [ -z "${VERSION}" ]; then echo "Try: make dist VERSION=0.5" ; exit 1 ; fi
|
||||
|
||||
@@ -58,7 +58,7 @@ z/Z zero-terminatted string (ascii, wide-ascii)
|
||||
PORTABILITY
|
||||
===========
|
||||
r0 is known to build and run on several OS.
|
||||
- GNU, Linux, OSX, Windows (mingw), DOS, cygwin, Solaris, BSD, ...
|
||||
- GNU/Hurd, Plan9, DOS, BSD, Solaris, Linux, macOS, Windows, Wasm, Javascript, ...
|
||||
|
||||
TODO:
|
||||
=====
|
||||
|
||||
@@ -146,7 +146,7 @@ static void cin_putback (RNum *num, RNumCalc *nc, char c) {
|
||||
nc->oc = c;
|
||||
}
|
||||
|
||||
R_API const char *r_num_calc_index (RNum *num, const char *p) {
|
||||
R_API const char *r_num_calc_index(RNum *num, const char *p) {
|
||||
if (num == NULL)
|
||||
return NULL;
|
||||
if (p) {
|
||||
@@ -294,7 +294,7 @@ static void load_token(RNum *num, RNumCalc *nc, const char *s) {
|
||||
nc->calc_err = NULL;
|
||||
}
|
||||
|
||||
R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) {
|
||||
R_API ut64 r_num_calc(RNum *num, const char *str, const char **err) {
|
||||
RNumCalcValue n;
|
||||
RNumCalc *nc, nc_local;
|
||||
if (!str || !*str)
|
||||
@@ -328,19 +328,7 @@ R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) {
|
||||
return n.n;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int main(int argc, char* argv[]) {
|
||||
RNumCalcValue n;
|
||||
RNumCalc nc;
|
||||
while (!feof (stdin)) {
|
||||
get_token (nc);
|
||||
if (nc.curr_tok == RNCEND) break;
|
||||
if (nc.curr_tok == RNCPRINT) continue;
|
||||
n = expr (num, nc, 0);
|
||||
if (n.d == ((double)(int)n.d))
|
||||
printf ("%llx\n", n.n);
|
||||
else printf ("%lf\n", n.d);
|
||||
}
|
||||
return nc->errors;
|
||||
R_API ut64 calc(const char *str) {
|
||||
return r_num_calc (NULL, str, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
static int cmd_hexdump(char *arg) {
|
||||
static int cmd_hexdump(const char *arg) {
|
||||
int len = bsize;
|
||||
ut8 *buf = getcurblk(arg, &len);
|
||||
if(buf && len>0) {
|
||||
@@ -32,7 +32,7 @@ static int cmd_hexdump(char *arg) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int cmd_print(char *arg) {
|
||||
static int cmd_print(const char *arg) {
|
||||
ut8 *buf;
|
||||
int len = bsize;
|
||||
if(*arg) {
|
||||
@@ -49,6 +49,41 @@ static int cmd_print(char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_system(const char *arg) {
|
||||
int len = bsize;
|
||||
char str[1024];
|
||||
ut8 *buf;
|
||||
if(strstr(arg, "BLOCK")) {
|
||||
FILE *fd = fopen(".curblk", "wb");
|
||||
if(fd) {
|
||||
if((buf = getcurblk("", &len))) {
|
||||
setenv("BLOCK", ".curblk", 1);
|
||||
fwrite(buf, len, 1, fd);
|
||||
free(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
if(strstr(arg, "BSIZE")) {
|
||||
sprintf(str, "%d", len);
|
||||
setenv("BSIZE", str, 1);
|
||||
}
|
||||
if(strstr(arg, "OFFSET")) {
|
||||
sprintf(str, "%"LLF"d", curseek);
|
||||
setenv("OFFSET", str, 1);
|
||||
}
|
||||
if(strstr(arg, "XOFFSET")) {
|
||||
sprintf(str, "0x%"LLF"x", curseek);
|
||||
setenv("XOFFSET", str, 1);
|
||||
}
|
||||
#if HAVE_SYSTEM
|
||||
if(io_system(arg)<0)
|
||||
perror("system");
|
||||
#endif
|
||||
unlink(".curblk");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if USE_DISASM
|
||||
static int cmd_disasm(const char *arg) {
|
||||
char output[256];
|
||||
@@ -62,7 +97,7 @@ static int cmd_disasm(const char *arg) {
|
||||
for(i = 0; i < len ;i++) {
|
||||
*output = 0;
|
||||
ilen = disasm(buf + i, len - i, curseek+i, output);
|
||||
printf("0x%08llx ", curseek+i);
|
||||
printf("0x%08"LLF"x ", curseek+i);
|
||||
pad = 10;
|
||||
if (ilen > 0) {
|
||||
pad -= ilen;
|
||||
@@ -80,6 +115,11 @@ static int cmd_disasm(const char *arg) {
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int cmd_disasm(const char *arg) {
|
||||
return cmd_system("echo X | r0 -n $BLOCK | rasm2 -o $OFFSET -D -"); // |head -n $(($LINES-1))");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmd_bytedump(const char *arg) {
|
||||
@@ -122,26 +162,26 @@ static int cmd_search(const char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_bsize(char *arg) {
|
||||
static int cmd_bsize(const char *arg) {
|
||||
if(!*arg) printf("%d\n", bsize);
|
||||
else if(*arg=='+') bsize += (int)str2ut64(arg+1);
|
||||
else if(*arg=='-') bsize -= (int)str2ut64(arg+1);
|
||||
else bsize = str2ut64(arg);
|
||||
else if(*arg=='+') bsize += (int)calc(arg+1);
|
||||
else if(*arg=='-') bsize -= (int)calc(arg+1);
|
||||
else bsize = calc(arg);
|
||||
if(bsize<1) bsize = 1;
|
||||
obsize = bsize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_seek(char *arg) {
|
||||
static int cmd_seek(const char *arg) {
|
||||
if(!*arg) printf("%"LLF"d\n", curseek);
|
||||
else if(*arg=='+') curseek += str2ut64(arg+1);
|
||||
else if(*arg=='-') curseek -= str2ut64(arg+1);
|
||||
else curseek = str2ut64(arg);
|
||||
else if(*arg=='+') curseek += calc(arg+1);
|
||||
else if(*arg=='-') curseek -= calc(arg+1);
|
||||
else curseek = calc(arg);
|
||||
io_seek((oldseek=curseek), 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_dump(char *file) {
|
||||
static int cmd_dump(const char *file) {
|
||||
int len = bsize;
|
||||
ut8 *buf = getcurblk("", &len);
|
||||
if(len<1 || buf) {
|
||||
@@ -160,7 +200,7 @@ static int cmd_dump(char *file) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_load(char *file) {
|
||||
static int cmd_load(const char *file) {
|
||||
FILE *fd = fopen(file, "rb");
|
||||
if(fd) {
|
||||
void *buf = malloc(bsize);
|
||||
@@ -206,7 +246,7 @@ static int cmd_write(const char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_help(char *arg) {
|
||||
static int cmd_help(const char *arg) {
|
||||
if(*arg) {
|
||||
ut64 ret = r_num_calc (NULL, arg, NULL);
|
||||
printf("0x%"LLF"x %"LLF"d 0%"LLF"o\n", ret, ret, ret);
|
||||
@@ -230,7 +270,7 @@ static int cmd_help(char *arg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_resize(char *arg) {
|
||||
static int cmd_resize(const char *arg) {
|
||||
ut8 *buf;
|
||||
ut64 tail, n;
|
||||
int i, len, ret = 0;
|
||||
@@ -239,7 +279,7 @@ static int cmd_resize(char *arg) {
|
||||
printf("%"LLF"d\n", (ut64)io_seek(0, SEEK_END));
|
||||
break;
|
||||
case '+': // XXX: needs cleanup
|
||||
n = str2ut64(arg+1);
|
||||
n = calc(arg+1);
|
||||
len = (ut64)io_seek(0, SEEK_END);
|
||||
tail = len-curseek;
|
||||
if((buf=malloc(tail))) { // XXX: Use block
|
||||
@@ -256,7 +296,7 @@ static int cmd_resize(char *arg) {
|
||||
case '-':
|
||||
buf = malloc(bsize);
|
||||
if(buf) {
|
||||
n = str2ut64(arg+1);
|
||||
n = calc(arg+1);
|
||||
for(i=0;!ret;i+=len) {
|
||||
io_seek(curseek+n+i, SEEK_SET);
|
||||
if((len = io_read(buf, bsize))>0) {
|
||||
@@ -271,43 +311,9 @@ static int cmd_resize(char *arg) {
|
||||
} else perror("malloc");
|
||||
break;
|
||||
default:
|
||||
ret = io_truncate(str2ut64(arg));
|
||||
ret = io_truncate(calc(arg));
|
||||
}
|
||||
if(ret<0) perror("truncate");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_system(char *arg) {
|
||||
int len = bsize;
|
||||
char str[1024];
|
||||
ut8 *buf;
|
||||
if(strstr(arg, "BLOCK")) {
|
||||
FILE *fd = fopen(".curblk", "wb");
|
||||
if(fd) {
|
||||
if((buf = getcurblk("", &len))) {
|
||||
setenv("BLOCK", ".curblk", 1);
|
||||
fwrite(buf, len, 1, fd);
|
||||
free(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
if(strstr(arg, "BSIZE")) {
|
||||
sprintf(str, "%d", len);
|
||||
setenv("BSIZE", str, 1);
|
||||
}
|
||||
if(strstr(arg, "OFFSET")) {
|
||||
sprintf(str, "%"LLF"d", curseek);
|
||||
setenv("OFFSET", str, 1);
|
||||
}
|
||||
if(strstr(arg, "XOFFSET")) {
|
||||
sprintf(str, "0x%"LLF"x", curseek);
|
||||
setenv("XOFFSET", str, 1);
|
||||
}
|
||||
#if HAVE_SYSTEM
|
||||
if(io_system(arg)<0)
|
||||
perror("system");
|
||||
#endif
|
||||
unlink(".curblk");
|
||||
return 1;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ struct inst_arm {
|
||||
uint32_t (*func)(struct thumb_disasm_t*, uint32_t);
|
||||
};
|
||||
|
||||
static char const tbl_regs[][4] = {
|
||||
static const char *tbl_regs[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
|
||||
"fp", "ip", "sp", "lr", "pc", "cpsr"
|
||||
};
|
||||
@@ -159,7 +159,7 @@ static uint16_t thumb_disasm_blocktrans(struct thumb_disasm_t *ai, uint16_t inst
|
||||
static uint16_t thumb_disasm_condbranch(struct thumb_disasm_t *ai, uint16_t inst) {
|
||||
uint16_t offset = inst & 0x00ff;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"b%s 0x%lx", tbl_cond[(inst >> 8) & 0x0f], ai->pc+offset);
|
||||
"b%s 0x%x", tbl_cond[(inst >> 8) & 0x0f], ai->pc+offset);
|
||||
ai->jmp = ai->pc + offset;
|
||||
ai->fail = ai->pc + 4;
|
||||
return 0;
|
||||
@@ -169,7 +169,7 @@ static uint16_t thumb_disasm_uncondbranch(struct thumb_disasm_t *ai, uint16_t in
|
||||
short offset = (inst & 0x07ff) << 1;
|
||||
if (offset & 0x0800) offset |= 0xf000;
|
||||
offset += 4;
|
||||
snprintf (ai->str, sizeof (ai->str), "b 0x%lx", ai->pc+offset);
|
||||
snprintf (ai->str, sizeof (ai->str), "b 0x%x", ai->pc+offset);
|
||||
ai->jmp = ai->pc+offset;
|
||||
return 0;
|
||||
}
|
||||
@@ -277,7 +277,7 @@ static uint16_t thumb_disasm_movshift(struct thumb_disasm_t *ai, uint16_t inst)
|
||||
|
||||
static uint32_t thumb2_disasm_branchlinked(struct thumb_disasm_t *ai, uint32_t inst) {
|
||||
uint32_t offset = (((inst & 0x07ff0000) >> 4) | ((inst & 0x000007ff) << 1)) + 4;
|
||||
snprintf (ai->str, sizeof (ai->str), "bl 0x%lx", ai->pc+offset);
|
||||
snprintf (ai->str, sizeof (ai->str), "bl 0x%x", ai->pc+offset);
|
||||
ai->jmp = ai->pc+offset;
|
||||
return 0;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ static uint32_t thumb2_disasm_coprocmov1(struct thumb_disasm_t *ai, uint32_t ins
|
||||
char last[32];
|
||||
if (opc2) snprintf (last, sizeof (last), ", #%u", opc2); else *last = 0;
|
||||
snprintf (ai->str, sizeof (ai->str),
|
||||
"%s%s p%lu, #%u, %s, cr%lu, cr%lu%s", (inst & 0x00100000)?"mrc":"mcr",
|
||||
"%s%s p%u, #%u, %s, cr%u, cr%u%s", (inst & 0x00100000)?"mrc":"mcr",
|
||||
(inst & 0x10000000)?"2":"", get_nibble(inst, 2), opc1,
|
||||
tbl_regs[get_nibble(inst, 3)], get_nibble(inst, 4), get_nibble(inst, 0), last);
|
||||
return 0;
|
||||
|
||||
@@ -27,81 +27,10 @@ typedef unsigned short word;
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned long qword;
|
||||
|
||||
extern byte *map;
|
||||
#define USE_FPU 0
|
||||
#define USE_SSE 0
|
||||
|
||||
static inline const void *read_data(off_t offset)
|
||||
{
|
||||
return map + offset;
|
||||
}
|
||||
|
||||
static inline byte read_byte(off_t offset)
|
||||
{
|
||||
return map[offset];
|
||||
}
|
||||
|
||||
static inline word read_word(off_t offset)
|
||||
{
|
||||
return *(word *)(map + offset);
|
||||
}
|
||||
|
||||
static inline dword read_dword(off_t offset)
|
||||
{
|
||||
return *(dword *)(map + offset);
|
||||
}
|
||||
|
||||
static inline qword read_qword(off_t offset)
|
||||
{
|
||||
return *(qword *)(map + offset);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_WARN
|
||||
#define warn(...) fprintf(stderr, "Warning: " __VA_ARGS__)
|
||||
#else
|
||||
#define warn(...)
|
||||
#endif
|
||||
|
||||
/* Common globals */
|
||||
|
||||
#define DUMPHEADER 0x01
|
||||
#define DUMPRSRC 0x02
|
||||
#define DUMPEXPORT 0x04
|
||||
#define DUMPIMPORT 0x08
|
||||
#define DISASSEMBLE 0x10
|
||||
#define SPECFILE 0x80
|
||||
extern word mode; /* what to dump */
|
||||
|
||||
#define DISASSEMBLE_ALL 0x01
|
||||
#define DEMANGLE 0x02
|
||||
#define NO_SHOW_RAW_INSN 0x04
|
||||
#define NO_SHOW_ADDRESSES 0x08
|
||||
#define COMPILABLE 0x10
|
||||
#define FULL_CONTENTS 0x20
|
||||
extern word opts; /* additional options */
|
||||
|
||||
extern enum asm_syntax
|
||||
{
|
||||
GAS,
|
||||
NASM,
|
||||
MASM,
|
||||
} asm_syntax;
|
||||
|
||||
extern const char *const rsrc_types[];
|
||||
extern const size_t rsrc_types_count;
|
||||
|
||||
extern char **resource_filters;
|
||||
extern unsigned resource_filters_count;
|
||||
|
||||
/* Whether to print addresses relative to the image base for PE files. */
|
||||
extern int pe_rel_addr;
|
||||
|
||||
/* Entry points */
|
||||
void dumpmz(void);
|
||||
void dumpne(long offset_ne);
|
||||
void dumppe(long offset_pe);
|
||||
#include "x32.h"
|
||||
#define asm_syntax NASM
|
||||
#define opts 0
|
||||
|
||||
/* this is easier than doing bitfields */
|
||||
#define MODOF(x) ((x) >> 6)
|
||||
@@ -898,6 +827,7 @@ static const struct op instructions_0F[] = {
|
||||
{0xCF, 8, -1, "bswap", DI},
|
||||
};
|
||||
|
||||
#if USE_FPU
|
||||
/* mod < 3 (instructions with memory args) */
|
||||
static const struct op instructions_fpu_m[64] = {
|
||||
{0xD8, 0, 32, "fadd", MEM, 0, OP_S},
|
||||
@@ -1098,7 +1028,9 @@ static int get_fpu_instr(const byte *p, struct op *op) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_SSE
|
||||
static const struct op instructions_sse[] = {
|
||||
{0x10, 8, 0, "movups", XMM, XM},
|
||||
{0x11, 8, 0, "movups", XM, XMM},
|
||||
@@ -1531,6 +1463,7 @@ static const struct op instructions_sse_single_op32[] = {
|
||||
{0x3A, 0x62, 0, "pcmpistrm", XMM, XM, OP_ARG2_IMM8},
|
||||
{0x3A, 0x63, 0, "pcmpistri", XMM, XM, OP_ARG2_IMM8},
|
||||
};
|
||||
#endif
|
||||
|
||||
/* returns the flag if it's a prefix, 0 otherwise */
|
||||
static word get_prefix(word opcode, int bits) {
|
||||
@@ -1560,9 +1493,10 @@ static int instr_matches(const byte opcode, const byte subcode, const struct op
|
||||
return ((opcode == op->opcode) && ((op->subcode == 8) || (subcode == op->subcode)));
|
||||
}
|
||||
|
||||
#if USE_SSE
|
||||
/* aka 3 byte opcode */
|
||||
static int get_sse_single(byte opcode, byte subcode, struct instr *instr) {
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
if (instr->prefix & PREFIX_OP32) {
|
||||
for (i = 0; i < sizeof(instructions_sse_single_op32)/sizeof(struct op); i++) {
|
||||
@@ -1588,7 +1522,7 @@ static int get_sse_single(byte opcode, byte subcode, struct instr *instr) {
|
||||
|
||||
static int get_sse_instr(const byte *p, struct instr *instr) {
|
||||
byte subcode = REGOF(p[1]);
|
||||
unsigned i;
|
||||
size_t i;
|
||||
|
||||
/* Clear the prefix if it matches. This makes the disassembler work right,
|
||||
* but it might break things later if we want to interpret these. The
|
||||
@@ -1629,6 +1563,7 @@ static int get_sse_instr(const byte *p, struct instr *instr) {
|
||||
|
||||
return get_sse_single(p[0], p[1], instr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int get_0f_instr(const byte *p, struct instr *instr) {
|
||||
byte subcode = REGOF(p[1]);
|
||||
@@ -1639,17 +1574,19 @@ static int get_0f_instr(const byte *p, struct instr *instr) {
|
||||
if (p[0] == 0x01 && MODOF(p[1]) == 3) {
|
||||
instr->op.opcode = 0x0F01;
|
||||
instr->op.subcode = p[1];
|
||||
const char *opname = NULL;
|
||||
switch (p[1]) {
|
||||
case 0xC1: strcpy(instr->op.name, "vmcall"); break;
|
||||
case 0xC2: strcpy(instr->op.name, "vmlaunch"); break;
|
||||
case 0xC3: strcpy(instr->op.name, "vmresume"); break;
|
||||
case 0xC4: strcpy(instr->op.name, "vmcall"); break;
|
||||
case 0xC8: strcpy(instr->op.name, "monitor"); break;
|
||||
case 0xC9: strcpy(instr->op.name, "mwait"); break;
|
||||
case 0xD0: strcpy(instr->op.name, "xgetbv"); break;
|
||||
case 0xD1: strcpy(instr->op.name, "xsetbv"); break;
|
||||
case 0xF9: strcpy(instr->op.name, "rdtscp"); break;
|
||||
case 0xC1: opname= "vmcall"; break;
|
||||
case 0xC2: opname= "vmlaunch"; break;
|
||||
case 0xC3: opname= "vmresume"; break;
|
||||
case 0xC4: opname= "vmcall"; break;
|
||||
case 0xC8: opname= "monitor"; break;
|
||||
case 0xC9: opname= "mwait"; break;
|
||||
case 0xD0: opname= "xgetbv"; break;
|
||||
case 0xD1: opname= "xsetbv"; break;
|
||||
case 0xF9: opname= "rdtscp"; break;
|
||||
}
|
||||
if (opname) strcpy(instr->op.name, opname);
|
||||
return 1;
|
||||
} else if (p[0] == 0xAE && MODOF(p[1]) == 3) {
|
||||
instr->op.opcode = 0x0FAE;
|
||||
@@ -1667,8 +1604,13 @@ static int get_0f_instr(const byte *p, struct instr *instr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!instr->op.name[0])
|
||||
if (!instr->op.name[0]) {
|
||||
#if USE_SSE
|
||||
len = get_sse_instr(p, instr);
|
||||
#else
|
||||
len = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
instr->op.opcode = 0x0F00 | p[0];
|
||||
return len;
|
||||
@@ -1875,22 +1817,16 @@ static const char reg64[17][4] = {
|
||||
"rax","rcx","rdx","rbx","rsp","rbp","rsi","rdi","r8","r9","r10","r11","r12","r13","r14","r15","rip"
|
||||
};
|
||||
|
||||
static void get_seg16(char *out, byte reg) {
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
static inline void get_seg16(char *out, byte reg) {
|
||||
strcat(out, (const char *)seg16[reg]);
|
||||
}
|
||||
|
||||
static void get_reg8(char *out, byte reg, int rex) {
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
static inline void get_reg8(char *out, byte reg, int rex) {
|
||||
strcat(out, rex ? reg8_rex[reg] : reg8[reg]);
|
||||
}
|
||||
|
||||
static void get_reg16(char *out, signed char reg, int size) {
|
||||
static inline void get_reg16(char *out, signed char reg, int size) {
|
||||
if (reg != -1) {
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
if (size == 16)
|
||||
strcat(out, reg16[reg]);
|
||||
if (size == 32)
|
||||
@@ -1900,16 +1836,12 @@ static void get_reg16(char *out, signed char reg, int size) {
|
||||
}
|
||||
}
|
||||
|
||||
static void get_xmm(char *out, byte reg) {
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
static inline void get_xmm(char *out, byte reg) {
|
||||
strcat(out, "xmm0");
|
||||
out[strlen(out)-1] = '0'+reg;
|
||||
}
|
||||
|
||||
static void get_mmx(char *out, byte reg) {
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
strcat(out, "mm0");
|
||||
out[strlen(out)-1] = '0'+reg;
|
||||
}
|
||||
@@ -1949,39 +1881,39 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
|
||||
switch (arg->type) {
|
||||
case ONE:
|
||||
strcat(out, (asm_syntax == GAS) ? "$0x1" : "1h");
|
||||
strcat(out, "1h");
|
||||
break;
|
||||
case IMM8:
|
||||
if (instr->op.flags & OP_STACK) { /* 6a */
|
||||
if (instr->op.size == 64)
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%016lx" : "qword 0x%016lx", (qword) (int8_t) value);
|
||||
sprintf(out, "qword 0x%016lx", (qword) (int8_t) value);
|
||||
else if (instr->op.size == 32)
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%08x" : "dword 0x%08X", (dword) (int8_t) value);
|
||||
sprintf(out, "dword 0x%08X", (dword) (int8_t) value);
|
||||
else
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%04x" : "word 0x%04X", (word) (int8_t) value);
|
||||
sprintf(out, "word 0x%04X", (word) (int8_t) value);
|
||||
} else
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%02lx" : "%02lXh", value);
|
||||
sprintf(out, "%02lXh", value);
|
||||
break;
|
||||
case IMM16:
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%04lx" : "%04lXh", value);
|
||||
sprintf(out, "%04lXh", value);
|
||||
break;
|
||||
case IMM:
|
||||
if (instr->op.flags & OP_STACK) {
|
||||
if (instr->op.size == 64)
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%016lx" : "qword %016lXh", value);
|
||||
sprintf(out, "qword %016lXh", value);
|
||||
else if (instr->op.size == 32)
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%08lx" : "dword %08lXh", value);
|
||||
sprintf(out, "dword %08lXh", value);
|
||||
else
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%04lx" : "word %04lXh", value);
|
||||
sprintf(out, "word %04lXh", value);
|
||||
} else {
|
||||
if (instr->op.size == 8)
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%02lx" : "%02lXh", value);
|
||||
sprintf(out, "%02lXh", value);
|
||||
else if (instr->op.size == 16)
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%04lx" : "%04lXh", value);
|
||||
sprintf(out, "%04lXh", value);
|
||||
else if (instr->op.size == 64 && (instr->op.flags & OP_IMM64))
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%016lx" : "%016lXh", value);
|
||||
sprintf(out, "%016lXh", value);
|
||||
else
|
||||
sprintf(out, (asm_syntax == GAS) ? "$0x%08lx" : "%08lXh", value);
|
||||
sprintf(out, "%08lXh", value);
|
||||
}
|
||||
break;
|
||||
case REL8:
|
||||
@@ -1992,55 +1924,38 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
/* should always be relocated */
|
||||
break;
|
||||
case MOFFS16:
|
||||
if (asm_syntax == GAS) {
|
||||
if (instr->prefix & PREFIX_SEG_MASK) {
|
||||
get_seg16(out, (instr->prefix & PREFIX_SEG_MASK)-1);
|
||||
strcat(out, ":");
|
||||
}
|
||||
sprintf(out+strlen(out), "0x%04lx", value);
|
||||
} else {
|
||||
out[0] = '[';
|
||||
if (instr->prefix & PREFIX_SEG_MASK) {
|
||||
get_seg16(out, (instr->prefix & PREFIX_SEG_MASK)-1);
|
||||
strcat(out, ":");
|
||||
}
|
||||
sprintf(out+strlen(out), "0x%04lX]", value);
|
||||
}
|
||||
instr->usedmem = 1;
|
||||
break;
|
||||
case DSBX:
|
||||
case DSSI:
|
||||
if (asm_syntax != NASM) {
|
||||
if (instr->prefix & PREFIX_SEG_MASK) {
|
||||
get_seg16(out, (instr->prefix & PREFIX_SEG_MASK)-1);
|
||||
strcat(out, ":");
|
||||
}
|
||||
strcat(out, (asm_syntax == GAS) ? "(" : "[");
|
||||
strcat(out, "[");
|
||||
get_reg16(out, (arg->type == DSBX) ? 3 : 6, instr->addrsize);
|
||||
strcat(out, (asm_syntax == GAS) ? ")" : "]");
|
||||
}
|
||||
strcat(out, "]");
|
||||
instr->usedmem = 1;
|
||||
break;
|
||||
case ESDI:
|
||||
if (asm_syntax != NASM) {
|
||||
strcat(out, (asm_syntax == GAS) ? "%es:(" : "es:[");
|
||||
strcat(out, "es:[");
|
||||
get_reg16(out, 7, instr->addrsize);
|
||||
strcat(out, (asm_syntax == GAS) ? ")" : "]");
|
||||
}
|
||||
strcat(out, "]");
|
||||
instr->usedmem = 1;
|
||||
break;
|
||||
case ALS:
|
||||
if (asm_syntax == GAS)
|
||||
strcpy(out, "%al");
|
||||
strcpy(out, "als");
|
||||
break;
|
||||
case AXS:
|
||||
if (asm_syntax == GAS)
|
||||
strcpy(out, "%ax");
|
||||
strcpy(out, "axs");
|
||||
break;
|
||||
case DXS:
|
||||
if (asm_syntax == GAS)
|
||||
strcpy(out, "(%dx)");
|
||||
else
|
||||
strcpy(out, "dx");
|
||||
break;
|
||||
/* register/memory. this is always the first byte after the opcode,
|
||||
@@ -2055,7 +1970,7 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
if (arg->type == XM) {
|
||||
get_xmm(out, instr->modrm_reg);
|
||||
if (instr->vex_256)
|
||||
out[asm_syntax == GAS ? 1 : 0] = 'y';
|
||||
out[0] = 'y';
|
||||
break;
|
||||
} else if (arg->type == MM) {
|
||||
get_mmx(out, instr->modrm_reg);
|
||||
@@ -2080,59 +1995,6 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
/* MASM: <size> ptr <seg>:[<reg>+<reg>+/-<offset>h] */
|
||||
/* GAS: *%<seg>:<->0x<offset>(%<reg>,%<reg>) */
|
||||
|
||||
if (asm_syntax == GAS) {
|
||||
if (instr->op.opcode == 0xFF && instr->op.subcode >= 2 && instr->op.subcode <= 5)
|
||||
strcat(out, "*");
|
||||
|
||||
if (instr->prefix & PREFIX_SEG_MASK) {
|
||||
get_seg16(out, (instr->prefix & PREFIX_SEG_MASK)-1);
|
||||
strcat(out, ":");
|
||||
}
|
||||
|
||||
/* offset */
|
||||
if (instr->modrm_disp == DISP_8) {
|
||||
int8_t svalue = (int8_t) value;
|
||||
if (svalue < 0)
|
||||
sprintf(out+strlen(out), "-0x%02x", -svalue);
|
||||
else
|
||||
sprintf(out+strlen(out), "0x%02x", svalue);
|
||||
} else if (instr->modrm_disp == DISP_16 && instr->addrsize == 16) {
|
||||
int16_t svalue = (int16_t) value;
|
||||
if (instr->modrm_reg == -1) {
|
||||
sprintf(out+strlen(out), "0x%04lx", value); /* absolute memory is unsigned */
|
||||
return;
|
||||
}
|
||||
if (svalue < 0)
|
||||
sprintf(out+strlen(out), "-0x%04x", -svalue);
|
||||
else
|
||||
sprintf(out+strlen(out), "0x%04x", svalue);
|
||||
} else if (instr->modrm_disp == DISP_16) {
|
||||
int32_t svalue = (int32_t) value;
|
||||
if (instr->modrm_reg == -1) {
|
||||
sprintf(out+strlen(out), "0x%08lx", value); /* absolute memory is unsigned */
|
||||
return;
|
||||
}
|
||||
if (svalue < 0)
|
||||
sprintf(out+strlen(out), "-0x%08x", -svalue);
|
||||
else
|
||||
sprintf(out+strlen(out), "0x%08x", svalue);
|
||||
}
|
||||
|
||||
strcat(out, "(");
|
||||
|
||||
if (instr->addrsize == 16) {
|
||||
strcat(out, modrm16_gas[instr->modrm_reg]);
|
||||
} else {
|
||||
get_reg16(out, instr->modrm_reg, instr->addrsize);
|
||||
if (instr->sib_scale && instr->sib_index != -1) {
|
||||
strcat(out, ",");
|
||||
get_reg16(out, instr->sib_index, instr->addrsize);
|
||||
strcat(out, ",0");
|
||||
out[strlen(out)-1] = '0'+instr->sib_scale;
|
||||
}
|
||||
}
|
||||
strcat(out, ")");
|
||||
} else {
|
||||
int has_sib = (instr->sib_scale != 0 && instr->sib_index != -1);
|
||||
if (instr->op.flags & OP_FAR)
|
||||
strcat(out, "far ");
|
||||
@@ -2145,27 +2007,21 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
case 80: strcat(out, "tword "); break;
|
||||
default: break;
|
||||
}
|
||||
if (asm_syntax == MASM) /* && instr->op.size == 0? */
|
||||
strcat(out, "ptr ");
|
||||
} else if (instr->op.opcode == 0x0FB6 || instr->op.opcode == 0x0FBE) { /* mov*b* */
|
||||
strcat(out,"byte ");
|
||||
if (asm_syntax == MASM)
|
||||
strcat(out, "ptr ");
|
||||
} else if (instr->op.opcode == 0x0FB7 || instr->op.opcode == 0x0FBF) { /* mov*w* */
|
||||
strcat(out,"word ");
|
||||
if (asm_syntax == MASM)
|
||||
strcat(out, "ptr ");
|
||||
}
|
||||
|
||||
if (asm_syntax == NASM)
|
||||
strcat(out, "[");
|
||||
|
||||
if (instr->prefix & PREFIX_SEG_MASK) {
|
||||
get_seg16(out, (instr->prefix & PREFIX_SEG_MASK)-1);
|
||||
strcat(out, ":");
|
||||
}
|
||||
|
||||
if (asm_syntax == MASM)
|
||||
strcat(out, "[");
|
||||
|
||||
if (instr->modrm_reg != -1) {
|
||||
@@ -2207,7 +2063,6 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
sprintf(out+strlen(out), "+%08xh", svalue);
|
||||
}
|
||||
strcat(out, "]");
|
||||
}
|
||||
break;
|
||||
case REG:
|
||||
case REGONLY:
|
||||
@@ -2238,42 +2093,26 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
warn_at("Invalid control register %ld\n", value);
|
||||
break;
|
||||
}
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
strcat(out, "cr0");
|
||||
out[strlen(out)-1] = '0'+value;
|
||||
break;
|
||||
case DR32:
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
strcat(out, "dr0");
|
||||
out[strlen(out)-1] = '0'+value;
|
||||
break;
|
||||
case TR32:
|
||||
if (value < 3)
|
||||
warn_at("Invalid test register %ld\n", value);
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
strcat(out, "tr0");
|
||||
out[strlen(out)-1] = '0'+value;
|
||||
break;
|
||||
case ST:
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
strcat(out, "st");
|
||||
if (asm_syntax == NASM)
|
||||
strcat(out, "0");
|
||||
strcat(out, "st0");
|
||||
break;
|
||||
case STX:
|
||||
if (asm_syntax == GAS)
|
||||
strcat(out, "%");
|
||||
strcat(out, "st");
|
||||
if (asm_syntax != NASM)
|
||||
strcat(out, "(");
|
||||
strcat(out, "0");
|
||||
strcat(out, "st(0");
|
||||
out[strlen(out)-1] = '0' + value;
|
||||
if (asm_syntax != NASM)
|
||||
strcat(out, ")");
|
||||
strcat(out, ")");
|
||||
break;
|
||||
case MMX:
|
||||
case MMXONLY:
|
||||
@@ -2283,7 +2122,7 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
case XMMONLY:
|
||||
get_xmm(out, value);
|
||||
if (instr->vex_256)
|
||||
out[asm_syntax == GAS ? 1 : 0] = 'y';
|
||||
out[0] = 'y';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2291,23 +2130,22 @@ static void print_arg(char *_ip, struct instr *instr, int i, int bits) {
|
||||
}
|
||||
|
||||
/* helper to tack a length suffix onto a name */
|
||||
static void suffix_name(struct instr *instr) {
|
||||
if ((instr->op.flags & OP_LL) == OP_LL)
|
||||
strcat(instr->op.name, "ll");
|
||||
else if (instr->op.flags & OP_S)
|
||||
strcat(instr->op.name, "s");
|
||||
else if (instr->op.flags & OP_L)
|
||||
strcat(instr->op.name, "l");
|
||||
else if (instr->op.size == 80)
|
||||
strcat(instr->op.name, "t");
|
||||
else if (instr->op.size == 8)
|
||||
strcat(instr->op.name, "b");
|
||||
else if (instr->op.size == 16)
|
||||
strcat(instr->op.name, "w");
|
||||
else if (instr->op.size == 32)
|
||||
strcat(instr->op.name, (asm_syntax == GAS) ? "l" : "d");
|
||||
else if (instr->op.size == 64)
|
||||
strcat(instr->op.name, "q");
|
||||
static const char *suffix_name(struct instr *instr) {
|
||||
const int opflags = instr->op.flags;
|
||||
if ((opflags & OP_LL) == OP_LL)
|
||||
return "ll";
|
||||
if (opflags & OP_S)
|
||||
return "s";
|
||||
if (opflags & OP_L)
|
||||
return "l";
|
||||
switch(instr->op.size) {
|
||||
case 80: return "t";
|
||||
case 8: return "b";
|
||||
case 16: return "w";
|
||||
case 32: return "d";
|
||||
case 64: return "q";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Paramters:
|
||||
@@ -2323,7 +2161,7 @@ static void suffix_name(struct instr *instr) {
|
||||
* ensure they only get printed once), so we will need to watch out for
|
||||
* multiple prefixes, invalid instructions, etc.
|
||||
*/
|
||||
int get_instr(dword ip, const byte *p, struct instr *instr, int bits) {
|
||||
static int get_instr(dword ip, const byte *p, struct instr *instr, int bits) {
|
||||
int len = 0;
|
||||
byte opcode;
|
||||
word prefix;
|
||||
@@ -2355,14 +2193,18 @@ int get_instr(dword ip, const byte *p, struct instr *instr, int bits) {
|
||||
instr->vex = 1;
|
||||
if ((p[len] & 0x1F) == 2) subcode = 0x38;
|
||||
else if ((p[len] & 0x1F) == 3) subcode = 0x3A;
|
||||
else warn("Unhandled subcode %x at %x\n", p[len], ip);
|
||||
// else fprintf(stderr, "Unhandled subcode %x at %x\n", p[len], ip);
|
||||
len++;
|
||||
instr->vex_reg = ~((p[len] >> 3) & 7);
|
||||
instr->vex_256 = (p[len] & 4) ? 1 : 0;
|
||||
if ((p[len] & 3) == 3) instr->prefix |= PREFIX_REPNE;
|
||||
else if ((p[len] & 3) == 2) instr->prefix |= PREFIX_REPE;
|
||||
else if ((p[len] & 3) == 1) instr->prefix |= PREFIX_OP32;
|
||||
#if USE_SSE
|
||||
len += get_sse_single(subcode, p[len+1], instr);
|
||||
#else
|
||||
len = -1;
|
||||
#endif
|
||||
} else if (opcode == 0xC5 && MODOF(p[len+1]) == 3 && bits != 16) {
|
||||
len++;
|
||||
instr->vex = 1;
|
||||
@@ -2385,7 +2227,11 @@ int get_instr(dword ip, const byte *p, struct instr *instr, int bits) {
|
||||
len++;
|
||||
len += get_0f_instr(p+len, instr);
|
||||
} else if (opcode >= 0xD8 && opcode <= 0xDF) {
|
||||
#if USE_FPU
|
||||
len += get_fpu_instr(p+len, &instr->op);
|
||||
#else
|
||||
len = -1;
|
||||
#endif
|
||||
} else {
|
||||
unsigned i;
|
||||
for (i=0; i<sizeof(instructions_group)/sizeof(struct op); i++) {
|
||||
@@ -2463,54 +2309,47 @@ int get_instr(dword ip, const byte *p, struct instr *instr, int bits) {
|
||||
|
||||
/* modify the instruction name if appropriate */
|
||||
|
||||
if (asm_syntax == GAS) {
|
||||
if (instr->op.opcode == 0x0FB6) {
|
||||
strcpy(instr->op.name, "movzb");
|
||||
suffix_name(instr);
|
||||
} else if (instr->op.opcode == 0x0FB7) {
|
||||
strcpy(instr->op.name, "movzw");
|
||||
suffix_name(instr);
|
||||
} else if (instr->op.opcode == 0x0FBE) {
|
||||
strcpy(instr->op.name, "movsb");
|
||||
suffix_name(instr);
|
||||
} else if (instr->op.opcode == 0x0FBF) {
|
||||
strcpy(instr->op.name, "movsw");
|
||||
suffix_name(instr);
|
||||
} else if (instr->op.opcode == 0x63 && bits == 64)
|
||||
strcpy(instr->op.name, "movslq");
|
||||
}
|
||||
|
||||
if ((instr->op.flags & OP_STACK) && (instr->prefix & PREFIX_OP32))
|
||||
const char *opsufx = NULL;
|
||||
const char *opname = NULL;
|
||||
if ((instr->op.flags & OP_STACK) && (instr->prefix & PREFIX_OP32)) {
|
||||
suffix_name(instr);
|
||||
else if ((instr->op.flags & OP_STRING) && asm_syntax != GAS)
|
||||
} else if ((instr->op.flags & OP_STRING)) {
|
||||
suffix_name(instr);
|
||||
else if (instr->op.opcode == 0x98)
|
||||
strcpy(instr->op.name, instr->op.size == 16 ? "cbw" : instr->op.size == 32 ? "cwde" : "cdqe");
|
||||
else if (instr->op.opcode == 0x99)
|
||||
strcpy(instr->op.name, instr->op.size == 16 ? "cwd" : instr->op.size == 32 ? "cdq" : "cqo");
|
||||
else if (instr->op.opcode == 0xE3)
|
||||
strcpy(instr->op.name, instr->op.size == 16 ? "jcxz" : instr->op.size == 32 ? "jecxz" : "jrcxz");
|
||||
else if (instr->op.opcode == 0xD4 && instr->args[0].value == 10) {
|
||||
strcpy(instr->op.name, "aam");
|
||||
} else if (instr->op.opcode == 0x98) {
|
||||
opname = instr->op.size == 16 ? "cbw" : instr->op.size == 32 ? "cwde" : "cdqe";
|
||||
} else if (instr->op.opcode == 0x99) {
|
||||
opname = instr->op.size == 16 ? "cwd" : instr->op.size == 32 ? "cdq" : "cqo";
|
||||
} else if (instr->op.opcode == 0xE3) {
|
||||
opname = instr->op.size == 16 ? "jcxz" : instr->op.size == 32 ? "jecxz" : "jrcxz";
|
||||
} else if (instr->op.opcode == 0xD4 && instr->args[0].value == 10) {
|
||||
opname = "aam";
|
||||
instr->op.arg0 = NONE;
|
||||
} else if (instr->op.opcode == 0xD5 && instr->args[0].value == 10) {
|
||||
strcpy(instr->op.name, "aad");
|
||||
opname = "aad";
|
||||
instr->op.arg0 = NONE;
|
||||
} else if (instr->op.opcode == 0x0FC7 && instr->op.subcode == 1 && (instr->prefix & PREFIX_REXW))
|
||||
strcpy(instr->op.name, "cmpxchg16b");
|
||||
else if (asm_syntax == GAS) {
|
||||
if (instr->op.flags & OP_FAR) {
|
||||
memmove(instr->op.name+1, instr->op.name, strlen(instr->op.name));
|
||||
instr->op.name[0] = 'l';
|
||||
} else if (!is_reg(instr->op.arg0) && !is_reg(instr->op.arg1) &&
|
||||
instr->modrm_disp != DISP_REG)
|
||||
suffix_name(instr);
|
||||
} else if (asm_syntax != GAS && (instr->op.opcode == 0xCA || instr->op.opcode == 0xCB))
|
||||
strcat(instr->op.name, "f");
|
||||
} else if (instr->op.opcode == 0x0FC7 && instr->op.subcode == 1 && (instr->prefix & PREFIX_REXW)) {
|
||||
opname = "cmpxchg16b";
|
||||
} else if ((instr->op.opcode == 0xCA || instr->op.opcode == 0xCB)) {
|
||||
opsufx = "f";
|
||||
}
|
||||
if (opname) {
|
||||
strcpy(instr->op.name, opname);
|
||||
}
|
||||
if (opsufx) {
|
||||
strcat(instr->op.name, opsufx);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
#define DISASSEMBLE_ALL 0x01
|
||||
#define DEMANGLE 0x02
|
||||
#define NO_SHOW_RAW_INSN 0x04
|
||||
#define NO_SHOW_ADDRESSES 0x08
|
||||
#define COMPILABLE 0x10
|
||||
#define FULL_CONTENTS 0x20
|
||||
void print_instr(char *ip, const byte *p, int len, byte flags, struct instr *instr, const char *comment, int bits) {
|
||||
int i;
|
||||
|
||||
@@ -2576,11 +2415,11 @@ void print_instr(char *ip, const byte *p, int len, byte flags, struct instr *ins
|
||||
warn_at("Operand-size override used with opcode 0x%02x %s\n", instr->op.opcode, instr->op.name);
|
||||
printf((asm_syntax == GAS) ? "data32 " : "o32 "); /* fixme: how should MASM print it? */
|
||||
}
|
||||
if ((instr->prefix & PREFIX_ADDR32) && (asm_syntax == NASM) && (instr->op.flags & OP_STRING)) {
|
||||
if ((instr->prefix & PREFIX_ADDR32) && (instr->op.flags & OP_STRING)) {
|
||||
printf("a32 ");
|
||||
} else if ((instr->prefix & PREFIX_ADDR32) && !instr->usedmem && instr->op.opcode != 0xE3) { /* jecxz */
|
||||
warn_at("Address-size prefix used with opcode 0x%02x %s\n", instr->op.opcode, instr->op.name);
|
||||
printf((asm_syntax == GAS) ? "addr32 " : "a32 "); /* fixme: how should MASM print it? */
|
||||
printf("a32 "); /* fixme: how should MASM print it? */
|
||||
}
|
||||
if (instr->prefix & PREFIX_LOCK) {
|
||||
if(!(instr->op.flags & OP_LOCK))
|
||||
@@ -2608,17 +2447,6 @@ void print_instr(char *ip, const byte *p, int len, byte flags, struct instr *ins
|
||||
if (instr->args[0].string[0] || instr->args[1].string[0])
|
||||
printf(" ");
|
||||
|
||||
if (asm_syntax == GAS) {
|
||||
/* fixme: are all of these orderings correct? */
|
||||
if (instr->args[1].string[0])
|
||||
printf("%s,", instr->args[1].string);
|
||||
if (instr->vex_reg)
|
||||
printf("%%ymm%d, ", instr->vex_reg);
|
||||
if (instr->args[0].string[0])
|
||||
printf("%s", instr->args[0].string);
|
||||
if (instr->args[2].string[0])
|
||||
printf(",%s", instr->args[2].string);
|
||||
} else {
|
||||
if (instr->args[0].string[0])
|
||||
printf("%s", instr->args[0].string);
|
||||
if (instr->args[1].string[0])
|
||||
@@ -2629,14 +2457,9 @@ void print_instr(char *ip, const byte *p, int len, byte flags, struct instr *ins
|
||||
printf("%s", instr->args[1].string);
|
||||
if (instr->args[2].string[0])
|
||||
printf(", %s", instr->args[2].string);
|
||||
}
|
||||
if (comment) {
|
||||
printf(asm_syntax == GAS ? " // " : " ;");
|
||||
printf(" <%s>", comment);
|
||||
}
|
||||
|
||||
/* if we have more than 7 bytes on this line, wrap around */
|
||||
if (len > 7 && !(opts & NO_SHOW_RAW_INSN)) {
|
||||
if (len > 7 && !(0 & NO_SHOW_RAW_INSN)) {
|
||||
printf(" ");
|
||||
for (i=7; i<len; i++) {
|
||||
printf("%02x", p[i]);
|
||||
@@ -2645,9 +2468,10 @@ void print_instr(char *ip, const byte *p, int len, byte flags, struct instr *ins
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void sprint_instr(char *output, const byte *p, int len, struct instr *instr, int bits) {
|
||||
*output = 0;
|
||||
*output = 0;
|
||||
print_arg(NULL, instr, 0, bits);
|
||||
print_arg(NULL, instr, 1, bits);
|
||||
print_arg(NULL, instr, 2, bits);
|
||||
@@ -2667,7 +2491,7 @@ static void sprint_instr(char *output, const byte *p, int len, struct instr *ins
|
||||
warn_at("Operand-size override used with opcode 0x%02x %s\n", instr->op.opcode, instr->op.name);
|
||||
strcpy (output, "o32 ");
|
||||
}
|
||||
if ((instr->prefix & PREFIX_ADDR32) && (asm_syntax == NASM) && (instr->op.flags & OP_STRING)) {
|
||||
if ((instr->prefix & PREFIX_ADDR32) && (instr->op.flags & OP_STRING)) {
|
||||
strcpy (output, "a32 ");
|
||||
} else if ((instr->prefix & PREFIX_ADDR32) && !instr->usedmem && instr->op.opcode != 0xE3) { /* jecxz */
|
||||
strcpy (output, "a32 ");
|
||||
@@ -2685,25 +2509,25 @@ static void sprint_instr(char *output, const byte *p, int len, struct instr *ins
|
||||
strcpy (output, "wait ");
|
||||
}
|
||||
strcat (output, instr->op.name);
|
||||
if (instr->args[0].string[0] || instr->args[1].string[0]) {
|
||||
strcat (output, " ");
|
||||
}
|
||||
if (instr->args[0].string[0] || instr->args[1].string[0]) { strcat (output, " ");
|
||||
}
|
||||
|
||||
if (instr->args[0].string[0])
|
||||
strcat (output, instr->args[0].string);
|
||||
if (instr->args[1].string[0])
|
||||
strcat (output, ", ");
|
||||
if (instr->vex_reg) {
|
||||
char b[32];
|
||||
sprintf(b, "ymm%d, ", instr->vex_reg);
|
||||
strcat (output, b);
|
||||
}
|
||||
if (instr->args[1].string[0])
|
||||
strcat(output, instr->args[1].string);
|
||||
if (instr->args[2].string[0]) {
|
||||
strcat(output, ",");
|
||||
strcat(output, instr->args[2].string);
|
||||
}
|
||||
if (instr->args[0].string[0])
|
||||
strcat (output, instr->args[0].string);
|
||||
if (instr->args[1].string[0])
|
||||
strcat (output, ", ");
|
||||
if (instr->vex_reg) {
|
||||
char b[32];
|
||||
sprintf(b, "ymm%d, ", instr->vex_reg);
|
||||
strcat (output, b);
|
||||
}
|
||||
if (instr->args[1].string[0]) {
|
||||
strcat(output, instr->args[1].string);
|
||||
}
|
||||
if (instr->args[2].string[0]) {
|
||||
strcat(output, ",");
|
||||
strcat(output, instr->args[2].string);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int disasm(const unsigned char *_bytes, unsigned int max, int offset, char *output) {
|
||||
|
||||
@@ -134,9 +134,6 @@ struct instr {
|
||||
int vex_256:1;
|
||||
};
|
||||
|
||||
extern int get_instr(dword ip, const byte *p, struct instr *instr, int bits);
|
||||
extern void print_instr(char *ip, const byte *p, int len, byte flags, struct instr *instr, const char *comment, int bits);
|
||||
|
||||
/* 66 + 67 + seg + lock/rep + 2 bytes opcode + modrm + sib + 4 bytes displacement + 4 bytes immediate */
|
||||
#define MAX_INSTR 16
|
||||
|
||||
|
||||
@@ -570,7 +570,7 @@ unsigned int disasm(const unsigned char *__bytes, unsigned int max, unsigned lon
|
||||
instructions = standard_instructions;
|
||||
if (opcode == 0x0F) { // Extended opcodes
|
||||
if (max < 2 || *bytes == 0x0F || *bytes == 0xA6 || *bytes == 0xA7 || *bytes == 0xF7 || *bytes == 0xFF) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
instructions = extended_instructions;
|
||||
@@ -659,98 +659,98 @@ OUTPUT:
|
||||
}
|
||||
|
||||
switch (instructions[opcode].arguments[i]) {
|
||||
case RM:
|
||||
if (modRM_mod != 3) {
|
||||
switch (instructions[opcode].size) {
|
||||
case BYTE:
|
||||
strcat(output, "BYTE PTR ");
|
||||
break;
|
||||
case WORD:
|
||||
strcat(output, "WORD PTR ");
|
||||
break;
|
||||
case DWORD:
|
||||
strcat(output, "DWORD PTR ");
|
||||
break;
|
||||
case QWORD:
|
||||
strcat(output, "QWORD PTR ");
|
||||
break;
|
||||
case FWORD:
|
||||
strcat(output, "FWORD PTR ");
|
||||
break;
|
||||
case XMMWORD:
|
||||
strcat(output, "XMMWORD PTR ");
|
||||
break;
|
||||
}
|
||||
case RM:
|
||||
if (modRM_mod != 3) {
|
||||
switch (instructions[opcode].size) {
|
||||
case BYTE:
|
||||
strcat(output, "BYTE PTR ");
|
||||
break;
|
||||
case WORD:
|
||||
strcat(output, "WORD PTR ");
|
||||
break;
|
||||
case DWORD:
|
||||
strcat(output, "DWORD PTR ");
|
||||
break;
|
||||
case QWORD:
|
||||
strcat(output, "QWORD PTR ");
|
||||
break;
|
||||
case FWORD:
|
||||
strcat(output, "FWORD PTR ");
|
||||
break;
|
||||
case XMMWORD:
|
||||
strcat(output, "XMMWORD PTR ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strcat(output, RM_output);
|
||||
break;
|
||||
case R:
|
||||
strcat(output, R_output);
|
||||
break;
|
||||
case IMM8:
|
||||
sprintf(output + strlen(output), "0x%x", *bytes++);
|
||||
break;
|
||||
case IMM16:
|
||||
sprintf(output + strlen(output), "0x%x", *(short *)bytes);
|
||||
bytes += 2;
|
||||
break;
|
||||
case IMM32:
|
||||
sprintf(output + strlen(output), "0x%x", *(int *)bytes);
|
||||
bytes += 4;
|
||||
break;
|
||||
case REL8:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int) (offset + ((bytes - base) + 1) + *bytes));
|
||||
strcat(output, RM_output);
|
||||
break;
|
||||
case R:
|
||||
strcat(output, R_output);
|
||||
break;
|
||||
case IMM8:
|
||||
sprintf(output + strlen(output), "0x%x", *bytes++);
|
||||
break;
|
||||
case IMM16:
|
||||
sprintf(output + strlen(output), "0x%x", *(short *)bytes);
|
||||
bytes += 2;
|
||||
break;
|
||||
case IMM32:
|
||||
sprintf(output + strlen(output), "0x%x", *(int *)bytes);
|
||||
bytes += 4;
|
||||
break;
|
||||
case REL8:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int) (offset + ((bytes - base) + 1) + *bytes));
|
||||
bytes++;
|
||||
break;
|
||||
case REL16:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int)(offset + ((bytes - base) + 2) + *(short *)bytes));
|
||||
bytes += 2;
|
||||
break;
|
||||
case REL32:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int)(offset + ((bytes - base) + 4) + *(int *)bytes));
|
||||
bytes += 4;
|
||||
break;
|
||||
case PTR1632:
|
||||
sprintf(output + strlen(output), "0x%x:0x%x", *(short *)(bytes + 4), *(int *)bytes);
|
||||
bytes += 6;
|
||||
break;
|
||||
case AL:
|
||||
strcat(output, "al");
|
||||
break;
|
||||
case EAX:
|
||||
strcat(output, "eax");
|
||||
break;
|
||||
case ES:
|
||||
strcat(output, "es");
|
||||
break;
|
||||
case CS:
|
||||
strcat(output, "cs");
|
||||
break;
|
||||
case SS:
|
||||
strcat(output, "ss");
|
||||
break;
|
||||
case DS:
|
||||
strcat(output, "ds");
|
||||
break;
|
||||
case ONE:
|
||||
strcat(output, "1");
|
||||
break;
|
||||
case CL:
|
||||
strcat(output, "cl");
|
||||
break;
|
||||
case XMM0:
|
||||
strcat(output, "xmm0");
|
||||
break;
|
||||
case BND0:
|
||||
strcat(output, "bnd0");
|
||||
break;
|
||||
case BAD:
|
||||
bytes++;
|
||||
break;
|
||||
case MM0:
|
||||
strcat(output, "mm0");
|
||||
break;
|
||||
break;
|
||||
case REL16:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int)(offset + ((bytes - base) + 2) + *(short *)bytes));
|
||||
bytes += 2;
|
||||
break;
|
||||
case REL32:
|
||||
sprintf(output + strlen(output), "0x%x", (unsigned int)(offset + ((bytes - base) + 4) + *(int *)bytes));
|
||||
bytes += 4;
|
||||
break;
|
||||
case PTR1632:
|
||||
sprintf(output + strlen(output), "0x%x:0x%x", *(short *)(bytes + 4), *(int *)bytes);
|
||||
bytes += 6;
|
||||
break;
|
||||
case AL:
|
||||
strcat(output, "al");
|
||||
break;
|
||||
case EAX:
|
||||
strcat(output, "eax");
|
||||
break;
|
||||
case ES:
|
||||
strcat(output, "es");
|
||||
break;
|
||||
case CS:
|
||||
strcat(output, "cs");
|
||||
break;
|
||||
case SS:
|
||||
strcat(output, "ss");
|
||||
break;
|
||||
case DS:
|
||||
strcat(output, "ds");
|
||||
break;
|
||||
case ONE:
|
||||
strcat(output, "1");
|
||||
break;
|
||||
case CL:
|
||||
strcat(output, "cl");
|
||||
break;
|
||||
case XMM0:
|
||||
strcat(output, "xmm0");
|
||||
break;
|
||||
case BND0:
|
||||
strcat(output, "bnd0");
|
||||
break;
|
||||
case BAD:
|
||||
bytes++;
|
||||
break;
|
||||
case MM0:
|
||||
strcat(output, "mm0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,5 +758,5 @@ OUTPUT:
|
||||
return bytes - base;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* io.c - MIT - Copyleft 2009-2020 -- pancake */
|
||||
/* io.c - MIT - Copyleft 2009-2021 -- pancake */
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
#define HAVE_FTRUNCATE 1
|
||||
@@ -8,7 +8,7 @@
|
||||
#if DEMO
|
||||
int bo = 0;
|
||||
char b[4096];
|
||||
static inline int io_open(char *file) {
|
||||
static inline int io_open(const char *file) {
|
||||
memset (b, 0, sizeof (b));
|
||||
return 10;
|
||||
}
|
||||
@@ -29,7 +29,7 @@ static int io_seek (int x,int y) {
|
||||
|
||||
#include <windows.h>
|
||||
static HANDLE _fd = NULL;
|
||||
static inline int io_open(char *file) {
|
||||
static inline int io_open(const char *file) {
|
||||
_fd = CreateFile(file, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
@@ -55,7 +55,7 @@ static inline int io_read(void *x, int y) {
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
static int _fd = -1;
|
||||
static inline int io_open(char *file) {
|
||||
static inline int io_open(const char *file) {
|
||||
_fd = open(file, O_RDWR|O_CREAT, 0644);
|
||||
if(_fd == -1) _fd = open(file, O_RDONLY);
|
||||
return _fd;
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
.Os
|
||||
.Th R0 1
|
||||
.Sh NAME
|
||||
ired \- interactive raw editor
|
||||
r0 \- interactive raw editor
|
||||
.Sh SYNOPSIS
|
||||
.Nm ired
|
||||
.Nm r0
|
||||
.Op Fl hnv
|
||||
.Op Fl i Ar script
|
||||
.Ar file ...
|
||||
@@ -22,9 +22,9 @@ Show version information
|
||||
.It Fl n
|
||||
Do not be verbose
|
||||
.It Fl i Ar script
|
||||
Interpret a script file as ired commands.
|
||||
Interpret a script file as r0 commands.
|
||||
.Pp
|
||||
Same as "ired file < script"
|
||||
Same as "r0 file < script"
|
||||
.El
|
||||
.PP
|
||||
.Sh COMMANDS
|
||||
@@ -117,7 +117,7 @@ quit
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Pp
|
||||
.Xr vired(1)
|
||||
.Xr r0v(1)
|
||||
.Sh AUTHORS
|
||||
.PP
|
||||
pancake <@nopcode.org>
|
||||
@@ -11,20 +11,23 @@ static int cmdn = 0;
|
||||
static char **cmds = 0;
|
||||
static ut64 oldseek, curseek = 0LL;
|
||||
static int obsize, bsize = 256;
|
||||
static int red_cmd(char *cmd); // XXX : recursive depenency
|
||||
int r0_cmd(const char *cmd); // XXX : recursive depenency
|
||||
#if defined(__WATCOMC__)
|
||||
#define HAVE_FTRUNCATE 0
|
||||
#define BUFSZ 1024
|
||||
#elif __wasi__
|
||||
#define BUFSZ 128
|
||||
#else
|
||||
#define BUFSZ 128*1024
|
||||
#endif
|
||||
|
||||
ut64 calc(const char *str);
|
||||
#include "r0.h"
|
||||
#include "util.c"
|
||||
#include "calc.c"
|
||||
#include "cmd.c"
|
||||
|
||||
static void red_slurpin() {
|
||||
static void r0_slurpin() {
|
||||
ut8 buf[BUFSZ];
|
||||
for(;;) {
|
||||
int len = read(0, buf, sizeof(buf));
|
||||
@@ -34,14 +37,14 @@ static void red_slurpin() {
|
||||
}
|
||||
}
|
||||
|
||||
static int red_interpret(const char *file) {
|
||||
static int r0_interpret(const char *file) {
|
||||
char buf[BUFSZ];
|
||||
FILE *fd = fopen(file, "r");
|
||||
if(fd != NULL) {
|
||||
for(;;) {
|
||||
if(fgets(buf, sizeof(buf), fd) == NULL)
|
||||
break;
|
||||
red_cmd(buf);
|
||||
r0_cmd(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
} else if (file)
|
||||
@@ -49,23 +52,19 @@ static int red_interpret(const char *file) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int red_cmd(char *cmd) {
|
||||
char *arg = cmd+1;
|
||||
int r0_cmd(const char *cmd) {
|
||||
const char *arg = cmd+1;
|
||||
SKIPSPACES(arg);
|
||||
switch(*cmd) {
|
||||
case 'q': return 0;
|
||||
case ';': case '#': break; // comment
|
||||
case '>': return cmd_dump(arg); break;
|
||||
case '<': return cmd_load(arg); break;
|
||||
case '.': return red_interpret(arg); break;
|
||||
case '.': return r0_interpret(arg); break;
|
||||
case 's': return cmd_seek(arg); break;
|
||||
case 'b': return cmd_bsize(arg); break;
|
||||
case '/': return cmd_search(arg); break;
|
||||
#if USE_DISASM
|
||||
case 'd': return cmd_disasm(arg); break;
|
||||
#else
|
||||
case 'd': return cmd_system("echo X | r0 -n $BLOCK | rasm2 -o $OFFSET -D - |head -n $(($LINES-1))");
|
||||
#endif
|
||||
case 'p': return cmd_print(arg); break;
|
||||
case 'r': return cmd_resize(arg); break;
|
||||
case 'x': return cmd_hexdump(arg); break;
|
||||
@@ -79,7 +78,7 @@ static int red_cmd(char *cmd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int red_prompt() {
|
||||
static int r0_prompt() {
|
||||
char *at, *at2, line[BUFSZ];
|
||||
if(verbose) {
|
||||
printf("[0x%08"LLF"x]> ", curseek);
|
||||
@@ -97,30 +96,30 @@ static int red_prompt() {
|
||||
at2 = strchr(++at, ':');
|
||||
if(at2) {
|
||||
*at2 = 0; at2++;
|
||||
if(*at2) bsize = (int)str2ut64(at2);
|
||||
if(*at2) bsize = (int)calc(at2);
|
||||
}
|
||||
if(*at) curseek = str2ut64(at);
|
||||
if(*at) curseek = calc(at);
|
||||
}
|
||||
}
|
||||
at = line;
|
||||
SKIPSPACES(at);
|
||||
return red_cmd(at);
|
||||
return r0_cmd(at);
|
||||
}
|
||||
|
||||
static int red_open(char *file) {
|
||||
int r0_open(const char *file) {
|
||||
int ret = io_open(file);
|
||||
if(ret != -1) {
|
||||
oldseek = 0;
|
||||
setenv("FILE", file, 1);
|
||||
if(scripts)
|
||||
for (ret=0;ret<scriptn;ret++)
|
||||
red_interpret(scripts[ret]);
|
||||
r0_interpret(scripts[ret]);
|
||||
if(cmds)
|
||||
for (ret=0;ret<cmdn;ret++)
|
||||
red_cmd(cmds[ret]);
|
||||
r0_cmd(cmds[ret]);
|
||||
if(earlyquit)
|
||||
return 0;
|
||||
while((ret=red_prompt())>0) {
|
||||
while((ret=r0_prompt())>0) {
|
||||
curseek = oldseek;
|
||||
bsize = obsize;
|
||||
}
|
||||
@@ -130,7 +129,7 @@ static int red_open(char *file) {
|
||||
return ret==-1 ?1:0;
|
||||
}
|
||||
|
||||
static int red_help() {
|
||||
static int r0_help() {
|
||||
puts("r0 [-qhnv] [-c cmd] [-i script] [-|file ..]");
|
||||
return 0;
|
||||
}
|
||||
@@ -140,24 +139,27 @@ int main(int argc, char **argv) {
|
||||
argc++;
|
||||
cmdn = 0;
|
||||
scriptn = 0;
|
||||
scripts = malloc(sizeof(const char*)*argc);
|
||||
cmds = malloc(sizeof(const char*)*argc);
|
||||
if(argc>1 && argv[1])
|
||||
for(i=1; i<argc; i++) {
|
||||
if(argv[i] && argv[i][0]=='-')
|
||||
switch(argv[i][1]) {
|
||||
case 'q': earlyquit = 1; break;
|
||||
case 'i': scripts[scriptn++] = argv[++i]; break;
|
||||
case 'c': cmds[cmdn++] = argv[++i]; break;
|
||||
case 'n': verbose = 0; break;
|
||||
case 'v': puts(VERSION); ret = 0; break;
|
||||
case 'h': ret = red_help(); break;
|
||||
case 0x0: red_slurpin(); ret = 0; break;
|
||||
} else {
|
||||
if (!argv[i]) break;
|
||||
ret = red_open(argv[i]);
|
||||
scripts = calloc(sizeof(const char*), argc);
|
||||
cmds = calloc(sizeof(const char*), argc);
|
||||
if(argc > 1 && argv[1]) {
|
||||
for(i = 1; i < argc; i++) {
|
||||
if(argv[i] && argv[i][0]=='-')
|
||||
switch(argv[i][1]) {
|
||||
case 'q': earlyquit = 1; break;
|
||||
case 'i': scripts[scriptn++] = argv[++i]; break;
|
||||
case 'c': cmds[cmdn++] = argv[++i]; break;
|
||||
case 'n': verbose = 0; break;
|
||||
case 'v': puts(VERSION); ret = 0; break;
|
||||
case 'h': ret = r0_help(); break;
|
||||
case 0x0: r0_slurpin(); ret = 0; break;
|
||||
} else {
|
||||
if (!argv[i]) break;
|
||||
ret = r0_open(argv[i]);
|
||||
}
|
||||
}
|
||||
} else ret = red_help();
|
||||
} else {
|
||||
ret = r0_help();
|
||||
}
|
||||
free(scripts);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#define VERSION "0.8"
|
||||
#define VERSION "0.9"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -10,7 +10,11 @@
|
||||
|
||||
#define SKIPSPACES(x) for(;*(x)==' '||*(x)=='\t';x++) {};
|
||||
|
||||
#if(plan9)
|
||||
#if(R0_NOENV)
|
||||
#define LLF "ll"
|
||||
#define setenv(x,y,z) //
|
||||
// static int setenv(char *var, char *val, int force) { return 0; }
|
||||
#elif(plan9)
|
||||
static int setenv(char *var, char *val, int force) {
|
||||
char str[256];
|
||||
snprintf(str, sizeof(str), "echo %s > /env/%s", var, val);
|
||||
|
||||
@@ -302,6 +302,8 @@ int bdiff(const char *filea, const char *fileb) {
|
||||
la = lb = 0;
|
||||
for(h = l.base; h != l.head; h++) {
|
||||
if(h->a1 != la || h->b1 != lb) {
|
||||
if (h->b1 > bn) break;
|
||||
if (lb > bn) break;
|
||||
len = bl[h->b1].l - bl[lb].l;
|
||||
offa = al[la].l - al->l;
|
||||
offb = al[h->a1].l - al->l;
|
||||
@@ -316,6 +318,8 @@ int bdiff(const char *filea, const char *fileb) {
|
||||
|
||||
if(len == rlen) {
|
||||
for(i=0; i<len; i++) {
|
||||
if (lb < bn) break;
|
||||
if (la < bn) break;
|
||||
if(bl[lb].l[i] != bl[la].l[i])
|
||||
fprintf(stderr, "%02x %02x\n",
|
||||
(unsigned char)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# vired: the visual raw editor
|
||||
# r0v: the visual raw editor
|
||||
# copyleft: pancake at nopcode dot org @ 2009-2013
|
||||
|
||||
PATH=.:$PATH
|
||||
@@ -11,8 +11,8 @@ bye() {
|
||||
}
|
||||
case "$1" in
|
||||
-) : ; ;;
|
||||
'') echo "vired [-hv] [file]" ; exit 1 ; ;;
|
||||
*) $0 - | ired -n $@ ; bye ; ;;
|
||||
'') echo "r0v [-hv] [file]" ; exit 1 ; ;;
|
||||
*) $0 - | r0 -n $@ ; bye ; ;;
|
||||
esac
|
||||
|
||||
ttyset=`stty -g`
|
||||
@@ -53,7 +53,7 @@ while : ; do
|
||||
echo '!clear'
|
||||
# autobs
|
||||
case $P in
|
||||
#'d') echo '!echo X | ired -n $| rasm2 -o $OFFSET -vd -|head -n '$LINES ; ;;
|
||||
#'d') echo '!echo X | r0 -n $| rasm2 -o $OFFSET -vd -|head -n '$LINES ; ;;
|
||||
d) echo d ;;
|
||||
*) echo x ;;
|
||||
esac
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
.Os
|
||||
.Th VR0 1
|
||||
.Sh NAME
|
||||
vired \- visual interactive raw editor
|
||||
r0v \- visual radare zero
|
||||
.Sh SYNOPSIS
|
||||
.Nm vired
|
||||
.Nm r0v
|
||||
.Ar file
|
||||
.Sh DESCRIPTION
|
||||
Visual mode for ired(1)
|
||||
Visual mode for r0(1)
|
||||
.Pp
|
||||
.Sh KEYS
|
||||
.Bl -tag -width Fl
|
||||
@@ -17,7 +17,7 @@ seek left(-1), down(+16), up(-16), right(+1)
|
||||
.It +-*/
|
||||
change block size (+1,-1,+16,-16)
|
||||
.It :[cmd]
|
||||
input ired command
|
||||
input r0 command
|
||||
.It b
|
||||
prompt to change block size
|
||||
.It s
|
||||
@@ -27,7 +27,7 @@ prompt for resize, remove command
|
||||
.It p
|
||||
change print mode
|
||||
.It :
|
||||
enter raw ired command
|
||||
enter raw r0 command
|
||||
.It ?
|
||||
show help
|
||||
.It q
|
||||
@@ -35,7 +35,7 @@ quit program
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Pp
|
||||
.Xr ired(1)
|
||||
.Xr r0(1)
|
||||
.Sh AUTHORS
|
||||
.PP
|
||||
pancake <@nopcode.org>
|
||||
@@ -0,0 +1,7 @@
|
||||
while : ; do
|
||||
rm -f r0.x86
|
||||
gcc -DUSE_DISASM_X32=1 -flto -O3 r0.c -o r0.x86
|
||||
strip r0.x86
|
||||
ls -l r0.x86
|
||||
sleep 1
|
||||
done
|
||||
@@ -18,9 +18,9 @@ static inline void hexdump(const ut8 *buf, unsigned int len, int w) {
|
||||
}
|
||||
|
||||
#define u(x) ((unsigned long)(x&0xff))
|
||||
static void print_fmt(const ut8 *buf, char *fmt, unsigned int len) {
|
||||
static void print_fmt(const ut8 *buf, const char *fmt, unsigned int len) {
|
||||
unsigned int i, up, inc = 0, lup = 0, rep = 0;
|
||||
char *ofmt = fmt;
|
||||
const char *ofmt = fmt;
|
||||
do { /* TODO: needs cleanup */
|
||||
for(;(*fmt||rep);fmt++) {
|
||||
up = rep?rep:*fmt;
|
||||
@@ -101,7 +101,7 @@ static unsigned int hexstr2raw(ut8 *arg) {
|
||||
static ut8 *getcurblk(const char *arg, int *len) {
|
||||
ut8 *buf = NULL;
|
||||
if(*arg) {
|
||||
*len = (int)str2ut64((const char *)arg);
|
||||
*len = (int)calc((const char *)arg);
|
||||
if(*len<1) *len = bsize;
|
||||
}
|
||||
if(*len>0 && (buf = malloc(*len)) != NULL) {
|
||||
|
||||
Reference in new issue
Block a user