#include "dos_emu.hpp" #include #include #include #include #include static void dos_functions(mcontext_t& mcontext); static void dpmi_functions(mcontext_t& mcontext, long unsigned int& flags); void dos_emu_handler(int, siginfo_t*, void* c) { ucontext_t* context = (ucontext_t*) c; uint8_t* instruction = (uint8_t*) context->uc_mcontext.gregs[REG_EIP]; fprintf(stderr, "eip: 0x%lx\n", instruction); if (instruction[0] == 0xFB) //mnemonic STI { //we cant do this in user space so ignore for now. context->uc_mcontext.gregs[REG_EIP] += 1; } else if (instruction[0] == 0xCD) //mnemonic INT { if(instruction[1] == 0x21) { dos_functions(context->uc_mcontext); } if(instruction[1] == 0x31) { dpmi_functions(context->uc_mcontext, context->uc_flags); } //skip the interrupt and hopefully we handled it owk. context->uc_mcontext.gregs[REG_EIP] += 2; } else { //whoops we fucked up something fierce. abort(); } return; } static void dos_functions(mcontext_t& mcontext) { uint8_t ah = (mcontext.gregs[REG_EAX] & 0x0000FF00) >> 8; uint8_t al = mcontext.gregs[REG_EAX] & 0x000000FF; uint16_t ax = mcontext.gregs[REG_EAX] & 0x0000FFFF; uint16_t dx = mcontext.gregs[REG_EDX] & 0x0000FFFF; //Get dos version if(ah == 0x30) { mcontext.gregs[REG_EAX] &= 0xFFFF0000; mcontext.gregs[REG_EAX] |= 6 << 8; mcontext.gregs[REG_EAX] |= 22; mcontext.gregs[REG_EBX] &= 0xFFFF0000; mcontext.gregs[REG_EBX] |= 0x000000DE; mcontext.gregs[REG_ECX] = 0xDEADBEAF; if(al == 1) { mcontext.gregs[REG_EBX] |= 1 << 8; } else { mcontext.gregs[REG_EBX] |= 2 << 8; } } //Dos4gw install check if(ax == 0xFF00 && dx == 0x0078) { mcontext.gregs[REG_EAX] &= 0xFFFFFF00; mcontext.gregs[REG_EAX] |= 1; //should possible set GS... well fuck. } } static void dpmi_functions(mcontext_t& mcontext, long unsigned int& flags) { uint16_t ax = mcontext.gregs[REG_EAX] & 0x0000FFFF; //Get Segment base address if (ax == 0x0006) { mcontext.gregs[REG_ECX] &= 0xFFFF0000; mcontext.gregs[REG_EDX] &= 0xFFFF0000; flags = 0; } }