char *e_print_regs(void) { static char buf[300]; char *p = buf; char *q = eregbuf; while (*q) *p++ = *q++; *p=0; exprintl(rEAX,buf,(ERB_L1+ERB_LEFTM)); exprintl(rEBX,buf,(ERB_L1+ERB_LEFTM)+13); exprintl(rECX,buf,(ERB_L1+ERB_LEFTM)+26); exprintl(rEDX,buf,(ERB_L1+ERB_LEFTM)+39); exprintl(rESI,buf,(ERB_L2+ERB_LEFTM)); exprintl(rEDI,buf,(ERB_L2+ERB_LEFTM)+13); exprintl(rEBP,buf,(ERB_L2+ERB_LEFTM)+26); exprintl(rESP,buf,(ERB_L2+ERB_LEFTM)+39); if (TheCPU.eflags&EFLAGS_VM) exprintl(TheCPU.veflags,buf,(ERB_L3+ERB_LEFTM)); else exprintl(get_vFLAGS(TheCPU.eflags),buf,(ERB_L3+ERB_LEFTM)); exprintw(TheCPU.cs,buf,(ERB_L3+ERB_LEFTM)+13); exprintw(TheCPU.ds,buf,(ERB_L3+ERB_LEFTM)+26); exprintw(TheCPU.es,buf,(ERB_L3+ERB_LEFTM)+39); exprintw(TheCPU.fs,buf,(ERB_L4+ERB_LEFTM)); exprintw(TheCPU.gs,buf,(ERB_L4+ERB_LEFTM)+13); exprintw(TheCPU.ss,buf,(ERB_L4+ERB_LEFTM)+26); exprintl(TheCPU.eflags,buf,(ERB_L4+ERB_LEFTM)+39); if (debug_level('e')>4) { int i; unsigned char *st = MEM_BASE32(LONG_SS+TheCPU.esp); if ((st >= mem_base && st < (unsigned char *)MEM_BASE32(0x110000)) || (st > (unsigned char *)config.dpmi_base && st <= (unsigned char *)config.dpmi_base + config.dpmi * 1024)) { unsigned short *stk = (unsigned short *)st; for (i=(ERB_L5+ERB_LEFTM); i<(ERB_L6-2); i+=5) { exprintw(*stk++,buf,i); } } } else buf[ERB_L5]=0; return buf; }
uint32_t x86_pop(struct sigcontext *scp, x86_ins *x86) { unsigned ss_base = GetSegmentBase(_ss); unsigned char *mem = MEM_BASE32(ss_base + (_esp & wordmask[(x86->_32bit+1)*2])); if (x86->_32bit) _esp += x86->operand_size; else SP += x86->operand_size; return (x86->operand_size == 4 ? READ_DWORDP(mem) : READ_WORDP(mem)); }
static void r_munprotect(unsigned int addr, unsigned int len, unsigned char *eip) { if (EFLAGS & EFLAGS_DF) addr -= len; if (debug_level('e')>3) dbug_printf("\tR_MUNPROT %08x:%08x %s\n", addr,addr+len,(EFLAGS&EFLAGS_DF?"back":"fwd")); if (LINEAR2UNIX(addr) != MEM_BASE32(addr) && !e_querymark(addr, len)) return; InvalidateNodePage(addr,len,eip,NULL); e_resetpagemarks(addr,len); e_munprotect(addr,len); }
/* * Return address of the stub function is passed into eip */ static void m_munprotect(unsigned int addr, unsigned int len, unsigned char *eip) { if (debug_level('e')>3) e_printf("\tM_MUNPROT %08x:%p [%08x]\n", addr,eip,*((int *)(eip-3))); /* if only data in aliased low memory is hit, nothing to do */ if (LINEAR2UNIX(addr) != MEM_BASE32(addr) && !e_querymark(addr, len)) return; /* Always unprotect and clear all code in the pages * for either DPMI data or code. * Maybe the stub was set up before that code was parsed. * Clear that code */ if (debug_level('e')>1 && e_querymark(addr, len)) e_printf("CODE %08x hit in DATA %p patch\n",addr,eip); /* if (UnCpatch((void *)(eip-3))) leavedos_main(0); */ InvalidateNodePage(addr,len,eip,NULL); e_resetpagemarks(addr,len); e_munprotect(addr,len); }
int x86_handle_prefixes(struct sigcontext *scp, unsigned cs_base, x86_ins *x86) { unsigned eip = _eip; int prefix = 0; x86->rep = 0; x86->cs = 0; x86->ds = 0; x86->es = 0; x86->fs = 0; x86->gs = 0; x86->ss = 0; x86->address_size = x86->operand_size = (x86->_32bit + 1) * 2; for (;; eip++) { switch(*(unsigned char *)MEM_BASE32(cs_base + eip)) { /* handle (some) prefixes */ case 0x26: prefix++; x86->es = 1; break; case 0x2e: prefix++; x86->cs = 1; break; case 0x36: prefix++; x86->ss = 1; break; case 0x3e: prefix++; x86->ds = 1; break; case 0x64: prefix++; x86->fs = 1; break; case 0x65: prefix++; x86->gs = 1; break; case 0x66: prefix++; x86->operand_size = 6 - x86->operand_size; break; case 0x67: prefix++; x86->address_size = 6 - x86->address_size; break; case 0xf2: prefix++; x86->rep = REPNZ; break; case 0xf3: prefix++; x86->rep = REPZ; break; default: return prefix; } } return prefix; }
static int decode_segreg(struct sigcontext *scp) { unsigned cs, eip; unsigned char *csp, *orig_csp; int ret = -1; x86_ins x86; x86._32bit = dpmi_mhp_get_selector_size(_cs); cs = GetSegmentBase(_cs); eip = _eip + x86_handle_prefixes(scp, cs, &x86); csp = (unsigned char *)MEM_BASE32(cs + eip); orig_csp = (unsigned char *)MEM_BASE32(cs + _eip); switch(*csp) { case 0x8e: /* mov segreg,r/m16 */ ret = sreg_idx(*(unsigned char *)MEM_BASE32(cs + eip + 1) >> 3); _eip += instr_len(orig_csp, x86._32bit); break; case 0xca: /*retf imm 16*/ case 0xcb: /*retf*/ case 0xcf: /*iret*/ { unsigned tmp_eip = x86_pop(scp, &x86); x86_pop(scp, &x86); ret = cs_INDEX; switch (*(unsigned char *)MEM_BASE32(cs + eip)) { case 0xca: /*retf imm 16*/ _esp += ((unsigned short *) (MEM_BASE32(cs + eip + 1)))[0]; break; case 0xcf: /*iret*/ scp->eflags = x86_pop(scp, &x86); break; } _eip = tmp_eip; } break; case 0xea: /* jmp seg:off16/off32 */ { unsigned tmp_eip; tmp_eip = x86.operand_size == 4 ? READ_DWORDP(MEM_BASE32(cs + eip + 1)) : READ_WORDP(MEM_BASE32(cs + eip + 1)); ret = cs_INDEX; _eip = tmp_eip; } break; case 0xc4: /* les */ ret = es_INDEX; _eip += instr_len(orig_csp, x86._32bit); break; case 0xc5: /* lds */ ret = ds_INDEX; _eip += instr_len(orig_csp, x86._32bit); break; case 0x07: /* pop es */ case 0x17: /* pop ss */ case 0x1f: /* pop ds */ ret = sreg_idx(*(unsigned char *)MEM_BASE32(cs + eip) >> 3); x86_pop(scp, &x86); _eip = eip + 1; break; case 0x0f: eip++; switch (*(unsigned char *)MEM_BASE32(cs + eip)) { case 0xa1: /* pop fs */ case 0xa9: /* pop gs */ x86_pop(scp, &x86); ret = sreg_idx(*(unsigned char *)MEM_BASE32(cs + eip) >> 3); _eip = eip + 1; break; case 0xb2: /* lss */ ret = ss_INDEX; _eip += instr_len(orig_csp, x86._32bit); break; case 0xb4: /* lfs */ ret = fs_INDEX; _eip += instr_len(orig_csp, x86._32bit); break; case 0xb5: /* lgs */ ret = gs_INDEX; _eip += instr_len(orig_csp, x86._32bit); break; } break; } return ret; }