Browse code

disasm_x86 api.

Török Edvin authored on 2010/01/21 00:16:27
Showing 3 changed files
... ...
@@ -40,6 +40,7 @@
40 40
 #include "bytecode_api_impl.h"
41 41
 #include "others.h"
42 42
 #include "pe.h"
43
+#include "disasm.h"
43 44
 
44 45
 uint32_t cli_bcapi_test0(struct cli_bc_ctx *ctx, struct foo* s, uint32_t u)
45 46
 {
... ...
@@ -103,8 +104,18 @@ uint32_t cli_bcapi_setvirusname(struct cli_bc_ctx* ctx, const uint8_t *name, uin
103 103
 
104 104
 uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT *res, uint32_t len)
105 105
 {
106
-    //TODO: call disasm_x86_wrap, which outputs a MARIO struct
107
-    return -1;
106
+    int n;
107
+    const char *buf;
108
+    const char* next;
109
+    if (!res || !ctx->fmap || ctx->off >= ctx->fmap->len)
110
+	return -1;
111
+    /* FIXME: 4096 is an overestimate, how long is the longest instruction? */
112
+    n = MIN(4096, ctx->fmap->len - ctx->off);
113
+    buf = fmap_need_off_once(ctx->fmap, ctx->off, n);
114
+    next = cli_disasm_one(buf, n, res, 0);
115
+    if (!next)
116
+	return -1;
117
+    return ctx->off + next - buf;
108 118
 }
109 119
 
110 120
 /* TODO: field in ctx, id of last bytecode that called magicscandesc, reset
... ...
@@ -1254,7 +1254,7 @@ static void spam_x86(struct DISASMED *s, char *hr) {
1254 1254
 #define GETSIZE(X) (x86ops[table][s->table_op].X!=SIZE_WD?x86ops[table][s->table_op].X:((s->opsize)?SIZE_WORD:SIZE_DWORD))
1255 1255
 
1256 1256
 
1257
-static uint8_t *disasm_x86(uint8_t *command, unsigned int len, struct DISASMED *s) {
1257
+static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struct DISASMED *s) {
1258 1258
   unsigned int reversed=0, i;
1259 1259
   uint8_t b;
1260 1260
   unsigned int table = 0;
... ...
@@ -1679,52 +1679,63 @@ static uint8_t *disasm_x86(uint8_t *command, unsigned int len, struct DISASMED *
1679 1679
   }
1680 1680
 }
1681 1681
 
1682
-int disasmbuf(uint8_t *buff, unsigned int len, int fd) {
1683
-  uint8_t *next = buff;
1684
-  unsigned int counter=0;
1685
-  int gotsome=0;
1682
+const uint8_t* cli_disasm_one(const uint8_t* buff, unsigned int len,
1683
+			      struct DISASM_RESULT *w, int spam)
1684
+{
1686 1685
   struct DISASMED s;
1687
-  struct DISASM_RESULT w;
1688
-  memset(&w.extra[0], 0, sizeof(w.extra));
1686
+  int i;
1689 1687
 
1690
-  while(len && counter++<200) {
1691
-    int i;
1692
-    if(!(next = disasm_x86(next, len, &s))) {
1693
-      /* TODO: invd opcode or buff over */
1694
-      return gotsome;
1695
-    }
1696
-    if(cli_debug_flag) {
1688
+  memset(&w->extra[0], 0, sizeof(w->extra));
1689
+  buff = disasm_x86(buff, len, &s);
1690
+  if (!buff)
1691
+      return NULL;
1692
+  if (spam) {
1697 1693
       char hr[128];
1698 1694
       spam_x86(&s, hr);
1699 1695
       cli_dbgmsg("%s\n", hr);
1700
-    }
1701
-    
1702
-    len -= next-buff;
1703
-    buff=next;
1704
-
1705
-    w.real_op = le16_to_host(s.real_op);
1706
-    w.opsize = s.opsize;
1707
-    w.adsize = s.adsize;
1708
-    w.segment = s.segment;
1696
+  }
1697
+  w->real_op = le16_to_host(s.real_op);
1698
+  w->opsize = s.opsize;
1699
+  w->adsize = s.adsize;
1700
+  w->segment = s.segment;
1709 1701
 
1710
-    for (i=0; i<3; i++) {
1711
-      w.arg[i][0] = s.args[i].access;
1712
-      w.arg[i][1] = s.args[i].size;
1702
+  for (i=0; i<3; i++) {
1703
+      w->arg[i][0] = s.args[i].access;
1704
+      w->arg[i][1] = s.args[i].size;
1713 1705
       switch(s.args[i].access) {
1714 1706
       case ACCESS_MEM:
1715
-	w.arg[i][2]=s.args[i].arg.marg.r1;
1716
-	w.arg[i][3]=s.args[i].arg.marg.r2;
1717
-	w.arg[i][4]=s.args[i].arg.marg.scale;
1718
-	w.arg[i][5]=0;
1719
-	cli_writeint32(&w.arg[i][6], s.args[i].arg.marg.disp);
1707
+	w->arg[i][2]=s.args[i].arg.marg.r1;
1708
+	w->arg[i][3]=s.args[i].arg.marg.r2;
1709
+	w->arg[i][4]=s.args[i].arg.marg.scale;
1710
+	w->arg[i][5]=0;
1711
+	cli_writeint32(&w->arg[i][6], s.args[i].arg.marg.disp);
1720 1712
 	break;
1721 1713
       case ACCESS_REG:
1722
-	w.arg[i][1] = s.args[i].reg;
1714
+	w->arg[i][1] = s.args[i].reg;
1723 1715
       default:
1724
-	cli_writeint32(&w.arg[i][2], s.args[i].arg.q);
1725
-	cli_writeint32(&w.arg[i][6], s.args[i].arg.q>>32);
1716
+	cli_writeint32(&w->arg[i][2], s.args[i].arg.q);
1717
+	cli_writeint32(&w->arg[i][6], s.args[i].arg.q>>32);
1726 1718
       }
1719
+  }
1720
+  return buff;
1721
+}
1722
+
1723
+int disasmbuf(const uint8_t *buff, unsigned int len, int fd) {
1724
+  const uint8_t *next = buff;
1725
+  unsigned int counter=0;
1726
+  int gotsome=0;
1727
+  struct DISASM_RESULT w;
1728
+  memset(&w.extra[0], 0, sizeof(w.extra));
1729
+
1730
+  while(len && counter++<200) {
1731
+    if(!(next = cli_disasm_one(next, len, &w, cli_debug_flag))) {
1732
+      /* TODO: invd opcode or buff over */
1733
+      return gotsome;
1727 1734
     }
1735
+    
1736
+    len -= next-buff;
1737
+    buff=next;
1738
+
1728 1739
     cli_writen(fd, &w, sizeof(w));
1729 1740
     gotsome = 1;
1730 1741
   }
... ...
@@ -27,6 +27,7 @@
27 27
 
28 28
 #include "others.h"
29 29
 
30
-int disasmbuf(uint8_t *, unsigned int, int);
30
+const uint8_t* cli_disasm_one(const uint8_t*, unsigned, struct DISASM_RESULT*, int);
31
+int disasmbuf(const uint8_t *, unsigned int, int);
31 32
 
32 33
 #endif