Về cơ bản, tôi có một chương trình chế độ người dùng gọi kernel32.CreateProcessA() mà nội bộ gọi kernel32.CreateProcessInternalW(). Trong hàm này, tôi quan tâm đến những gì đang xảy ra bên trong ntdll.NtCreateSection() để cố gắng ánh xạ thực thi trong bộ nhớ ảo. Khi ở trong chức năng này, chương trình sẽ nhanh chóng thiết lập cuộc gọi hạt nhân là EAX = 0x32 và thực thi lệnh SYSENTER.Làm cách nào để thực hiện gỡ lỗi chế độ người dùng/chế độ hạt nhân?
Rõ ràng là tôi không thể nhìn thấy ngoài cổng gọi trong trình gỡ lỗi chế độ người dùng. Tôi có một chút kinh nghiệm gỡ lỗi trình điều khiển chế độ hạt nhân, vì vậy tôi nạp một bản sao của XP SP3 trong một cửa sổ VMWare và sử dụng VirtualKD để conect ống để WinDbg (mà tôi xảy ra được chạy bên trong IDA). Sau khi kết nối trình gỡ rối hạt nhân, tôi đã sao chép chương trình EXE của người dùng và PDB vào máy ảo, nhưng tôi không biết làm thế nào để thiết lập điểm ngắt ban đầu trong chương trình chế độ người dùng của tôi đúng cách. Tôi không muốn chặn tất cả các cuộc gọi đến ntdll.ZwCreateSection() mà tôi tin là ở phía bên kia của cổng gọi. Lý tưởng nhất, tôi muốn đột nhập vào mã chế độ người dùng và bước qua cổng gọi đó ngay bây giờ khi tôi đang sử dụng trình gỡ lỗi hạt nhân, nhưng tôi không biết các bước đầu tiên là gì.
tôi đã thực hiện một số googling và tôi đã đến gần bằng cách thiết lập một "ntsd -d" giá trị trong
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\myprocess.exe
Điều này gây ra một vết rách ở debugger kernel khi tôi bắt đầu quá trình của tôi, nhưng tôi có thể dường như không thiết lập bất kỳ breakpoint sau lệnh .breakin tôi cần phải phát hành để IDA để có được dấu nhắc WinDbg. Tôi đã theo dõi điều này guide nơi tôi xác định quy trình của mình bằng quá trình! Sau đó chuyển sang ngữ cảnh và tải lại các ký hiệu nhưng tôi gặp sự cố khi đặt điểm ngắt trong quy trình của mình hoặc tiến lên điểm ngắt ban đầu được đặt bởi "ntsd -d" . Sau khi nhận được thông báo rằng điểm ngắt không thể được giải quyết và điểm ngắt được hoãn lại được thêm vào, tôi dường như không thể chuyển tiếp "vào" cho quy trình mà không xóa các điểm ngắt nếu điều đó có ý nghĩa gì. Đây là chồng mà tôi dường như là tại khi tôi nhấn mà phá vỡ ban đầu:
ChildEBP RetAddr
b2b55ccc 8060e302 nt!RtlpBreakWithStatusInstruction
b2b55d44 8053d638 nt!NtSystemDebugControl+0x128
b2b55d44 7c90e4f4 nt!KiFastCallEntry+0xf8
0007b270 7c90de3c ntdll!KiFastSystemCallRet
0007b274 6d5f5ca6 ntdll!ZwSystemDebugControl+0xc
0007bd48 6d5f6102 dbgeng!DotCommand+0xd0d
0007de8c 6d5f7077 dbgeng!ProcessCommands+0x318
0007dec4 6d5bec6c dbgeng!ProcessCommandsAndCatch+0x1a
0007eedc 6d5bed4d dbgeng!Execute+0x113
0007ef0c 010052ce dbgeng!DebugClient::Execute+0x63
0007ff3c 010069fb ntsd!MainLoop+0x1ec
0007ff44 01006b31 ntsd!main+0x10e
0007ffc0 7c817067 ntsd!mainCRTStartup+0x125
0007fff0 00000000 kernel32!BaseProcessStart+0x23
Thành thật mà nói, tôi không chắc chắn PDB của tôi đang được nạp nhưng tôi nghi ngờ có lẽ không vấn đề trước mắt của tôi nó; ngăn mô-đun của tôi chỉ hiển thị các mô-đun trình điều khiển hạt nhân, không hiển thị các mô-đun chế độ người dùng. Khi tôi đã thực hiện gỡ lỗi trình điều khiển trong quá khứ, tôi có thể thấy hình ảnh trình điều khiển của mình trong ngăn này và có biểu tượng đã được tải hay không, vì vậy tôi không chắc chắn về điều gì sẽ xảy ra với hình ảnh chế độ người dùng. Nếu không có hình ảnh, tôi thực sự không thể mong đợi trình gỡ lỗi giải quyết bất kỳ điểm ngắt nào.
Tôi nhận ra rằng mình có thể đang gặp vấn đề này hoàn toàn sai nhưng tôi không có may mắn khi tìm cách thực hiện gỡ lỗi lai chế độ người dùng/chế độ hạt nhân. Có ai ra khỏi đó có thể chỉ cho tôi đi đúng hướng để tôi có thể bước vào chức năng chế độ hạt nhân này từ một quá trình chế độ người dùng cụ thể? Hoặc, ít nhất thiết lập một điểm ngắt chế độ hạt nhân thích hợp để nó chỉ được kích hoạt như là kết quả của quá trình chế độ người dùng cụ thể của tôi?
CẬP NHẬT: Tôi đã tải mô-đun của mình (xảy ra có tên runlist.exe) trong trình gỡ rối chế độ người dùng trên hệ điều hành được gỡ rối (Tôi đã sử dụng OllyDbg). Khi tôi đã tạm dừng ở điểm dừng chế độ người dùng chỉ một vài hướng dẫn từ SYSENTER, tôi đã tạm ngưng hệ điều hành bằng trình gỡ lỗi hạt nhân. Sau đó tôi đặt bối cảnh quy trình. Lệnh WinDbg nội dung cửa sổ như sau:
WINDBG>!process 0 0 runlist.exe
PROCESS 820645a8 SessionId: 0 Cid: 01b4 Peb: 7ffd7000 ParentCid: 02b0
DirBase: 089c02e0 ObjectTable: e1671bb0 HandleCount: 8.
Image: runlist.exe
WINDBG>.process /i /r /p 820645a8
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
WINDBG>g
This command cannot be passed to the WinDbg plugin directly, please use IDA Debugger menu to achieve the same result.
Break instruction exception - code 80000003 (first chance)
WINDBG>.reload /user
Loading User Symbols
....
Caching 'Modules'... ok
WINDBG>lmu
start end module name
00400000 00405000 runlist C (no symbols)
7c340000 7c396000 MSVCR71 (private pdb symbols) g:\symcache\msvcr71.pdb\630C79175C1942C099C9BC4ED019C6092\msvcr71.pdb
7c800000 7c8f6000 kernel32 (pdb symbols) e:\windows\symbols\dll\kernel32.pdb
7c900000 7c9af000 ntdll (pdb symbols) e:\windows\symbols\dll\ntdll.pdb
WINDBG>bp 0x7c90d16a
WINDBG>bl
0 e 7c90d16a 0001 (0001) ntdll!ZwCreateSection+0xa
Mặc dù tôi không thể có được quá trình của tôi biểu tượng để tải với ".reload" (PDB là trong cùng thư mục - có thể cần phải sao chép nó vào những biểu tượng thư mục của tôi), breakpoint tôi quan tâm là trong ntdll anyway vì vậy tôi đặt nó vào địa chỉ 0x7C90D16A mà trình gỡ lỗi được công nhận là nằm trong ntdll.ZwCreateSection(). Oddly với tôi, trong chế độ người dùng mã địa chỉ này giải quyết để ntdll.NtCreateSection(), nhưng một trong hai cách mà breakpoint chỉ là 2 hướng dẫn từ nơi tôi đã có chế độ user-break của tôi. Khi tôi nối lại máy, ý định của tôi là "chạy" chế độ xử lý gỡ lỗi chế độ người dùng và điều này sẽ kích hoạt các lệnh breakpoint của chế độ lõi 2. Điểm ngắt hạt nhân không bao giờ bị nhấn và ứng dụng được tiếp tục lại qua điểm này. Tuy nhiên, sau đó khi tiếp tục hệ điều hành, điểm ngắt được lặp đi lặp lại bởi các quá trình khác ngăn cản tôi lấy lại trình gỡ lỗi chế độ người dùng để tôi có thể "chạy" nó đến vị trí đó chỉ trong vòng quá trình của riêng tôi.
CẬP NHẬT Kết hợp những lời khuyên được cung cấp bởi @conio, các bước sau đây làm việc cho tôi:
1> sau khi gắn debugger hạt nhân và khởi động hệ điều hành mục tiêu, đình chỉ hệ điều hành và áp dụng một số tùy chọn cấu hình:
!gflag +ksl //allow sxe to report user-mode module load events under kernel debugger
sxe ld myproc.exe //cause kernel debugger break upon process load
.sympath+ <path> //path to HOST machine's user-mode app's symbols
2> chạy debugger để tiếp tục hệ điều hành mục tiêu
3> trên mục tiêu, chạy EXE, chúng tôi muốn gỡ lỗi
4> trình gỡ lỗi hạt nhân sẽ bị hỏng; bây giờ nhập các lệnh sau để chuyển sang bối cảnh usermode:
!process 0 0 myproc.exe //get address of EProcess structure (first number on 1st line after "PROCESS")
.process /i /r /p <eprocess*> //set kernel debugger to process context
g //continue execution to allow the context switch; debugger will break after switch complete
.reload /user //reload user symbols
lmu //ensure you have symbols although not really necessary in my particular case
5> Bây giờ kể từ khi tôi đã biết những gì xảy ra ở phía usermode của ntdll.NtCreateSection(), tôi chỉ cần đi trước và thiết lập một breakpoint cho phía chế độ hạt nhân của hàm đó, nhưng xác định rằng tôi muốn breakpoint chỉ xảy ra trong ngữ cảnh của quá trình của tôi. Bằng cách này, các breakpoint không được kích hoạt hệ điều hành rộng:
bu /p <eprocess*> nt!NtCreateSection //set breakpoint in kernel side of function
g //run to break
6> nếu mọi việc suôn sẻ như kế hoạch, breakpoint sẽ thức dậy trình gỡ lỗi ở phía kernel mode của NtCreateSection(). Tôi đánh giá cao tất cả các câu trả lời và lời khuyên!
Cảm ơn bạn đã làm rõ! Esp. mẹo "sxe ld:" để ngắt tải mô-đun cho phép tôi bỏ qua trình gỡ lỗi chế độ người dùng trên đích cũng như cài đặt đăng ký "ntsd -d" đó. Bây giờ chỉ có một điều tôi chưa thể hiểu được. Bây giờ tôi có thể đi qua mã chế độ người dùng trong trình gỡ rối hạt nhân nhưng tôi muốn hoặc là qua bước SYSENTER hoặc đặt một điểm ngắt ở phía bên kia trong chế độ lõi ở trình xử lý ngắt hoặc hàm mà các trình xử lý ngắt để làm việc kỳ diệu của NtCreateSection. Tôi dường như không thể tìm ra các ví dụ cụ thể cho kỹ thuật này. –
byteptr
Bạn không thể thực sự "bước vào" một 'sysenter'. Điều dễ nhất để làm là đặt hoặc bật điểm ngắt trên hàm 'nt' tương ứng. Thông thường họ có cùng tên. Khi bạn vào 'ntdll! NtCreateSection', làm' bu nt! NtCreateSection' và đi. Bạn có thể thử và sử dụng các tùy chọn '/ p' hoặc'/t' bằng 'bu', nhưng được cảnh báo rằng chúng không hoạt động tốt. – conio
@conio ntsd -d không phải là một mớ hỗn độn tôi đã chỉnh sửa bài đăng của tôi để hiển thị cách thực hiện nó – blabb