Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

mgrzeg.net - Admin on Rails :)

0xe0434f4d = .COM, czyli SEH a .NET

Czas najwyższy rozwiązać zagadkę numerologiczną z poprzedniego wpisu :). Zacznijmy od krótkiego kodu

KOD 1 (Wyjątek przechwycony)

 class SEH
{
 public static void Main(string[] args)
 {
    try {
     throw new Exception();
    }
    catch (Exception ex) { System.Diagnostics.Debugger.Log(0, "Test", "Błąd aplikacji .NET & SEH"); }
 }
}

Odpalamy WinDbg, ładujemy naszą aplikację i jedziemy:

0:000> sxe *
0:000> g
ModLoad: 77dc0000 77e6c000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll

ModLoad: 79060000 790bb000   c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll
(4cc.dd4): CLR exception - code e0434f4d (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012f2d4 ebx=e0434f4d ecx=00000000 edx=00000028 esi=0012f360 edi=00191878
eip=7c812afb esp=0012f2d0 ebp=0012f324 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
KERNEL32!RaiseException+0x53:
7c812afb 5e              pop     esi
0:000> kb
ChildEBP RetAddr  Args to Child             
0012f324 79ef2bbc e0434f4d 00000001 00000001 KERNEL32!RaiseException+0x53
0012f384 79fccf80 013f9064 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x2a8
0012f448 00dc00c1 0012f478 013f9064 00000000 mscorwks!JIT_Throw+0xfc
...

Jak widać, zgłoszony został wyjątek SEH przez CLR, gdzie pierwszy parametr, dwExceptionCode ustawiony został na 0xe0434f4d. Jest to pierwsze zgłoszenie wyjątku (first chance), puszczamy aplikację dalej i mamy:

0:000> g
Test : Błąd aplikacji .NET & SEH
eax=00156320 ebx=00000000 ecx=00156320 edx=00150220 esi=7c90de6e edi=00000000
eip=7c90e514 esp=0012fc28 ebp=0012fd24 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCallRet:
7c90e514 c3              ret

i aplikacja zostaje zakończona.

W drugim przypadku puszczamy wyjątek bez przechwycenia:

KOD 2 (Wyjątek zgłoszony i nieprzechwycony)

class SEH
{
 public static void Main(string[] args)
 {
    throw null;
 }
}

0:000> sxe *
0:000> g
ModLoad: 77dc0000 77e6c000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll

ModLoad: 60340000 60348000   c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\culture.dll
(1580.16e8): CLR exception - code e0434f4d (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012f2cc ebx=e0434f4d ecx=00000000 edx=00000028 esi=0012f358 edi=00191838
eip=7c812afb esp=0012f2c8 ebp=0012f31c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
KERNEL32!RaiseException+0x53:
7c812afb 5e              pop     esi
0:000> kb
ChildEBP RetAddr  Args to Child             
0012f31c 79ef2bbc e0434f4d 00000001 00000001 KERNEL32!RaiseException+0x53
0012f37c 79f51c64 00c89004 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x2a8
0012f3b4 7a0cc290 0012f3d8 001b18b8 e0063e3b mscorwks!UnwindAndContinueRethrowHelperAfterCatch+0x70
0012f474 00b1008d 00c88ff4 0012f490 79e71b4c mscorwks!JIT_Throw+0x118
...

po czym puszczamy wykonywanie dalej

0:000> g
(1580.16e8): CLR exception - code e0434f4d (!!! second chance !!!)
eax=0012f2cc ebx=e0434f4d ecx=00000000 edx=00000028 esi=0012f358 edi=00191838
eip=7c812afb esp=0012f2c8 ebp=0012f31c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
KERNEL32!RaiseException+0x53:
7c812afb 5e              pop     esi
0:000> kb
ChildEBP RetAddr  Args to Child             
0012f31c 79ef2bbc e0434f4d 00000001 00000001 KERNEL32!RaiseException+0x53
0012f37c 79f51c64 00c89004 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x2a8
0012f3b4 7a0cc290 0012f3d8 001b18b8 e0063e3b mscorwks!UnwindAndContinueRethrowHelperAfterCatch+0x70
0012f474 00b1008d 00c88ff4 0012f490 79e71b4c mscorwks!JIT_Throw+0x118

jednak tym razem, w przeciwieństwie do poprzedniego przykładu dostajemy kolejny wyjątek CLR
Puszczając dalej wykonanie

0:000> g
WARNING: Continuing a non-continuable exception
(1580.16e8): Break instruction exception - code 80000003 (first chance)
eax=00000001 ebx=00000000 ecx=00000000 edx=0012f2f8 esi=00000000 edi=79ef2bcc
eip=7c90120e esp=0012ee58 ebp=0012f304 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3

Dochodzimy do miejsca, gdzie CLR zgłasza FatalError

0:000> kb
ChildEBP RetAddr  Args to Child             
0012ee54 7a0963ff 0012f2f8 79fa6a6b e006394b ntdll!DbgBreakPoint
0012f304 7a09672e 80131506 79ef2bcc 00000000 mscorwks!EEPolicy::LogFatalError+0x2b5
0012f31c 79ef2bd7 80131506 79ef2bcc 00000000 mscorwks!EEPolicy::HandleFatalError+0x4d
0012f37c 79f51c64 00c89004 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x2c3
0012f3b4 7a0cc290 0012f3d8 001b18b8 e0063e3b mscorwks!UnwindAndContinueRethrowHelperAfterCatch+0x70
0012f474 00b1008d 00c88ff4 0012f490 79e71b4c mscorwks!JIT_Throw+0x118

i czeka na to, co my z tym zrobimy, zależnie od ustawień rejestru i kluczy:
HKLM\Software\Microsoft\.NETFramework\DbgManagedDebugger
oraz wartości klucza
HKLM\Software\Microsoft\.NETFramework\DbgJITDebugLaunchSetting
Dalsze wykonanie programu kończy naszą przygodę :)

Okazuje się, że WSZYSTKIE wyjątki .NET zgłaszane są przez CLR do systemu w ramach strukturalnej obsługi wyjątków (structured exception handling, SEH) przez jedną wartość: 0xe0434f4d. Wymuszając w debugerze zatrzymanie na wszystkich wyjątkach (sxe *) oczywiście trafiliśmy również na wyjątek aplikacji .NET. Zamiast '*' możemy oczywiście skorzystać ze wspomnianej wartości, upraszcza nam to przechwytywanie wyjątków aplikacji .NET w debugerach natywnych. Dla przykładu w WinDbg wystarczy użyć:
>sxe 0xe0434f4d
i będziemy zatrzymywać się na zgłoszeniach wyjątków .NET.

Na koniec wykonajmy jeszcze jedno ćwiczenie w WinDbg:
0:000> .formats 0xe0434f4d
Evaluate expression:
 Hex:     e0434f4d
 Decimal: -532459699
 Octal:   34020647515
 Binary:  11100000 01000011 01001111 01001101
 Chars:   .COM
 Time:    ***** Invalid
 Float:   low -5.62942e+019 high 0
 Double:  1.85893e-314

Cóż, najwyraźniej wartość przekazywaną przez CLR do SEH twórcy .NET przyjęli jeszcze przed finalną nazwą swojego frameworku :)

Znacie jeszcze jakieś inne 'magic numbers' w .NET? :)

Opublikowane 10 lutego 2011 20:00 przez mgrzeg
Filed under: , ,

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

 

dotnetomaniak.pl said:

Dziękujemy za publikację - Trackback z dotnetomaniak.pl

lutego 10, 2011 22:43
 

Paweł Łukasik said:

Czyli dobrze zgadłem :).

Ale wyjaśnienie dodatkowo ciekawe.

Pozdrawiam,

Paweł

lutego 10, 2011 23:02

Co o tym myślisz?

(wymagane) 
(opcjonalne)
(wymagane) 

  
Wprowadź kod: (wymagane)
Wyślij

Subskrypcje

W oparciu o Community Server (Personal Edition), Telligent Systems