SetUnhandledExceptionFilter : Continue execution 1 opcode further

I'm working on an Xbox1 emulator in Delphi, and because I run the games on the local CPU I have to create a failsafe for ring0 instructions that can occur inside the game-code.

To be able to trap these instructions, I've learned that SetUnhandledExceptionFilter can register a function that's going to be called on non-Delphi exceptions (provided I set JITEnable to a value above 0). The signature of the registered callback function reads :

function ExceptionFilter(E: LPEXCEPTION_POINTERS): Integer; stdcall;

Inside that function, I can test for illegal instructions like this :

// STATUS_PRIVILEGED_INSTRUCTION = $C0000096
if E.ExceptionRecord.ExceptionCode = STATUS_PRIVILEGED_INSTRUCTION then

One of the offending instructions is WVINDB ($0F,$09) which I can detect like this :

 // See if the instruction pointer is a WBINVD opcode :
 if  (PAnsiChar(E.ExceptionRecord.ExceptionAddress)[0] = #$0F)
 and (PAnsiChar(E.ExceptionRecord.ExceptionAddress)[1] = #$09) then

This all works (provided I run this outside the debugger) but I can't get the code to execute beyond the failing instruction - I tried it like this:

  begin
    // Skip the WBINVD instruction, and continue execution :
    Inc(DWORD(E.ExceptionRecord.ExceptionAddress), 2);
    Result := EXCEPTION_CONTINUE_EXECUTION;
    Exit;
  end;

Alas, that doesn't work. Actually, I would have used the real instruction pointer (E.ContextRecord.Eip), but somehow the entire ContextRecord doesn't seem populated.

What can I do so this does work as intended?

PS: When running with the debugger, I would expect this code to end up in my ExceptionFilter routine, but it doesn't - it only works without the debugger; Why's that?

DebugHook := 0; // Act as if there's no debugger
// Trigger a privileged instruction exception via this ring0 instruction :
asm
  WBINVD
end;
// Prove that my exception-filter worked :
ShowMessage('WBINVD succesfully ignored!');

Answers


SetUnhandledExceptionFilter seems to be some kind of Delphi wrapper, maybe you have more luck if you do it directly?

You can register your own Exception handler with AddVectoredExceptionHandler, this will call a callback function that gives you an EXCEPTION_POINTERS structure. The Context member of that structure returns ao EIP which you can modify.

If you return EXCEPTION_CONTINUE_EXECUTION in the Callback execution continues at the given EIP.


Need Your Help

Get last record based on today's date

mysql

Hello I have a table for football games, and I need to get last game and next game based on today's date.

Viewing Row number in GridView Control C#

c# .net gridview datagridview

I want to know if it possible to add a row number for each row in the GridView Control in the boxes as shown in the image.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.