Returning to execution after handling invalid instruction

Programming, for all ages and all languages.
Post Reply
smeezekitty
Member
Member
Posts: 50
Joined: Sat Mar 21, 2009 9:42 pm

Returning to execution after handling invalid instruction

Post by smeezekitty »

Ok. Here is the thing. I am working on a Windows driver that is designed
to emulate Pentium (+MMX?) on 486 class CPUs to allow you to run newer software

I successfully was able to catch the illegal instructions, but cannot figure out how to return to normal execution

Code: Select all

__declspec(naked) void illegal_operand_handler (void) {
    __asm{
        push    ebp
        mov     ebp, esp
        pushad
        pushfd
        push    ds
        mov     ds, ax
        mov     esi, [ebp+4]
        cld
        lods    byte ptr [esi]
       cmp     al, 0xf 
      je      handle_0xf
GoPrevTrap01:
        pop     ds
        popfd
        popad
        pop     ebp 
        jmp     dword ptr [prevIllegalOpHandler]
       
handle_0xf:
      lods   byte ptr [esi] //Find out what the faulting instruction is
      cmp      al, 0xA2
        jne      not_cpuid    
      add     dword ptr [ebp+3], 4
        pop     ds
        popfd
        popad
        pop     ebp
        iretd      
not_cpuid:
      jmp short GoPrevTrap01
    };
} 
Keeping it simple, I am trying to just skip the "cpuid" instruction. But the program either crashes or the whole OS BSoDs

Anybody help please?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Returning to execution after handling invalid instructio

Post by Combuster »

mov ds, ax
Uninitialized variable?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
smeezekitty
Member
Member
Posts: 50
Joined: Sat Mar 21, 2009 9:42 pm

Re: Returning to execution after handling invalid instructio

Post by smeezekitty »

Uninitialized variable?
Yeah I did that when I was trying different things to make it work. But as far as I can tell, DS isn't even used in that code

I guess I am confused on the stack layout. What is on the stack at the time of an invalid instruction interrupt and what needs to be on the stack
to get back to normal execution.
I tried to look for a document that shows the CPU state after an illegal instruction but couldn't find one
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Returning to execution after handling invalid instructio

Post by sortie »

You will want to read the Intel CPU documentation. The state after an invalid instruction is pretty much just like a normal exception (because it is that). The processor pushes a few things, the usual osdev interrupt tutorials will cover that stuff.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Returning to execution after handling invalid instructio

Post by bluemoon »

smeezekitty wrote:
Uninitialized variable?
Yeah I did that when I was trying different things to make it work. But as far as I can tell, DS isn't even used in that code
How about these:

Code: Select all

mov     esi, [ebp+4]
lods    byte ptr [esi]
smeezekitty wrote:I guess I am confused on the stack layout. What is on the stack at the time of an invalid instruction interrupt and what needs to be on the stack to get back to normal execution.
According the to manual, #UD has no error code, so the usual interrupt handler's stack layout.
You inspect the return address to figure out what instruction was causing fault, and
1. emulate it, adjust return address, and return (skip it)
2. terminate the process by other mechanism
3. or signal it like windows SEP.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Returning to execution after handling invalid instructio

Post by Brendan »

Hi,
smeezekitty wrote:

Code: Select all

      add     dword ptr [ebp+3], 4
If this instruction had a comment, someone would have been able to compare the comment (the intended purpose of the instruction) to the code (the actual implementation of that intended purpose) and may have realised there's a mismatch between intent and implementation.

Basically, the main bug is a lack of comments (which makes it harder to find less important bugs).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
smeezekitty
Member
Member
Posts: 50
Joined: Sat Mar 21, 2009 9:42 pm

Re: Returning to execution after handling invalid instructio

Post by smeezekitty »

Ok you guys nailed it with the uninitialized (E)AX
I re-added mov eax, [ebp+8]
I was messing around and somehow removed it

It works now. I will later probably need some hlep emulating specific instructions but for now I got it skipping CPUID successfully.
But I will be leaving tomorrow and won't be able to get back to it for several days
add dword ptr [ebp+3], 4
ebp+3 is wrong. ebp+4 is correct

The point is to increment the return address so it doesn't jump back to the faulting instruction

Some resources that helped me understand the stack a little better
http://www.acm.uiuc.edu/sigops/roll_you ... 6/idt.html
http://pdos.csail.mit.edu/6.828/2005/le ... slides.pdf
Post Reply