/* * 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 /* For write() */ #include /* For strcpy(), strlen() */ #include /* * 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); } }