TODO: global id 0 is now a null pointer, need to adjust rest of conversion code
accordingly.
... | ... |
@@ -26,6 +26,7 @@ |
26 | 26 |
#include <sys/time.h> |
27 | 27 |
#include <stdlib.h> |
28 | 28 |
#include "bytecode.h" |
29 |
+#include "bytecode_priv.h" |
|
29 | 30 |
#include "clamav.h" |
30 | 31 |
#include "shared/optparser.h" |
31 | 32 |
#include "shared/misc.h" |
... | ... |
@@ -141,6 +142,7 @@ int main(int argc, char *argv[]) |
141 | 141 |
fprintf(stderr,"Out of memory\n"); |
142 | 142 |
exit(3); |
143 | 143 |
} |
144 |
+ ctx->trace_mask = BC_TRACE_ALL; |
|
144 | 145 |
|
145 | 146 |
if (opts->filename[1]) { |
146 | 147 |
funcid = atoi(opts->filename[1]); |
... | ... |
@@ -52,6 +52,13 @@ struct cli_bc_ctx *cli_bytecode_context_alloc(void) |
52 | 52 |
ctx->outfd = -1; |
53 | 53 |
ctx->tempfile = NULL; |
54 | 54 |
ctx->written = 0; |
55 |
+ ctx->trace_mask = 0; |
|
56 |
+ ctx->scope = NULL; |
|
57 |
+ ctx->scopeid = 0; |
|
58 |
+ ctx->file = NULL; |
|
59 |
+ ctx->directory = NULL; |
|
60 |
+ ctx->lastline = 0; |
|
61 |
+ ctx->lastcol = 0; |
|
55 | 62 |
return ctx; |
56 | 63 |
} |
57 | 64 |
|
... | ... |
@@ -98,6 +98,10 @@ uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT *res, |
98 | 98 |
//TODO: call disasm_x86_wrap, which outputs a MARIO struct |
99 | 99 |
} |
100 | 100 |
|
101 |
+/* TODO: field in ctx, id of last bytecode that called magicscandesc, reset |
|
102 |
+ * after hooks/other bytecodes are run. TODO: need a more generic solution |
|
103 |
+ * to avoid uselessly recursing on bytecode-unpacked files, but also a way to |
|
104 |
+ * override the limit if we need it in a special situation */ |
|
101 | 105 |
int32_t cli_bcapi_write(struct cli_bc_ctx *ctx, uint8_t*data, int32_t len) |
102 | 106 |
{ |
103 | 107 |
int32_t res; |
... | ... |
@@ -128,4 +132,101 @@ int32_t cli_bcapi_write(struct cli_bc_ctx *ctx, uint8_t*data, int32_t len) |
128 | 128 |
return res; |
129 | 129 |
} |
130 | 130 |
|
131 |
+uint32_t cli_bcapi_trace_scope(struct cli_bc_ctx *ctx, const const uint8_t *scope, uint32_t scopeid) |
|
132 |
+{ |
|
133 |
+ if (LIKELY(!ctx->trace_mask)) |
|
134 |
+ return 0; |
|
135 |
+ if ((ctx->trace_mask&BC_TRACE_FUNC) && (scope != ctx->scope)) { |
|
136 |
+ ctx->scope = scope; |
|
137 |
+ ctx->trace_mask |= BC_TRACE_TMP_FUNC; |
|
138 |
+ } |
|
139 |
+ if ((ctx->trace_mask&BC_TRACE_SCOPE) && (scopeid != ctx->scopeid)) { |
|
140 |
+ ctx->scopeid = scopeid; |
|
141 |
+ ctx->trace_mask |= BC_TRACE_TMP_SCOPE; |
|
142 |
+ } |
|
143 |
+} |
|
144 |
+ |
|
145 |
+uint32_t cli_bcapi_trace_source(struct cli_bc_ctx *ctx, const const uint8_t *file, uint32_t line) |
|
146 |
+{ |
|
147 |
+ if (LIKELY(!ctx->trace_mask)) |
|
148 |
+ return 0; |
|
149 |
+ if (ctx->trace_mask&BC_TRACE_TMP_FUNC) { |
|
150 |
+ cli_dbgmsg("[trace] %s:%u:%u -> %s:%u\t Entering function %s\n", |
|
151 |
+ ctx->file ? ctx->file : "??", ctx->lastline, |
|
152 |
+ ctx->lastcol, file ? file : "??", line, |
|
153 |
+ ctx->scope); |
|
154 |
+ ctx->file = file; |
|
155 |
+ ctx->lastline = line; |
|
156 |
+ cli_bytecode_debug_printsrc(ctx); |
|
157 |
+ } else if (ctx->trace_mask&BC_TRACE_TMP_SCOPE) { |
|
158 |
+ cli_dbgmsg("[trace] %s:%u:%u -> %s:%u\t entering scope\n", |
|
159 |
+ ctx->file ? ctx->file : "??", ctx->lastline, |
|
160 |
+ ctx->lastcol, file ? file : "??", line, |
|
161 |
+ ctx->scope); |
|
162 |
+ ctx->file = file; |
|
163 |
+ ctx->lastline = line; |
|
164 |
+ cli_bytecode_debug_printsrc(ctx); |
|
165 |
+ } else { |
|
166 |
+ if (ctx->file != file || ctx->lastline != line) { |
|
167 |
+ ctx->file = file; |
|
168 |
+ ctx->lastline = line; |
|
169 |
+ if (ctx->trace_mask&BC_TRACE_LINE) |
|
170 |
+ ctx->trace_mask |= BC_TRACE_TMP_SRC; |
|
171 |
+ } |
|
172 |
+ } |
|
173 |
+ ctx->trace_mask &= ~(BC_TRACE_TMP_FUNC|BC_TRACE_TMP_SCOPE); |
|
174 |
+ return 0; |
|
175 |
+} |
|
176 |
+ |
|
177 |
+uint32_t cli_bcapi_trace_op(struct cli_bc_ctx *ctx, const const uint8_t *op, uint32_t col) |
|
178 |
+{ |
|
179 |
+ if (LIKELY(!ctx->trace_mask)) |
|
180 |
+ return 0; |
|
181 |
+ if (ctx->lastcol != col) { |
|
182 |
+ ctx->lastcol = col; |
|
183 |
+ if (ctx->trace_mask&BC_TRACE_COL) |
|
184 |
+ ctx->trace_mask |= BC_TRACE_TMP_SRC; |
|
185 |
+ } |
|
186 |
+ if ((ctx->trace_mask&BC_TRACE_OP) && op) { |
|
187 |
+ if (ctx->trace_mask&BC_TRACE_TMP_SRC) { |
|
188 |
+ cli_dbgmsg("[trace] %s:%u:%u\t %s\n", |
|
189 |
+ ctx->file ? ctx->file : "??", ctx->lastline, col, |
|
190 |
+ op); |
|
191 |
+ cli_bytecode_debug_printsrc(ctx); |
|
192 |
+ ctx->trace_mask &= ~BC_TRACE_TMP_SRC; |
|
193 |
+ } else |
|
194 |
+ cli_dbgmsg("[trace] %s\n", op); |
|
195 |
+ } |
|
196 |
+ return 0; |
|
197 |
+} |
|
198 |
+ |
|
199 |
+uint32_t cli_bcapi_trace_value(struct cli_bc_ctx *ctx, const const uint8_t* name, uint32_t value) |
|
200 |
+{ |
|
201 |
+ if (LIKELY(!ctx->trace_mask)) |
|
202 |
+ return 0; |
|
203 |
+ if ((ctx->trace_mask&BC_TRACE_VAL) && name) { |
|
204 |
+ if (ctx->trace_mask&BC_TRACE_TMP_SRC) { |
|
205 |
+ cli_dbgmsg("[trace] %s:%u:%u\t %s = %u\n", |
|
206 |
+ ctx->file ? ctx->file : "??", |
|
207 |
+ ctx->lastline, ctx->lastcol, |
|
208 |
+ name, value); |
|
209 |
+ cli_bytecode_debug_printsrc(ctx); |
|
210 |
+ } else { |
|
211 |
+ cli_dbgmsg("[trace]\t %s = %u\n", name, value); |
|
212 |
+ } |
|
213 |
+ } else if (ctx->trace_mask&BC_TRACE_TMP_SRC) { |
|
214 |
+ cli_dbgmsg("[trace] %s:%u:%u\n", |
|
215 |
+ ctx->file ? ctx->file : "??", |
|
216 |
+ ctx->lastline, ctx->lastcol); |
|
217 |
+ cli_bytecode_debug_printsrc(ctx); |
|
218 |
+ } |
|
219 |
+ ctx->trace_mask &= ~BC_TRACE_TMP_SRC; |
|
220 |
+ return 0; |
|
221 |
+} |
|
131 | 222 |
|
223 |
+uint32_t cli_bcapi_trace_directory(struct cli_bc_ctx *ctx, const const uint8_t* dir, uint32_t dummy) |
|
224 |
+{ |
|
225 |
+ if (LIKELY(!ctx->trace_mask)) |
|
226 |
+ return 0; |
|
227 |
+ ctx->directory = dir; |
|
228 |
+} |
... | ... |
@@ -155,5 +155,15 @@ uint32_t debug_print_uint(uint32_t a, uint32_t b); |
155 | 155 |
* \sa DisassembleAt |
156 | 156 |
* */ |
157 | 157 |
uint32_t disasm_x86(struct DISASM_RESULT* result, uint32_t len); |
158 |
+ |
|
159 |
+/* tracing API */ |
|
160 |
+ |
|
161 |
+/* a scope: lexical block, function, or compile unit */ |
|
162 |
+uint32_t trace_directory(const uint8_t* directory, uint32_t dummy); |
|
163 |
+uint32_t trace_scope(const uint8_t* newscope, uint32_t scopeid); |
|
164 |
+uint32_t trace_source(const uint8_t* srcfile, uint32_t line); |
|
165 |
+uint32_t trace_op(const uint8_t* opname, uint32_t column); |
|
166 |
+uint32_t trace_value(const uint8_t* name, uint32_t v); |
|
167 |
+ |
|
158 | 168 |
#endif |
159 | 169 |
#endif |
... | ... |
@@ -42,6 +42,11 @@ uint32_t cli_bcapi_setvirusname(struct cli_bc_ctx *ctx, const const uint8_t*, ui |
42 | 42 |
uint32_t cli_bcapi_debug_print_str(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
43 | 43 |
uint32_t cli_bcapi_debug_print_uint(struct cli_bc_ctx *ctx, uint32_t, uint32_t); |
44 | 44 |
uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT*, uint32_t); |
45 |
+uint32_t cli_bcapi_trace_directory(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
46 |
+uint32_t cli_bcapi_trace_scope(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
47 |
+uint32_t cli_bcapi_trace_source(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
48 |
+uint32_t cli_bcapi_trace_op(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
49 |
+uint32_t cli_bcapi_trace_value(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
45 | 50 |
|
46 | 51 |
const struct cli_apiglobal cli_globals[] = { |
47 | 52 |
/* Bytecode globals BEGIN */ |
... | ... |
@@ -70,14 +75,14 @@ static uint16_t cli_tmp10[]={80, 32, 32, 16}; |
70 | 70 |
static uint16_t cli_tmp11[]={81}; |
71 | 71 |
static uint16_t cli_tmp12[]={32, 32, 32, 32, 32, 32, 32, 32, 32}; |
72 | 72 |
static uint16_t cli_tmp13[]={32}; |
73 |
-static uint16_t cli_tmp14[]={32, 84, 32}; |
|
74 |
-static uint16_t cli_tmp15[]={85}; |
|
75 |
-static uint16_t cli_tmp16[]={16, 8, 8, 8, 87, 86}; |
|
76 |
-static uint16_t cli_tmp17[]={8}; |
|
77 |
-static uint16_t cli_tmp18[]={88}; |
|
78 |
-static uint16_t cli_tmp19[]={8}; |
|
79 |
-static uint16_t cli_tmp20[]={32, 32, 32}; |
|
80 |
-static uint16_t cli_tmp21[]={32, 65, 32}; |
|
73 |
+static uint16_t cli_tmp14[]={32, 65, 32}; |
|
74 |
+static uint16_t cli_tmp15[]={32, 85, 32}; |
|
75 |
+static uint16_t cli_tmp16[]={86}; |
|
76 |
+static uint16_t cli_tmp17[]={16, 8, 8, 8, 88, 87}; |
|
77 |
+static uint16_t cli_tmp18[]={8}; |
|
78 |
+static uint16_t cli_tmp19[]={89}; |
|
79 |
+static uint16_t cli_tmp20[]={8}; |
|
80 |
+static uint16_t cli_tmp21[]={32, 32, 32}; |
|
81 | 81 |
static uint16_t cli_tmp22[]={32, 92, 32}; |
82 | 82 |
static uint16_t cli_tmp23[]={93}; |
83 | 83 |
static uint16_t cli_tmp24[]={92}; |
... | ... |
@@ -98,12 +103,12 @@ const struct cli_bc_type cli_apicall_types[]={ |
98 | 98 |
{DStructType, cli_tmp12, 9, 0, 0}, |
99 | 99 |
{DArrayType, cli_tmp13, 64, 0, 0}, |
100 | 100 |
{DFunctionType, cli_tmp14, 3, 0, 0}, |
101 |
- {DPointerType, cli_tmp15, 1, 0, 0}, |
|
102 |
- {DStructType, cli_tmp16, 6, 0, 0}, |
|
103 |
- {DArrayType, cli_tmp17, 29, 0, 0}, |
|
104 |
- {DArrayType, cli_tmp18, 10, 0, 0}, |
|
105 |
- {DArrayType, cli_tmp19, 3, 0, 0}, |
|
106 |
- {DFunctionType, cli_tmp20, 3, 0, 0}, |
|
101 |
+ {DFunctionType, cli_tmp15, 3, 0, 0}, |
|
102 |
+ {DPointerType, cli_tmp16, 1, 0, 0}, |
|
103 |
+ {DStructType, cli_tmp17, 6, 0, 0}, |
|
104 |
+ {DArrayType, cli_tmp18, 29, 0, 0}, |
|
105 |
+ {DArrayType, cli_tmp19, 10, 0, 0}, |
|
106 |
+ {DArrayType, cli_tmp20, 3, 0, 0}, |
|
107 | 107 |
{DFunctionType, cli_tmp21, 3, 0, 0}, |
108 | 108 |
{DFunctionType, cli_tmp22, 3, 0, 0}, |
109 | 109 |
{DPointerType, cli_tmp23, 1, 0, 0}, |
... | ... |
@@ -114,14 +119,19 @@ const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall |
114 | 114 |
const struct cli_apicall cli_apicalls[]={ |
115 | 115 |
/* Bytecode APIcalls BEGIN */ |
116 | 116 |
{"test0", 22, 0, 1}, |
117 |
- {"test1", 20, 0, 0}, |
|
118 |
- {"read", 21, 1, 1}, |
|
119 |
- {"write", 21, 2, 1}, |
|
120 |
- {"seek", 20, 1, 0}, |
|
121 |
- {"setvirusname", 21, 3, 1}, |
|
122 |
- {"debug_print_str", 21, 4, 1}, |
|
123 |
- {"debug_print_uint", 20, 2, 0}, |
|
124 |
- {"disasm_x86", 14, 5, 1} |
|
117 |
+ {"test1", 21, 0, 0}, |
|
118 |
+ {"read", 14, 1, 1}, |
|
119 |
+ {"write", 14, 2, 1}, |
|
120 |
+ {"seek", 21, 1, 0}, |
|
121 |
+ {"setvirusname", 14, 3, 1}, |
|
122 |
+ {"debug_print_str", 14, 4, 1}, |
|
123 |
+ {"debug_print_uint", 21, 2, 0}, |
|
124 |
+ {"disasm_x86", 15, 5, 1}, |
|
125 |
+ {"trace_directory", 14, 6, 1}, |
|
126 |
+ {"trace_scope", 14, 7, 1}, |
|
127 |
+ {"trace_source", 14, 8, 1}, |
|
128 |
+ {"trace_op", 14, 9, 1}, |
|
129 |
+ {"trace_value", 14, 10, 1} |
|
125 | 130 |
/* Bytecode APIcalls END */ |
126 | 131 |
}; |
127 | 132 |
const cli_apicall_int2 cli_apicalls0[] = { |
... | ... |
@@ -135,6 +145,11 @@ const cli_apicall_pointer cli_apicalls1[] = { |
135 | 135 |
(cli_apicall_pointer)cli_bcapi_write, |
136 | 136 |
(cli_apicall_pointer)cli_bcapi_setvirusname, |
137 | 137 |
(cli_apicall_pointer)cli_bcapi_debug_print_str, |
138 |
- (cli_apicall_pointer)cli_bcapi_disasm_x86 |
|
138 |
+ (cli_apicall_pointer)cli_bcapi_disasm_x86, |
|
139 |
+ (cli_apicall_pointer)cli_bcapi_trace_directory, |
|
140 |
+ (cli_apicall_pointer)cli_bcapi_trace_scope, |
|
141 |
+ (cli_apicall_pointer)cli_bcapi_trace_source, |
|
142 |
+ (cli_apicall_pointer)cli_bcapi_trace_op, |
|
143 |
+ (cli_apicall_pointer)cli_bcapi_trace_value |
|
139 | 144 |
}; |
140 | 145 |
const unsigned cli_apicall_maxapi = sizeof(cli_apicalls)/sizeof(cli_apicalls[0]); |
... | ... |
@@ -39,5 +39,10 @@ uint32_t cli_bcapi_setvirusname(struct cli_bc_ctx *ctx, const const uint8_t*, ui |
39 | 39 |
uint32_t cli_bcapi_debug_print_str(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
40 | 40 |
uint32_t cli_bcapi_debug_print_uint(struct cli_bc_ctx *ctx, uint32_t, uint32_t); |
41 | 41 |
uint32_t cli_bcapi_disasm_x86(struct cli_bc_ctx *ctx, struct DISASM_RESULT*, uint32_t); |
42 |
+uint32_t cli_bcapi_trace_directory(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
43 |
+uint32_t cli_bcapi_trace_scope(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
44 |
+uint32_t cli_bcapi_trace_source(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
45 |
+uint32_t cli_bcapi_trace_op(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
46 |
+uint32_t cli_bcapi_trace_value(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t); |
|
42 | 47 |
|
43 | 48 |
#endif |
... | ... |
@@ -103,6 +103,18 @@ struct cli_bc_dbgnode { |
103 | 103 |
}; |
104 | 104 |
|
105 | 105 |
#define MAX_OP ~0u |
106 |
+#define BC_TRACE_FUNC 0x1 |
|
107 |
+#define BC_TRACE_SCOPE 0x2 |
|
108 |
+#define BC_TRACE_LINE 0x4 |
|
109 |
+#define BC_TRACE_COL 0x8 |
|
110 |
+#define BC_TRACE_OP 0x10 |
|
111 |
+#define BC_TRACE_VAL 0x20 |
|
112 |
+#define BC_TRACE_TMP_FUNC 0x40 |
|
113 |
+#define BC_TRACE_TMP_SCOPE 0x80 |
|
114 |
+#define BC_TRACE_TMP_SRC 0x100 |
|
115 |
+#define BC_TRACE_SHOW_SOURCE 0x200 |
|
116 |
+#define BC_TRACE_ALL (BC_TRACE_FUNC | BC_TRACE_SCOPE | BC_TRACE_LINE | BC_TRACE_COL | BC_TRACE_OP | BC_TRACE_VAL | BC_TRACE_SHOW_SOURCE) |
|
117 |
+ |
|
106 | 118 |
struct cli_bc_ctx { |
107 | 119 |
/* id and params of toplevel function called */ |
108 | 120 |
const struct cli_bc *bc; |
... | ... |
@@ -122,6 +134,13 @@ struct cli_bc_ctx { |
122 | 122 |
char *tempfile; |
123 | 123 |
void *ctx; |
124 | 124 |
unsigned written; |
125 |
+ unsigned trace_mask; |
|
126 |
+ const char *scope; |
|
127 |
+ uint32_t scopeid; |
|
128 |
+ const char *file; |
|
129 |
+ const char *directory; |
|
130 |
+ unsigned lastline; |
|
131 |
+ unsigned lastcol; |
|
125 | 132 |
}; |
126 | 133 |
struct cli_all_bc; |
127 | 134 |
int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct cli_bc_func *func, const struct cli_bc_inst *inst); |
... | ... |
@@ -22,6 +22,7 @@ |
22 | 22 |
#define DEBUG_TYPE "clamavjit" |
23 | 23 |
#include "llvm/ADT/DenseMap.h" |
24 | 24 |
#include "llvm/ADT/BitVector.h" |
25 |
+#include "llvm/ADT/StringMap.h" |
|
25 | 26 |
#include "llvm/CallingConv.h" |
26 | 27 |
#include "llvm/DerivedTypes.h" |
27 | 28 |
#include "llvm/Function.h" |
... | ... |
@@ -37,10 +38,13 @@ |
37 | 37 |
#include "llvm/Support/CommandLine.h" |
38 | 38 |
#include "llvm/Support/ErrorHandling.h" |
39 | 39 |
#include "llvm/Support/ManagedStatic.h" |
40 |
+#include "llvm/Support/MemoryBuffer.h" |
|
40 | 41 |
#include "llvm/Support/raw_ostream.h" |
42 |
+#include "llvm/Support/SourceMgr.h" |
|
41 | 43 |
#include "llvm/Support/IRBuilder.h" |
42 | 44 |
#include "llvm/Support/PrettyStackTrace.h" |
43 | 45 |
#include "llvm/System/DataTypes.h" |
46 |
+#include "llvm/System/Mutex.h" |
|
44 | 47 |
#include "llvm/System/Signals.h" |
45 | 48 |
#include "llvm/System/Threading.h" |
46 | 49 |
#include "llvm/Target/TargetSelect.h" |
... | ... |
@@ -264,6 +268,8 @@ private: |
264 | 264 |
operand &= 0x7fffffff; |
265 | 265 |
assert(operand < globals.size() && "Global index out of range"); |
266 | 266 |
// Global |
267 |
+ if (!operand) |
|
268 |
+ return ConstantPointerNull::get(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
267 | 269 |
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(globals[operand])) { |
268 | 270 |
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GV->getInitializer())) { |
269 | 271 |
return CE; |
... | ... |
@@ -328,14 +334,22 @@ private: |
328 | 328 |
|
329 | 329 |
Constant *buildConstant(const Type *Ty, uint64_t *components, unsigned &c) |
330 | 330 |
{ |
331 |
- if (isa<PointerType>(Ty)) { |
|
332 |
- Constant *idxs[2] = { |
|
331 |
+ if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { |
|
332 |
+ Value *idxs[2] = { |
|
333 | 333 |
ConstantInt::get(Type::getInt32Ty(Context), 0), |
334 | 334 |
ConstantInt::get(Type::getInt32Ty(Context), components[c++]) |
335 | 335 |
}; |
336 | 336 |
unsigned idx = components[c++]; |
337 |
+ if (!idx) |
|
338 |
+ return ConstantPointerNull::get(PTy); |
|
337 | 339 |
assert(idx < globals.size()); |
338 | 340 |
GlobalVariable *GV = cast<GlobalVariable>(globals[idx]); |
341 |
+ const Type *GTy = GetElementPtrInst::getIndexedType(GV->getType(), idxs, 2); |
|
342 |
+ if (!GTy || GTy != PTy->getElementType()) { |
|
343 |
+ errs() << "Type mismatch for GEP: " << *PTy->getElementType() << " != " << *GTy |
|
344 |
+ << "; base is " << *GV << "\n"; |
|
345 |
+ llvm_report_error("(libclamav) Type mismatch converting constant"); |
|
346 |
+ } |
|
339 | 347 |
return ConstantExpr::getInBoundsGetElementPtr(GV, idxs, 2); |
340 | 348 |
} |
341 | 349 |
if (isa<IntegerType>(Ty)) { |
... | ... |
@@ -517,8 +531,8 @@ public: |
517 | 517 |
|
518 | 518 |
globals.reserve(bc->num_globals); |
519 | 519 |
BitVector FakeGVs; |
520 |
- FakeGVs.resize(bc->num_globals); |
|
521 |
- |
|
520 |
+ FakeGVs.resize(bc->num_globals+1); |
|
521 |
+ globals.push_back(0); |
|
522 | 522 |
for (unsigned i=0;i<bc->num_globals;i++) { |
523 | 523 |
const Type *Ty = mapType(bc->globaltys[i]); |
524 | 524 |
|
... | ... |
@@ -528,7 +542,7 @@ public: |
528 | 528 |
if (isa<PointerType>(Ty)) { |
529 | 529 |
unsigned g = bc->globals[i][1]; |
530 | 530 |
if (GVoffsetMap.count(g)) { |
531 |
- FakeGVs.set(i); |
|
531 |
+ FakeGVs.set(i+1); |
|
532 | 532 |
globals.push_back(0); |
533 | 533 |
continue; |
534 | 534 |
} |
... | ... |
@@ -596,7 +610,7 @@ public: |
596 | 596 |
Argument *Ctx = F->arg_begin(); |
597 | 597 |
struct cli_bc_ctx *N = 0; |
598 | 598 |
for (unsigned i=0;i<bc->num_globals;i++) { |
599 |
- if (!FakeGVs[i]) |
|
599 |
+ if (!FakeGVs[i+1]) |
|
600 | 600 |
continue; |
601 | 601 |
unsigned g = bc->globals[i][1]; |
602 | 602 |
unsigned offset = GVoffsetMap[g]; |
... | ... |
@@ -1207,4 +1221,67 @@ void cli_bytecode_debug(int argc, char **argv) |
1207 | 1207 |
cl::ParseCommandLineOptions(argc, argv); |
1208 | 1208 |
} |
1209 | 1209 |
|
1210 |
+struct lines { |
|
1211 |
+ MemoryBuffer *buffer; |
|
1212 |
+ std::vector<const char*> lines; |
|
1213 |
+}; |
|
1214 |
+ |
|
1215 |
+static struct lineprinter { |
|
1216 |
+ StringMap<struct lines*> files; |
|
1217 |
+} LinePrinter; |
|
1218 |
+ |
|
1219 |
+void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx) |
|
1220 |
+{ |
|
1221 |
+ if (!ctx->file || !ctx->directory || !ctx->lastline) { |
|
1222 |
+ errs() << (ctx->directory ? "d":"null") << ":" << (ctx->file ? "f" : "null")<< ":" << ctx->lastline << "\n"; |
|
1223 |
+ return; |
|
1224 |
+ } |
|
1225 |
+ // acquire a mutex here |
|
1226 |
+ sys::Mutex mtx(false); |
|
1227 |
+ sys::SmartScopedLock<false> lock(mtx); |
|
1228 |
+ |
|
1229 |
+ std::string path = std::string(ctx->directory) + "/" + std::string(ctx->file); |
|
1230 |
+ StringMap<struct lines*>::iterator I = LinePrinter.files.find(path); |
|
1231 |
+ struct lines *lines; |
|
1232 |
+ if (I == LinePrinter.files.end()) { |
|
1233 |
+ lines = new struct lines; |
|
1234 |
+ std::string ErrorMessage; |
|
1235 |
+ lines->buffer = MemoryBuffer::getFile(path, &ErrorMessage); |
|
1236 |
+ if (!lines->buffer) { |
|
1237 |
+ errs() << "Unable to open file '" << path << "'\n"; |
|
1238 |
+ return ; |
|
1239 |
+ } |
|
1240 |
+ LinePrinter.files[path] = lines; |
|
1241 |
+ } else { |
|
1242 |
+ lines = I->getValue(); |
|
1243 |
+ } |
|
1244 |
+ const char *linestart; |
|
1245 |
+ while (lines->lines.size() <= ctx->lastline+1) { |
|
1246 |
+ const char *p; |
|
1247 |
+ if (lines->lines.empty()) { |
|
1248 |
+ p = lines->buffer->getBufferStart(); |
|
1249 |
+ lines->lines.push_back(p); |
|
1250 |
+ } else { |
|
1251 |
+ p = lines->lines.back(); |
|
1252 |
+ if (p == lines->buffer->getBufferEnd()) |
|
1253 |
+ break; |
|
1254 |
+ p = strchr(p, '\n'); |
|
1255 |
+ if (!p) { |
|
1256 |
+ p = lines->buffer->getBufferEnd(); |
|
1257 |
+ lines->lines.push_back(p); |
|
1258 |
+ } else |
|
1259 |
+ lines->lines.push_back(p+1); |
|
1260 |
+ } |
|
1261 |
+ } |
|
1262 |
+ if (ctx->lastline >= lines->lines.size()) { |
|
1263 |
+ errs() << "Line number " << ctx->lastline << "out of file\n"; |
|
1264 |
+ return; |
|
1265 |
+ } |
|
1266 |
+ assert(ctx->lastline < lines->lines.size()); |
|
1267 |
+ SMDiagnostic diag(ctx->file, ctx->lastline ? ctx->lastline : -1, |
|
1268 |
+ ctx->lastcol ? ctx->lastcol-1 : -1, |
|
1269 |
+ "", std::string(lines->lines[ctx->lastline-1], lines->lines[ctx->lastline]-1)); |
|
1270 |
+ diag.Print("[trace]", errs()); |
|
1271 |
+} |
|
1272 |
+ |
|
1210 | 1273 |
int have_clamjit=1; |
... | ... |
@@ -353,8 +353,10 @@ void cli_errmsg(const char *str, ...); |
353 | 353 |
* such as debug paths, and error paths */ |
354 | 354 |
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2) |
355 | 355 |
#define UNLIKELY(cond) __builtin_expect(!!(cond), 0) |
356 |
+#define LIKELY(cond) __builtin_expect(!!(cond), 1) |
|
356 | 357 |
#else |
357 | 358 |
#define UNLIKELY(cond) (cond) |
359 |
+#define LIKELY(cond) (cond) |
|
358 | 360 |
#endif |
359 | 361 |
|
360 | 362 |
#ifdef __GNUC__ |
... | ... |
@@ -1949,6 +1949,7 @@ int cli_scanpe(cli_ctx *ctx) |
1949 | 1949 |
return CL_EREAD; |
1950 | 1950 |
} |
1951 | 1951 |
|
1952 |
+ cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset); |
|
1952 | 1953 |
CLI_UNPTEMP("yC",(spinned,exe_sections,0)); |
1953 | 1954 |
CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0)); |
1954 | 1955 |
} |
... | ... |
@@ -2,10 +2,10 @@ ClamBCaa`|``c``a```|`bjaabp`clamcoincidencejb |
2 | 2 |
Trojan.Foo.{A,B};Target:1;(((0|1|2)=42,2)|(3=10));EP+0:aabb;ffff;aaccee;f00d;dead |
3 | 3 |
Tedebieebheebgeebfeebeeebdeebbeebaeebadebcdaaa`aacb`bbadb`bdb`db`bcajbadbcebadbcebadbcebadbcebadbcecaab`bdagahdaeahdajahdabbaddabahdakah |
4 | 4 |
Eafaaafb`e|amcgefdgfgifbgegcgnfafmfef`` |
5 |
-Gd```hbhabieBdeBbgBofBjfBafBnfBnbBfdBofBof@`bheBad@`bheBbd@`bge@Aa@Ab`b`aAa`b`aC``a`bfeBedB`eBkbB`cBjcBafBafBbfBbf@`beeBffBffBffBff@`beeBffB`cB`cBdf@`bdeBafBafBcfBcfBefBef@`beeBdfBefBafBdf@`bbe@Af@@AgAa@AhAc@AiAb@AjAd`bad@Aa`bad@Ab`bad@Af`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bcdAdD```h`bcdAcD```h`bcdAbD```h`bcdAaD```h`bcd@D```h` |
|
5 |
+Gd```hbhabieBdeBbgBofBjfBafBnfBnbBfdBofBof@`bheBad@`bheBbd@`bge@Ab@Ac`b`aAa`b`aC``a`bfeBedB`eBkbB`cBjcBafBafBbfBbf@`beeBffBffBffBff@`beeBffB`cB`cBdf@`bdeBafBafBcfBcfBefBef@`beeBdfBefBafBdf@`bbe@Ag@@AhAa@AiAc@AjAb@AkAd`bad@Ab`bad@Ac`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bad@Ak`bcdAdD```h`bcdAcD```h`bcdAbD```h`bcdAaD```h`bcd@D```h` |
|
6 | 6 |
A`b`bLaeb`b`aa`aa`bad`b`b`Fahac |
7 |
-Bb`b`gbBca`aaaagab`b`AadTaaaaaaab |
|
8 |
-Baaabeab`b`AbdbadacoaabAl`Am`b`badabbafac@dTcab`b@d |
|
7 |
+Bb`b`gbBda`aaaagab`b`AadTaaaaaaab |
|
8 |
+Baaabeab`b`AbdbadacoaabAm`An`b`badabbafac@dTcab`b@d |
|
9 | 9 |
BTcab`b@dE |
10 | 10 |
A`aaLbcab`b`b`b`b`b`b`b`b`b`aa`aa`aa`aa`b`b`b`b`b`b`b`b`b`b`aa`aa`b`b`aa`aa`Fbdaaa |
11 |
-Bb`b`gbBga`b`baagbBfa`b`babgbBea`b`baca`aa`b`bada`acabaaaeeab`badBjbdaaaffab`bab@daaagfab`baa@daaahfab`b`@db`bai`aafb`baj`aagb`bak`aahb`bala`ajakb`bama`alaiaaaneab`bamAbdaaaok`anaeb`bb`agbBda`aabaaeab`bb`aAjdaabbal`aobaaTcaaabbaE |
|
11 |
+Bb`b`gbBha`b`baagbBga`b`babgbBfa`b`baca`aa`b`bada`acabaaaeeab`badBjbdaaaffab`bab@daaagfab`baa@daaahfab`b`@db`bai`aafb`baj`aagb`bak`aahb`bala`ajakb`bama`alaiaaaneab`bamAbdaaaok`anaeb`bb`agbBea`aabaaeab`bb`aAjdaabbal`aobaaTcaaabbaE |