असल में, मेरे पास एक उपयोगकर्ता मोड प्रोग्राम है जो kernel32.CreateProcessA() को कॉल करता है जो आंतरिक रूप से kernel32.CreateProcessInternalW() को कॉल करता है। इस फ़ंक्शन के भीतर, मुझे दिलचस्पी है कि ntdll.NtCreateSection() में क्या हो रहा है जो वर्चुअल मेमोरी में निष्पादन योग्य को मैप करने का प्रयास करता है। एक बार इस फ़ंक्शन में, प्रोग्राम जल्दी से कर्नेल कॉल को EAX = 0x32 के रूप में सेट करता है और SYSENTER निर्देश निष्पादित करता है।हाइब्रिड उपयोगकर्ता-मोड/कर्नेल-मोड डीबगिंग कैसे करें?
स्पष्ट रूप से मैं उपयोगकर्ता मोड डीबगर में कॉल गेट से परे नहीं देख सकता। मेरे पास कर्नेल-मोड ड्राइवरों को डीबग करने का थोड़ा सा अनुभव है, इसलिए मैंने एक वीएमवेयर विंडो में एक्सपी एसपी 3 की एक प्रति लोड की है और पाइप को WinDbg (जिसे मैं आईडीए के अंदर चल रहा हूं) को समझने के लिए वर्चुअलकेडी का उपयोग करता हूं। कर्नेल डीबगर को जोड़ने के बाद, मैंने वर्चुअल मशीन पर अपने यूजर-मोड EXE प्रोग्राम और पीडीबी की प्रतिलिपि बनाई, लेकिन मैं अपने उपयोगकर्ता-मोड प्रोग्राम में प्रारंभिक ब्रेकपॉइंट को सही तरीके से सेट करने के तरीके पर एक नुकसान का प्रकार हूं। मैं समकक्ष ntdll.ZwCreateSection() पर सभी कॉल को अवरुद्ध नहीं करना चाहता हूं, जिसे मैं कॉल गेट के दूसरी तरफ मानता हूं। आदर्श रूप में, मैं उपयोगकर्ता-मोड कोड में तोड़ना चाहता हूं और उस कॉल गेट के माध्यम से कदम उठाना चाहता हूं कि अब मैं कर्नेल डीबगर का उपयोग कर रहा हूं, लेकिन मुझे नहीं पता कि पहले चरण क्या हैं।
मैं कुछ Googling किया है और मैं करीब एक सेट करके आए हैं
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\myprocess.exe
कर्नल डीबगर में एक को तोड़ने का कारण बनता है जब मैं अपने प्रक्रिया शुरू में मूल्य "ntsd -d" है, लेकिन मैं यह कर सकते हैं .breakin कमांड के बाद किसी भी ब्रेकपॉइंट्स को सेट करने लगते हैं, मुझे WinDbg प्रॉम्प्ट पर जाने के लिए IDA को जारी करने की आवश्यकता है। मैं इस guide का पालन कर रहा हूं जहां मैं अपनी प्रक्रिया को ढूंढता हूं! प्रक्रिया फिर संदर्भ पर स्विच करें, और प्रतीकों को दोबारा लोड करें, लेकिन मुझे अपनी प्रक्रिया में ब्रेकपॉइंट सेट करने में समस्याएं आ रही हैं या "ntsd -d" द्वारा प्रारंभिक ब्रेकपॉइंट सेट को आगे बढ़ाने में समस्याएं आ रही हैं। । संदेश प्राप्त करने के बाद कि ब्रेकपॉइंट को हल नहीं किया जा सका और स्थगित ब्रेकपॉइंट जोड़ा गया है, तो अगर ब्रेकपॉइंट्स को साफ़ किए बिना मैं प्रक्रिया में "इन" करने के लिए प्रतीत नहीं कर पा रहा हूं, तो इससे कोई अर्थ हो। यहाँ है जहाँ मैं जब मुझे लगता है कि प्रारंभिक ब्रेक मारा पर होने लगते हैं के ढेर है:
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
ईमानदारी से कहूं तो मुझे यकीन है कि मेरी PDB लोड किया जा रहा है नहीं कर रहा हूँ, लेकिन मैं अपने शायद नहीं मेरी तात्कालिक समस्या संदेह है; मेरे मॉड्यूल फलक केवल कर्नेल ड्राइवर मॉड्यूल दिखा रहा है, न कि उपयोगकर्ता मोड मॉड्यूल। जब मैं अतीत में ड्राइवर डीबगिंग कर रहा था, तो मैं इस फलक में अपनी चालक छवि देख सकता था और प्रतीकों को लोड किया गया था या नहीं, इसलिए मुझे यकीन नहीं है कि उपयोगकर्ता-मोड छवि के लिए क्या उम्मीद करनी है। छवि के बिना, मैं वास्तव में किसी भी ब्रेकपॉइंट को हल करने के लिए डीबगर की अपेक्षा नहीं कर सकता।
मुझे एहसास है कि मैं इस बारे में पूरी तरह से गलत हो रहा हूं लेकिन मुझे कोई भाग्य नहीं है कि उपयोगकर्ता-मोड/कर्नेल-मोड हाइब्रिड डीबगिंग कैसे करें। क्या वहां कोई है जो मुझे सही दिशा में इंगित कर सकता है ताकि मैं इस कर्नेल मोड फ़ंक्शन में एक विशिष्ट उपयोगकर्ता-मोड प्रक्रिया से कदम उठा सकूं? या, कम से कम एक उचित कर्नेल-मोड ब्रेकपॉइंट सेट करें ताकि यह केवल मेरी विशेष उपयोगकर्ता-मोड प्रक्रिया के परिणामस्वरूप ट्रिगर हो?
अद्यतन: मैं भरी हुई मेरी मॉड्यूल डिबग ओएस पर एक उपयोगकर्ता के मोड डीबगर में (मैं OllyDbg उपयोग करने के लिए हुआ) (runlist.exe नामित किया जाना होता है)। एक बार जब मैं उपयोगकर्ता-मोड ब्रेकपॉइंट पर रोक दिया गया तो सिसेन्ट से केवल कुछ ही निर्देश दिए गए, मैंने कर्नेल डीबगर का उपयोग करके ओएस को निलंबित कर दिया। मैं फिर प्रक्रिया संदर्भ सेट। WinDbg कमांड विंडो सामग्री इस प्रकार थे:
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
हालांकि मैं अपनी प्रक्रिया ' ".reload" के साथ लोड करने के लिए प्रतीकों नहीं मिल सका (PDB एक ही निर्देशिका में है - मेरी प्रतीकों निर्देशिका करने के लिए इसे कॉपी करना पड़े), जिस ब्रेकपॉइंट की मैं परवाह करता हूं वह वैसे भी है, इसलिए मैंने इसे 0x7C90D16A पते पर सेट किया है जो डीबगर को ntdll.ZwCreateSection() के भीतर माना जाता है। विचित्र रूप से मेरे लिए, उपयोगकर्ता-मोड कोड में यह पता ntdll को हल करता है।NtCreateSection(), लेकिन किसी भी तरह से ब्रेकपॉइंट केवल 2 निर्देश थे जहां से मेरा उपयोगकर्ता-मोड ब्रेक था। जब मैंने मशीन को फिर से शुरू किया, तो मेरा इरादा उपयोगकर्ता-मोड डीबग-प्रक्रिया को "चलाने" देना था और इससे कर्नेल-मोड ब्रेकपॉइंट 2 निर्देशों को दूर कर दिया जाएगा। कर्नेल ब्रेकपॉइंट कभी हिट नहीं हुआ था और ऐप इस बिंदु से पहले फिर से शुरू हुआ था। हालांकि मैं ntdll पर एक ब्रेकपॉइंट सेट कर सकता हूं! ZwCreateSection() लेकिन फिर ओएस को फिर से शुरू करते समय, ब्रेकपॉइंट बार-बार अन्य प्रक्रियाओं द्वारा मारा जाता है जो मुझे उपयोगकर्ता-मोड डीबगर पर वापस जाने से रोकता है, इसलिए मैं इसे केवल उस स्थान पर "चला सकता हूं" मेरी अपनी प्रक्रिया
अद्यतन @conio द्वारा प्रदान की युक्तियों के विलय के लिए निम्न चरणों मेरे लिए काम किया:
1> कर्नेल डिबगर संलग्न और लक्ष्य ओएस बूट के बाद, ओएस को निरस्त करने और लागू कुछ कॉन्फ़िगरेशन को:
!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> चलाने डिबगर लक्ष्य ओएस
3> लक्ष्य को फिर से शुरू करने के लिए, EXE हम
डिबग करने के लिए चाहते हैं चलाने4> कर्नेल डीबगर को तोड़ना चाहिए; के बाद से मैं पहले से ही पता है कि ntdll.NtCreateSection() की 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> अब और के लिए एक ब्रेकपाइंट सेट: अब usermode संदर्भ में स्विच करने के निम्न कमांड दर्ज उस फ़ंक्शन के कर्नेल मोड पक्ष, लेकिन यह निर्दिष्ट करते हुए कि मैं ब्रेकपॉइंट केवल अपनी प्रक्रिया के संदर्भ में ही होना चाहता हूं। इस तरह, ब्रेकपाइंट ओएस विस्तृत ट्रिगर नहीं है:
bu /p <eprocess*> nt!NtCreateSection //set breakpoint in kernel side of function
g //run to break
6> अगर सब चला जाता है योजना के अनुसार, ब्रेकपाइंट NtCreateSection की कर्नेल मोड तरफ डिबगर जाग जाएगा()। मैं सभी प्रतिक्रियाओं और सुझावों की सराहना करता हूं!
स्पष्टीकरण के लिए धन्यवाद! Esp। "एसएक्सई एलडी:" मॉड्यूल लोड पर टिप करने के लिए टिप मुझे लक्ष्य पर उपयोगकर्ता-मोड डीबगर को बाईपास करने के साथ-साथ "ntsd -d" रजिस्ट्री सेटिंग को बाईपास करने की इजाजत देता है। अब केवल एक चीज है जिसे मैं अभी तक नहीं समझ सकता। अब मैं कर्नेल डीबगर में उपयोगकर्ता-मोड कोड के माध्यम से कदम उठा सकता हूं लेकिन मैं या तो SYSENTER के माध्यम से कदम उठाना चाहता हूं या दूसरी तरफ कर्नेल मोड में ब्रेकपॉइंट सेट करना चाहता हूं या तो इंटरप्ट हैंडलर या इंटरप्ट हैंडलर कॉल NtCreateSection के जादू का काम करने के लिए। मुझे इस तकनीक के लिए ठोस उदाहरण नहीं मिल रहे हैं। –
byteptr
आप वास्तव में "sysenter' में" कदम नहीं उठा सकते हैं। करने के लिए सबसे आसान बात संबंधित 'एनटी' फ़ंक्शन पर ब्रेकपॉइंट सेट या सक्षम करना होगा। आमतौर पर उनके पास एक ही नाम होता है। जब आप 'ntdll! NtCreateSection' में जाते हैं, तो' bu nt! NtCreateSection' करें और जाएं। आप 'bu' के साथ'/p' या '/ t' विकल्पों को आजमा सकते हैं और उपयोग कर सकते हैं, लेकिन चेतावनी दीजिये कि वे हमेशा अच्छी तरह से काम नहीं करते हैं। – conio
@conio ntsd -d एक गड़बड़ नहीं है मैंने यह दिखाने के लिए अपनी पोस्ट संपादित की है कि यह कैसे करें – blabb