Browse code

file_find, file_byteat bytecode APIs.

Török Edvin authored on 2010/01/20 23:19:18
Showing 4 changed files
... ...
@@ -30,6 +30,7 @@
30 30
 #include <stdlib.h>
31 31
 #include <fcntl.h>
32 32
 #include <errno.h>
33
+#include <string.h>
33 34
 #include "cltypes.h"
34 35
 #include "clambc.h"
35 36
 #include "bytecode.h"
... ...
@@ -252,3 +253,60 @@ uint32_t cli_bcapi_pe_rawaddr(struct cli_bc_ctx *ctx, uint32_t rva, uint32_t dum
252 252
     return PE_INVALID_RVA;
253 253
   return ret;
254 254
 }
255
+
256
+static inline const char* cli_memmem(const char *haystack, unsigned hlen,
257
+				     const unsigned char *needle, unsigned nlen)
258
+{
259
+    const char *p;
260
+    unsigned char c;
261
+    if (!needle || !haystack)
262
+	return NULL;
263
+    c = *needle++;
264
+    if (nlen == 1)
265
+	return memchr(haystack, c, hlen);
266
+
267
+    while (hlen >= nlen) {
268
+	p = haystack;
269
+	haystack = memchr(haystack, c, hlen - nlen + 1);
270
+	if (!haystack)
271
+	    return NULL;
272
+	p = haystack + 1;
273
+	if (!memcmp(p, needle, nlen-1))
274
+	    return haystack;
275
+	hlen -= p - haystack;
276
+	haystack = p;
277
+    }
278
+    return NULL;
279
+}
280
+
281
+int32_t cli_bcapi_file_find(struct cli_bc_ctx *ctx, const uint8_t* data, uint32_t len)
282
+{
283
+    char buf[4096];
284
+    fmap_t *map = ctx->fmap;
285
+    uint32_t off = ctx->off, newoff;
286
+    int n;
287
+
288
+    if (!map || len > sizeof(buf)/4 || len <= 0)
289
+	return -1;
290
+    for (;;) {
291
+	const char *p;
292
+	n = fmap_readn(map, buf, off, sizeof(buf));
293
+	if ((unsigned)n < len)
294
+	    return -1;
295
+	p = cli_memmem(buf, n, data, len);
296
+	if (p)
297
+	    return off + p - buf;
298
+	off += n-len;
299
+    }
300
+    return -1;
301
+}
302
+
303
+int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx, uint32_t off, uint32_t dummy)
304
+{
305
+    unsigned char c;
306
+    if (!ctx->fmap)
307
+	return -1;
308
+    if (fmap_readn(ctx->fmap, &c, off, 1) != 1)
309
+	return -1;
310
+    return c;
311
+}
... ...
@@ -178,5 +178,17 @@ uint32_t trace_ptr(const uint8_t* ptr, uint32_t dummy);
178 178
   */
179 179
 uint32_t pe_rawaddr(uint32_t rva, uint32_t dummy);
180 180
 
181
+/** Looks for the specified sequence of bytes in the current file.
182
+  * @param[in] data the sequence of bytes to look for
183
+  * @param len length of \p data, cannot be more than 1024
184
+  * @return offset in the current file if match is found, -1 otherwise */
185
+int32_t file_find(const uint8_t* data, uint32_t len); 
186
+
187
+/** Read a single byte from current file
188
+  * @param offset file offset
189
+  * @return byte at offset \p off in the current file, or -1 if offset is
190
+  * invalid */
191
+int32_t file_byteat(uint32_t offset, uint32_t dummy);
192
+
181 193
 #endif
182 194
 #endif
... ...
@@ -49,6 +49,8 @@ uint32_t cli_bcapi_trace_op(struct cli_bc_ctx *ctx, const const uint8_t*, uint32
49 49
 uint32_t cli_bcapi_trace_value(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t);
50 50
 uint32_t cli_bcapi_trace_ptr(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t);
51 51
 uint32_t cli_bcapi_pe_rawaddr(struct cli_bc_ctx *ctx, uint32_t, uint32_t);
52
+int32_t cli_bcapi_file_find(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t);
53
+int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx, uint32_t, uint32_t);
52 54
 
53 55
 const struct cli_apiglobal cli_globals[] = {
54 56
 /* Bytecode globals BEGIN */
... ...
@@ -141,14 +143,17 @@ const struct cli_apicall cli_apicalls[]={
141 141
 	{"trace_op", 17, 9, 1},
142 142
 	{"trace_value", 17, 10, 1},
143 143
 	{"trace_ptr", 17, 11, 1},
144
-	{"pe_rawaddr", 16, 3, 0}
144
+	{"pe_rawaddr", 16, 3, 0},
145
+	{"file_find", 17, 12, 1},
146
+	{"file_byteat", 16, 4, 0}
145 147
 /* Bytecode APIcalls END */
146 148
 };
147 149
 const cli_apicall_int2 cli_apicalls0[] = {
148 150
 	(cli_apicall_int2)cli_bcapi_test1,
149 151
 	(cli_apicall_int2)cli_bcapi_seek,
150 152
 	(cli_apicall_int2)cli_bcapi_debug_print_uint,
151
-	(cli_apicall_int2)cli_bcapi_pe_rawaddr
153
+	(cli_apicall_int2)cli_bcapi_pe_rawaddr,
154
+	(cli_apicall_int2)cli_bcapi_file_byteat
152 155
 };
153 156
 const cli_apicall_pointer cli_apicalls1[] = {
154 157
 	(cli_apicall_pointer)cli_bcapi_test0,
... ...
@@ -162,6 +167,7 @@ const cli_apicall_pointer cli_apicalls1[] = {
162 162
 	(cli_apicall_pointer)cli_bcapi_trace_source,
163 163
 	(cli_apicall_pointer)cli_bcapi_trace_op,
164 164
 	(cli_apicall_pointer)cli_bcapi_trace_value,
165
-	(cli_apicall_pointer)cli_bcapi_trace_ptr
165
+	(cli_apicall_pointer)cli_bcapi_trace_ptr,
166
+	(cli_apicall_pointer)cli_bcapi_file_find
166 167
 };
167 168
 const unsigned cli_apicall_maxapi = sizeof(cli_apicalls)/sizeof(cli_apicalls[0]);
... ...
@@ -46,5 +46,7 @@ uint32_t cli_bcapi_trace_op(struct cli_bc_ctx *ctx, const const uint8_t*, uint32
46 46
 uint32_t cli_bcapi_trace_value(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t);
47 47
 uint32_t cli_bcapi_trace_ptr(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t);
48 48
 uint32_t cli_bcapi_pe_rawaddr(struct cli_bc_ctx *ctx, uint32_t, uint32_t);
49
+int32_t cli_bcapi_file_find(struct cli_bc_ctx *ctx, const const uint8_t*, uint32_t);
50
+int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx, uint32_t, uint32_t);
49 51
 
50 52
 #endif