diff options
| author | Camille Mougey <commial@gmail.com> | 2015-07-21 12:54:09 +0200 |
|---|---|---|
| committer | Camille Mougey <commial@gmail.com> | 2015-07-21 12:54:09 +0200 |
| commit | 97463558ea31744a24e3330ab3227e2098878d03 (patch) | |
| tree | 480e2af9a1f30c027b07c8feb2889eb8bed01a77 | |
| parent | e82d888243fc5f283e7a3d5b12e5cefaf950edc5 (diff) | |
| parent | 2ff7161eaba5da7845c69be28e8092f030b94bed (diff) | |
| download | miasm-97463558ea31744a24e3330ab3227e2098878d03.tar.gz miasm-97463558ea31744a24e3330ab3227e2098878d03.zip | |
Merge pull request #196 from serpilliere/fix_pushw
Fix pushw
| -rw-r--r-- | miasm2/arch/x86/arch.py | 73 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 68 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 66 | ||||
| -rw-r--r-- | test/arch/x86/unit/mn_stack.py | 60 | ||||
| -rw-r--r-- | test/test_all.py | 1 |
5 files changed, 213 insertions, 55 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 33fd428f..f966c860 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -3751,13 +3751,30 @@ addop("outsd", [bs8(0x6f), bs_opmode64]) # addop("pause", [bs8(0xf3), bs8(0x90)]) -addop("pop", [bs8(0x8f), stk] + rmmod(d0)) -addop("pop", [bs("01011"), stk, reg]) -addop("pop", [bs8(0x1f), stk, d_ds]) -addop("pop", [bs8(0x07), stk, d_es]) -addop("pop", [bs8(0x17), stk, d_ss]) -addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs]) -addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs]) +addop("popw", [bs8(0x8f), stk, bs_opmode16] + rmmod(d0)) +addop("popw", [bs("01011"), stk, reg, bs_opmode16]) +addop("popw", [bs8(0x1f), stk, d_ds, bs_opmode16]) +addop("popw", [bs8(0x07), stk, d_es, bs_opmode16]) +addop("popw", [bs8(0x17), stk, d_ss, bs_opmode16]) +addop("popw", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode16]) +addop("popw", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode16]) + +addop("pop", [bs8(0x8f), stk, bs_opmode32] + rmmod(d0)) +addop("pop", [bs("01011"), stk, reg, bs_opmode32]) +addop("pop", [bs8(0x1f), stk, d_ds, bs_opmode32]) +addop("pop", [bs8(0x07), stk, d_es, bs_opmode32]) +addop("pop", [bs8(0x17), stk, d_ss, bs_opmode32]) +addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode32]) +addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode32]) + +addop("pop", [bs8(0x8f), stk, bs_opmode64] + rmmod(d0)) +addop("pop", [bs("01011"), stk, reg, bs_opmode64]) +addop("pop", [bs8(0x1f), stk, d_ds, bs_opmode64]) +addop("pop", [bs8(0x07), stk, d_es, bs_opmode64]) +addop("pop", [bs8(0x17), stk, d_ss, bs_opmode64]) +addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode64]) +addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode64]) + # popa_name = {16:'POPA', 32:'POPAD'} # bs_popa_name = bs_modname_size(l=0, name=popa_name) @@ -3777,16 +3794,38 @@ addop("prefetch1", [bs8(0x0f), bs8(0x18)] + rmmod(d2, rm_arg_m08)) addop("prefetch2", [bs8(0x0f), bs8(0x18)] + rmmod(d3, rm_arg_m08)) addop("prefetchnta", [bs8(0x0f), bs8(0x18)] + rmmod(d0, rm_arg_m08)) -addop("push", [bs8(0xff), stk] + rmmod(d6)) -addop("push", [bs("01010"), stk, reg]) -addop("push", [bs8(0x6a), s08, stk]) -addop("push", [bs8(0x68), d_imm, stk]) -addop("push", [bs8(0x0e), stk, d_cs]) -addop("push", [bs8(0x16), stk, d_ss]) -addop("push", [bs8(0x1e), stk, d_ds]) -addop("push", [bs8(0x06), stk, d_es]) -addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs]) -addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs]) +addop("pushw", [bs8(0xff), stk, bs_opmode16] + rmmod(d6)) +addop("pushw", [bs("01010"), stk, reg, bs_opmode16]) +addop("pushw", [bs8(0x6a), s08, stk, bs_opmode16]) +addop("pushw", [bs8(0x68), d_imm, stk, bs_opmode16]) +addop("pushw", [bs8(0x0e), stk, d_cs, bs_opmode16]) +addop("pushw", [bs8(0x16), stk, d_ss, bs_opmode16]) +addop("pushw", [bs8(0x1e), stk, d_ds, bs_opmode16]) +addop("pushw", [bs8(0x06), stk, d_es, bs_opmode16]) +addop("pushw", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode16]) +addop("pushw", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode16]) + +addop("push", [bs8(0xff), stk, bs_opmode32] + rmmod(d6)) +addop("push", [bs("01010"), stk, reg, bs_opmode32]) +addop("push", [bs8(0x6a), s08, stk, bs_opmode32]) +addop("push", [bs8(0x68), d_imm, stk, bs_opmode32]) +addop("push", [bs8(0x0e), stk, d_cs, bs_opmode32]) +addop("push", [bs8(0x16), stk, d_ss, bs_opmode32]) +addop("push", [bs8(0x1e), stk, d_ds, bs_opmode32]) +addop("push", [bs8(0x06), stk, d_es, bs_opmode32]) +addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode32]) +addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode32]) + +addop("push", [bs8(0xff), stk, bs_opmode64] + rmmod(d6)) +addop("push", [bs("01010"), stk, reg, bs_opmode64]) +addop("push", [bs8(0x6a), s08, stk, bs_opmode64]) +addop("push", [bs8(0x68), d_imm, stk, bs_opmode64]) +addop("push", [bs8(0x0e), stk, d_cs, bs_opmode64]) +addop("push", [bs8(0x16), stk, d_ss, bs_opmode64]) +addop("push", [bs8(0x1e), stk, d_ds, bs_opmode64]) +addop("push", [bs8(0x06), stk, d_es, bs_opmode64]) +addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode64]) +addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode64]) # pusha_name = {16:'PUSHA', 32:'PUSHAD'} # bs_pusha_name = bs_modname_size(l=0, name=pusha_name) diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 4dafc809..6b5ae583 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -620,55 +620,57 @@ def dec(ir, instr, a): return e, [] -def push(ir, instr, a): +def push_gen(ir, instr, a, size): e = [] - s = instr.mode - size = instr.v_opmode() - opmode, admode = s, instr.v_admode() - # special case segment regs - if a in [ES, CS, SS, DS, FS, GS]: - off = admode - else: - off = a.size - if not s in [16, 32, 64]: + if not size in [16, 32, 64]: raise ValueError('bad size stacker!') - if isinstance(a, m2_expr.ExprInt): - a = m2_expr.ExprInt_fromsize(s, a.arg) + if a.size < size: + a = a.zeroExtend(size) + elif a.size == size: + pass + else: + raise ValueError('strange arg size') - c = mRSP[instr.mode][:s] - m2_expr.ExprInt_fromsize(s, off / 8) - e.append(m2_expr.ExprAff(mRSP[instr.mode][:s], c)) - # we sub vopmode to stack, but mem access is arg size wide + sp = mRSP[instr.mode] + new_sp = sp - m2_expr.ExprInt_from(sp, size / 8) + e.append(m2_expr.ExprAff(sp, new_sp)) if ir.do_stk_segm: - c = m2_expr.ExprOp('segm', SS, c) - e.append(m2_expr.ExprAff(m2_expr.ExprMem(c, a.size), a)) + new_sp = m2_expr.ExprOp('segm', SS, new_sp) + e.append(m2_expr.ExprAff(m2_expr.ExprMem(new_sp, size), a)) return e, [] +def push(ir, instr, a): + return push_gen(ir, instr, a, instr.mode) -def pop(ir, instr, a): +def pushw(ir, instr, a): + return push_gen(ir, instr, a, 16) + + +def pop_gen(ir, instr, a, size): e = [] - s = instr.mode - size = instr.v_opmode() - opmode, admode = s, instr.v_admode() - # special case segment regs - if a in [ES, CS, SS, DS, FS, GS]: - off = admode - else: - off = a.size - if not s in [16, 32, 64]: + if not size in [16, 32, 64]: raise ValueError('bad size stacker!') - new_esp = mRSP[instr.mode][:s] + m2_expr.ExprInt_fromsize(s, off / 8) + + sp = mRSP[instr.mode] + new_sp = sp + m2_expr.ExprInt_from(sp, size / 8) # don't generate ESP incrementation on POP ESP if a != ir.sp: - e.append(m2_expr.ExprAff(mRSP[instr.mode][:s], new_esp)) + e.append(m2_expr.ExprAff(sp, new_sp)) # XXX FIX XXX for pop [esp] if isinstance(a, m2_expr.ExprMem): - a = a.replace_expr({mRSP[instr.mode]: new_esp}) - c = mRSP[instr.mode][:s] + a = a.replace_expr({sp: new_sp}) + c = sp if ir.do_stk_segm: c = m2_expr.ExprOp('segm', SS, c) e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(c, a.size))) return e, [] +def pop(ir, instr, a): + return pop_gen(ir, instr, a, instr.mode) + +def popw(ir, instr, a): + return pop_gen(ir, instr, a, 16) + def sete(ir, instr, a): e = [] @@ -944,7 +946,7 @@ def pushfd(ir, instr): def pushfw(ir, instr): - return push(ir, instr, compose_eflag(16)) + return pushw(ir, instr, compose_eflag(16)) def popfd(ir, instr): @@ -3175,7 +3177,9 @@ mnemo_func = {'mov': mov, 'inc': inc, 'dec': dec, 'push': push, + 'pushw': pushw, 'pop': pop, + 'popw': popw, 'sete': sete, 'setnz': setnz, 'setl': setl, diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 9d4e464d..93b651c0 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -1075,14 +1075,20 @@ reg_tests = [ # "f390"), - (m16, "00000000 POP WORD PTR [BX+SI]", + (m16, "00000000 POPW WORD PTR [BX+SI]", "8f00"), + (m32, "00000000 POPW WORD PTR [BX+SI]", + "66678f00"), (m32, "00000000 POP DWORD PTR [EAX]", "8f00"), (m64, "00000000 POP QWORD PTR [RAX]", "8f00"), + (m16, "00000000 POPW AX", + "8fC0"), + (m32, "00000000 POPW AX", + "668fC0"), (m32, "00000000 POP EAX", "8fC0"), (m64, "00000000 POP RAX", @@ -1106,6 +1112,28 @@ reg_tests = [ (m32, "00000000 POP GS", "0fa9"), + (m16, "00000000 POPW DS", + "1f"), + (m16, "00000000 POPW ES", + "07"), + (m16, "00000000 POPW SS", + "17"), + (m16, "00000000 POPW FS", + "0fa1"), + (m16, "00000000 POPW GS", + "0fa9"), + + (m32, "00000000 POPW DS", + "661f"), + (m32, "00000000 POPW ES", + "6607"), + (m32, "00000000 POPW SS", + "6617"), + (m32, "00000000 POPW FS", + "660fa1"), + (m32, "00000000 POPW GS", + "660fa9"), + (m16, "00000000 POPA", "61"), (m32, "00000000 POPAD", @@ -1130,7 +1158,7 @@ reg_tests = [ "0f1800"), - (m16, "00000000 PUSH AX", + (m16, "00000000 PUSHW AX", "50"), (m32, "00000000 PUSH EAX", "50"), @@ -1138,9 +1166,9 @@ reg_tests = [ "50"), (m64, "00000000 PUSH R10", "4152"), - (m16, "00000000 PUSH WORD PTR [BX+SI]", + (m16, "00000000 PUSHW WORD PTR [BX+SI]", "FF30"), - (m16, "00000000 PUSH WORD PTR [EAX]", + (m16, "00000000 PUSHW WORD PTR [EAX]", "67FF30"), (m16, "00000000 PUSH DWORD PTR [EAX]", "6667FF30"), @@ -1149,11 +1177,11 @@ reg_tests = [ (m64, "00000000 PUSH QWORD PTR [RAX]", "FF30"), - (m16, "00000000 PUSH 0x11", + (m16, "00000000 PUSHW 0x11", "6a11"), (m32, "00000000 PUSH 0x11223344", "6844332211"), - (m32, "00000000 PUSH 0x1122", + (m32, "00000000 PUSHW 0x1122", "66682211"), (m32, "00000000 PUSH 0x80", "6880000000"), @@ -1177,6 +1205,32 @@ reg_tests = [ (m32, "00000000 PUSH GS", "0fa8"), + (m32, "00000000 PUSHW CS", + "660e"), + (m32, "00000000 PUSHW SS", + "6616"), + (m32, "00000000 PUSHW DS", + "661E"), + (m32, "00000000 PUSHW ES", + "6606"), + (m32, "00000000 PUSHW FS", + "660fa0"), + (m32, "00000000 PUSHW GS", + "660fa8"), + + (m16, "00000000 PUSHW CS", + "0e"), + (m16, "00000000 PUSHW SS", + "16"), + (m16, "00000000 PUSHW DS", + "1E"), + (m16, "00000000 PUSHW ES", + "06"), + (m16, "00000000 PUSHW FS", + "0fa0"), + (m16, "00000000 PUSHW GS", + "0fa8"), + (m16, "00000000 PUSHA", "60"), (m32, "00000000 PUSHAD", diff --git a/test/arch/x86/unit/mn_stack.py b/test/arch/x86/unit/mn_stack.py new file mode 100644 index 00000000..dd349d54 --- /dev/null +++ b/test/arch/x86/unit/mn_stack.py @@ -0,0 +1,60 @@ +#! /usr/bin/env python +from asm_test import Asm_Test + + +class Test_PUSHPOP(Asm_Test): + TXT = ''' + main: + MOV EBP, ESP + PUSH 0x11223344 + POP EAX + CMP EBP, ESP + JNZ BAD + + PUSHW 0x1122 + POPW AX + CMP EBP, ESP + JNZ BAD + + PUSH SS + POP EAX + CMP EBP, ESP + JNZ BAD + + PUSHW SS + POPW AX + CMP EBP, ESP + JNZ BAD + + PUSHFD + POP EAX + CMP EBP, ESP + JNZ BAD + + PUSHFW + POPW AX + CMP EBP, ESP + JNZ BAD + + PUSH EAX + POPFD + CMP EBP, ESP + JNZ BAD + + PUSHW AX + POPFW + CMP EBP, ESP + JNZ BAD + + RET + +BAD: + INT 0x3 + RET + ''' + def check(self): + assert(self.myjit.cpu.ESP-4 == self.myjit.cpu.EBP) + + +if __name__ == "__main__": + [test()() for test in [Test_PUSHPOP]] diff --git a/test/test_all.py b/test/test_all.py index 895dbdac..f59e3781 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -35,6 +35,7 @@ testset += RegressionTest(["x86/arch.py"], base_dir="arch", for script in ["x86/sem.py", "x86/unit/mn_strings.py", "x86/unit/mn_float.py", + "x86/unit/mn_stack.py", "arm/arch.py", "arm/sem.py", "msp430/arch.py", |