Browse code

Add new bytecode APIs to access the environment.

check_platform(...) is an API that can be used to:
- blacklist JIT/bytecode on just a very specific platform (not recommended)
- mask (with 0xf/0xff) some fields, and keep just the flags that uniquely
identify the system where a bug occurs (for example linux + ppc32).
- it returns a bool so you can do further checks if needed.

The bytecode also has access to all the information collected from the
environment, so it can make more detailed decisions (based on CPU, presence of
SELinux/PaX, etc.).
You can't introduce new detections via bytecode, but you can write new
conditions using existing ones.

The previously added builtin bytecode moved all the JIT disable logic to
bytecode for easy updating.

Török Edvin authored on 2010/07/29 19:40:13
Showing 4 changed files
... ...
@@ -1215,3 +1215,110 @@ int32_t cli_bcapi_input_switch(struct cli_bc_ctx *ctx , int32_t extracted_file)
1215 1215
     cli_dbgmsg("bytecode api: input switched to extracted file\n");
1216 1216
     return 0;
1217 1217
 }
1218
+
1219
+uint32_t cli_bcapi_get_environment(struct cli_bc_ctx *ctx , struct cli_environment* env, uint32_t len)
1220
+{
1221
+    if (len > sizeof(*env)) {
1222
+	cli_dbgmsg("cli_bcapi_get_environment len %d > %d\n", len, sizeof(*env));
1223
+	return -1;
1224
+    }
1225
+    memcpy(env, ctx->env, len);
1226
+    return 0;
1227
+}
1228
+
1229
+uint32_t cli_bcapi_disable_bytecode_if(struct cli_bc_ctx *ctx , const int8_t* reason, uint32_t len, uint32_t cond)
1230
+{
1231
+    if (ctx->bc->kind != BC_STARTUP) {
1232
+	cli_dbgmsg("Bytecode must be BC_STARTUP to call disable_bytecode_if\n");
1233
+	return -1;
1234
+    }
1235
+    if (!cond)
1236
+	return ctx->bytecode_disable_status;
1237
+    if (*reason == '^')
1238
+	cli_warnmsg("Bytecode: disabling completely because %s\n", reason+1);
1239
+    else
1240
+	cli_dbgmsg("Bytecode: disabling completely because %s\n", reason);
1241
+    ctx->bytecode_disable_status = 2;
1242
+    return ctx->bytecode_disable_status;
1243
+}
1244
+
1245
+uint32_t cli_bcapi_disable_jit_if(struct cli_bc_ctx *ctx , const int8_t* reason, uint32_t len, uint32_t cond)
1246
+{
1247
+    if (ctx->bc->kind != BC_STARTUP) {
1248
+	cli_dbgmsg("Bytecode must be BC_STARTUP to call disable_jit_if\n");
1249
+	return -1;
1250
+    }
1251
+    if (!cond)
1252
+	return ctx->bytecode_disable_status;
1253
+    if (*reason == '^')
1254
+	cli_warnmsg("Bytecode: disabling JIT because %s\n", reason+1);
1255
+    else
1256
+	cli_dbgmsg("Bytecode: disabling JIT because %s\n", reason);
1257
+    if (ctx->bytecode_disable_status != 2) /* no reenabling */
1258
+	ctx->bytecode_disable_status = 1;
1259
+    return ctx->bytecode_disable_status;
1260
+}
1261
+
1262
+int32_t cli_bcapi_version_compare(struct cli_bc_ctx *ctx , const uint8_t* lhs, uint32_t lhs_len, 
1263
+				  const uint8_t* rhs, uint32_t rhs_len)
1264
+{
1265
+    char *endl, *endr;
1266
+    unsigned i = 0, j = 0;
1267
+    unsigned long li, ri;
1268
+    do {
1269
+	while (i < lhs_len && j < rhs_len && lhs[i] == rhs[j] &&
1270
+	       !isdigit(lhs[i]) && !isdigit(rhs[j])) {
1271
+	    i++; j++;
1272
+	}
1273
+	if (i == lhs_len && j == rhs_len)
1274
+	    return 0;
1275
+	if (i == lhs_len)
1276
+	    return -1;
1277
+	if (j == rhs_len)
1278
+	    return 1;
1279
+	if (!isdigit(lhs[i]) || !isdigit(rhs[j]))
1280
+	    return lhs[i] < rhs[j] ? -1 : 1;
1281
+	while (isdigit(lhs[i]) && i < lhs_len)
1282
+	    li = 10*li + (lhs[i] - '0');
1283
+	while (isdigit(rhs[j]) && j < rhs_len)
1284
+	    ri = 10*ri + (rhs[j] - '0');
1285
+	if (li < ri)
1286
+	    return -1;
1287
+	if (li > ri)
1288
+	    return 1;
1289
+    } while (1);
1290
+}
1291
+
1292
+static int check_bits(uint32_t query, uint32_t value, uint8_t shift, uint8_t mask)
1293
+{
1294
+    uint8_t q = (query >> shift)&mask;
1295
+    uint8_t v = (value >> shift)&mask;
1296
+    /* q == mask -> ANY */
1297
+    if (q == v || q == mask)
1298
+	return 1;
1299
+    return 0;
1300
+}
1301
+
1302
+uint32_t cli_bcapi_check_platform(struct cli_bc_ctx *ctx , uint32_t a, uint32_t b , uint32_t c)
1303
+{
1304
+    unsigned ret =
1305
+	check_bits(a, ctx->env->platform_id_a, 24, 0xff) &&
1306
+	check_bits(a, ctx->env->platform_id_a, 20, 0xf) &&
1307
+	check_bits(a, ctx->env->platform_id_a, 16, 0xf) &&
1308
+	check_bits(a, ctx->env->platform_id_a, 8, 0xff) &&
1309
+	check_bits(a, ctx->env->platform_id_a, 0, 0xff) &&
1310
+	check_bits(b, ctx->env->platform_id_b, 28, 0xf) &&
1311
+	check_bits(b, ctx->env->platform_id_b, 24, 0xf) &&
1312
+	check_bits(b, ctx->env->platform_id_b, 16, 0xff) &&
1313
+	check_bits(b, ctx->env->platform_id_b, 8, 0xff) &&
1314
+	check_bits(b, ctx->env->platform_id_b, 0, 0xff) &&
1315
+	check_bits(c, ctx->env->platform_id_c, 24, 0xff) &&
1316
+	check_bits(c, ctx->env->platform_id_c, 16, 0xff) &&
1317
+	check_bits(c, ctx->env->platform_id_c, 8, 0xff) &&
1318
+	check_bits(c, ctx->env->platform_id_c, 0, 0xff);
1319
+    if (ret) {
1320
+	cli_dbgmsg("check_platform(0x%08x,0x%08x,0x%08x) = match\n",a,b,c);
1321
+    }
1322
+    return ret;
1323
+}
1324
+
... ...
@@ -33,6 +33,7 @@
33 33
 #include "bytecode_execs.h"
