LCF-AT Posted August 30, 2017 Posted August 30, 2017 Hi guys, today I would like to ask how to implement a 100% working handler to log exception.So in the past I tried already to do this and its also working so far but I think its not working always so that the reason why I do ask to know how to do it correctly.So the main basic way I choosed is only using SetUnhandledExceptionFilter API with address to my Handler routine to read exception infos / log them / MessageBox them. invoke SetUnhandledExceptionFilter,offset HANDLER_SEH2 HANDLER_SEH2 proc log code etc invoke MessageBox,NULL, BUFFIS,chr$("Exception Info!"),MB_ICONINFORMATION mov eax, 1h ret As result I get this so far (mostly)... 30.08.2017 21:00:40 Exception: C0000005 regEax 00000000 regEcx 00000000 regEdx 00000022 regEbx 00000000 regEsp 0012FAE0 regEbp 0012FAE0 regEsi 00000111 regEdi 0012FB5C regEip 004010A2 BaseAddress: 00401000 AllocationBase: 00400000 Exception occurs into module bones.exe -----------EXECPTION----------- 004010A2 MOV DWORD PTR [EAX] , EAX ------------------------------- 004010A4 MOV EAX , 00000000H 004010A9 LEAVE 004010AA RETN 0010H 004010AD JMP 00401114H 004010AF CMP DWORD PTR [EBP+0CH] , 05H 004010B3 JNE 004010C0H 004010B5 MOV EAX , 00000000H 004010BA LEAVE 004010BB RETN 0010H 004010BE JMP 00401114H 004010C0 CMP DWORD PTR [EBP+0CH] , 4EH 004010C4 JNE 004010C8H 004010C6 JMP 00401114H 004010C8 CMP DWORD PTR [EBP+0CH] , 00000138H 004010CF JNE 004010D7H 004010D1 LEAVE 004010D2 RETN 0010H 004010D5 JMP 00401114H 004010D7 CMP DWORD PTR [EBP+0CH] , 7BH ...using DISAM lib to read commands and log them etc.But the problem is that its not working always and I am not sure why.Sometimes I dont get the messagebox at the end of my routine what makes me think that my handler routine wasnt called after the exception happend.So I wanna be just sure that it will always access my Handler routine if any exception occurs to log / show it.You know,similar as windows does to show a error MSG & infos.I am not sure whether using SetUnhandledExceptionFilter one time with my Handler routine is enough or not or whether it could be disabled by anything etc.Maybe you have some ideas how to do it right or example/s. Thank you
atom0s Posted August 30, 2017 Posted August 30, 2017 If anything else calls SetUnhandledExceptionFilter after you have placed yours, it will override your exception handling. If that is the case, what you can do is hook SetUnhandledExceptionFilter and block any future calls to it after you have personally placed your own filter. Another exception method to look into is: AddVectoredExceptionHandler 1
VirtualPuppet Posted August 30, 2017 Posted August 30, 2017 SutUnhandledExceptionFilter will only catch uncatched exceptions. If a previous exception-handler catches and exception and "handles" it (even if wrongly), it will not reach your handler (even if it might turn out to crash the application). If you use AddVectoredExceptionHandler instead, you will catch all exceptions (even if a handler is actively waiting for them) and can atleast log the trace-data, and return a value indicating that the exception-handler frame should search for a new handler. 1
LCF-AT Posted August 30, 2017 Author Posted August 30, 2017 Hi again, ok so you guys mean I should better use AddVectoredExceptionHandler.So just be sure again,so I dont wanna handle any exception with my code and will only log them if any does occur so thats all.At the end it should work go on with the original way etc you know.Also in that case I have another question.If I set a handler and it gets triggerd should I then remove it in my handler routine?If yes,what is if the exception gets successfully handled and later comes another exception so then it will no more access my Handler routine anymore.Just asking because I want to prevent any loops if no handlers are present etc. invoke AddVectoredExceptionHandler,TRUE,offset HANDLER_SEH2 mov HANDLER,eax int 3h <--- test exception HANDLER_SEH2 proc.. ...... invoke RemoveVectoredExceptionHandler,HANDLER <---- invoke MessageBox,NULL, BUFFIS,chr$("Exception Info!"),MB_ICONINFORMATION mov eax, EXCEPTION_CONTINUE_EXECUTION <---- ret HANDLER_SEH2 endp Or should I just use EXCEPTION_CONTINUE_SEARCH at the end without to remove the Handler handle?Would be that ok?As I said I just wanna log / MSG it thats all. PS: But what is if I procduce a exception in my Handler routine itself?Just asking if that could happen anyhow etc you know. greetz
VirtualPuppet Posted August 30, 2017 Posted August 30, 2017 6 minutes ago, LCF-AT said: Hi again, ok so you guys mean I should better use AddVectoredExceptionHandler.So just be sure again,so I dont wanna handle any exception with my code and will only log them if any does occur so thats all.At the end it should work go on with the original way etc you know.Also in that case I have another question.If I set a handler and it gets triggerd should I then remove it in my handler routine?If yes,what is if the exception gets successfully handled and later comes another exception so then it will no more access my Handler routine anymore.Just asking because I want to prevent any loops if no handlers are present etc. invoke AddVectoredExceptionHandler,TRUE,offset HANDLER_SEH2 mov HANDLER,eax int 3h <--- test exception HANDLER_SEH2 proc.. ...... invoke RemoveVectoredExceptionHandler,HANDLER <---- invoke MessageBox,NULL, BUFFIS,chr$("Exception Info!"),MB_ICONINFORMATION mov eax, EXCEPTION_CONTINUE_EXECUTION <---- ret HANDLER_SEH2 endp Or should I just use EXCEPTION_CONTINUE_SEARCH at the end without to remove the Handler handle?Would be that ok?As I said I just wanna log / MSG it thats all. PS: But what is if I procduce a exception in my Handler routine itself?Just asking if that could happen anyhow etc you know. greetz Basically, AddVectoredExceptionHandler adds to the top of the chain, so it is the first to be called (will get called by _all_ exceptions, even those that gets handled, so it is perfect for logging). You shouldn't perform code that can have exceptions inside an exception-handler, but if it does happen, you will just have a new exception raised, and if it's a repeated exception in the exception-handler, you'll enter an infinite loop And no, do not return EXCEPTION_CONTINUE_EXECUTION. It means you've handled the exception. You want to return EXCEPTION_CONTINUE_SEARCH, which means "I did not handle the exceptin, please keep searching in the chain." 1
LCF-AT Posted August 31, 2017 Author Posted August 31, 2017 Hi, yes I want to prevent such possible INI Loops if something was going wrong in my Handler log code etc. Good ok,so I could add a marker at the top of my Handler routine which I can reset at the end = Handler routine successfully passed = EXCEPTION_CONTINUE_SEARCH return or RemoveVectoredExceptionHandler and EXCEPTION_EXECUTE_HANDLER return or maybe just RemoveVectoredExceptionHandler & EXCEPTION_CONTINUE_SEARCH should also work to not come back to my Handler anymore.I will test a little around. greetz
VirtualPuppet Posted August 31, 2017 Posted August 31, 2017 (edited) 1 hour ago, LCF-AT said: Hi, yes I want to prevent such possible INI Loops if something was going wrong in my Handler log code etc. Good ok,so I could add a marker at the top of my Handler routine which I can reset at the end = Handler routine successfully passed = EXCEPTION_CONTINUE_SEARCH return or RemoveVectoredExceptionHandler and EXCEPTION_EXECUTE_HANDLER return or maybe just RemoveVectoredExceptionHandler & EXCEPTION_CONTINUE_SEARCH should also work to not come back to my Handler anymore.I will test a little around. greetz You shouldn't remove it. Just leave the handler there statically, and log exceptions through it Edited August 31, 2017 by VirtualPuppet 1
LCF-AT Posted September 1, 2017 Author Posted September 1, 2017 Hi again, so there is a problem with that infinite loop inside my Handler.So if there happens a exception because of any reason then my Handler routine gets called again / again etc without to stop = loop I wanted to prevent.Also if I just remove the Handler handle via RemoveVectoredExceptionHandler API right at the top. invoke RemoveVectoredExceptionHandler,HANDLER ; 1 call in my routine ..... int 3h ; setting exception at the end for testing ..... mov eax,EXCEPTION_CONTINUE_SEARCH ret In this case the exception happens inside my exception log routine and then I come back again at the top of my routine also if I used the remove API = INFI LOOP for ever.So whats the right way now to prevent such INFI Loops in that case?Seems to be a little tricky or? greetz
VirtualPuppet Posted September 1, 2017 Posted September 1, 2017 1 hour ago, LCF-AT said: Hi again, so there is a problem with that infinite loop inside my Handler.So if there happens a exception because of any reason then my Handler routine gets called again / again etc without to stop = loop I wanted to prevent.Also if I just remove the Handler handle via RemoveVectoredExceptionHandler API right at the top. invoke RemoveVectoredExceptionHandler,HANDLER ; 1 call in my routine ..... int 3h ; setting exception at the end for testing ..... mov eax,EXCEPTION_CONTINUE_SEARCH ret In this case the exception happens inside my exception log routine and then I come back again at the top of my routine also if I used the remove API = INFI LOOP for ever.So whats the right way now to prevent such INFI Loops in that case?Seems to be a little tricky or? greetz You're not supposed to generate exceptions in a handler, so it's not supported by the Windows API.
LCF-AT Posted September 2, 2017 Author Posted September 2, 2017 Hi, so thats why I am asking for it what to do in a case if happens a excetpion in my handler log routine who should log exceptions.If that happens then = INFI Loop for ever and need to exit the app from outside. greetz
LCF-AT Posted September 3, 2017 Author Posted September 3, 2017 Hi, I have another problem using a messagebox in my handler routine to show exception infos.So if I use diffrent threads and timers them my Handler proc + messagebox gets called also in a loop and then I have many same messageboxes open etc.So what to do in that case?Is there anything to stop entire app process so long the messagebox is shown etc?So at the moment I have disabled a MSG. greetz
evlncrn8 Posted September 3, 2017 Posted September 3, 2017 put a spinlock in the handler at the start, that'll do the job theres also addvectoredcontinuehandler which might be of intrest 1
LCF-AT Posted September 3, 2017 Author Posted September 3, 2017 Hi evlncrn8, listen,could you maybe just post any example?Just need to know the important set APIs & what to set for APIs / lock in my Handler routine proc etc I could test later.Just wanna prevent that self accessing loops and prevent calling tons of same MSG boxes if the app works in the background with other threads etc you know. Handler proc Pause All work in app API/s suspend threads etc Here my Log stuf / if exception happens here = dont call Handler proc again etc MSG Infos / user get MSG to see so long till Ok was pressed At the end xy / resume etc not sure yet Continue / ret Do you have something / code etc where I can have a look at?Just would like to know this parts correctly for 100 %. Thanks
evlncrn8 Posted September 4, 2017 Posted September 4, 2017 knocked this up for you quickly.. to do it as x64 its pretty much the same, just some register alteration.. which im sure you can do yourself the idea is in the exception handler exception handler start -> set spinlock -> do stuff at the return from the exception handler make sure to unset the spinlock before returning otherwise you'll go into an infinite loop in the exception handler, after the spinlock do your logging / logic etc.. .data? global_exception_spinlock BYTE ? ; make sure its in uninitialized data .code ; set spinlock push TRUE push FALSE push offset global_exception_spinlock call ASM_SpinLock ; do stuff.. all other threads causing exceptions will be 'trapped' in the spinlock, with the pause opcode the cpu usage is minimal ; reset spinlock push FALSE push TRUE push offset global_exception_spinlock call ASM_SpinLock ========== ASM_SpinLock proc uses eax ebx ecx, addressofspinlock:LPVOID, value1:BYTE, value2:BYTE cmp [addressofspinlock], (NULL) je outoffunction movzx eax, [value1] movzx ebx, [value2] mov ecx, [addressofspinlock] dospinlockwaitbyte: lock cmpxchg BYTE PTR [ecx], bl optimisedcinditionalspinlockokorspinlockwaiter: jz spinlockok spinlockwaiter: db 0f3h, 090h ; repz nop (pause) movzx eax, [value1] ; this line might be redundant jmp dospinlockwaitbyte spinlockok: outoffunction: ret ASM_SpinLock endp 1
LCF-AT Posted September 4, 2017 Author Posted September 4, 2017 Hi again, thanks for the example.Ok I see what you mean.If somewhere else a exception raised then it hangs inside so long till it was reset.Good idea so far.I have test it a little and get also some trouble.If I force a exception then its showing the MSG box with infos I made.In the background are sill running other threads.So if I now set mem BP on my app then it stops on the running thread and if now force another exception then its also jumping to my handler in your SpinLock where it loops inside but now I the app hangs and I cant move the MSG box or press Ok button it etc.Not happens always so / sometimes its working to show MSG by MSG.Maybe it has something to do that I test it in debugger itself.Not sure so far whether I could trust this method for 100 % you know.Maybe its really no good idea to use a MSG box and maybe I should just log datas to file only. PS: So I think on this forum are many coder people who building apps and using surely also something like that to log exception / error logs etc.So did nobody build something like this by itself or are there just ready codes you can just add without to take care about it anymore?Just asking of course.For MASM I didnt found anything like that yet. greetz
LCF-AT Posted September 7, 2017 Author Posted September 7, 2017 Hi, one more short question.Could anyone tell whether it was possible to get the exception name by exception code?Dont remember anymore how it was working to get the names. greetz
atom0s Posted September 7, 2017 Posted September 7, 2017 I'm not aware of any API that can pull exception info, just error info (ie. GetLastError -> FormatMessage) Other info regarding this: https://stackoverflow.com/a/33044673/1080150 1
evlncrn8 Posted September 7, 2017 Posted September 7, 2017 if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) exceptioninfo->ExceptionRecord->ExceptionCode, (SUBLANG_DEFAULT << 10), (LPSTR) &errorcodemessagebuffer, (sizeof(errorcodemessagebuffer)), NULL)) small snippet from what i use.. in the example you allocate the buffer and size yourself.. otherwise you have localfree overheads and shit... that code should be relatively easy to port to asm... 1
LCF-AT Posted September 7, 2017 Author Posted September 7, 2017 Hi, so FormatMessage I cant use to get the string of any exception code.Also I dont wanna code a bunch of exception value with names extra to add it in my code and make a compare to find the right exception name for exception code etc you know. @evlncrn8 I tried it but dosent work to get anything.... 0012FF6C 00401022 /CALL to FormatMessageA from bones.0040101D 0012FF70 00001200 |Flags = IGNORE_INSERTS|FROM_SYSTEM|0x0 0012FF74 00000000 |pSource = NULL 0012FF78 C0000005 |MessageId = 0xC0000005 0012FF7C 00000001 |LanguageId = 0x1 (LANG_ARABIC) 0012FF80 00438519 |Buffer = bones.00438519 0012FF84 00000100 |BufSize = 100 (256.) 0012FF88 00000000 \Arguments = NULL LastErr 00003B01 0012FF6C 00401022 /CALL to FormatMessageA from bones.0040101D 0012FF70 00001200 |Flags = IGNORE_INSERTS|FROM_SYSTEM|0x0 0012FF74 00000000 |pSource = NULL 0012FF78 C0000005 |MessageId = 0xC0000005 0012FF7C 00000000 |LanguageId = 0x0 (LANG_NEUTRAL) 0012FF80 00438519 |Buffer = bones.00438519 0012FF84 00000100 |BufSize = 100 (256.) 0012FF88 00000000 \Arguments = NULL ERROR_MR_MID_NOT_FOUND (0000013D) Other question: So I found on my HDD a file called ntstatus.inc.Inside of the inc file I can see all exception equ values and names too.Now I can add it into my MASM project but how to make a compare without to compare? STATUS_WAIT_1 equ 00000001 STATUS_WAIT_2 equ 00000002 ..... ; MessageId: STATUS_ACCESS_VIOLATION ; ; MessageText: ; ; The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s". ; STATUS_ACCESS_VIOLATION equ 0C0000005h ; winnt ....etc As I said I only have the exception codes but how to get the name of it with that file above?There is also lib but this I cant use = not for MASM only this inc file.Can I do something with that maybe? greetz
atom0s Posted September 8, 2017 Posted September 8, 2017 3 hours ago, evlncrn8 said: if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) exceptioninfo->ExceptionRecord->ExceptionCode, (SUBLANG_DEFAULT << 10), (LPSTR) &errorcodemessagebuffer, (sizeof(errorcodemessagebuffer)), NULL)) small snippet from what i use.. in the example you allocate the buffer and size yourself.. otherwise you have localfree overheads and shit... that code should be relatively easy to port to asm... FormatMessage wont work on actual exceptions from the system, for example access violations. (0xC0000005) With your code the call will fail with another error 0x13D as it is not meant to handle exception codes. The best bet method is to create a lookup table that includes exceptions you know can happen with your application and add more as you go or as they happen. There are some public lists of full exception ids and names along with some in the various Windows SDK headers offered by Microsoft to get started. In the plugin SDK for one of my projects, I have a simple C++ wrapper around a handful of known exceptions to convert them to strings, which can be seen here: http://git.ashita.atom0s.com/Ashita/Ashitav3-Release/src/master/plugins/ADK/AS_Exception.h This uses some preprocessor magic / macros to turn the raw codes into strings for the purpose of my project. 1
LCF-AT Posted September 8, 2017 Author Posted September 8, 2017 Hi, so what about the compare / set exception string names?Lets say I only check for 10 diffrent exception then I also need to write the exception names extra to output them.So in windows.inc file are already a few exceptions listet... STATUS_BREAKPOINT equ 80000003h STATUS_SINGLE_STEP equ 80000004h STATUS_ACCESS_VIOLATION equ 0C0000005h .... ...now I can check exception code for STATUS_ACCESS_VIOLATION for example....ok but to output the name I have to write also STATUS_ACCESS_VIOLATION another time etc you know what I mean right.So all in all I have to write a wolf if I wanna add all exception names.Thats just bad.I think somehow it should be work else anyhow.What about Olly or x32 Debugger?Did they also add all that manually? My exception log looks so now at the moment.... 09.09.2017 00:34:24 Exception: 80000003 regEax 00000001 regEcx 0012FA88 regEdx 77676C74 regEbx 00000000 regEsp 0012FAD8 regEbp 0012FAE0 regEsi 00000111 regEdi 75FEDB13 regEip 75FEDB13 Exception Address D:\WinAsm\Exception Test\bones.exe BaseAddress: 00401000 AllocationBase: 00400000 BaseAddress: 75FED000 AllocationBase: 75FA0000 Exception occurs into module: kernel32.dll API address and name at or before Exception: 75FEDB13 GetModuleHandleA Stack: 75FEDB13 ------------------------------ 00000000 | 0012FAD8 | 0040110D bones.exe 00000004 | 0012FADC | 00000000 00000008 | 0012FAE0 | 0012FB0C 0000000C | 0012FAE4 | 7616C4B7 user32.dll 00000010 | 0012FAE8 | 004E03C0 00000014 | 0012FAEC | 00000111 00000018 | 0012FAF0 | 000003EB ...... 75FEDB13 INT3 75FEDB14 INT3 75FEDB15 INT3 75FEDB16 INT3 75FEDB17 IN AL , DX 75FEDB18 POP EBP 75FEDB19 JMP 75FEDB08H 75FEDB1B NOP 75FEDB1C NOP 75FEDB1D NOP ....I think that should be enough infos I need to know so far. greetz
LCF-AT Posted March 22, 2022 Author Posted March 22, 2022 Hi again, long time after now I did check my code and was looking for a complete NTSTATUS error list and found that of MSDN.... https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 ...but I also found that list which has more (not all too) values of errors inside... https://davidvielmetter.com/tips/ntstatus-error-code-list/ ....so I wrote already a compare code (masm) of all values from that MSDN list in my source but now I see there are missing many more.So why did MSDN not added the other values or just all into their list?Just would like to have a complete error value list of all you know.Just want prevent using FormatMessage function. PS: Found this old link... https://www.codeproject.com/articles/6503/an-ntstatus-lookup-application ....but I can not download it.So can anyone download the demo & source zip and attach it here?Thank you. greetz
PoorPlayer Posted March 22, 2022 Posted March 22, 2022 (edited) 30 minutes ago, LCF-AT said: ...but I can not download it.So can anyone download the demo & source zip and attach it here?Thank you. NtStatus_demo.zip NtStatus_src.zip Edited March 22, 2022 by PoorPlayer Error .zip file 2
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now