+2009-03-24 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * gen-md-tests.c: Add stream-header and cli-metadata
+ helpers.
+
+ * cli-metadata-tests.md: New tests for the cli metadata header
+ and streams.
+
+ * Makefile: Add new tests.
+
2009-03-19 Rodrigo Kumpera <rkumpera@novell.com>
* cli-header-tests.md: More tests for the cli header.
./gen-md-tests cli-header-tests.md
touch cli-header-tests.ok
-generate-stamp: header-tests.ok section-table-tests.ok data-directory-tests.ok resources-tests.ok cli-header-tests.ok
+cli-metadata-tests.ok: gen-md-tests cli-metadata-tests.md simple-assembly.exe
+ ./gen-md-tests cli-metadata-tests.md
+ touch cli-metadata-tests.ok
+
+generate-stamp: header-tests.ok section-table-tests.ok data-directory-tests.ok resources-tests.ok cli-header-tests.ok cli-metadata-tests.ok
touch generate-stamp
clean-stamps:
--- /dev/null
+cli-metadata-root {
+ assembly simple-assembly.exe
+
+ #signature
+ valid offset translate.rva.ind ( cli-header + 8 ) set-uint 0x424A5342
+ valid offset cli-metadata + 0 set-uint 0x424A5342
+
+ invalid offset cli-metadata + 0 set-uint 0x434A5342
+ invalid offset cli-metadata + 0 set-uint 0x42455342
+ invalid offset cli-metadata + 0 set-uint 0x424A0342
+ invalid offset cli-metadata + 0 set-uint 0x424A5332
+
+ #we don't care about major/minor versions no runtime cares about them
+
+ #size too small
+ invalid offset cli-header + 12 set-uint 15
+ invalid offset cli-header + 12 set-uint 20
+ invalid offset cli-header + 12 set-uint 30
+
+ #version name is irrelevant as well
+
+ #the stream must have exactly 5 streams
+ valid offset cli-metadata + 16 + read.uint ( cli-metadata + 12 ) + 2 set-ushort 5
+ invalid offset cli-metadata + 16 + read.uint ( cli-metadata + 12 ) + 2 set-ushort 4
+}
+
+cli-metadata-stream-headers {
+ assembly simple-assembly.exe
+ #simple-assembly has version v2.0.50727 so the heade takes 32 bytes
+
+ #just to make sure
+ valid offset cli-metadata + 32 set-uint 0x6c
+ valid offset stream-header ( 0 ) + 0 set-uint 0x6c
+
+ #size too small
+ invalid offset cli-header + 12 set-uint 34
+ invalid offset cli-header + 12 set-uint 39
+
+
+ #offset doesn't bounds check
+ invalid offset stream-header ( 0 ) + 0 set-uint 0x888888
+ invalid offset stream-header ( 1 ) + 0 set-uint 0x888888
+ invalid offset stream-header ( 2 ) + 0 set-uint 0x888888
+ invalid offset stream-header ( 3 ) + 0 set-uint 0x888888
+ invalid offset stream-header ( 4 ) + 0 set-uint 0x888888
+
+ #size doesn't bounds check
+ invalid offset stream-header ( 0 ) + 4 set-uint 0x888888
+ invalid offset stream-header ( 1 ) + 4 set-uint 0x888888
+ invalid offset stream-header ( 2 ) + 4 set-uint 0x888888
+ invalid offset stream-header ( 3 ) + 4 set-uint 0x888888
+ invalid offset stream-header ( 4 ) + 4 set-uint 0x888888
+
+ #unkwnown name
+ invalid offset stream-header ( 0 ) + 8 set-byte 0x42
+
+ #duplicate name, change #~ to #US
+ invalid offset stream-header ( 0 ) + 9 set-byte 0x55 , offset stream-header ( 0 ) + 10 set-byte 0x53
+}
\ No newline at end of file
fun_name:
read.uint |
translate.rva |
- translate.rva.ind
+ translate.rva.ind |
+ stream-header
arg_list:
expression |
pe-optional-header |
pe-signature |
section-table |
- cli-header
+ cli-header |
+ cli-metadata
TODO For the sake of a simple implementation, tokens are space delimited.
*/
exit (INVALID_RVA);
}
+static guint32
+get_cli_header (test_entry_t *entry)
+{
+ guint32 offset = get_pe_header (entry) + 20; /*pe-optional-header*/
+ offset += 208; /*cli header entry offset in the pe-optional-header*/
+ return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
+}
+
+static guint32
+get_cli_metadata_root (test_entry_t *entry)
+{
+ guint32 offset = get_cli_header (entry);
+ offset += 8; /*metadata rva offset*/
+ return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
+}
+
+static guint32
+pad4 (guint32 offset)
+{
+ if (offset % 4)
+ offset += 4 - (offset % 4);
+ return offset;
+}
+
static guint32
lookup_var (test_entry_t *entry, const char *name)
{
return get_pe_header (entry) + 20;
if (!strcmp ("section-table", name))
return get_pe_header (entry) + 244;
- if (!strcmp ("cli-header", name)) {
- guint32 offset = get_pe_header (entry) + 20; /*pe-optional-header*/
- offset += 208; /*cli header entry offset in the pe-optional-header*/
-
- return translate_rva (entry, READ_VAR (guint32, entry->data + offset));
- }
+ if (!strcmp ("cli-header", name))
+ return get_cli_header (entry);
+ if (!strcmp ("cli-metadata", name))
+ return get_cli_metadata_root (entry);
printf ("Unknown variable in expression %s\n", name);
exit (INVALID_VARIABLE_NAME);
rva = READ_VAR (guint32, entry->data + rva);
return translate_rva (entry, rva);
}
+ if (!strcmp ("stream-header", name)) {
+ guint32 idx, offset;
+ if (g_slist_length (args) != 1) {
+ printf ("Invalid number of args to translate.rva %d\b", g_slist_length (args));
+ exit (INVALID_ARG_COUNT);
+ }
+ idx = expression_eval (args->data, entry);
+ offset = get_cli_metadata_root (entry);
+ offset = pad4 (offset + 16 + READ_VAR (guint32, entry->data + offset + 12));
+
+ offset += 4;
+
+ while (idx--) {
+ int i;
+
+ offset += 8;
+ for (i = 0; i < 32; ++i) {
+ if (!READ_VAR (guint8, entry->data + offset))
+ break;
+ }
+ offset = pad4 (offset);
+ }
+ return offset;
+ }
printf ("Unknown function %s\n", name);
exit (INVALID_FUNCTION_NAME);