import os
import vtrace
import atlasutils.envi_x86 as ax86
import atlasutils.vtraceutils as av
from atlasutils.envi_x86 import REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_ESI, REG_EDI, REG_EIP, REG_ESP, REG_EBP

y='QkJCQjIAAACR2PFtcCA6q2eaC8SR+8dmD/zNzLQC+td3tFQ4qx8O447TDeuZw5P+0SsbEcYR78jKLw=='.decode('base64')
x="""
eb04afc2bfa381ec   0001000031c9880c
0cfec175f931c0ba   efbeadde02040c00
d0c1ca088a1c0c8a   3c04881c04883c0c 
fec175e8e95c0000   0089e381c3040000 
005c583d41414141   7543583d42424242 
753b5a89d189e689   df29cff3a489de89 
d189df29cf31c031   db31d2fec0021c06 
8a14068a341e8834   0688141e00f230f6 
8a1c168a1730da88   17474975de31db89 
d8fec0cd809090e8   9dffffff41414141""".replace('\n','').replace(' ','')

z = x.decode('hex') + y 


#emu.run()
#file('output','wb').write(emu.readMemory(emu.getRegister(REG_ESI)-50,50))

os.system('su -c /usr/bin/wineserver atlas')
emu=ax86.geti386Emulator(z)
trace = av.atch('wineserver')

def init(emu, trace):
    global vstackbase, emustackbase
    #trace
    trace.writeMemory(0x8048100, z)
    #trace.addBreakByAddr(0x8048193)
    trace.setProgramCounter(0x8048100)

    #emu


    for x in 'eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp' :
        trace.setRegisterByName(x, 0)
        emu.setRegisterByName(x, 0)

    vstackbase = trace.getMemoryMap(trace.getStackCounter())[0] & 0xfffff000
    emustackbase = 0xbffff000
    trace.setStackCounter(vstackbase + 0xe00)
    trace.setRegister(REG_EBP, vstackbase + 0xe00)
    emu.setStackCounter(emustackbase + 0xe00)
    emu.setRegister(REG_EBP, emustackbase + 0xe00)



def test(emu, trace):
    global vstackbase, emustackbase
    try:
        emumem = emu.readMemory(emu.getRegister(REG_ESI)-50,50)
        tracemem = trace.readMemory(trace.getRegister(REG_ESI)-50,50)
        if emumem != tracemem:
            print repr(emumem)
            print repr(tracemem)
            raise Exception( "Difference!")
    except Exception, e:
        print e
        pass
    for ridx in xrange(6):
        tr = trace.getRegister(ridx)
        er = emu.getRegister(ridx)
        if er & 0xffff0000 == 0xbfff0000:
            er -= emustackbase
            tr -= vstackbase
        if tr != er:
            print "0x%x:   ridx: %x, t= %x, emu= %x" % (trace.getProgramCounter(), ridx, tr, er)
            raise Exception( "Difference!")

init(emu, trace)
while True:
    ip = emu.getProgramCounter()
    emu.stepi()
    trace.stepi()
    if ip == trace.getProgramCounter():
        op = trace.parseOpcode(ip)
        trace.addBreakByAddr(ip+len(op))
        trace.run()
        print "sleeping while we wait for the traced program to complete this opcode."
        while trace.running:
            time.sleep(.1)

    test(emu, trace)


