2015-05-11 15 views
5

Tôi có vùng kết xuất x64 của ứng dụng được quản lý (C#) mà p/gọi đến mã gốc. Các bãi chứa được thực hiện sau khi mã nguồn gốc cố gắng để dereference một vị trí bộ nhớ xấu, và sau khi các marshaler. NET đã biến nó thành một AccessViolationException. Kết quả là, khung ngăn xếp nơi xảy ra lỗi là không còn nữa, và thread nơi ngoại trừ tại xảy ra là bị bắt cóc bởi các handler CLR ngoại lệ:Làm cách nào để truy xuất Ngữ cảnh Đăng ký từ AccessViolationException?

0:017> kb 
# RetAddr   : Args to Child               : Call Site 
00 000007fe`fd3b10dc : 00000000`0402958b 00000000`20000002 00000000`00000e54 00000000`00000e4c : ntdll!NtWaitForSingleObject+0xa 
01 000007fe`ea9291eb : 00000000`00000000 00000000`00000cdc 00000000`00000000 00000000`00000cdc : KERNELBASE!WaitForSingleObjectEx+0x79 
02 000007fe`ea929197 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!CLREventWaitHelper2+0x38 
03 000007fe`ea929120 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!CLREventWaitHelper+0x1f 
04 000007fe`ead8cae5 : 00000000`29cbc7c0 00000000`3213ce40 00000000`00000000 00000000`ffffffff : clr!CLREventBase::WaitEx+0x70 
05 000007fe`ead8c9d0 : 00000000`29cbc7c0 00000000`00000000 00000000`0002b228 00000000`0002b228 : clr!Thread::WaitSuspendEventsHelper+0xf5 
06 000007fe`eacf2145 : 00000000`007ea060 000007fe`ea924676 00000000`00000000 000007fe`fd3b18da : clr!Thread::WaitSuspendEvents+0x11 
07 000007fe`eaccc00c : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!Thread::RareEnablePreemptiveGC+0x33a905 
08 000007fe`eae2c762 : 00000000`00000000 00000000`007cbce0 00000000`29cbc7c0 00000000`00000001 : clr!Thread::RareDisablePreemptiveGC+0x31b40c 
09 000007fe`eaf662d4 : 00000000`00000000 00000000`007cbce0 00000000`29cbc7c0 00000000`00000000 : clr!EEDbgInterfaceImpl::DisablePreemptiveGC+0x22 
0a 000007fe`eaf66103 : 00000000`29cb0100 00000000`00000000 00000000`3213cf80 00000000`29cbca20 : clr!Debugger::SendExceptionHelperAndBlock+0x174 
0b 000007fe`eaf65d0d : ffffffff`ffffffff 00000000`29cbca20 00000000`29cbc700 000007fe`eaf62100 : clr!Debugger::SendExceptionEventsWorker+0x343 
0c 000007fe`eaf61bd8 : 00000000`00000100 00000000`00000000 00000000`00000019 00000000`3213dd01 : clr!Debugger::SendException+0x15d 
0d 000007fe`eadac75d : 00000000`007cbce0 00000000`3213d258 00000000`3213d1e8 00000000`00000001 : clr!Debugger::LastChanceManagedException+0x1f8 
0e 000007fe`eaf698c7 : 000075ce`2b30e018 00000000`00000000 00000000`00000001 00000000`00000000 : clr!NotifyDebuggerLastChance+0x6d 
0f 000007fe`eaf6af20 : 00000000`00000000 000007fe`8cf40020 000007fe`8cfa200c 4328fffe`43e0fffe : clr!Debugger::UnhandledHijackWorker+0x1a7 
10 000007fe`eaaacbf0 : 00000000`0000000a 00000000`2ab23e30 00000000`00000001 00000000`00000000 : clr!ExceptionHijackWorker+0xc0 
11 00000000`3213d8c0 : 00000000`3213ddb0 00000000`00000001 00000000`00000000 00000000`0000000b : clr!ExceptionHijack+0x30 
12 00000000`3213ddb0 : 00000000`00000001 00000000`00000000 00000000`0000000b 00000000`0035578c : 0x3213d8c0 
13 00000000`00000001 : 00000000`00000000 00000000`0000000b 00000000`0035578c ffffffff`00000002 : 0x3213ddb0 
14 00000000`00000000 : 00000000`0000000b 00000000`0035578c ffffffff`00000002 00000000`00350268 : 0x1 

.exr -1 (hiển thị ngoại lệ gần đây nhất) trả về:

0:017> .exr -1 
ExceptionAddress: 00000000771d685a (user32!ZwUserMessageCall+0x000000000000000a) 
    ExceptionCode: 80000004 (Single step exception) 
    ExceptionFlags: 00000000 
NumberParameters: 0 

Cuộc gọi đến user32!ZwUserMessageCall ở trên cùng của ngăn xếp của chủ đề 0, không phải 17 nơi ngoại lệ gốc xảy ra, vì vậy tôi chỉ có thể giả định nó không trỏ đến ngoại lệ của tôi.

tôi có thể đổ ngoại lệ truy cập vi phạm để có được một số thông tin về lỗi mẹ đẻ:

0:017> !DumpObj /d 0000000012175640 
Name:  System.AccessViolationException 
MethodTable: 000007fee9a61fe8 
EEClass:  000007fee9528300 
Size:  176(0xb0) bytes 
File:  C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll 
Fields: 
       MT Field Offset     Type VT  Attr   Value Name 
000007fee9a50e08 4000002  8  System.String 0 instance 000000001217b538 _className 
000007fee9a5b218 4000003  10 ...ection.MethodBase 0 instance 0000000000000000 _exceptionMethod 
000007fee9a50e08 4000004  18  System.String 0 instance 0000000000000000 _exceptionMethodString 
000007fee9a50e08 4000005  20  System.String 0 instance 0000000012179818 _message 
000007fee9a61f18 4000006  28 ...tions.IDictionary 0 instance 0000000000000000 _data 
000007fee9a51038 4000007  30  System.Exception 0 instance 0000000000000000 _innerException 
000007fee9a50e08 4000008  38  System.String 0 instance 0000000000000000 _helpURL 
000007fee9a513e8 4000009  40  System.Object 0 instance 0000000012179ad0 _stackTrace 
000007fee9a513e8 400000a  48  System.Object 0 instance 0000000012179c68 _watsonBuckets 
000007fee9a50e08 400000b  50  System.String 0 instance 0000000000000000 _stackTraceString 
000007fee9a50e08 400000c  58  System.String 0 instance 0000000000000000 _remoteStackTraceString 
000007fee9a53980 400000d  88   System.Int32 1 instance    0 _remoteStackIndex 
000007fee9a513e8 400000e  60  System.Object 0 instance 0000000000000000 _dynamicMethods 
000007fee9a53980 400000f  8c   System.Int32 1 instance  -2147467261 _HResult 
000007fee9a50e08 4000010  68  System.String 0 instance 0000000000000000 _source 
000007fee9a54a00 4000011  78  System.IntPtr 1 instance    0 _xptrs 
000007fee9a53980 4000012  90   System.Int32 1 instance  -532462766 _xcode 
000007fee9a02d50 4000013  80  System.UIntPtr 1 instance    0 _ipForWatsonBuckets 
000007fee9a3d210 4000014  70 ...ializationManager 0 instance 0000000012179900 _safeSerializationManager 
000007fee9a513e8 4000001  0  System.Object 0 shared   static s_EDILock 
           >> Domain:Value 00000000007e09b0:NotInit << 
000007fee9a54a00 400018a  98  System.IntPtr 1 instance  7fedad179f4 _ip 
000007fee9a54a00 400018b  a0  System.IntPtr 1 instance fffffffc2ab22078 _target 
000007fee9a53980 400018c  94   System.Int32 1 instance    0 _accessType 

Từ này tôi thấy các địa chỉ hướng dẫn mà thất bại (7fedad179f4) và địa chỉ rằng mã cố gắng dereference (fffffffc2ab22078). Nó dường như là một phần mở rộng dấu hiệu hoặc lỗi tràn bằng cách nào đó, nhưng nó không rõ ràng trong mã như thế nào mà có thể đã xảy ra. Các hướng dẫn tham chiếu là:

0:017> u 7fedad179f4 
MYDLL!_interpolate+0x174 [c:\my\source\file.c @ 85]: 
000007fe`dad179f4 f3450f59548404 mulss xmm10,dword ptr [r12+rax*4+4] 

Để gỡ lỗi này hơn nữa, tôi cần bối cảnh đăng ký từ khi mã gốc bị rơi để xem những gì đang ở trong r12rax. Điều này có thể truy xuất được không?


Edit: tôi đã cố gắng để có được thông tin về các thông số để ExceptionHijackWorker, nhưng giá trị không có ý nghĩa đối với tôi. Chữ ký chức năng theo liên kết của @ S.T. là

void STDCALL ExceptionHijackWorker(T_CONTEXT * pContext, 
            EXCEPTION_RECORD * pRecord, 
            EHijackReason::EHijackReason reason, 
            void * pData); 

Vì vậy, tham số đầu tiên là không có ý nghĩa như một con trỏ. Và bán phá giá tham số thứ hai 000000002ab23e30 mang dữ liệu vô nghĩa cho EXCEPTION_RECORD:

0:017> dd 000000002ab23e30 
00000000`2ab23e30 00000019 00000019 2ab23e40 00000000 
00000000`2ab23e40 42b8f800 42b8de00 42b89b00 42b85000 
00000000`2ab23e50 42b81b00 42b7a000 42b72600 42b6fa00 
00000000`2ab23e60 42b6a000 42b67a00 42b63600 42b59c00 
00000000`2ab23e70 42b4fc00 42b4da00 42b49e00 42b46a00 
00000000`2ab23e80 42b38e00 42b31c00 42b2d600 42b29000 
00000000`2ab23e90 42b2ec00 42b2fa00 42b2a000 42b27a00 
00000000`2ab23ea0 42b23e00 42b6e800 42b6ab00 42b66c80 

0x190x19 cho ExceptionCodeExceptionFlags không có ý nghĩa; không có mã nào có giá trị đó và cờ được ghi là không hoặc EXCEPTION_NONCONTINUABLE, được định nghĩa là 1.

Tôi có hiểu sai điều gì ở đây không?

+0

Vì vậy, '.exr -1' đã đề cập đến ngoại lệ .NET? Tôi đoán nó sẽ trở nên khó khăn trên x64 kể từ khi đăng ký được sử dụng cho nhiều mục đích trong hội nghị kêu gọi x64. Có lẽ bạn có thể thêm vào bài viết mà bạn biết về 'r'and' .frame' như đã đề cập trong phần bình luận của câu trả lời đã xóa của tôi. –

+1

Bạn có thấy http://blogs.msdn.com/b/ntdebugging/archive/2010/05/12/x64-manual-stack-reconstruction-and-stack-walking.aspx không? –

+0

@ThomasWeller Cảm ơn bạn đã liên kết. Tôi nghĩ rằng tôi sẽ có thể sử dụng thông tin đó để thư giãn từ 'clr! ExceptionHijack' mặc dù tôi không thấy như thế nào; nó không đẩy bất kỳ thanh ghi nào theo '.fnent'. Tôi tin rằng '.exr -1' đã trỏ đến AVE, nhưng nó không rõ ràng. Tôi đã đăng đầu ra của nó là tốt. –

Trả lời

3

Làm theo lời khuyên từ @S.T., tôi bắt đầu thăm dò xung quanh ngăn xếp cuộc gọi để xem liệu tôi có thể tìm thấy bản ghi ngoại lệ hoặc bản ghi ngữ cảnh hay không.Tôi bắt đầu xung quanh lạ ở dưới cùng của ngăn xếp, cụ thể là:

0:017> k 
# Child-SP   RetAddr   Call Site 
... 
0f 00000000`3213d210 000007fe`eaf6af20 clr!Debugger::UnhandledHijackWorker+0x1a7 
10 00000000`3213d850 000007fe`eaaacbf0 clr!ExceptionHijackWorker+0xc0 
11 00000000`3213d880 00000000`3213d8c0 clr!ExceptionHijack+0x30 
12 00000000`3213d8a8 00000000`3213ddb0 0x3213d8c0 
13 00000000`3213d8b0 00000000`00000001 0x3213ddb0 
14 00000000`3213d8b8 00000000`00000000 0x1 

tôi tình cờ tìm thấy bản ghi ngoại lệ:

0:017> .exr 00000000`3213ddb0 
ExceptionAddress: 000007fedad179f4 (SMTCV!_interpolate+0x0000000000000174) 
    ExceptionCode: c0000005 (Access violation) 
    ExceptionFlags: 00000000 
NumberParameters: 2 
    Parameter[0]: 0000000000000000 
    Parameter[1]: fffffffc2ab22078 
Attempt to read from address fffffffc2ab22078 

Và sau đó tôi tình cờ tìm thấy hồ sơ ngữ cảnh (những gì tôi đang tìm kiếm for):

0:017> .cxr 00000000`3213d8c0 
rax=0000000000000019 rbx=000000000000000a rcx=00000000709c7c88 
rdx=0000000000000002 rsi=000000002ab23e30 rdi=0000000080000000 
rip=000007fedad179f4 rsp=000000003213dff0 rbp=0000000000000019 
r8=000007ffffe22000 r9=0000000070910000 r10=0000000000000000 
r11=000000003213e0a0 r12=fffffffc2ab22010 r13=000000002b50ae40 
r14=000000002ab241ec r15=0000000000000003 
iopl=0   nv up ei pl nz na pe nc 
cs=0033 ss=002b ds=0000 es=0000 fs=0000 gs=0000    efl=00010200 
MYDLL!_interpolate+0x174: 
000007fe`dad179f4 f3450f59548404 mulss xmm10,dword ptr [r12+rax*4+4] ds:fffffffc`2ab22078=???????? 

Tôi có thể thấy con trỏ xấu của mình trong r12 ngay bây giờ!

Tôi không hiểu những khung ngăn xếp này là gì hoặc tại sao ngoại lệ và bản ghi ngữ cảnh được lưu trữ làm địa chỉ trả lại cho chúng. Bất kỳ ý kiến ​​về điều này sẽ là tuyệt vời, cho tôi và cho độc giả trong tương lai.

+1

có cách nào để truy cập vào bãi chứa này không, tôi có muốn khám phá thêm hoặc đoạn mã repro không? – Addy

+1

Thật không may tôi không thể phát hành bãi chứa, và không có biểu tượng nó sẽ là khá vô giá trị để phân tích. Nó khá dễ dàng để tạo một đoạn mã repro. Bạn chỉ cần một phương thức C mà dereferences bộ nhớ xấu, và sau đó p/gọi phương thức đó từ C#. –

+1

Phiên bản khung nào là bạn trên 4.o hoặc 4.5 tôi không mong đợi nhiều sự khác biệt nhưng chỉ trong trường hợp. – Addy

Các vấn đề liên quan