diff options
| author | serpilliere <devnull@localhost> | 2013-02-22 15:51:08 +0100 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2013-02-22 15:51:08 +0100 |
| commit | f38372e5e052453c4878cbf0516a23e59b4d712b (patch) | |
| tree | 5c1a9490fbd9362788804b1d53fd59f63f3aa0f6 | |
| parent | 4f1d29d8527375e81f190dbb0d345eca1eb541f0 (diff) | |
| parent | 7d1b50444f2c952b1287bf45d046eea222d4ba18 (diff) | |
| download | miasm-f38372e5e052453c4878cbf0516a23e59b4d712b.tar.gz miasm-f38372e5e052453c4878cbf0516a23e59b4d712b.zip | |
merge
| -rwxr-xr-x | example/disas_and_graph.py | 2 | ||||
| -rw-r--r-- | miasm/arch/ia32_arch.py | 40 | ||||
| -rw-r--r-- | miasm/arch/ia32_sem.py | 115 | ||||
| -rw-r--r-- | miasm/expression/expression.py | 2 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.c | 84 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.h | 20 | ||||
| -rw-r--r-- | miasm/tools/nux_api.py | 2 | ||||
| -rw-r--r-- | miasm/tools/pe_helper.py | 27 | ||||
| -rw-r--r-- | miasm/tools/seh_helper.py | 211 | ||||
| -rw-r--r-- | miasm/tools/to_c_helper.py | 32 |
10 files changed, 425 insertions, 110 deletions
diff --git a/example/disas_and_graph.py b/example/disas_and_graph.py index 124b8f4a..0a6a3e5d 100755 --- a/example/disas_and_graph.py +++ b/example/disas_and_graph.py @@ -121,7 +121,7 @@ elif data.startswith("\xca\xfe\xba\xbe"): else: - print 'WARNING cannot autodetect file type, using raw' + print 'WARNING cannot autodetect file type, using raw', repr(data[:10]) in_str = bin_stream.bin_stream(data) if ad_to_dis == None: ad_to_dis = 0 diff --git a/miasm/arch/ia32_arch.py b/miasm/arch/ia32_arch.py index 3f6a5af4..2493948e 100644 --- a/miasm/arch/ia32_arch.py +++ b/miasm/arch/ia32_arch.py @@ -166,7 +166,8 @@ unsanity_mnemo = ['nop', 'monitor', 'mwait', 'fadd', 'faddp', 'fiadd', 'fcmovb', 'fnstsw', 'fsub', 'fsubr', 'fisubr', 'fsubrp', 'ftst', 'fucom', 'fucompp', 'fxam', 'fxtract', 'fyl2x', 'fyl2xp1', 'fsqrt', 'fsincos', 'fsin', 'fscale', 'fcos', 'fdecstp', 'fnop', 'fpatan', 'fprem', 'fprem1', 'fptan', 'frndint', "shl", 'sal', 'sar', 'fabs', "jmpff", - "fcomi", "fucomi", "fucomip", "fdivp"] + "fcomi", "fucomi", "fucomip", "fdivp", + "fisubr", "fsubp"] mask_drcrsg = {cr:0x100, dr:0x200, sg:0x400} @@ -1096,7 +1097,7 @@ class x86allmncs: addop("fadd", [0xD8], d0, no_rm , {sd:(0,2)} ,{} , {}, ) addop("fadd", [0xD8, 0xC0], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) addop("fiadd", [0xDA], d0, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("faddp", [0xDE, 0xC0], reg, no_rm , {} ,{sd:False} , {}, ) + addop("faddp", [0xDE, 0xC0], reg, [r_eax] , {} ,{sd:False,sw:True}, {}, ) addop("fbld", [0xDF], d4, no_rm , {} ,{} , {}, ) addop("fbstp", [0xDF], d6, no_rm , {} ,{} , {}, ) @@ -1126,13 +1127,15 @@ class x86allmncs: addop("fdiv", [0xD8], d6, no_rm , {sd:(0,2)} ,{} , {}, ) - addop("fdiv", [0xD8, 0xF0], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) + addop("fdivr", [0xD8], d7, no_rm , {sd:(0,2)} ,{} , {}, ) + addop("fdiv", [0xDC, 0xF8], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) addop("fidiv", [0xDA], d6, no_rm , {wd:(0,2)} ,{} , {}, ) addop("fidivr",[0xDA], d7, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("fdivp", [0xDE, 0xF8], reg, no_rm , {} ,{sd:True} , {}, ) + addop("fdivp", [0xDE, 0xF8], reg, [r_eax] , {} ,{sd:True,sw:True} , {}, ) - addop("fdivr", [0xD8], d7, no_rm , {sd:(0,2)} ,{} , {}, ) - addop("fdivr", [0xD8, 0xF8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) + addop("fdiv", [0xD8, 0xF0], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + addop("fdivr", [0xD8, 0xF8], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + addop("fdivr", [0xDC, 0xF0], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) addop("fdivrp",[0xDE, 0xF0], reg, no_rm , {} ,{sd:False} , {}, ) addop("ffree", [0xDD, 0xC0], reg, no_rm , {} ,{sd:False} , {}, ) @@ -1159,7 +1162,7 @@ class x86allmncs: addop("fmul", [0xD8], d1, no_rm , {sd:(0,2)} ,{} , {}, ) addop("fmul", [0xD8, 0xC8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) addop("fimul", [0xDA], d1, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("fmulp", [0xDE, 0xC8], reg, no_rm , {} ,{sd:False} , {}, ) + addop("fmulp", [0xDE, 0xC8], reg, [r_eax] , {} ,{sd:False,sw:True}, {}, ) addop("frstor",[0xDD], d4, no_rm , {} ,{wd:False} , {}, ) #XXX 94/108 @@ -1170,7 +1173,7 @@ class x86allmncs: addop("fst", [0xD9], d2, no_rm , {sd:(0,2)} ,{} , {}, ) addop("fst", [0xDD, 0xD0], reg, no_rm , {} ,{sd:False} , {}, ) - addop("fstp", [0xD9], d3, no_rm , {sd:(0,2)} ,{sd:False} , {}, ) + addop("fstp", [0xD9], d3, no_rm , {sd:(0,2)} ,{sd:True} , {}, ) addop("fstp", [0xDB], d7, no_rm , {} ,{sd:False} , {}, ) #XXX 80 addop("fstp", [0xDD, 0xD8], reg, no_rm , {} ,{sd:True} , {}, ) @@ -1224,14 +1227,25 @@ class x86allmncs: #ddop("fstsw",[0x9B, 0xDF, 0xE0], noafs, no_rm , {} ,{wd:False} , {}, ) #XXX no mnemo addop("fnstsw",[0xDF, 0xE0], noafs, no_rm , {} ,{wd:False} , {}, ) + #addop("fsub", [0xD8], d4, no_rm , {sd:(0,2)} ,{} , {}, ) + #addop("fsubr", [0xD8], d5, no_rm , {sd:(0,2)} ,{} , {}, ) + #addop("fsub", [0xD8, 0xE0], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + #addop("fisub", [0xDA], d4, no_rm , {wd:(0,2)} ,{} , {}, ) + #addop("fsubp", [0xDE, 0xE8], reg, [r_eax] , {} ,{sd:False,sw:True}, {}, ) + # + #addop("fsubr", [0xD8, 0xE8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) + #addop("fisubr",[0xDA], d5, no_rm , {wd:(0,2)} ,{} , {}, ) + #addop("fsubrp",[0xDE, 0xE0], reg, no_rm , {} ,{sd:False} , {}, ) addop("fsub", [0xD8], d4, no_rm , {sd:(0,2)} ,{} , {}, ) - addop("fsub", [0xD8, 0xE0], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) - addop("fisub", [0xDA], d4, no_rm , {wd:(0,2)} ,{} , {}, ) - addop("fsubp", [0xDE, 0xE8], reg, no_rm , {} ,{sd:False} , {}, ) - addop("fsubr", [0xD8], d5, no_rm , {sd:(0,2)} ,{} , {}, ) - addop("fsubr", [0xD8, 0xE8], reg, [r_eax] , {sw:(0,2)} ,{sd:True,sw:False}, {}, ) + addop("fsub", [0xDC, 0xE8], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) + addop("fisub", [0xDA], d4, no_rm , {wd:(0,2)} ,{} , {}, ) addop("fisubr",[0xDA], d5, no_rm , {wd:(0,2)} ,{} , {}, ) + addop("fsubp", [0xDE, 0xE8], reg, [r_eax] , {} ,{sd:True,sw:True} , {}, ) + + addop("fsub", [0xD8, 0xE0], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + addop("fsubr", [0xD8, 0xE8], reg, [r_eax] , { } ,{sd:True,sw:False}, {}, ) + addop("fsubr", [0xDC, 0xE0], reg, [r_eax] , { } ,{sd:True,sw:True }, {}, ) addop("fsubrp",[0xDE, 0xE0], reg, no_rm , {} ,{sd:False} , {}, ) addop("ftst", [0xD9, 0xE4], noafs, no_rm , {} ,{sd:False} , {}, ) diff --git a/miasm/arch/ia32_sem.py b/miasm/arch/ia32_sem.py index 46619e1a..059661e4 100644 --- a/miasm/arch/ia32_sem.py +++ b/miasm/arch/ia32_sem.py @@ -269,6 +269,17 @@ float_st5 = ExprId(reg_float_st5, 64) float_st6 = ExprId(reg_float_st6, 64) float_st7 = ExprId(reg_float_st7, 64) +float_list = [ + float_st0 , + float_st1 , + float_st2 , + float_st3 , + float_st4 , + float_st5 , + float_st6 , + float_st7 , + ] + init_regs = { @@ -839,35 +850,7 @@ def shl(info, a, b): return e def shld_cl(info, a, b): - e= [] - shifter = ExprOp('&',ecx, ExprInt_from(a, 0x1f)) - c = ExprOp('|', - ExprOp('<<', a, shifter), - ExprOp('>>', b, ExprOp('-', - ExprInt_from(a, a.get_size()), - shifter) - ) - ) - - new_cf = ExprOp('&', - ExprInt_from(a, 1), - ExprOp('>>', - a, - ExprOp('-', - ExprInt_from(b, a.get_size()), - shifter - ) - ) - ) - e.append(ExprAff(cf, ExprCond(shifter, - new_cf, - cf) - ) - ) - e+=update_flag_znp(c) - e.append(ExprAff(of, ExprOp('^', get_op_msb(c), new_cf))) - e.append(ExprAff(a, c)) - return e + return shld(info, a, b, ecx) def shld(info, a, b, c): e= [] @@ -895,9 +878,12 @@ def shld(info, a, b, c): cf) ) ) + # XXX todo: don't update flag if shifter is 0 e+=update_flag_znp(c) e.append(ExprAff(of, ExprOp('^', get_op_msb(c), new_cf))) - e.append(ExprAff(a, c)) + e.append(ExprAff(a, ExprCond(shifter, + c, + a))) return e @@ -1645,8 +1631,17 @@ def movs(info, a, b): return e +def float_prev(flt): + if not flt in float_list: + return None + i = float_list.index(flt) + if i == 0: + fds + flt = float_list[i-1] + return flt def float_pop(avoid_flt = None): + avoid_flt = float_prev(avoid_flt) e= [] if avoid_flt != float_st0: e.append(ExprAff(float_st0, float_st1)) @@ -1803,11 +1798,17 @@ def fadd(info, a, b = None): return e def faddp(info, a, b = None): - e = fadd(a, b) if b == None: - e+=float_pop(float_st0) + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) else: - e+=float_pop(a) + src = b + e.append(ExprAff(float_prev(a), ExprOp('fadd', a, src))) + e += set_float_cs_eip(info) + e += float_pop(a) return e def fninit(info): @@ -1881,11 +1882,47 @@ def fdiv(info, a, b = None): e += set_float_cs_eip(info) return e +def fdivr(info, a, b = None): + if b == None: + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) + else: + src = b + e.append(ExprAff(a, ExprOp('fdiv', src, a))) + e += set_float_cs_eip(info) + return e + def fdivp(info, a): # Invalid emulation + if b == None: + b = a + a = float_st0 e = [] - e.append(ExprAff(a, ExprOp('fdiv', a, float_st0))) - e+=float_pop(a) + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) + else: + src = b + e.append(ExprAff(float_prev(a), ExprOp('fdiv', a, src))) + e += set_float_cs_eip(info) + e += float_pop(a) + return e + +def fmulp(info, a, b): + # Invalid emulation + if b == None: + b = a + a = float_st0 + e = [] + if isinstance(b, ExprMem): + src = ExprOp('mem_%.2d_to_double'%b.get_size(), b) + else: + src = b + e.append(ExprAff(float_prev(a), ExprOp('fmul', a, src))) + e += set_float_cs_eip(info) + e += float_pop(a) return e def ftan(info, a): @@ -1922,12 +1959,6 @@ def fptan(info): e.append(ExprAff(float_stack_ptr, ExprOp('+', float_stack_ptr, ExprInt32(1)))) return e - e.append(ExprAff(float_st0, ExprOp('ftan', src))) - - e = ftan(a) - e+=float_pop(a) - return e - def frndint(info): e = [] @@ -2421,7 +2452,9 @@ mnemo_func = {'mov': mov, 'faddp':faddp, 'fsub':fsub, 'fmul':fmul, + 'fmulp':fmulp, 'fdiv':fdiv, + 'fdivr':fdivr, 'fdivp':fdivp, 'fxch':fxch, 'fptan':fptan, diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py index 6018be4a..5ec5f4f0 100644 --- a/miasm/expression/expression.py +++ b/miasm/expression/expression.py @@ -444,7 +444,7 @@ class ExprOp(Expr): return "parity(%s&0x%x)"%(self.args[0].toC(), my_size_mask[self.args[0].get_size()]) elif self.op == '!': return "(~ %s)&0x%x"%(self.args[0].toC(), my_size_mask[self.args[0].get_size()]) - elif self.op in ['int_32_to_double', 'int_64_to_double']: + elif self.op in ['int_16_to_double', 'int_32_to_double', 'int_64_to_double']: return "%s(%s)"%(self.op, self.args[0].toC()) elif self.op == 'double_to_int_32': return "%s(%s)"%(self.op, self.args[0].toC()) diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c index 31a2be31..ba491e16 100644 --- a/miasm/tools/emul_lib/libcodenat.c +++ b/miasm/tools/emul_lib/libcodenat.c @@ -683,8 +683,9 @@ int imul_hi_op_16(short a, short b) int imul_hi_op_32(int a, int b) { int64_t res = 0; - res = a*b; - return res>>32; + res = (int64_t)a*(int64_t)b; + //printf("%x %x dd %"PRIx64"\n", a, b, res); + return res>>32ULL; } unsigned int umul16_lo(unsigned short a, unsigned short b) @@ -918,6 +919,20 @@ unsigned int cpuid(unsigned int a, unsigned int reg_num) #define DEBUG_MIASM_DOUBLE + +void dump_float(void) +{ + printf("%e\n", vmcpu.float_st0); + printf("%e\n", vmcpu.float_st1); + printf("%e\n", vmcpu.float_st2); + printf("%e\n", vmcpu.float_st3); + printf("%e\n", vmcpu.float_st4); + printf("%e\n", vmcpu.float_st5); + printf("%e\n", vmcpu.float_st6); + printf("%e\n", vmcpu.float_st7); + +} + double mem_32_to_double(unsigned int m) { float f; @@ -926,7 +941,8 @@ double mem_32_to_double(unsigned int m) f = *((float*)&m); d = f; #ifdef DEBUG_MIASM_DOUBLE - printf("%d %e\n", m, d); + dump_float(); + printf("%d float %e\n", m, d); #endif return d; } @@ -937,7 +953,20 @@ double mem_64_to_double(uint64_t m) double d; d = *((double*)&m); #ifdef DEBUG_MIASM_DOUBLE - printf("%"PRId64" %e\n", m, d); + dump_float(); + printf("%"PRId64" double %e\n", m, d); +#endif + return d; +} + +double int_16_to_double(unsigned int m) +{ + double d; + + d = (double)(m&0xffff); +#ifdef DEBUG_MIASM_DOUBLE + dump_float(); + printf("%d double %e\n", m, d); #endif return d; } @@ -948,7 +977,8 @@ double int_32_to_double(unsigned int m) d = (double)m; #ifdef DEBUG_MIASM_DOUBLE - printf("%d %e\n", m, d); + dump_float(); + printf("%d double %e\n", m, d); #endif return d; } @@ -959,7 +989,8 @@ double int_64_to_double(uint64_t m) d = (double)m; #ifdef DEBUG_MIASM_DOUBLE - printf("%"PRId64" %e\n", m, d); + dump_float(); + printf("%"PRId64" double %e\n", m, d); #endif return d; } @@ -970,7 +1001,8 @@ int double_to_int_32(double d) i = (int)d; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %d\n", d, i); + dump_float(); + printf("%e int %d\n", d, i); #endif return i; } @@ -980,7 +1012,8 @@ double fadd(double a, double b) double c; c = a + b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e + %e -> %e\n", a, b, c); #endif return c; } @@ -990,7 +1023,8 @@ double fsub(double a, double b) double c; c = a - b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e - %e -> %e\n", a, b, c); #endif return c; } @@ -1000,7 +1034,8 @@ double fmul(double a, double b) double c; c = a * b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e * %e -> %e\n", a, b, c); #endif return c; } @@ -1010,7 +1045,8 @@ double fdiv(double a, double b) double c; c = a / b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e / %e -> %e\n", a, b, c); #endif return c; } @@ -1020,7 +1056,8 @@ double ftan(double a) double b; b = tan(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e tan %e\n", a, b); #endif return b; } @@ -1032,7 +1069,8 @@ double frndint(double a) b = (int64_t)a; c = (double)b; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, c); + dump_float(); + printf("%e double %e\n", a, c); #endif return c; } @@ -1042,7 +1080,8 @@ double fsin(double a) double b; b = sin(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e sin %e\n", a, b); #endif return b; } @@ -1052,7 +1091,8 @@ double fcos(double a) double b; b = cos(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e cos %e\n", a, b); #endif return b; } @@ -1063,7 +1103,8 @@ double fscale(double a, double b) double c; c = a * exp2(trunc(b)); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e %e\n", a, b, c); + dump_float(); + printf("%e *exp2 %e -> %e\n", a, b, c); #endif return c; } @@ -1073,7 +1114,8 @@ double f2xm1(double a) double b; b = exp2(a)-1; #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e exp2 -1 %e\n", a, b); #endif return b; } @@ -1083,7 +1125,8 @@ double fsqrt(double a) double b; b = sqrt(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e sqrt %e\n", a, b); #endif return b; } @@ -1093,7 +1136,8 @@ double fabs(double a) double b; b = abs(a); #ifdef DEBUG_MIASM_DOUBLE - printf("%e %e\n", a, b); + dump_float(); + printf("%e abs %e\n", a, b); #endif return b; } @@ -1130,6 +1174,7 @@ unsigned int double_to_mem_32(double d) f = d; m = *((unsigned int*)&f); #ifdef DEBUG_MIASM_DOUBLE + dump_float(); printf("%d %e\n", m, d); #endif return m; @@ -1140,6 +1185,7 @@ uint64_t double_to_mem_64(double d) uint64_t m; m = *((uint64_t*)&d); #ifdef DEBUG_MIASM_DOUBLE + dump_float(); printf("%"PRId64" %e\n", m, d); #endif return m; diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h index 43d247e8..d0f4930a 100644 --- a/miasm/tools/emul_lib/libcodenat.h +++ b/miasm/tools/emul_lib/libcodenat.h @@ -506,6 +506,7 @@ unsigned int fcom_c3(double a, double b); double mem_32_to_double(unsigned int m); double mem_64_to_double(uint64_t m); +double int_16_to_double(unsigned int m); double int_32_to_double(unsigned int m); double int_64_to_double(uint64_t m); int double_to_int_32(double d); @@ -515,26 +516,25 @@ uint64_t double_to_mem_64(double d); #define shift_right_arith_08(a, b)\ - ((((char)(a)) >> ((int)(b)))&0xff) + ((((char)(a)) >> ((int)(b)&0x1f))&0xff) #define shift_right_arith_16(a, b)\ - ((((short)(a)) >> ((int)(b)))&0xffff) + ((((short)(a)) >> ((int)(b)&0x1f))&0xffff) #define shift_right_arith_32(a, b)\ - ((((int)(a)) >> ((int)(b)))&0xffffffff) + ((((int)(a)) >> ((int)(b)&0x1f))&0xffffffff) #define shift_right_logic_08(a, b)\ - ((((unsigned char)(a)) >> ((unsigned int)(b)))&0xff) + ((((unsigned char)(a)) >> ((unsigned int)(b)&0x1f))&0xff) #define shift_right_logic_16(a, b)\ - ((((unsigned short)(a)) >> ((unsigned int)(b)))&0xffff) + ((((unsigned short)(a)) >> ((unsigned int)(b)&0x1f))&0xffff) #define shift_right_logic_32(a, b)\ - ((((unsigned int)(a)) >> ((unsigned int)(b)))&0xffffffff) - + ((((unsigned int)(a)) >> ((unsigned int)(b)&0x1f))&0xffffffff) #define shift_left_logic_08(a, b)\ - (((a)<<(b))&0xff) + (((a)<<((b)&0x1f))&0xff) #define shift_left_logic_16(a, b)\ - (((a)<<(b))&0xffff) + (((a)<<((b)&0x1f))&0xffff) #define shift_left_logic_32(a, b)\ - (((a)<<(b))&0xffffffff) + (((a)<<((b)&0x1f))&0xffffffff) #endif diff --git a/miasm/tools/nux_api.py b/miasm/tools/nux_api.py index 07a7aca9..569a0f3b 100644 --- a/miasm/tools/nux_api.py +++ b/miasm/tools/nux_api.py @@ -693,6 +693,8 @@ def parse_fmt(s): i+=1 while fmt[i+j] in "0123456789$.": j+=1 + if fmt[i+j] in ['l']: + j +=1 if fmt[i+j] == "h": x = fmt[i+j:i+j+2] else: diff --git a/miasm/tools/pe_helper.py b/miasm/tools/pe_helper.py index f8955eb1..b3c70278 100644 --- a/miasm/tools/pe_helper.py +++ b/miasm/tools/pe_helper.py @@ -64,13 +64,13 @@ def func_from_import(pe_name, func): if type(func) is str: for i, n in enumerate(e.DirExport.f_names): if n.name.name == func: - found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal] + found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal].rva break elif type(func) in [int, long]: for i, n in enumerate(e.DirExport.f_names): if e.DirExport.f_nameordinals[i].ordinal+e.DirExport.expdesc.base == func: - found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal] + found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal].rva break else: raise ValueError('unknown fund type', func) @@ -300,6 +300,10 @@ def code_is_jmp_imp(e, ad, imp_d): return is_jmp_imp(l, imp_d) +def test_ret_and_cc(in_str, ad): + while in_str[ad] == "\xCC": + ad -=1 + return in_str[ad] == '\xC3' or in_str[ad-2] == "\xC2" # giving e and address in function guess function start def guess_func_start(in_str, line_ad, max_offset = 0x200): @@ -317,7 +321,10 @@ def guess_func_start(in_str, line_ad, max_offset = 0x200): if in_str[ad] == "\xCC": if in_str[((ad+3)&~3)-1] == "\xCC": ad_found = ((ad+3)&~3) - break + if test_ret_and_cc(in_str, ad_found): + break + else: + continue else: continue l = x86_mn.dis(in_str[ad:ad+15]) @@ -388,8 +395,10 @@ def is_redirected_export(e, ad): def canon_libname_libfunc(libname, libfunc): dn = libname.split('.')[0] - fn = "%s"%libfunc - return "%s_%s"%(dn, fn) + if type(libfunc) == str: + return "%s_%s"%(dn, libfunc) + else: + return str(dn), libfunc class libimp: def __init__(self, lib_base_ad = 0x77700000): @@ -661,10 +670,18 @@ def preload_elf(e, patch_vm_imp = True, lib_base_ad = 0x77700000): def get_export_name_addr_list(e): out = [] + # add func name for i, n in enumerate(e.DirExport.f_names): addr = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal] f_name = n.name.name + #print f_name, hex(e.rva2virt(addr.rva)) out.append((f_name, e.rva2virt(addr.rva))) + + # add func ordinal + for i, o in enumerate(e.DirExport.f_nameordinals): + addr = e.DirExport.f_address[o.ordinal] + #print o.ordinal, e.DirExport.expdesc.base, hex(e.rva2virt(addr.rva)) + out.append((o.ordinal+e.DirExport.expdesc.base, e.rva2virt(addr.rva))) return out diff --git a/miasm/tools/seh_helper.py b/miasm/tools/seh_helper.py index c0d95d3f..efdd7191 100644 --- a/miasm/tools/seh_helper.py +++ b/miasm/tools/seh_helper.py @@ -17,7 +17,16 @@ # #from codenat import * from to_c_helper import * +from elfesteem import * import to_c_helper +import logging + + +log = logging.getLogger("seh_helper") +console_handler = logging.StreamHandler() +console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) +log.addHandler(console_handler) +log.setLevel(logging.WARN) FS_0_AD = 0x7ff70000 PEB_AD = 0x7ffdf000 @@ -32,17 +41,21 @@ peb_ldr_data_offset = 0x1ea0 peb_ldr_data_address = LDR_AD + peb_ldr_data_offset#PEB_AD + 0x1000 -InInitializationOrderModuleList_offset = 0x1f48 +modules_list_offset = 0x1f00 + +InInitializationOrderModuleList_offset = 0x1ee0 #0x1f48 InInitializationOrderModuleList_address = LDR_AD + InInitializationOrderModuleList_offset#PEB_AD + 0x2000 -InLoadOrderModuleList_offset = 0x1f48 + MAX_MODULES*0x1000 +InLoadOrderModuleList_offset = 0x1ee0+MAX_MODULES*0x1000#0x1f48 + MAX_MODULES*0x1000 InLoadOrderModuleList_address = LDR_AD + InLoadOrderModuleList_offset#PEB_AD + 0x2000 #in_load_order_module_1 = LDR_AD + in_load_order_module_list_offset#PEB_AD + 0x3000 default_seh = PEB_AD + 0x20000 +process_environment_address = 0x10000 +process_parameters_address = 0x200000 -context_address = 0x200000 +context_address = 0x201000 exception_record_address = context_address+0x1000 return_from_exception = 0x6eadbeef @@ -86,6 +99,7 @@ def build_fake_peb(): +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA + +0x010 processparameter """ offset_serverdata = 0x100 @@ -98,6 +112,7 @@ def build_fake_peb(): else: o += "AAAA" o += pdw(peb_ldr_data_address) + o += pdw(process_parameters_address) o += (0x54 - len(o)) *"A" o += pdw(peb_address+offset_serverdata) @@ -113,7 +128,7 @@ def build_fake_peb(): return o -def build_fake_ldr_data(): +def build_fake_ldr_data(modules_info): """ +0x000 Length : Uint4B +0x004 Initialized : UChar @@ -127,9 +142,31 @@ def build_fake_ldr_data(): o += "\x00" * peb_ldr_data_offset o += "\x00"*0xc #text XXX - o += pdw(InLoadOrderModuleList_address) + pdw(0) - o += pdw(InInitializationOrderModuleList_address+8) + pdw(0) - o += pdw(InInitializationOrderModuleList_address+0x10) + pdw(0) + + # get main pe info + m_e = None + for bname, (addr, e) in modules_info.items(): + if e == main_pe: + m_e = (e, bname, addr) + break + if not m_e: + log.warn('no main pe, ldr data will be unconsistant') + else: + print 'inloadorder first', hex(m_e[2]) + o += pdw(m_e[2]) + pdw(0) + + # get ntdll + ntdll_e = None + for bname, (addr, e) in modules_info.items(): + if bname[::2].lower() == "ntdll.dll": + ntdll_e = (e, bname, addr) + continue + if not ntdll_e: + log.warn('no ntdll, ldr data will be unconsistant') + else: + print 'ntdll', hex(ntdll_e[2]) + o += pdw(ntdll_e[2]+0x10) + pdw(0) # XXX TODO + o += pdw(ntdll_e[2]+0x10) + pdw(0) return o @@ -237,6 +274,151 @@ def build_fake_InInitializationOrderModuleList(modules_name): return o +dummy_e = pe_init.PE() +dummy_e.NThdr.ImageBase = 0 +dummy_e.Opthdr.AddressOfEntryPoint = 0 +dummy_e.NThdr.sizeofimage = 0 + +def create_modules_chain(modules_name): + modules_info = {} + base_addr = LDR_AD + modules_list_offset #XXXX + offset_name = 0x500 + offset_path = 0x600 + + + out = "" + for i, m in enumerate([(main_pe_name, main_pe), ("", dummy_e)] + modules_name): + addr = base_addr + i*0x1000 + #fname = os.path.join('win_dll', m) + if isinstance(m, tuple): + fname, e = m + else: + fname, e = m, None + bpath = fname.replace('/', '\\') + bname = os.path.split(fname)[1].lower() + bname = "\x00".join(bname)+"\x00" + print "add module", repr(bname), repr(bpath) + #print hex(InInitializationOrderModuleList_address+i*0x1000) + if e == None: + e = pe_init.PE(open(fname, 'rb').read()) + modules_info[bname] = addr, e + + m_o = "" + m_o += pdw(0) + m_o += pdw(0) + m_o += pdw(0) + m_o += pdw(0) + m_o += pdw(0) + m_o += pdw(0) + m_o += pdw(e.NThdr.ImageBase) + m_o += pdw(e.rva2virt(e.Opthdr.AddressOfEntryPoint)) + m_o += pdw(e.NThdr.sizeofimage) + + m_o += (0x24 - len(m_o))*"A" + print hex(len(bname)), repr(bname) + m_o += struct.pack('HH', len(bname), len(bname)+2) + m_o += pdw(addr+offset_path) + + m_o += (0x2C - len(m_o))*"A" + m_o += struct.pack('HH', len(bname), len(bname)+2) + m_o += pdw(addr + offset_name) + + m_o += (offset_name - len(m_o))*"B" + m_o += bname + m_o += "\x00"*3 + + m_o += (offset_path - len(m_o))*"B" + m_o += "\x00".join(bpath)+"\x00" + m_o += "\x00"*3 + #out += m_o + vm_set_mem(addr, m_o) + return modules_info + + +def fix_InLoadOrderModuleList(module_info): + # first binary is PE + # last is dumm_e + olist =[] + m_e = None + d_e = None + for bname, (addr, e) in module_info.items(): + print bname + if e == main_pe: + m_e = (e, bname, addr) + continue + elif e == dummy_e: + d_e = (e, bname, addr) + continue + olist.append((e, bname, addr)) + if not m_e or not d_e: + log.warn('no main pe, ldr data will be unconsistant') + else: + olist[0:0] =[m_e] + olist.append(d_e) + + last_addr = 0 + for i in xrange(len(olist)): + e, bname, addr = olist[i] + p_e, p_bname, p_addr = olist[(i-1)%len(olist)] + n_e, n_bname, n_addr = olist[(i+1)%len(olist)] + vm_set_mem(addr+0, pdw(p_addr)+pdw(n_addr)) + + + +def fix_InInitializationOrderModuleList(module_info): + # first binary is ntdll + # second binary is kernel32 + olist =[] + ntdll_e = None + kernel_e= None + for bname, (addr, e) in module_info.items(): + if bname[::2].lower() == "ntdll.dll": + ntdll_e = (e, bname, addr) + continue + elif bname[::2].lower() == "kernel32.dll": + kernel_e = (e, bname, addr) + continue + elif e == dummy_e: + d_e = (e, bname, addr) + continue + elif e == main_pe: + continue + olist.append((e, bname, addr)) + if not ntdll_e or not kernel_e or not d_e: + log.warn('no kernel ntdll, ldr data will be unconsistant') + else: + olist[0:0] =[ntdll_e] + olist[1:1] =[kernel_e] + + olist.append(d_e) + + last_addr = 0 + for i in xrange(len(olist)): + e, bname, addr = olist[i] + p_e, p_bname, p_addr = olist[(i-1)%len(olist)] + n_e, n_bname, n_addr = olist[(i+1)%len(olist)] + vm_set_mem(addr+0x10, pdw(p_addr)+pdw(n_addr)) + + +def add_process_env(): + env_str = 'ALLUSERSPROFILE=C:\\Documents and Settings\\All Users\x00' + env_str = '\x00'.join(env_str) + env_str += "\x00"*0x10 + vm_add_memory_page(process_environment_address, + PAGE_READ | PAGE_WRITE, + env_str) + vm_set_mem(process_environment_address, env_str) + +def add_process_parameters(): + o = "" + o+= pdw(0x1000) #size + o += "E"*(0x48 - len(o)) + o += pdw(process_environment_address) + vm_add_memory_page(process_parameters_address, + PAGE_READ | PAGE_WRITE, + o) + + def build_fake_InLoadOrderModuleList(modules_name): """ +0x000 Flink : Ptr32 -+ This distance @@ -349,13 +531,24 @@ def init_seh(): vm_add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, build_fake_peb()) #vm_add_memory_page(peb_ldr_data_address, PAGE_READ | PAGE_WRITE, p(0) * 3 + p(in_load_order_module_list_address) + p(0) * 0x20) - ldr_data = build_fake_ldr_data() + """ ldr_data += "\x00"*(InInitializationOrderModuleList_offset - len(ldr_data)) ldr_data += build_fake_InInitializationOrderModuleList(loaded_modules) ldr_data += "\x00"*(InLoadOrderModuleList_offset - len(ldr_data)) ldr_data += build_fake_InLoadOrderModuleList(loaded_modules) + """ + vm_add_memory_page(LDR_AD, PAGE_READ | PAGE_WRITE, "\x00"*MAX_MODULES*0x1000) + module_info = create_modules_chain(loaded_modules) + fix_InLoadOrderModuleList(module_info) + fix_InInitializationOrderModuleList(module_info) + + ldr_data = build_fake_ldr_data(module_info) + vm_set_mem(LDR_AD, ldr_data) + add_process_env() + add_process_parameters() + + #fds - vm_add_memory_page(LDR_AD, PAGE_READ | PAGE_WRITE, ldr_data) #vm_add_memory_page(in_load_order_module_list_address, PAGE_READ | PAGE_WRITE, p(0) * 40) # vm_add_memory_page(in_load_order_module_list_address, PAGE_READ | PAGE_WRITE, build_fake_inordermodule(loaded_modules)) vm_add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, p(0xffffffff) + p(0x41414141) + p(0x42424242)) diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py index 38f21272..d8d77db1 100644 --- a/miasm/tools/to_c_helper.py +++ b/miasm/tools/to_c_helper.py @@ -1163,7 +1163,11 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs): from miasm.tools import pe_helper from miasm.tools import codenat - e = pe_init.PE(open(fname_in, 'rb').read()) + parse_resources = True + if 'parse_resources' in kargs: + parse_resources = kargs['parse_resources'] + e = pe_init.PE(open(fname_in, 'rb').read(), + parse_resources = parse_resources) vm_init_regs() init_memory_page_pool_py() @@ -1201,7 +1205,7 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs): seh_helper.runtime_dll = runtime_dll if options.loadmainpe: seh_helper.main_pe = e - seh_helper.main_pe_name = "c:\\xxx\\"+kargs.get("main_pe_name", "toto.exe") + seh_helper.main_pe_name = kargs.get("main_pe_name", "toto.exe") seh_helper.loaded_modules = all_pe dll_dyn_funcs = pe_helper.preload_lib(e, runtime_dll) @@ -1215,7 +1219,11 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs): if 'stack_size' in kargs: stack_size = kargs['stack_size'] - stack_base_ad = kargs.get('stack_base_ad', 0x1230000) + stack_base = 0x1230000 + if 'stack_base' in kargs: + stack_base = kargs['stack_base'] + + stack_base_ad = kargs.get('stack_base_ad', stack_base) stack_size = kargs.get('stack_size', stack_size) vm_add_memory_page(stack_base_ad, codenat.PAGE_READ|codenat.PAGE_WRITE, @@ -1269,13 +1277,15 @@ def vm2pe(fname, runtime_dll = None, e_orig = None, max_addr = 1<<64): xx = str(mye) mye.content = xx ad = e_orig.rva2virt(e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva) - ad = mye.virt2rva(ad) - mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva = ad - mye.DirRes = pe.DirRes.unpack(xx,ad,mye) - #print repr(mye.DirRes) - s_res = mye.SHList.add_section(name = "myres", rawsize = len(mye.DirRes)) - mye.DirRes.set_rva(s_res.addr) - print repr(mye.DirRes) + print 'dirres', hex(ad) + if ad != 0: + ad = mye.virt2rva(ad) + mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva = ad + mye.DirRes = pe.DirRes.unpack(xx,ad,mye) + #print repr(mye.DirRes) + s_res = mye.SHList.add_section(name = "myres", rawsize = len(mye.DirRes)) + mye.DirRes.set_rva(s_res.addr) + print repr(mye.DirRes) # generation open(fname, 'w').write(str(mye)) @@ -1319,7 +1329,7 @@ def do_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, if not known_blocs[my_eip].b.lines: raise ValueError('cannot disasm bloc') try: - my_eip = vm_exec_blocs(my_eip, known_blocs) + my_eip = vm_exec_bloc(my_eip, known_blocs) except KeyboardInterrupt: return None, None py_exception = vm_get_exception() |