about summary refs log tree commit diff stats
path: root/test/expr_type
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2017-08-06 01:27:00 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2017-08-08 09:25:57 +0200
commit4405b72e1a7fe5e4d20c67091f5a039bec01c42e (patch)
tree0c10c8661b0ab5d0fa654b89d44ecb479fba9dc5 /test/expr_type
parent4b200beb1bda68ee94844a81bd9d618da634f8e9 (diff)
downloadfocaccia-miasm-4405b72e1a7fe5e4d20c67091f5a039bec01c42e.tar.gz
focaccia-miasm-4405b72e1a7fe5e4d20c67091f5a039bec01c42e.zip
Objc: add regression test
Diffstat (limited to 'test/expr_type')
-rw-r--r--test/expr_type/test_chandler.py550
1 files changed, 550 insertions, 0 deletions
diff --git a/test/expr_type/test_chandler.py b/test/expr_type/test_chandler.py
new file mode 100644
index 00000000..2fa3f979
--- /dev/null
+++ b/test/expr_type/test_chandler.py
@@ -0,0 +1,550 @@
+"""
+Regression test for objc
+* ast parsed C to C Miasm expression
+* C Miasm expression to native expression
+* Miasm expression to type
+"""
+
+from miasm2.expression.expression import ExprInt, ExprId, ExprMem
+from miasm2.expression.simplifications import expr_simp
+
+from miasm2.core.objc import parse_access
+from miasm2.core.objc import ast_get_c_access_expr
+from miasm2.core.objc import ExprCToExpr, ExprToAccessC, CHandler
+
+
+from miasm2.core.ctypesmngr import CTypeStruct, CTypeUnion, CAstTypes, CTypePtr, CTypeId
+from miasm2.core.objc import CTypesManagerNotPacked
+
+from miasm2.arch.x86.ctype import CTypeAMD64_unk
+
+
+text_1 = """
+# 1 "test.h"
+typedef enum {
+    TMP0,
+    TMP1,
+    TMP2,
+    TMP3,
+} MyEnum;
+
+
+typedef struct mini_st {
+        int x;
+        int y;
+        short z;
+} Mini;
+
+typedef union mini_un {
+        int x;
+        int y;
+        short z;
+} MiniUnion;
+
+typedef unsigned char block[8];
+
+typedef struct mini_st mini_st_struct;
+
+typedef mini_st_struct mini_st_struct2;
+
+
+typedef struct test_st {
+        int a;
+        int b;
+        int** ptr;
+        short tab1[4*sizeof(int)];
+        short* tab2[2*2+4*4-16/4];
+        int* xptr;
+        int tab3[0x10][0x20];
+
+        Mini f_mini;
+
+        Mini minitab[0x10];
+
+        Mini *minitabptr[0x10];
+        int (*(tab4[0x20]))[0x10];
+        MyEnum myenum;
+        block chunk;
+
+        union testU{
+            int  myint;
+            char mychars[4];
+        } myunion;
+
+        union testV{
+            int  myint;
+            char mychars[4];
+            struct tutu {
+                int a;
+                unsigned int b;
+            } mystruct_x;
+        } myunion_x;
+
+
+        union testW{
+            union testX{
+                int a;
+                unsigned int b;
+                char c;
+            } u0;
+            union testX{
+                int a;
+                char b;
+            } u1;
+        } myunion_y;
+
+        union {
+            int a1;
+        };
+        struct {
+            int a2;
+        };
+
+        Mini (*(tab5[0x20]))[0x10];
+        int *tab6[4][4][4][4];
+
+} Test;
+
+typedef int (*func)(int, char);
+
+typedef func (  *(xxx[5])  )[4];
+
+typedef union char_int_st {
+    char a;
+    int b;
+} Char_int;
+
+typedef int array1[4];
+typedef int array2[4];
+typedef unsigned int array3[4];
+typedef Char_int array4[4];
+
+typedef char dummy[((sizeof(char)<<3) >> 1)*4/2 - 1 + 2];
+
+struct recurse {
+        struct recurse* next;
+        int a;
+};
+
+int strlen(const char *s);
+    """
+
+text_2 = """
+struct test_context {
+        int a;
+        struct test_st test;
+        int b;
+};
+
+"""
+base_types = CTypeAMD64_unk()
+types_ast = CAstTypes()
+
+# Add C types definition
+types_ast.add_c_decl(text_1)
+types_ast.add_c_decl(text_2)
+
+
+types_mngr = CTypesManagerNotPacked(types_ast, base_types)
+
+for type_id, type_desc in types_mngr.types_ast._types.iteritems():
+    print type_id
+    obj = types_mngr.get_objc(type_id)
+    print obj
+    print repr(obj)
+    types_mngr.check_objc(obj)
+
+for type_id, type_desc in types_mngr.types_ast._typedefs.iteritems():
+    print type_id
+    obj = types_mngr.get_objc(type_id)
+    print obj
+    print repr(obj)
+    types_mngr.check_objc(obj)
+
+void_ptr = types_mngr.void_ptr
+
+obj_dummy = types_mngr.get_objc(CTypeId("dummy"))
+obj_int = types_mngr.get_objc(CTypeId("int"))
+obj_uint = types_mngr.get_objc(CTypeId("unsigned", "int"))
+obj_long = types_mngr.get_objc(CTypeId("long"))
+obj_array1 = types_mngr.get_objc(CTypeId("array1"))
+obj_array2 = types_mngr.get_objc(CTypeId("array2"))
+obj_array3 = types_mngr.get_objc(CTypeId("array3"))
+obj_array4 = types_mngr.get_objc(CTypeId("array4"))
+
+obj_charint = types_mngr.get_objc(CTypeUnion("char_int"))
+
+assert cmp(obj_int, obj_uint) != 0
+assert cmp(obj_int, obj_long) != 0
+
+assert cmp(obj_array1, obj_array1) == 0
+assert cmp(obj_array1, obj_array2) == 0
+assert cmp(obj_array1, obj_array3) != 0
+assert cmp(obj_array1, obj_array4) != 0
+
+assert cmp(obj_charint, obj_charint) == 0
+assert cmp(obj_charint, obj_uint) != 0
+
+obj_test = types_mngr.get_objc(CTypePtr(CTypeId("Test")))
+
+ptr_test = ExprId("ptr_Test", 64)
+obj_recurse = types_mngr.get_objc(CTypePtr(CTypeStruct("recurse")))
+# Test cmp same recursive object
+obj_recurse_bis = types_mngr.get_objc(CTypePtr(CTypeStruct("recurse")))
+assert cmp(obj_recurse, obj_recurse_bis) == 0
+
+
+set_test = set([obj_recurse, obj_recurse_bis])
+assert len(set_test) == 1
+ptr_recurse = ExprId("ptr_recurse", 64)
+
+
+obj_test_st = types_mngr.get_objc(CTypeStruct("test_st"))
+print repr(obj_test_st)
+obj_test_context = types_mngr.get_objc(CTypeStruct("test_context"))
+print repr(obj_test_context)
+assert obj_test_context.size > obj_test_st.size
+
+assert cmp(obj_test_st, obj_recurse) != 0
+
+
+expr_types = {ptr_test: (obj_test,),
+              ptr_recurse: (obj_recurse,)}
+
+
+c_context = {ptr_test.name: obj_test,
+             ptr_recurse.name: obj_recurse}
+
+
+tests = [
+    (
+        ExprMem(ptr_test, 32),
+        [("int", "(ptr_Test)->a")]
+    ),
+    (
+        ptr_test,
+        [('struct test_st *', "ptr_Test")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(0, 64), 32),
+        [("int", "(ptr_Test)->a")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(8, 64), 64),
+        [("int **", "(ptr_Test)->ptr")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(8, 64), 64) + ExprInt(8 * 3, 64),
+        [("int **", "&(((ptr_Test)->ptr)[3])")]
+    ),
+    (
+        ExprMem(ExprMem(ptr_test + ExprInt(8, 64), 64) +
+                ExprInt(8 * 3, 64), 64),
+        [("int *", "((ptr_Test)->ptr)[3]")]
+    ),
+    (
+        ExprMem(
+            ExprMem(
+                ExprMem(
+                    ptr_test + ExprInt(8, 64),
+                    64) + ExprInt(8 * 3, 64),
+                64) + ExprInt(4 * 9, 64),
+            32),
+        [("int", "(((ptr_Test)->ptr)[3])[9]")]
+    ),
+    (
+        ptr_test + ExprInt(0x10, 64),
+        [("short [16]", "(ptr_Test)->tab1")]
+    ),
+    (
+        ptr_test + ExprInt(0x12, 64),
+        [("short *", "&(((ptr_Test)->tab1)[1])")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(0x10, 64), 16),
+        [("short", "*((ptr_Test)->tab1)")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(0x10 + 2 * 3, 64), 16),
+        [("short", "((ptr_Test)->tab1)[3]")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(0xb8 + 4, 64), 32),
+        [("int", "(((ptr_Test)->tab3)[0])[1]")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(0xb8 + 32 * 4 * 3 + 4 * 7, 64), 32),
+        [("int", "(((ptr_Test)->tab3)[3])[7]")]
+    ),
+    (
+        ptr_test + ExprInt(0xb8 + 4, 64),
+        [("int *", "&((((ptr_Test)->tab3)[0])[1])")]
+    ),
+
+    # struct of struct
+    (
+        ptr_test + ExprInt(0x8b8, 64),
+        [("struct mini_st *", '&((ptr_Test)->f_mini)')]
+    ),
+    (
+        ptr_test + ExprInt(0x8bc, 64),
+        [("int *", "&(((ptr_Test)->f_mini).y)")]
+    ),
+    (
+        ExprMem(ptr_test + ExprInt(0x8bc, 64), 32),
+        [("int", "((ptr_Test)->f_mini).y")]
+    ),
+
+    # struct of array of struct
+    (
+        ptr_test + ExprInt(0x8c4, 64),
+        [('struct mini_st [16]', '(ptr_Test)->minitab')]
+    ),
+
+    (
+        ptr_test + ExprInt(0x8c4 + 3 * 4, 64),
+        [('struct mini_st *', '&(((ptr_Test)->minitab)[1])')]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(0x8c4, 64), 32),
+        [("int", "((ptr_Test)->minitab)->x")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(0x8c4 + 12 * 4, 64), 32),
+        [("int", "(((ptr_Test)->minitab)[4]).x")]
+    ),
+
+
+    (
+        ExprMem(ptr_test + ExprInt(0x8c4 + 4, 64), 32),
+        [("int", "((ptr_Test)->minitab)->y")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(0x8c4 + 12 * 4 + 4, 64), 32),
+        [("int", "(((ptr_Test)->minitab)[4]).y")]
+    ),
+
+    # struct of array of ptr of struct
+
+    (
+        ExprMem(ptr_test + ExprInt(0x988 + 8 * 4, 64), 64),
+        [('struct mini_st *', "((ptr_Test)->minitabptr)[4]")]
+    ),
+
+    (
+        ExprMem(
+            (ExprMem(ptr_test + ExprInt(0x988 + 8 * 4, 64), 64) +
+             ExprInt(8, 64)),
+            16),
+        [("short", "(((ptr_Test)->minitabptr)[4])->z")]
+    ),
+
+    # tab4
+
+    (
+        ptr_test + ExprInt(0xa08, 64),
+        [("int (*[32])[16]", "(ptr_Test)->tab4")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(0xa08 + 0x8 * 2, 64), 64),
+        [("int (*)[16]", "((ptr_Test)->tab4)[2]")]
+    ),
+
+    (
+        ExprMem(ExprMem(ptr_test + ExprInt(0xa08 + 0x8 * 2, 64), 64), 64),
+        [("int [16]", "*(((ptr_Test)->tab4)[2])")]
+    ),
+
+    (
+        ExprMem(ExprMem(ptr_test + ExprInt(0xa08 + 0x8 * 2, 64), 64), 64) + ExprInt(4 * 5, 64),
+        [("int *", "&((*(((ptr_Test)->tab4)[2]))[5])")]
+    ),
+
+    # enum
+    (
+        ExprMem(ptr_test + ExprInt(2824, 64), 32),
+        [("int", "(ptr_Test)->myenum")]
+    ),
+
+    # typedef array
+    (
+        ExprMem(ptr_test + ExprInt(2828 + 1, 64), 8),
+        [("uchar", "((ptr_Test)->chunk)[1]")]
+    ),
+
+
+    # union
+    (
+        ptr_test + ExprInt(2836, 64),
+        [("union testU *", '&((ptr_Test)->myunion)')]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(2836, 64), 8),
+        [("char", "*(((ptr_Test)->myunion).mychars)")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(2836 + 1, 64), 8),
+        [("char", "(((ptr_Test)->myunion).mychars)[1]")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(2836, 64), 32),
+        [("int", "((ptr_Test)->myunion).myint")]
+    ),
+
+    # union struct
+    (
+        ExprMem(ptr_test + ExprInt(2840, 64), 8),
+        [("char", "*(((ptr_Test)->myunion_x).mychars)")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(2840 + 1, 64), 8),
+        [("char", "(((ptr_Test)->myunion_x).mychars)[1]")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(2840, 64), 32),
+        [("int", "((ptr_Test)->myunion_x).myint"),
+         ("int", "(((ptr_Test)->myunion_x).mystruct_x).a")]
+    ),
+
+    (
+        ptr_test + ExprInt(2840, 64),
+        [('union testV *', '&((ptr_Test)->myunion_x)')]
+    ),
+
+
+    # union union
+    (
+        ptr_test + ExprInt(2848, 64),
+        [('union testW *', '&((ptr_Test)->myunion_y)')]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(2848, 64), 32),
+        [('int', '(((ptr_Test)->myunion_y).u0).a'),
+         ('uint', '(((ptr_Test)->myunion_y).u0).b'),
+         ('int', '(((ptr_Test)->myunion_y).u1).a')]
+    ),
+
+    # recurse
+    (
+        ptr_recurse,
+        [('struct recurse *', 'ptr_recurse')]
+    ),
+
+    (
+        ptr_recurse + ExprInt(8, 64),
+        [('int *', '&((ptr_recurse)->a)')]
+    ),
+
+    (
+        ExprMem(ptr_recurse, 64),
+        [('struct recurse *', '(ptr_recurse)->next')]
+    ),
+
+    (
+        ExprMem(ExprMem(ptr_recurse, 64), 64),
+        [('struct recurse *', '((ptr_recurse)->next)->next')]
+    ),
+
+
+    (
+        ExprMem(ExprMem(ExprMem(ptr_recurse, 64), 64) + ExprInt(8, 64), 32),
+        [('int', '(((ptr_recurse)->next)->next)->a')]
+    ),
+
+
+
+    # tab5
+
+    (
+        ptr_test + ExprInt(0xb30, 64),
+        [("struct mini_st (*[32])[16]", "(ptr_Test)->tab5")]
+    ),
+
+    (
+        ExprMem(ptr_test + ExprInt(0xb30 + 0x8 * 2, 64), 64),
+        [("struct mini_st (*)[16]", "((ptr_Test)->tab5)[2]")]
+    ),
+
+    (
+        ExprMem(ExprMem(ptr_test + ExprInt(0xb30 + 0x8 * 2, 64), 64), 64),
+        [("struct mini_st [16]", "*(((ptr_Test)->tab5)[2])")]
+    ),
+
+    (
+        ExprMem(ExprMem(ptr_test + ExprInt(0xb30 + 0x8 * 2, 64), 64), 64) + ExprInt(12*3 + 8, 64),
+        [("short *", "&(((*(((ptr_Test)->tab5)[2]))[3]).z)")]
+    ),
+
+    (
+        ExprMem(ExprMem(ExprMem(ptr_test + ExprInt(0xb30 + 0x8 * 2, 64), 64), 64) +
+                ExprInt(12*3 + 8, 64), 16),
+        [("short", "((*(((ptr_Test)->tab5)[2]))[3]).z")]
+    ),
+
+
+    # tab 6
+    (
+        ExprMem(ptr_test + ExprInt(0xc30 + ((((3) * 4 + 2)*4 + 0)*4 + 1)*8, 64), 64),
+        [("int *", "(((((ptr_Test)->tab6)[3])[2])[0])[1]")]
+    ),
+
+    (
+        ExprMem(ExprMem(ptr_test + ExprInt(0xc30 + ((((3) * 4 + 2)*4 + 0)*4 + 1)*8, 64), 64), 32),
+        [("int", "*((((((ptr_Test)->tab6)[3])[2])[0])[1])")]
+    ),
+
+
+
+]
+
+mychandler = CHandler(types_mngr, expr_types)
+exprc2expr = ExprCToExpr(expr_types, types_mngr)
+mychandler.updt_expr_types(expr_types)
+
+
+for (expr, result) in tests[4:]:
+    print "*" * 80
+    print "Native expr:", expr
+    result = set(result)
+    expr_c = mychandler.expr_to_c(expr)
+    types = mychandler.expr_to_types(expr)
+
+    target_type = mychandler.expr_to_types(expr)
+
+    access_c_gen = ExprToAccessC(expr_types, types_mngr)
+    computed = set()
+    for c_str, ctype in mychandler.expr_to_c_and_types(expr):
+        print c_str, ctype
+        computed.add((str(ctype), c_str))
+    assert computed == result
+
+
+    for out_type, out_str in computed:
+        parsed_expr = mychandler.c_to_expr(out_str, c_context)
+        parsed_type = mychandler.c_to_type(out_str, c_context)
+        print "Access expr:", parsed_expr
+        print "Access type:", parsed_type
+
+        ast = parse_access(out_str)
+        access_c = ast_get_c_access_expr(ast, c_context)
+        print "Generated access:", access_c
+
+        parsed_expr_bis, parsed_type_bis = mychandler.exprc2expr.get_expr(access_c, c_context)
+        assert parsed_expr_bis is not None
+        assert parsed_expr == parsed_expr_bis
+        assert parsed_type == parsed_type_bis
+
+        expr_new1 = expr_simp(parsed_expr)
+        expr_new2 = expr_simp(expr)
+        print "\t", expr_new1
+        assert expr_new1 == expr_new2