34 34
 #include "bytecode_pe.h"
35 35
 #include "bytecode_disasm.h"
36
+#include "bytecode_detect.h"
36 37
 #endif
37 38
 
38 39
 #ifndef __CLAMBC__
... ...
@@ -85,7 +86,6 @@ extern const uint32_t __clambc_filesize[1];
85 85
 /** Kind of the bytecode */
86 86
 const uint16_t __clambc_kind;
87 87
 /* ---------------- END GLOBALS --------------------------------------------- */
88
-
89 88
 /* ---------------- BEGIN 0.96 APIs (don't touch) --------------------------- */
90 89
 /** Test api. 
91 90
   @param a 0xf00dbeef
... ...
@@ -652,5 +652,52 @@ int32_t extract_set_container(uint32_t container);
652 652
 int32_t input_switch(int32_t extracted_file);
653 653
 
654 654
 /* ---------------- END 0.96.1 APIs ------------------------------------- */
655
+/* ---------------- BEGIN 0.96.2 APIs ----------------------------------- */
656
+
657
+uint32_t get_environment(struct cli_environment *env, uint32_t len);
658
+/** Disables the bytecode completely if condition is true.
659
+  Can only be called from the BC_STARTUP bytecode.
660
+  @param reason - why the bytecode had to be disabled
661
+  @param len - length of reason
662
+  @param cond - condition
663
+  @return 0 - auto mode
664
+          1 - JIT disabled
665
+          2 - fully disabled
666
+  */
667
+uint32_t disable_bytecode_if(const int8_t *reason, uint32_t len, uint32_t cond);
668
+
669
+/** Disables the JIT completely if condition is true.
670
+  Can only be called from the BC_STARTUP bytecode.
671
+  @param reason - why the JIT had to be disabled
672
+  @param len - length of reason
673
+  @param cond - condition
674
+  @return 0 - auto mode
675
+          1 - JIT disabled
676
+          2 - fully disabled
677
+  */
678
+uint32_t disable_jit_if(const int8_t* reason, uint32_t len, uint32_t cond);
679
+
680
+/** Compares two version numbers.
681
+  * @param[in] lhs - left hand side of comparison
682
+    @param lhs_len - length of \p lhs
683
+    @param[in] rhs - right hand side of comparison
684
+    @param rhs_len - length of \p rhs
685
+    @return -1 - lhs < rhs
686
+            0 - lhs == rhs
687
+            1 - lhs > rhs */
688
+int32_t version_compare(const uint8_t* lhs, uint32_t lhs_len,
689
+                    const uint8_t* rhs, uint32_t rhs_len);
690
+
691
+/** Disables the JIT if the platform id matches.
692
+  * 0xff can be used instead of a field to mark ANY.
693
+  * @param a -  os_category << 24 | arch << 20 | compiler << 16 | flevel << 8 | dconf
694
+    @param b -  big_endian << 28 | sizeof_ptr << 24 | cpp_version
695
+    @param c -  os_features << 24 | c_version
696
+    @return 0 - no match
697
+            1 - match */
698
+uint32_t check_platform(uint32_t a, uint32_t b, uint32_t c);
699
+
700
+
701
+/* ---------------- END 0.96.2 APIs   ----------------------------------- */
655 702
 #endif
