def x86_das(ctx, i): al = operand.get_register(ctx, i, 'al') result_al = ctx.tmp(8) tmp0 = ctx.tmp(16) tmp1 = ctx.tmp(8) # ((al & 0xf) > 9 ctx.emit(and_(al, imm(0xf, 8), result_al)) ctx.emit(sub_(result_al, imm(9, 8), tmp0)) ctx.emit(and_(tmp0, imm(0xff00, 16), tmp0)) ctx.emit(bisnz_(tmp0, tmp1)) # || af == 1) ctx.emit(or_(tmp1, r('af', 8), tmp1)) ctx.emit(jcc_(tmp1, 'adjust0')) ctx.emit(str_(imm(0, 8), r('af', 8))) ctx.emit(jcc_(imm(1, 8), 'done0')) ctx.emit('adjust0') ctx.emit(sub_(result_al, imm(6, 8), tmp0)) ctx.emit(str_(tmp0, result_al)) ctx.emit(str_(imm(1, 8), r('af', 8))) ctx.emit('done0') # al > 0x99 ctx.emit(sub_(al, imm(0x99, 8), tmp0)) ctx.emit(and_(tmp0, imm(0xff00, 16), tmp0)) ctx.emit(bisnz_(tmp0, tmp1)) # || cf == 1 ctx.emit(or_(tmp1, r('cf', 8), tmp1)) ctx.emit(jcc_(tmp1, 'adjust1')) ctx.emit(str_(imm(0, 8), r('cf', 8))) ctx.emit(jcc_(imm(1, 8), 'done1')) ctx.emit('adjust1') ctx.emit(sub_(result_al, imm(0x60, 8), tmp0)) ctx.emit(str_(tmp0, result_al)) ctx.emit(str_(imm(1, 8), r('cf', 8))) ctx.emit('done1') set_sf(ctx, result_al) set_zf(ctx, result_al) set_pf(ctx, result_al) ctx.emit(undef_(r('of', 8))) operand.set_register(ctx, i, 'al', result_al)
def x86_das(ctx, i): al = operand.get_register(ctx, i, 'al') result_al = ctx.tmp(8) tmp0 = ctx.tmp(16) tmp1 = ctx.tmp(8) # ((al & 0xf) > 9 ctx.emit( and_ (al, imm(0xf, 8), result_al)) ctx.emit( sub_ (result_al, imm(9, 8), tmp0)) ctx.emit( and_ (tmp0, imm(0xff00, 16), tmp0)) ctx.emit( bisnz_(tmp0, tmp1)) # || af == 1) ctx.emit( or_ (tmp1, r('af', 8), tmp1)) ctx.emit( jcc_ (tmp1, 'adjust0')) ctx.emit( str_ (imm(0, 8), r('af', 8))) ctx.emit( jcc_ (imm(1, 8), 'done0')) ctx.emit('adjust0') ctx.emit( sub_ (result_al, imm(6, 8), tmp0)) ctx.emit( str_ (tmp0, result_al)) ctx.emit( str_ (imm(1, 8), r('af', 8))) ctx.emit('done0') # al > 0x99 ctx.emit( sub_ (al, imm(0x99, 8), tmp0)) ctx.emit( and_ (tmp0, imm(0xff00, 16), tmp0)) ctx.emit( bisnz_(tmp0, tmp1)) # || cf == 1 ctx.emit( or_ (tmp1, r('cf', 8), tmp1)) ctx.emit( jcc_ (tmp1, 'adjust1')) ctx.emit( str_ (imm(0, 8), r('cf', 8))) ctx.emit( jcc_ (imm(1, 8), 'done1')) ctx.emit('adjust1') ctx.emit( sub_ (result_al, imm(0x60, 8), tmp0)) ctx.emit( str_ (tmp0, result_al)) ctx.emit( str_ (imm(1, 8), r('cf', 8))) ctx.emit('done1') set_sf(ctx, result_al) set_zf(ctx, result_al) set_pf(ctx, result_al) ctx.emit( undef_(r('of', 8))) operand.set_register(ctx, i, 'al', result_al)
def x86_lods(ctx, i, size): src = ctx.source value = ctx.tmp(size) if i.mnemonic.startswith('rep'): rep_prologue(ctx, i) ctx.emit( ldm_ (src, value)) if size == 8: operand.set_register(ctx, i, 'al', value) elif size == 16: operand.set_register(ctx, i, 'ax', value) elif size == 32: operand.set_register(ctx, i, 'eax', value) else: operand.set_register(ctx, i, 'rax', value) ctx.emit( jcc_ (r('df', 8), 'decrement')) ctx.emit('increment') ctx.emit( add_ (src, imm(value.size // 8, ctx.word_size), src)) ctx.emit( jcc_ (imm(1, 8), 'set')) ctx.emit('decrement') ctx.emit( sub_ (src, imm(value.size // 8, ctx.word_size), src)) ctx.emit('set') ctx.emit( str_ (src, ctx.source)) if i.mnemonic.startswith('rep'): rep_epilogue(ctx, i)
def x86_lahf(ctx, i): result_ah = ctx.tmp(8) ctx.emit(str_(imm(0, 8), result_ah)) ctx.emit(or_(r('sf', 8), result_ah)) ctx.emit(lshl_(result_ah, imm(1, 8), result_ah)) ctx.emit(or_(r('zf', 8), result_ah)) ctx.emit(lshl_(result_ah, imm(2, 8), result_ah)) ctx.emit(or_(r('af', 8), result_ah)) ctx.emit(lshl_(result_ah, imm(2, 8), result_ah)) ctx.emit(or_(r('pf', 8), result_ah)) ctx.emit(lshl_(result_ah, imm(1, 8), result_ah)) ctx.emit(or_(imm(1, 8), result_ah)) ctx.emit(lshl_(result_ah, imm(1, 8), result_ah)) ctx.emit(or_(r('cf', 8), result_ah)) operand.set_register(ctx, i, 'ah', result_ah)
def x86_lahf(ctx, i): result_ah = ctx.tmp(8) ctx.emit( str_ (imm(0, 8), result_ah)) ctx.emit( or_ (r('sf', 8), result_ah)) ctx.emit( lshl_ (result_ah, imm(1, 8), result_ah)) ctx.emit( or_ (r('zf', 8), result_ah)) ctx.emit( lshl_ (result_ah, imm(2, 8), result_ah)) ctx.emit( or_ (r('af', 8), result_ah)) ctx.emit( lshl_ (result_ah, imm(2, 8), result_ah)) ctx.emit( or_ (r('pf', 8), result_ah)) ctx.emit( lshl_ (result_ah, imm(1, 8), result_ah)) ctx.emit( or_ (imm(1, 8), result_ah)) ctx.emit( lshl_ (result_ah, imm(1, 8), result_ah)) ctx.emit( or_ (r('cf', 8), result_ah)) operand.set_register(ctx, i, 'ah', result_ah)
def x86_cmpxchg8b(ctx, i): edx = operand.get_register(ctx, i, 'edx') eax = operand.get_register(ctx, i, 'eax') edx_eax = ctx.tmp(64) ecx = operand.get_register(ctx, i, 'ecx') ebx = operand.get_register(ctx, i, 'ebx') ecx_ebx = ctx.tmp(64) value = operand.get(ctx, i, 0) tmp0 = ctx.tmp(64) tmp1 = ctx.tmp(8) result_eax = ctx.tmp(32) result_edx = ctx.tmp(32) ctx.emit(lshl_(edx, imm(32, 8), edx_eax)) ctx.emit(str_(eax, tmp0)) ctx.emit(or_(edx_eax, tmp0, edx_eax)) ctx.emit(equ_(value, edx_eax, tmp1)) ctx.emit(jcc_(tmp1, 'equal')) ctx.emit('not-equal') ctx.emit(str_(value, result_eax)) ctx.emit(lshr_(value, imm(32, 8), value)) ctx.emit(str_(value, result_edx)) operand.set_register(ctx, i, 'edx', result_edx) operand.set_register(ctx, i, 'eax', result_eax) ctx.emit(str_(imm(0, 8), r('zf', 8))) ctx.emit(jcc_(imm(1, 8), 'done')) ctx.emit('equal') ctx.emit(lshl_(ecx, imm(32, 8), ecx_ebx)) ctx.emit(str_(ebx, tmp0)) ctx.emit(or_(ecx_ebx, tmp0, ecx_ebx)) operand.set(ctx, i, 0, ecx_ebx) ctx.emit(str_(imm(1, 8), r('zf', 8))) ctx.emit('done') ctx.emit(nop_())
def x86_cmpxchg8b(ctx, i): edx = operand.get_register(ctx, i, 'edx') eax = operand.get_register(ctx, i, 'eax') edx_eax = ctx.tmp(64) ecx = operand.get_register(ctx, i, 'ecx') ebx = operand.get_register(ctx, i, 'ebx') ecx_ebx = ctx.tmp(64) value = operand.get(ctx, i, 0) tmp0 = ctx.tmp(64) tmp1 = ctx.tmp(8) result_eax = ctx.tmp(32) result_edx = ctx.tmp(32) ctx.emit( lshl_ (edx, imm(32, 8), edx_eax)) ctx.emit( str_ (eax, tmp0)) ctx.emit( or_ (edx_eax, tmp0, edx_eax)) ctx.emit( equ_ (value, edx_eax, tmp1)) ctx.emit( jcc_ (tmp1, 'equal')) ctx.emit('not-equal') ctx.emit( str_ (value, result_eax)) ctx.emit( lshr_ (value, imm(32, 8), value)) ctx.emit( str_ (value, result_edx)) operand.set_register(ctx, i, 'edx', result_edx) operand.set_register(ctx, i, 'eax', result_eax) ctx.emit( str_ (imm(0, 8), r('zf', 8))) ctx.emit( jcc_ (imm(1, 8), 'done')) ctx.emit('equal') ctx.emit( lshl_ (ecx, imm(32, 8), ecx_ebx)) ctx.emit( str_ (ebx, tmp0)) ctx.emit( or_ (ecx_ebx, tmp0, ecx_ebx)) operand.set(ctx, i, 0, ecx_ebx) ctx.emit( str_ (imm(1, 8), r('zf', 8))) ctx.emit('done') ctx.emit( nop_())
def x86_cmpxchg16b(ctx, i): rdx = operand.get_register(ctx, i, 'rdx') rax = operand.get_register(ctx, i, 'rax') rdx_rax = ctx.tmp(128) rcx = operand.get_register(ctx, i, 'rcx') rbx = operand.get_register(ctx, i, 'rbx') rcx_rbx = ctx.tmp(128) value = operand.get(ctx, i, 0) tmp0 = ctx.tmp(128) tmp1 = ctx.tmp(8) result_rax = ctx.tmp(64) result_rdx = ctx.tmp(64) ctx.emit( lshl_ (rdx, imm(64, 8), rdx_rax)) ctx.emit( str_ (rax, tmp0)) ctx.emit( or_ (rdx_rax, tmp0, rdx_rax)) ctx.emit( equ_ (value, rdx_rax, tmp1)) ctx.emit( jcc_ (tmp1, 'equal')) ctx.emit('not-equal') ctx.emit( str_ (value, result_rax)) ctx.emit( lshr_ (value, imm(64, 8), value)) ctx.emit( str_ (value, result_rdx)) operand.set_register(ctx, i, 'rdx', result_rdx) operand.set_register(ctx, i, 'rax', result_rax) ctx.emit( str_ (imm(0, 8), r('zf', 8))) ctx.emit( jcc_ (imm(1, 8), 'done')) ctx.emit('equal') ctx.emit( lshl_ (rcx, imm(64, 8), rcx_rbx)) ctx.emit( str_ (rbx, tmp0)) ctx.emit( or_ (rcx_rbx, tmp0, rcx_rbx)) operand.set(ctx, i, 0, rcx_rbx) ctx.emit( str_ (imm(1, 8), r('zf', 8))) ctx.emit('done') ctx.emit( nop_())
def x86_cmpxchg16b(ctx, i): rdx = operand.get_register(ctx, i, 'rdx') rax = operand.get_register(ctx, i, 'rax') rdx_rax = ctx.tmp(128) rcx = operand.get_register(ctx, i, 'rcx') rbx = operand.get_register(ctx, i, 'rbx') rcx_rbx = ctx.tmp(128) value = operand.get(ctx, i, 0) tmp0 = ctx.tmp(128) tmp1 = ctx.tmp(8) result_rax = ctx.tmp(64) result_rdx = ctx.tmp(64) ctx.emit(lshl_(rdx, imm(64, 8), rdx_rax)) ctx.emit(str_(rax, tmp0)) ctx.emit(or_(rdx_rax, tmp0, rdx_rax)) ctx.emit(equ_(value, rdx_rax, tmp1)) ctx.emit(jcc_(tmp1, 'equal')) ctx.emit('not-equal') ctx.emit(str_(value, result_rax)) ctx.emit(lshr_(value, imm(64, 8), value)) ctx.emit(str_(value, result_rdx)) operand.set_register(ctx, i, 'rdx', result_rdx) operand.set_register(ctx, i, 'rax', result_rax) ctx.emit(str_(imm(0, 8), r('zf', 8))) ctx.emit(jcc_(imm(1, 8), 'done')) ctx.emit('equal') ctx.emit(lshl_(rcx, imm(64, 8), rcx_rbx)) ctx.emit(str_(rbx, tmp0)) ctx.emit(or_(rcx_rbx, tmp0, rcx_rbx)) operand.set(ctx, i, 0, rcx_rbx) ctx.emit(str_(imm(1, 8), r('zf', 8))) ctx.emit('done') ctx.emit(nop_())
def x86_aaa(ctx, i): al = operand.get_register(ctx, i, 'al') ah = operand.get_register(ctx, i, 'ah') result_al = ctx.tmp(8) result_ah = ctx.tmp(8) tmp0 = ctx.tmp(16) tmp1 = ctx.tmp(8) # ((al & 0xf) > 9 ctx.emit( and_ (al, imm(0xf, 8), result_al)) ctx.emit( sub_ (result_al, imm(9, 8), tmp0)) ctx.emit( and_ (tmp0, imm(0xff00, 16), tmp0)) ctx.emit( bisnz_(tmp0, tmp1)) # || af == 1) ctx.emit( or_ (tmp1, r('af', 8), tmp1)) ctx.emit( jcc_ (tmp1, 'adjust')) ctx.emit( str_ (imm(0, 8), r('af', 8))) ctx.emit( str_ (imm(0, 8), r('cf', 8))) ctx.emit( jcc_ (imm(1, 8), 'done')) ctx.emit('adjust') ctx.emit( add_ (result_al, imm(6, 8), tmp0)) ctx.emit( str_ (tmp0, result_al)) ctx.emit( add_ (ah, imm(1, 8), tmp0)) ctx.emit( str_ (tmp0, result_ah)) ctx.emit( str_ (imm(1, 8), r('af', 8))) ctx.emit( str_ (imm(1, 8), r('cf', 8))) ctx.emit('done') ctx.emit( undef_(r('of', 8))) ctx.emit( undef_(r('sf', 8))) ctx.emit( undef_(r('zf', 8))) ctx.emit( undef_(r('pf', 8))) operand.set_register(ctx, i, 'al', result_al) operand.set_register(ctx, i, 'ah', result_ah)
def x86_aaa(ctx, i): al = operand.get_register(ctx, i, 'al') ah = operand.get_register(ctx, i, 'ah') result_al = ctx.tmp(8) result_ah = ctx.tmp(8) tmp0 = ctx.tmp(16) tmp1 = ctx.tmp(8) # ((al & 0xf) > 9 ctx.emit(and_(al, imm(0xf, 8), result_al)) ctx.emit(sub_(result_al, imm(9, 8), tmp0)) ctx.emit(and_(tmp0, imm(0xff00, 16), tmp0)) ctx.emit(bisnz_(tmp0, tmp1)) # || af == 1) ctx.emit(or_(tmp1, r('af', 8), tmp1)) ctx.emit(jcc_(tmp1, 'adjust')) ctx.emit(str_(imm(0, 8), r('af', 8))) ctx.emit(str_(imm(0, 8), r('cf', 8))) ctx.emit(jcc_(imm(1, 8), 'done')) ctx.emit('adjust') ctx.emit(add_(result_al, imm(6, 8), tmp0)) ctx.emit(str_(tmp0, result_al)) ctx.emit(add_(ah, imm(1, 8), tmp0)) ctx.emit(str_(tmp0, result_ah)) ctx.emit(str_(imm(1, 8), r('af', 8))) ctx.emit(str_(imm(1, 8), r('cf', 8))) ctx.emit('done') ctx.emit(undef_(r('of', 8))) ctx.emit(undef_(r('sf', 8))) ctx.emit(undef_(r('zf', 8))) ctx.emit(undef_(r('pf', 8))) operand.set_register(ctx, i, 'al', result_al) operand.set_register(ctx, i, 'ah', result_ah)
def x86_aad(ctx, i): al = operand.get_register(ctx, i, 'al') ah = operand.get_register(ctx, i, 'ah') base = imm(10, 8) result_al = ctx.tmp(8) tmp0 = ctx.tmp(16) ctx.emit( mul_ (ah, base, tmp0)) ctx.emit( add_ (al, tmp0, tmp0)) ctx.emit( str_ (tmp0, result_al)) set_sf(ctx, result_al) set_zf(ctx, result_al) set_pf(ctx, result_al) ctx.emit( undef_(r('of', 8))) ctx.emit( undef_(r('af', 8))) ctx.emit( undef_(r('cf', 8))) operand.set_register(ctx, i, 'al', result_al)
def x86_aad(ctx, i): al = operand.get_register(ctx, i, 'al') ah = operand.get_register(ctx, i, 'ah') base = imm(10, 8) result_al = ctx.tmp(8) tmp0 = ctx.tmp(16) ctx.emit(mul_(ah, base, tmp0)) ctx.emit(add_(al, tmp0, tmp0)) ctx.emit(str_(tmp0, result_al)) set_sf(ctx, result_al) set_zf(ctx, result_al) set_pf(ctx, result_al) ctx.emit(undef_(r('of', 8))) ctx.emit(undef_(r('af', 8))) ctx.emit(undef_(r('cf', 8))) operand.set_register(ctx, i, 'al', result_al)
def x86_aam(ctx, i): al = operand.get_register(ctx, i, 'al') ah = operand.get_register(ctx, i, 'ah') base = imm(10, 8) result_al = ctx.tmp(8) result_ah = imm(0, 8) tmp0 = ctx.tmp(16) ctx.emit( div_ (al, base, result_ah)) ctx.emit( mod_ (al, tmp0, result_al)) set_sf(ctx, result_al) set_zf(ctx, result_al) set_pf(ctx, result_al) ctx.emit( undef_(r('of', 8))) ctx.emit( undef_(r('af', 8))) ctx.emit( undef_(r('cf', 8))) operand.set_register(ctx, i, 'al', result_al) operand.set_register(ctx, i, 'ah', result_ah)
def x86_aam(ctx, i): al = operand.get_register(ctx, i, 'al') ah = operand.get_register(ctx, i, 'ah') base = imm(10, 8) result_al = ctx.tmp(8) result_ah = imm(0, 8) tmp0 = ctx.tmp(16) ctx.emit(div_(al, base, result_ah)) ctx.emit(mod_(al, tmp0, result_al)) set_sf(ctx, result_al) set_zf(ctx, result_al) set_pf(ctx, result_al) ctx.emit(undef_(r('of', 8))) ctx.emit(undef_(r('af', 8))) ctx.emit(undef_(r('cf', 8))) operand.set_register(ctx, i, 'al', result_al) operand.set_register(ctx, i, 'ah', result_ah)
def x86_cpuid(ctx, i): eax = operand.get_register(ctx, i, 'eax') flag = ctx.tmp(8) ctx.emit( equ_ (eax, imm(0, 32), flag)) ctx.emit( jcc_ (flag, 'cpuid_basic')) ctx.emit( jcc_ (imm(1, 8), 'done')) ctx.emit('cpuid_basic') operand.set_register(ctx, i, 'eax', imm(0, 32)) operand.set_register(ctx, i, 'ebx', imm(0x756e6547, 32)) operand.set_register(ctx, i, 'ecx', imm(0x49656e69, 32)) operand.set_register(ctx, i, 'edx', imm(0x6c65746e, 32)) ctx.emit( jcc_ (imm(1, 8), 'done')) ctx.emit('done') ctx.emit( nop_())
def x86_cpuid(ctx, i): eax = operand.get_register(ctx, i, 'eax') flag = ctx.tmp(8) ctx.emit(equ_(eax, imm(0, 32), flag)) ctx.emit(jcc_(flag, 'cpuid_basic')) ctx.emit(jcc_(imm(1, 8), 'done')) ctx.emit('cpuid_basic') operand.set_register(ctx, i, 'eax', imm(0, 32)) operand.set_register(ctx, i, 'ebx', imm(0x756e6547, 32)) operand.set_register(ctx, i, 'ecx', imm(0x49656e69, 32)) operand.set_register(ctx, i, 'edx', imm(0x6c65746e, 32)) ctx.emit(jcc_(imm(1, 8), 'done')) ctx.emit('done') ctx.emit(nop_())
def x86_imul(ctx, i): if len(i.operands) == 1: # single operand form b = operand.get(ctx, i, 0) if b.size == 64: a_reg = 'rax' b_reg = 'rdx' elif b.size == 32: a_reg = 'eax' b_reg = 'edx' elif b.size == 16: a_reg = 'ax' b_reg = 'dx' elif b.size == 8: a_reg = 'al' b_reg = 'ah' a = operand.get_register(ctx, i, a_reg) result = ctx.tmp(b.size * 2) result_value = ctx.tmp(b.size) ctx.emit( mul_ (a, b, result)) ctx.emit( str_ (result, result_value)) operand.set_register(ctx, i, a_reg, result_value) ctx.emit( lshr_ (result, imm(b.size, 8), result_value)) operand.set_register(ctx, i, b_reg, result_value) _imul_set_flags(ctx, result) elif len(i.operands) == 2: # double operand form a = operand.get(ctx, i, 0) b = operand.get(ctx, i, 1) result = ctx.tmp(a.size * 2) ctx.emit( mul_ (a, b, result)) operand.set(ctx, i, 0, result) _imul_set_flags(ctx, result) else: # triple operand form a = operand.get(ctx, i, 1) b = operand.get(ctx, i, 2) if b.size < a.size: prev_b = b b = ctx.tmp(a.size) ctx.emit( sex_ (prev_b, b)) result = ctx.tmp(a.size * 2) ctx.emit( mul_ (a, b, result)) operand.set(ctx, i, 0, result) _imul_set_flags(ctx, result)
def x86_imul(ctx, i): if len(i.operands) == 1: # single operand form b = operand.get(ctx, i, 0) if b.size == 64: a_reg = 'rax' b_reg = 'rdx' elif b.size == 32: a_reg = 'eax' b_reg = 'edx' elif b.size == 16: a_reg = 'ax' b_reg = 'dx' elif b.size == 8: a_reg = 'al' b_reg = 'ah' a = operand.get_register(ctx, i, a_reg) result = ctx.tmp(b.size * 2) result_value = ctx.tmp(b.size) ctx.emit(mul_(a, b, result)) ctx.emit(str_(result, result_value)) operand.set_register(ctx, i, a_reg, result_value) ctx.emit(lshr_(result, imm(b.size, 8), result_value)) operand.set_register(ctx, i, b_reg, result_value) _imul_set_flags(ctx, result) elif len(i.operands) == 2: # double operand form a = operand.get(ctx, i, 0) b = operand.get(ctx, i, 1) result = ctx.tmp(a.size * 2) ctx.emit(mul_(a, b, result)) operand.set(ctx, i, 0, result) _imul_set_flags(ctx, result) else: # triple operand form a = operand.get(ctx, i, 1) b = operand.get(ctx, i, 2) if b.size < a.size: prev_b = b b = ctx.tmp(a.size) ctx.emit(sex_(prev_b, b)) result = ctx.tmp(a.size * 2) ctx.emit(mul_(a, b, result)) operand.set(ctx, i, 0, result) _imul_set_flags(ctx, result)