/*
* LANGDISASM - Quick & dirty stack machine code disassembler
*
* Author:
* Emile van Bergen, emile@evbergen.xs4all.nl
*
* Permission to redistribute an original or modified version of this program
* in source, intermediate or object code form is hereby granted exclusively
* under the terms of the GNU General Public License, version 2. Please see the
* file COPYING for details, or refer to http://www.gnu.org/copyleft/gpl.html.
*
* History:
* 2001/05/06 - EvB - Created
* 2001/10/29 - EvB - Cleanup
*/
char langdisasm_id[] = "LANGDISASM - Copyright (C) 2001 Emile van Bergen.";
/*
* INCLUDES & DEFINES
*/
#include <unistd.h> /* For write() */
#include <string.h> /* For strcpy(), strlen() */
#include <language.h>
/*
* GLOBALS
*/
#define OPCCNT 81
struct {
int op;
char *name;
} opcmap[OPCCNT + 1] = {
{ OP_HALT, "HALT" },
{ OP_ABORT, "ABORT" },
{ OP_ACCEPT, "ACCEPT" },
{ OP_REJECT, "REJECT" },
{ OP_ACCTRESP, "ACCTRESP" },
{ OP_NOP, "NOP" },
{ OP_PUSHINT, "PUSHINT" },
{ OP_PUSHSTR, "PUSHSTR" },
{ OP_PUSHAV, "PUSHAVREF" },
{ OP_POP, "POP" },
{ OP_NEG, "NEG" },
{ OP_NOT, "NOT" },
{ OP_MUL, "MUL" },
{ OP_DIV, "DIV" },
{ OP_CIDRMASK, "CIDRMASK" },
{ OP_MOD, "MOD" },
{ OP_ADD, "ADD" },
{ OP_SUB, "SUB" },
{ OP_SHL, "SHL" },
{ OP_SHR, "SHR" },
{ OP_XOR, "XOR" },
{ OP_AND, "AND" },
{ OP_OR, "OR" },
{ OP_GE, "GE" },
{ OP_LE, "LE" },
{ OP_GT, "GT" },
{ OP_LT, "LT" },
{ OP_EQ, "EQ" },
{ OP_NE, "NE" },
{ OP_BF, "BF" },
{ OP_AF, "AF" },
{ OP_BL, "BL" },
{ OP_AL, "AL" },
{ OP_FO, "FO" },
{ OP_LO, "LO" },
{ OP_MD5, "MD5" },
{ OP_HEX, "HEX" },
{ OP_UPPER, "UPPER" },
{ OP_LOWER, "LOWER" },
{ OP_RANDOM, "RANDOM" },
{ OP_XORSTR, "XORSTR" },
{ OP_CONCAT, "CONCAT" },
{ OP_DICTENC, "DICTENC" },
{ OP_GESTR, "GESTR" },
{ OP_LESTR, "LESTR" },
{ OP_GTSTR, "GTSTR" },
{ OP_LTSTR, "LTSTR" },
{ OP_EQSTR, "EQSTR" },
{ OP_NESTR, "NESTR" },
{ OP_ORD2OCTSTR, "ORD2OCTSTR" },
{ OP_ORD2DECSTR, "ORD2DECSTR" },
{ OP_ORD2HEXSTR, "ORD2HEXSTR" },
{ OP_ORD2RAWSTR, "ORD2RAWSTR" },
{ OP_ORD2IPASTR, "ORD2IPASTR" },
{ OP_ORD2DATSTR, "ORD2DATSTR" },
{ OP_ORD2DFMSTR, "ORD2DFMSTR" },
{ OP_STR2MAC, "STR2MAC" },
{ OP_PAPDECR, "PAPDECR" },
{ OP_PAPENCR, "PAPENCR" },
{ OP_UNIXCRYPT, "UNIXCRYPT" },
{ OP_HMACMD5, "HMACMD5" },
{ OP_DICTDEC, "DICTDEC" },
{ OP_OCTSTR2ORD, "OCTSTR2ORD" },
{ OP_DECSTR2ORD, "DECSTR2ORD" },
{ OP_HEXSTR2ORD, "HEXSTR2ORD" },
{ OP_RAWSTR2ORD, "RAWSTR2ORD" },
{ OP_IPASTR2ORD, "IPASTR2ORD" },
{ OP_DATSTR2ORD, "DATSTR2ORD" },
{ OP_INTSTR2ORD, "INTSTR2ORD" },
{ OP_EXISTS, "EXISTS" },
{ OP_BOOLNOT, "BOOLNOT" },
{ OP_JMPZ, "JMPZ" },
{ OP_JMPNZ, "JMPNZ" },
{ OP_ADDAV, "ADDAV" },
{ OP_REPLACEAV, "REPLACEAV" },
{ OP_POKEAV, "POKEAV" },
{ OP_DELAV, "DELAV" },
{ OP_DELALLAV, "DELALLAV" },
{ OP_MOVEALLAV, "MOVEALLAV" },
{ OP_JOINSTR, "JOINSTR" },
{ OP_CALLIFACE, "CALLIFACE" },
{ -1, "???" }}; /* Must not be included in OPCCNT */
/*
* FUNCTIONS
*/
void lang_disassemble(META *m, INSN *code, ssize_t codelen)
{
static char buf[1024];
INSN *i, *e;
char *o;
int n;
e = (INSN *)((char *)code + codelen);
for(i = code; i < e; i++) {
o = buf;
/* Show relative instruction pointer */
o += meta_ordtoa(o, 128, 0, 10, i - code);
*o++ = ':'; *o++ = ' ';
/* Show instruction name */
for(n = 0; n < OPCCNT && i->op != opcmap[n].op; n++);
strcpy(o, opcmap[n].name); o += strlen(o); *o++ = ' ';
/* For some instructions, show and/or do something extra */
switch(i->op) {
case OP_PUSHINT:
o += meta_ordtoa(o, 128, 0, 10, i->imm.ord);
strcpy(o, " (0x"); o += 4;
o += meta_ordtoa(o, 128, 0, 16, i->imm.ord);
*o++ = ')';
break;
case OP_PUSHSTR:
*o++ = '\"';
o += meta_atoprt((char *)(i + 1), i->imm.d.str_len,
0, 0, 0, 0,
o, sizeof(buf) - 4 - (o - buf));
*o++ = '\"';
i += i->imm.d.disp;
break;
case OP_PUSHAV:
strcpy(o, i->imm.i.item->spc->name);
o += strlen(o); *o++ = '/';
strcpy(o, meta_getvndbynr(m, i->imm.i.item->vnd)->name);
o += strlen(o); *o++ = '/';
strcpy(o, i->imm.i.item->name);
o += strlen(o);
strcpy(o, i->imm.i.flags&AV_FIRST ? " (first":" (last");
o += strlen(o);
if (i->imm.i.flags & AV_USEREPVALID)
strcpy(o, i->imm.i.flags & AV_USEREP ?
" from REP)" : " from REQ)");
else
strcpy(o, i->imm.i.flags & AV_USEREP ?
" from NONSTD list for OP)" :
" from STD list for OP)");
o += strlen(o);
break;
case OP_JMPZ:
case OP_JMPNZ:
if (i->imm.d.disp >= 0) *o++ = '+';
o += meta_ordtoa(o, 128, 0, 10, i->imm.d.disp);
break;
}
*o++ = '\n';
write(2, buf, o - buf);
}
}
syntax highlighted by Code2HTML, v. 0.9.1