Esempio n. 1
0
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_())
Esempio n. 2
0
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_())
Esempio n. 3
0
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_())
Esempio n. 4
0
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_())
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
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)
Esempio n. 9
0
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)
Esempio n. 10
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
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)
Esempio n. 13
0
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_())
Esempio n. 14
0
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_())
Esempio n. 15
0
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)
Esempio n. 16
0
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)