656 703
 #endif
... ...
@@ -104,6 +104,11 @@ uint32_t cli_bcapi_engine_scan_options(struct cli_bc_ctx *ctx );
104 104
 uint32_t cli_bcapi_engine_db_options(struct cli_bc_ctx *ctx );
105 105
 int32_t cli_bcapi_extract_set_container(struct cli_bc_ctx *ctx , uint32_t);
106 106
 int32_t cli_bcapi_input_switch(struct cli_bc_ctx *ctx , int32_t);
107
+uint32_t cli_bcapi_get_environment(struct cli_bc_ctx *ctx , struct cli_environment*, uint32_t);
108
+uint32_t cli_bcapi_disable_bytecode_if(struct cli_bc_ctx *ctx , const int8_t*, uint32_t, uint32_t);
109
+uint32_t cli_bcapi_disable_jit_if(struct cli_bc_ctx *ctx , const int8_t*, uint32_t, uint32_t);
110
+int32_t cli_bcapi_version_compare(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t, const uint8_t*, uint32_t);
111
+uint32_t cli_bcapi_check_platform(struct cli_bc_ctx *ctx , uint32_t, uint32_t, uint32_t);
107 112
 
108 113
 const struct cli_apiglobal cli_globals[] = {
109 114
 /* Bytecode globals BEGIN */
... ...
@@ -128,25 +133,29 @@ static uint16_t cli_tmp4[]={16, 8, 8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16
128 128
 static uint16_t cli_tmp5[]={32, 16, 16, 32, 32, 32, 16, 16};
129 129
 static uint16_t cli_tmp6[]={32};
130 130
 static uint16_t cli_tmp7[]={32};
131
-static uint16_t cli_tmp8[]={32, 32};
132
-static uint16_t cli_tmp9[]={32};
131
+static uint16_t cli_tmp8[]={32, 32, 32, 32};
132
+static uint16_t cli_tmp9[]={32, 65, 32, 65, 32};
133 133
 static uint16_t cli_tmp10[]={32, 65, 32, 32};
134
-static uint16_t cli_tmp11[]={65, 32, 32};
135
-static uint16_t cli_tmp12[]={32, 32, 32};
136
-static uint16_t cli_tmp13[]={32, 65, 32};
137
-static uint16_t cli_tmp14[]={32, 65, 32, 65, 32};
138
-static uint16_t cli_tmp15[]={32, 32, 32, 32};
139
-static uint16_t cli_tmp16[]={32, 65, 32, 32, 32, 32};
140
-static uint16_t cli_tmp17[]={32, 87, 32};
141
-static uint16_t cli_tmp18[]={88};
142
-static uint16_t cli_tmp19[]={32, 32, 32, 32, 32, 32, 32, 32, 32};
143
-static uint16_t cli_tmp20[]={65, 32};
134
+static uint16_t cli_tmp11[]={32, 81, 32};
135
+static uint16_t cli_tmp12[]={82};
136
+static uint16_t cli_tmp13[]={32, 32, 32, 32, 32, 32, 32, 83, 83, 83, 83, 83, 83, 83, 8, 8, 8, 8, 8, 8, 8, 8, 8};
137
+static uint16_t cli_tmp14[]={8};
138
+static uint16_t cli_tmp15[]={32, 32};
139
+static uint16_t cli_tmp16[]={32};
140
+static uint16_t cli_tmp17[]={65, 32, 32};
141
+static uint16_t cli_tmp18[]={32, 32, 32};
142
+static uint16_t cli_tmp19[]={32, 65, 32};
143
+static uint16_t cli_tmp20[]={32, 65, 32, 32, 32, 32};
144 144
 static uint16_t cli_tmp21[]={32, 91, 32};
145 145
 static uint16_t cli_tmp22[]={92};
146
-static uint16_t cli_tmp23[]={16, 8, 8, 8, 94, 93};
147
-static uint16_t cli_tmp24[]={8};
148
-static uint16_t cli_tmp25[]={95};
149
-static uint16_t cli_tmp26[]={8};
146
+static uint16_t cli_tmp23[]={32, 32, 32, 32, 32, 32, 32, 32, 32};
147
+static uint16_t cli_tmp24[]={65, 32};
148
+static uint16_t cli_tmp25[]={32, 95, 32};
149
+static uint16_t cli_tmp26[]={96};
150
+static uint16_t cli_tmp27[]={16, 8, 8, 8, 98, 97};
151
+static uint16_t cli_tmp28[]={8};
152
+static uint16_t cli_tmp29[]={99};
153
+static uint16_t cli_tmp30[]={8};
150 154
 
151 155
 const struct cli_bc_type cli_apicall_types[]={
152 156
 	{DStructType, cli_tmp0, 13, 0, 0},
... ...
@@ -157,101 +166,110 @@ const struct cli_bc_type cli_apicall_types[]={
157 157
 	{DStructType, cli_tmp5, 8, 0, 0},
158 158
 	{DArrayType, cli_tmp6, 1, 0, 0},
159 159
 	{DArrayType, cli_tmp7, 64, 0, 0},
160
-	{DFunctionType, cli_tmp8, 2, 0, 0},
161
-	{DFunctionType, cli_tmp9, 1, 0, 0},
160
+	{DFunctionType, cli_tmp8, 4, 0, 0},
161
+	{DFunctionType, cli_tmp9, 5, 0, 0},
162 162
 	{DFunctionType, cli_tmp10, 4, 0, 0},
163 163
 	{DFunctionType, cli_tmp11, 3, 0, 0},
164
-	{DFunctionType, cli_tmp12, 3, 0, 0},
165
-	{DFunctionType, cli_tmp13, 3, 0, 0},
166
-	{DFunctionType, cli_tmp14, 5, 0, 0},
167
-	{DFunctionType, cli_tmp15, 4, 0, 0},
168
-	{DFunctionType, cli_tmp16, 6, 0, 0},
164
+	{DPointerType, cli_tmp12, 1, 0, 0},
165
+	{DStructType, cli_tmp13, 23, 0, 0},
166
+	{DArrayType, cli_tmp14, 65, 0, 0},
167
+	{DFunctionType, cli_tmp15, 2, 0, 0},
168
+	{DFunctionType, cli_tmp16, 1, 0, 0},
169 169
 	{DFunctionType, cli_tmp17, 3, 0, 0},
170
-	{DPointerType, cli_tmp18, 1, 0, 0},
171
-	{DStructType, cli_tmp19, 9, 0, 0},
172
-	{DFunctionType, cli_tmp20, 2, 0, 0},
170
+	{DFunctionType, cli_tmp18, 3, 0, 0},
171
+	{DFunctionType, cli_tmp19, 3, 0, 0},
172
+	{DFunctionType, cli_tmp20, 6, 0, 0},
173 173
 	{DFunctionType, cli_tmp21, 3, 0, 0},
174 174
 	{DPointerType, cli_tmp22, 1, 0, 0},
175
-	{DStructType, cli_tmp23, 6, 0, 0},
176
-	{DArrayType, cli_tmp24, 29, 0, 0},
177
-	{DArrayType, cli_tmp25, 3, 0, 0},
178
-	{DArrayType, cli_tmp26, 10, 0, 0}
175
+	{DStructType, cli_tmp23, 9, 0, 0},
176
+	{DFunctionType, cli_tmp24, 2, 0, 0},
177
+	{DFunctionType, cli_tmp25, 3, 0, 0},
178
+	{DPointerType, cli_tmp26, 1, 0, 0},
179
+	{DStructType, cli_tmp27, 6, 0, 0},
180
+	{DArrayType, cli_tmp28, 29, 0, 0},
181
+	{DArrayType, cli_tmp29, 3, 0, 0},
182
+	{DArrayType, cli_tmp30, 10, 0, 0}
179 183
 };
180 184
 
181 185
 const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
182 186
 const struct cli_apicall cli_apicalls[]={
183 187
 /* Bytecode APIcalls BEGIN */
184
-	{"test1", 12, 0, 0},
185
-	{"read", 13, 0, 1},
186
-	{"write", 13, 1, 1},
187
-	{"seek", 12, 1, 0},
188
-	{"setvirusname", 13, 2, 1},
189
-	{"debug_print_str", 13, 3, 1},
190
-	{"debug_print_uint", 8, 0, 2},
191
-	{"disasm_x86", 21, 4, 1},
192
-	{"trace_directory", 13, 5, 1},
193
-	{"trace_scope", 13, 6, 1},
194
-	{"trace_source", 13, 7, 1},
195
-	{"trace_op", 13, 8, 1},
196
-	{"trace_value", 13, 9, 1},
197
-	{"trace_ptr", 13, 10, 1},
198
-	{"pe_rawaddr", 8, 1, 2},
199
-	{"file_find", 13, 11, 1},
200
-	{"file_byteat", 8, 2, 2},
201
-	{"malloc", 20, 0, 3},
202
-	{"test2", 8, 3, 2},
203
-	{"get_pe_section", 17, 12, 1},
204
-	{"fill_buffer", 16, 0, 4},
205
-	{"extract_new", 8, 4, 2},
206
-	{"read_number", 8, 5, 2},
207
-	{"hashset_new", 9, 0, 5},
208
-	{"hashset_add", 12, 2, 0},
209
-	{"hashset_remove", 12, 3, 0},
210
-	{"hashset_contains", 12, 4, 0},
211
-	{"hashset_done", 8, 6, 2},
212
-	{"hashset_empty", 8, 7, 2},
213
-	{"buffer_pipe_new", 8, 8, 2},
214
-	{"buffer_pipe_new_fromfile", 8, 9, 2},
215
-	{"buffer_pipe_read_avail", 8, 10, 2},
216
-	{"buffer_pipe_read_get", 11, 0, 6},
217
-	{"buffer_pipe_read_stopped", 12, 5, 0},
218
-	{"buffer_pipe_write_avail", 8, 11, 2},
219
-	{"buffer_pipe_write_get", 11, 1, 6},
220
-	{"buffer_pipe_write_stopped", 12, 6, 0},
221
-	{"buffer_pipe_done", 8, 12, 2},
222
-	{"inflate_init", 15, 0, 7},
223
-	{"inflate_process", 8, 13, 2},
224
-	{"inflate_done", 8, 14, 2},
225
-	{"bytecode_rt_error", 8, 15, 2},
226
-	{"jsnorm_init", 8, 16, 2},
227
-	{"jsnorm_process", 8, 17, 2},
228
-	{"jsnorm_done", 8, 18, 2},
229
-	{"ilog2", 12, 7, 0},
230
-	{"ipow", 15, 1, 7},
231
-	{"iexp", 15, 2, 7},
232
-	{"isin", 15, 3, 7},
233
-	{"icos", 15, 4, 7},
234
-	{"memstr", 14, 0, 8},
235
-	{"hex2ui", 12, 8, 0},
236
-	{"atoi", 13, 13, 1},
237
-	{"debug_print_str_start", 13, 14, 1},
238
-	{"debug_print_str_nonl", 13, 15, 1},
239
-	{"entropy_buffer", 13, 16, 1},
240
-	{"map_new", 12, 9, 0},
188
+	{"test1", 18, 0, 0},
189
+	{"read", 19, 0, 1},
190
+	{"write", 19, 1, 1},
191
+	{"seek", 18, 1, 0},
192
+	{"setvirusname", 19, 2, 1},
193
+	{"debug_print_str", 19, 3, 1},
194
+	{"debug_print_uint", 15, 0, 2},
195
+	{"disasm_x86", 25, 4, 1},
196
+	{"trace_directory", 19, 5, 1},
197
+	{"trace_scope", 19, 6, 1},
198
+	{"trace_source", 19, 7, 1},
199
+	{"trace_op", 19, 8, 1},
200
+	{"trace_value", 19, 9, 1},
201
+	{"trace_ptr", 19, 10, 1},
202
+	{"pe_rawaddr", 15, 1, 2},
203
+	{"file_find", 19, 11, 1},
204
+	{"file_byteat", 15, 2, 2},
205
+	{"malloc", 24, 0, 3},
206
+	{"test2", 15, 3, 2},
207
+	{"get_pe_section", 21, 12, 1},
208
+	{"fill_buffer", 20, 0, 4},
209
+	{"extract_new", 15, 4, 2},
210
+	{"read_number", 15, 5, 2},
211
+	{"hashset_new", 16, 0, 5},
212
+	{"hashset_add", 18, 2, 0},
213
+	{"hashset_remove", 18, 3, 0},
214
+	{"hashset_contains", 18, 4, 0},
215
+	{"hashset_done", 15, 6, 2},
216
+	{"hashset_empty", 15, 7, 2},
217
+	{"buffer_pipe_new", 15, 8, 2},
218
+	{"buffer_pipe_new_fromfile", 15, 9, 2},
219
+	{"buffer_pipe_read_avail", 15, 10, 2},
220
+	{"buffer_pipe_read_get", 17, 0, 6},
221
+	{"buffer_pipe_read_stopped", 18, 5, 0},
222
+	{"buffer_pipe_write_avail", 15, 11, 2},
223
+	{"buffer_pipe_write_get", 17, 1, 6},
224
+	{"buffer_pipe_write_stopped", 18, 6, 0},
225
+	{"buffer_pipe_done", 15, 12, 2},
226
+	{"inflate_init", 8, 0, 7},
227
+	{"inflate_process", 15, 13, 2},
228
+	{"inflate_done", 15, 14, 2},
229
+	{"bytecode_rt_error", 15, 15, 2},
230
+	{"jsnorm_init", 15, 16, 2},
231
+	{"jsnorm_process", 15, 17, 2},
232
+	{"jsnorm_done", 15, 18, 2},
233
+	{"ilog2", 18, 7, 0},
234
+	{"ipow", 8, 1, 7},
235
+	{"iexp", 8, 2, 7},
236
+	{"isin", 8, 3, 7},
237
+	{"icos", 8, 4, 7},
238
+	{"memstr", 9, 0, 8},
239
+	{"hex2ui", 18, 8, 0},
240
+	{"atoi", 19, 13, 1},
241
+	{"debug_print_str_start", 19, 14, 1},
242
+	{"debug_print_str_nonl", 19, 15, 1},
243
+	{"entropy_buffer", 19, 16, 1},
244
+	{"map_new", 18, 9, 0},
241 245
 	{"map_addkey", 10, 0, 9},
242 246
 	{"map_setvalue", 10, 1, 9},
243 247
 	{"map_remove", 10, 2, 9},
244 248
 	{"map_find", 10, 3, 9},
245
-	{"map_getvaluesize", 8, 19, 2},
246
-	{"map_getvalue", 11, 2, 6},
247
-	{"map_done", 8, 20, 2},
249
+	{"map_getvaluesize", 15, 19, 2},
250
+	{"map_getvalue", 17, 2, 6},
251
+	{"map_done", 15, 20, 2},
248 252
 	{"file_find_limit", 10, 4, 9},
249
-	{"engine_functionality_level", 9, 1, 5},
250
-	{"engine_dconf_level", 9, 2, 5},
251
-	{"engine_scan_options", 9, 3, 5},
252
-	{"engine_db_options", 9, 4, 5},
253
-	{"extract_set_container", 8, 21, 2},
254
-	{"input_switch", 8, 22, 2}
253
+	{"engine_functionality_level", 16, 1, 5},
254
+	{"engine_dconf_level", 16, 2, 5},
255
+	{"engine_scan_options", 16, 3, 5},
256
+	{"engine_db_options", 16, 4, 5},
257
+	{"extract_set_container", 15, 21, 2},
258
+	{"input_switch", 15, 22, 2},
259
+	{"get_environment", 11, 17, 1},
260
+	{"disable_bytecode_if", 10, 5, 9},
261
+	{"disable_jit_if", 10, 6, 9},
262
+	{"version_compare", 9, 1, 8},
263
+	{"check_platform", 8, 5, 7}
255 264
 /* Bytecode APIcalls END */
256 265
 };
257 266
 const cli_apicall_int2 cli_apicalls0[] = {
... ...
@@ -283,7 +301,8 @@ const cli_apicall_pointer cli_apicalls1[] = {
283 283
 	(cli_apicall_pointer)cli_bcapi_atoi,
284 284
 	(cli_apicall_pointer)cli_bcapi_debug_print_str_start,
285 285
 	(cli_apicall_pointer)cli_bcapi_debug_print_str_nonl,
286
-	(cli_apicall_pointer)cli_bcapi_entropy_buffer
286
+	(cli_apicall_pointer)cli_bcapi_entropy_buffer,
287
+	(cli_apicall_pointer)cli_bcapi_get_environment
287 288
 };
288 289
 const cli_apicall_int1 cli_apicalls2[] = {
289 290
 	(cli_apicall_int1)cli_bcapi_debug_print_uint,
... ...
@@ -333,16 +352,20 @@ const cli_apicall_int3 cli_apicalls7[] = {
333 333
 	(cli_apicall_int3)cli_bcapi_ipow,
334 334
 	(cli_apicall_int3)cli_bcapi_iexp,
335 335
 	(cli_apicall_int3)cli_bcapi_isin,
336
-	(cli_apicall_int3)cli_bcapi_icos
336
+	(cli_apicall_int3)cli_bcapi_icos,
337
+	(cli_apicall_int3)cli_bcapi_check_platform
337 338
 };
338 339
 const cli_apicall_2bufs cli_apicalls8[] = {
339
-	(cli_apicall_2bufs)cli_bcapi_memstr
340
+	(cli_apicall_2bufs)cli_bcapi_memstr,
341
+	(cli_apicall_2bufs)cli_bcapi_version_compare
340 342
 };
341 343
 const cli_apicall_ptrbufid cli_apicalls9[] = {
342 344
 	(cli_apicall_ptrbufid)cli_bcapi_map_addkey,
343 345
 	(cli_apicall_ptrbufid)cli_bcapi_map_setvalue,
344 346
 	(cli_apicall_ptrbufid)cli_bcapi_map_remove,
345 347
 	(cli_apicall_ptrbufid)cli_bcapi_map_find,
346
-	(cli_apicall_ptrbufid)cli_bcapi_file_find_limit
348
+	(cli_apicall_ptrbufid)cli_bcapi_file_find_limit,
349
+	(cli_apicall_ptrbufid)cli_bcapi_disable_bytecode_if,
350
+	(cli_apicall_ptrbufid)cli_bcapi_disable_jit_if
347 351
 };
348 352
 const unsigned cli_apicall_maxapi = sizeof(cli_apicalls)/sizeof(cli_apicalls[0]);
... ...
@@ -30,6 +30,7 @@
30 30
 #define BYTECODE_API_IMPL_H
31 31
 
32 32
 struct cli_bc_bctx;
33
+struct cli_environment;
33 34
 uint32_t cli_bcapi_test1(struct cli_bc_ctx *ctx , uint32_t, uint32_t);
34 35
 int32_t cli_bcapi_read(struct cli_bc_ctx *ctx , uint8_t*, int32_t);
35 36
 int32_t cli_bcapi_write(struct cli_bc_ctx *ctx , uint8_t*, int32_t);
... ...
@@ -101,5 +102,10 @@ uint32_t cli_bcapi_engine_scan_options(struct cli_bc_ctx *ctx );
101 101
 uint32_t cli_bcapi_engine_db_options(struct cli_bc_ctx *ctx );
102 102
 int32_t cli_bcapi_extract_set_container(struct cli_bc_ctx *ctx , uint32_t);
103 103
 int32_t cli_bcapi_input_switch(struct cli_bc_ctx *ctx , int32_t);
104
+uint32_t cli_bcapi_get_environment(struct cli_bc_ctx *ctx , struct cli_environment*, uint32_t);
105
+uint32_t cli_bcapi_disable_bytecode_if(struct cli_bc_ctx *ctx , const int8_t*, uint32_t, uint32_t);
106
+uint32_t cli_bcapi_disable_jit_if(struct cli_bc_ctx *ctx , const int8_t*, uint32_t, uint32_t);
107
+int32_t cli_bcapi_version_compare(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t, const uint8_t*, uint32_t);
108
+uint32_t cli_bcapi_check_platform(struct cli_bc_ctx *ctx , uint32_t, uint32_t, uint32_t);
104 109
 
105 110
 #endif