SetUnhandledExceptionFilter mit EXCEPTION_CONTINUE_EXECUTION Problem



  • Hallo zusammen,

    hab was kniffliges was auch in den Assemblerbereich gehören könnte, da ich aber (fast) kein Assembler kann, fühle ich mich hier besser aufgehoben 😃

    Ich verwende in meinem Programm SetUnhandledExceptionFilter um ungehandelte Exceptions abzufangen.
    Meine Frage ist nun wie ich nach der Exception mein Programm weiter laufen lassen kann, wenn es möglich ist (ist über ExceptionFlags vorgegeben)?

    Einfach EXCEPTION_CONTINUE_EXECUTION zurüchzugeben reicht nicht, da der EIP immer noch an der Stelle der Exception steht.
    Im Internet habe ich ein Beispiel gefunden in dem er den EIP einfach eins hochzählt, allerdings führte das bei mir immer nur zu weiteren Exceptions und endlos Callstacks. 😞

    Hoffe mir kann hier jemand helfen, oder jemand weiß wer es wissen könnte 😃

    Gruß
    yogle



  • Grob gesagt: Es geht nicht.
    Auf eine unhandled exception kannst Du nicht einfach weitermachen. Du hast ja keine Ahnung, warum diese aufgetreten ist geschweige denn wo Du fortsetzen sollst.

    Baue ein try __except da ein wo eine Exception auftreten kann, dann hast Du es "korrekt" gelöst.

    Es mag zwar Situationen geben, wo man nach einer Unhandled Exception ein Stück weitermachen kann, aber diese sind doch sehr beschränkt und auf keinen Fall allgemein anwendbar.

    Also: Prozess beenden und nötigenfalls zuvor sich selber nochmals starten.



  • Ich hab das mal gemacht, allerdings nur für den Spezialfall einer Breakpoint-Exception (int 3). In dem Fall ist dann die Länge des Opcodes bekannt (1 von int 3). Ich denke, dass der Beispielcode für diesen Fall gedacht war. Ansonsten verschiebt das ändern des IP dich unter Umständen mitten in den nächsten Befehl, was dann wohl ziemlich bald zur nächsten Exception führt.



  • Ansonsten verschiebt das ändern des IP dich unter Umständen mitten in den nächsten Befehl, was dann wohl ziemlich bald zur nächsten Exception führt.

    Jep so sieht es ziemlich genau aus. Nach einer Versuchs-Access-Violation, musste z.B. zwei mal der EIP erhöht werden, danach konnte das Programm aber weitergeführt werden.
    Ob dies Möglich ist, ist halt abhängig von der Art der Exception, z.B. bei einem versuchten Zugriff auf eine Funktion die von einer Dll exportiert wurde und nicht über GetProcAddress initialisiert wurde, steht der EIP dann auf 0x00000000! Heißt, da kann man ihn lange erhöhen, bis man irgendwo in gescheitem Code landet 😃
    Und es ist auch davon abhängig was der weitere Code macht. Aber gut die Option lasse ich drinnen.

    Danke für eure Antworten

    Gruß
    yogle



  • yogle schrieb:

    z.B. bei einem versuchten Zugriff auf eine Funktion die von einer Dll exportiert wurde und nicht über GetProcAddress initialisiert wurde, steht der EIP dann auf 0x00000000!

    Das hab ich jetzt nicht ganz verstanden... 😕



  • Jochen Kalmbach schrieb:

    yogle schrieb:

    z.B. bei einem versuchten Zugriff auf eine Funktion die von einer Dll exportiert wurde und nicht über GetProcAddress initialisiert wurde, steht der EIP dann auf 0x00000000!

    Das hab ich jetzt nicht ganz verstanden... 😕

    Lol, ja ich wusste nicht, wie ich es beschreiben sollte.

    So was meinte ich:

    typedef BOOL (* BadFunction)(void);
    
    int main()
    {
        BadFunction Bad = NULL;
    
        Bad();    // <-- Hier passiert ja die Exception
    }
    

    Dann ist der EIP bei mir 0, da er ja diese Funktion ausführen will, die aber zeigt auf nichts (0).
    Oder sollte das nicht so sein?

    Als Möglichkeit solche Dinge zu "umgehen", könnte man doch die letzte korrekte Stelle des EIP zu nehmen und dann um nicht 1 sonder 2 zu erhöhen.
    Ich hätte auch noch einen Disassembler zur Hand (im Programm), mit dem könnte ich doch den kommenden Code disassemblen und den EIP auf die erste korrekte Stelle nach der Exception setzen, würde zumindest die Chance auf ein erfolgreiches Fortsetzen des Programmes erhöhen. Was meint ihr?

    Gruß
    yogle



  • Warum fragst Du nicht

    if (Bad != NULL) Bad()
    

    ab?



  • Jochen Kalmbach schrieb:

    Warum fragst Du nicht

    if (Bad != NULL) Bad()
    

    ab?

    Achso, Jetzt verstehe ich! Ähm ich hab einen Exception Filter Lib programmiert, die von anderen verwendet werden kann.
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-157905.html

    Somit hätte sich die Frage dann auch erledigt, oder?
    Aber was hältst du von dem Vorschlag mit dem Disassembler? Hatte sogar mal was gelesen vonwegen den Code zu reparieren. Alles sehr interessant, aber nicht einfach! 😉

    Gruß
    yogle



  • yogle schrieb:

    Aber was hältst du von dem Vorschlag mit dem Disassembler? Hatte sogar mal was gelesen vonwegen den Code zu reparieren.

    Wie ich sachon sagte: Es mag in Spezialfällen gehen; aber niemals allgemeingültig.



  • Jochen Kalmbach schrieb:

    yogle schrieb:

    Aber was hältst du von dem Vorschlag mit dem Disassembler? Hatte sogar mal was gelesen vonwegen den Code zu reparieren.

    Wie ich sachon sagte: Es mag in Spezialfällen gehen; aber niemals allgemeingültig.

    Ganz klar, aber ich möchte dem User so häufig wie möglich die Möglichkeit geben seine z.B. noch geöffneten Dateien etc. abzuspeichern. Ich schaue mal was sich machen lässt.

    Gruß
    yogle



  • Die IMHO einzig Sinnvolle Möglichkeit ist, dass Du um alle Codestellen, die Kritisch sein können ein "try-catch/__expect rumbaust und dann dort das "Speichern" aufrufst!


Anmelden zum Antworten