... | ... |
@@ -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 |
} |