A debugger is the second thing after a compiler needed to create programs. However, many of those who write computer programs and use a debugger are not aware of the principles and mechanisms of its operation.


It's hard to be a debugger...

In light of the fact that programmers use the debugger day and night, especially when they enter deep debugging mode, it is worth saying that if the debugger were not a program, but a piece of hardware, it would probably overheat and break. Because even the compiler doesn’t have as much work as the debugger gets.

Of course, since there are now many different programming languages, there are different debuggers for each of them. And, naturally, for different categories of these languages ​​there are differences in the work of debuggers: for example, a debugger for programs in interpreted Ruby will work differently than for one compiled into bytecode Java language, and the debugger for Java, in turn, will have differences from the Visual C++ debugger.

I'll talk about debugging for the Windows platform. Having understood the principles of operation of debuggers for it, it will be possible to understand both debuggers for POSIX systems and debuggers that work not at the operating system level, but at the level of a virtual machine or some interpreter.


Debuggers for Windows: two types

There are two fundamentally different types of debuggers for Windows. I think everyone came across the first one when programming in Delphi (didn’t program in it? It’s hard to believe. What did you program in at school and in junior college?). These are custom application debuggers. There are many of them, and they exist both individually and (especially, by the way, often) as part of integrated application development environments. Among debuggers distributed as separate software products, OllyDbg is traditionally highlighted, and I once wrote about it in Computer News.

The second type of debugger is the operating system kernel debugger. They are found and used less frequently and their design differs significantly from custom application debuggers. The most famous, and at the same time, the best kernel debugger is SoftIce. Perhaps you have not only heard about it, but even used it.

Since the work of each of the two types of debuggers has its own specifics, I will talk about each of them in more detail.


Custom Application Debugger

The debugger for user applications is simpler, since the operating system takes on the most menial and dirty work. Windows has special software interfaces that are designed for debugging user-level applications - they are called Windows Debugging API. It is the debugging APIs that are used by all debuggers that are built into popular integrated development environments for Windows.

In order for debugging to begin, the debugger must launch the process being debugged in a special way - so that the system knows that this process will be under debugging. After this, the debugging cycle begins: the program is executed until a certain event occurs, which is called a debug event. This runs the debugging loop in a separate thread to prevent the debugger from hanging.

But this is just the beginning. Because the fun of the debugger begins when the debug event occurs. After all, what is the job of a debugger? To help the programmer localize an error with precision to a specific function, a specific operation, a specific variable. The debugger can also help with this difficult task operating system.

So, a debugging event has occurred, and then we need to somehow find out how this is related to the program text. This is only possible if the program itself includes special debugging information - a table of debugging symbols. It contains information about the correspondence between addresses and names of functions, data types, and line numbers of code. It is thanks to them that the debugging that every Windows programmer is familiar with is possible. Symbol tables have different formats, and therefore it is not always possible to debug a program compiled by one developer's compiler using a debugger from another manufacturer. But, however, the most common format can still be specified - this is PDB (Program Database), and it was developed, naturally, by Microsoft Corporation.

So, if the debug symbol table is in PDB format, then you can use a special tool from Microsoft - the symbolic debug processor. Once upon a time it was part of the system core and was called Imagehlp.dll, but a long time ago it was separated into a separate library. The character processor allows you to find the nearest open function or global variable at a given address, as well as the line number and name of the source file in which this line is located. Inverse operations are also supported, for example, searching for the address of a function by its name.

This, of course, is not all the work that the custom application debugger does. For example, when debugging multi-threaded applications, many very subtle issues arise related to the interaction of threads. Even when debugging such relatively simple things as services, there are some nuances.

But we won’t dwell on the nuances now - at the end of the article I will tell you where to read about them. Now let's look at kernel debuggers.


Kernel Debugger

Kernel debuggers are much more complex programs than user application debuggers, and I think it's quite clear why: they do not have an operating system assistant. In this case, she is their client, because it is she who, ultimately, must debug.

Most kernel debuggers require two computers connected by a null modem cable to operate. A null modem is a way to connect two computers directly with a cable through their COM or LTP ports. A second computer is needed because the part of the debugger sitting on the first one (on the one where the system being debugged is installed) has limited access to the hardware, and therefore all data output goes via a null modem to the second computer.

Modern Intel x86 processors have special debugging registers (both the old 368 and newer processor models have only eight of them, they are called DR0-DR7). These registers allow the debugger to set breakpoints on memory reads and writes, as well as on I/O ports. In general, everything looks exactly like this, and I don’t think it’s worth describing in detail now what each of the debug registers is responsible for, what interrupts implement breakpoints, and give other similar information. It’s better to tell you about specific existing kernel debuggers for Windows.

Well, firstly, it is a debugger built into the operating system kernel itself. It is present in all NT line operating systems, starting with Windows 2000. It is part of the NTOSKRNL.EXE file, and can be enabled by setting the "/Debug" option for the operating system in BOOT.INI. This debugger requires a null modem connection and a second computer with the same OS.

There is another kernel debugger from Microsoft - WinDBG. Strictly speaking, this is not a kernel debugger, but a hybrid debugger that can also be used to debug user-level applications. It, unlike the debugger built into the kernel, has a graphical shell, and therefore is easier to use. This debugger also supports special extensions that can be useful for some debugging tasks. But it also requires two computers to debug the kernel.

However, there is a kernel debugger that can debug on a single computer. This is SoftIce. At the same time, SoftIce can also debug application programs. The use of this debugger for user programs is justified, for example, in the case of debugging real-time systems tied to the system timer. If you debug using a regular debugger, the result may be incorrect even if the program is running correctly, and SoftIce will stop both the program and the timer. This is useful when debugging multi-threaded applications. In addition, SoftIce has very, very well-developed means of displaying information about all threads in the system, about thread synchronization for multi-threaded applications, information about handles... The only disadvantage of this debugger is its complexity for an application programmer. But of the kernel debuggers this is the simplest and most effective.


For the most curious

Now, of course, talking about debuggers for Windows applications is not as relevant as it was ten years ago. The whole world became interested in the Internet, and the main users of SoftIce were crackers, tireless workers in the field of piracy. However, it's not that bad. Communication with SoftIce undoubtedly develops a person in terms of computer knowledge, although, of course, if you communicate only with debuggers and not communicate with real people, some side effects are possible. Well, I think everyone already guesses about this.

Debuggers are some of the most distinctive types of software, but in terms of development, even user-level program debuggers are quite complex. But, nevertheless, if you have the desire and time to develop your own debugger, your knowledge in the field of operating systems and programming will increase significantly, which means your chances of getting a well-paid job will increase.

So, if you want to create your own debugger, you should first read the materials on this topic. In my opinion, the best book to start with is John Robbins's book, Debugging Windows Applications. It is already old, published in 2001, but the information contained in it is still relevant today, since it is of a general, even in some way fundamental, nature. This book contains examples of writing debuggers for Windows, and it will also be useful if you program in C++ and want to better understand exception handling. Actually, it was from this book that I learned the information about debuggers presented in the article. If you can’t find this book (after all, it’s already quite old), there are several addresses that may be useful to you. The first one is like this: www.xakep.ru/post/19158/default.asp. This article from Hacker magazine goes into a little more detail about kernel debuggers than I did, and also contains code for a simple debugger. And at kalashnikoff.ru/Assembler/issues/016.htm you can learn how to write a DOS debugger. But, of course, it is best to read MSDN and at the same time find some open source debugger to understand it. And, of course, if you have taken up writing a debugger, then success to you in this difficult task!

This series of articles appeared for two reasons. First of all, I like working with the project HackSysExtremeVulnerableDriver. Secondly, I received a lot of wishes to cover this topic.

All code used in writing this series is in my repository.

In this series of articles we will look at writing kernel-level exploits in Windows. It's important to note that we will be dealing with known vulnerabilities and there is no need for reverse engineering (at least for the driver).

It is expected that after reading all the articles, you will know all the most common classes of vulnerabilities and methods of exploitation, and will also be able to port exploits from x86 architecture to x64 architecture (if possible) and become familiar with new protection methods in Windows 10.

Kernel debug circuit

Unlike user-level debugging, which suspends the execution of a single process, kernel-level debugging involves the entire system, and we will not be able to use this method. Accordingly, we need a separate debugging machine that can communicate with the system where the kernel is being debugged, view memory and kernel structures, and also catch system crashes.

Additional material to study:

Exploiting kernel vulnerabilities

This process is much more fun than operating at the user J level.

The main goal is to achieve privileged execution in the context of the kernel. And then everything depends on our imagination, from a feast with homemade beer to the introduction of state-sponsored malware.
In general, our task is to obtain a shell with system privileges.

Topics of articles in this series

  • Part 1: Setting up your work environment
    • Configuring three virtual machines and a system that will act as a debugger.
    • Configuring the WinDBG debugger.
  • Part 2: Payloads
    • Explore the most common payloads. Subsequent parts will address specific vulnerabilities and, where appropriate, provide links to this article.
  • The remaining parts.
    • Consideration of vulnerabilities.

Kernel exploit development life cycle

  • Finding a vulnerability. This topic will not be discussed in this series, since we already know exactly where the gaps are.
  • Intercepting the thread of execution. Some vulnerabilities involve code execution, and some have additional requirements.
  • Privilege escalation. The main goal is to get a shell with system privileges.
  • Restoring the thread of execution. Unchecked exceptions at the kernel level cause the system to crash. If you are not going to write an exploit for a DoS attack, you should take this fact into account.

Types of target systems

We will work with vulnerabilities in the following systems (the specific version is not important):

  • Win7 x86 VM
  • Win7 x64 VM
  • Win10 x64 VM

Let's start with the x86 architecture, and then we will port the exploit to the Win7 x64 system. Some exploits will not run on Win10 machines due to the presence of new protections. In this case, we will either change the logic of the exploit or use a completely different approach.

Software used:

  • Hypervisor (lots of options).
  • Windows 7 x86 VM
  • Windows 7 x64 VM
  • Windows 10 x64 VM

Setting up systems for debugging

The debug systems we will be interacting with are designed to load the vulnerable driver. These machines will crash frequently, since most exceptions in the kernel contribute to this type of phenomenon. It is necessary to allocate enough random access memory for these systems.

On each machine that will be debugged, you need to do the following:

  • Inside the VirtualKD directory, run the file target\vminstall.exe. A new one will be added boot record and debug functions will be available and automatic connection to the VirtualKD server installed on the system, which acts as a debugger.

In the case of Windows 10 VM, you need to enable test signing mode, which allows you to load unsigned drivers into the kernel.

After running the bcdedit /set testsinging on command and rebooting, “Test Mode” will appear on the desktop.

Brief description of the HEVD module

The DriverEntry procedure is the starting procedure for each driver:

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) (
UINT32 i = 0;
PDEVICE_OBJECT DeviceObject = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING DeviceName, DosDeviceName = (0);

UNREFERENCED_PARAMETER(RegistryPath);
PAGED_CODE();

RtlInitUnicodeString(&DeviceName, L"\\Device\\HackSysExtremeVulnerableDriver");
RtlInitUnicodeString(&DosDeviceName, L"\\DosDevices\\HackSysExtremeVulnerableDriver");

//Create the device
Status = IoCreateDevice(DriverObject,
0,
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE
&DeviceObject);

  • This procedure contains a call to the IoCreateDevice function, which contains the name of the driver that we will use during communication.
  • The necessary structures and function pointers will be added to the DriverObject object.
  • What is important for us is the function pointer associated with the DriverObject->MajorFunction procedure, which is responsible for processing IOCTL (I/O Control);
  • In HEVD this function is called IrpDeviceIoCtlHandler which is a big conditional expression with multiple branches for each IOCTL. Each vulnerability has a unique IOCTL.

Example: HACKSYS_EVD_IOCTL_STACK_OVERFLOW is an IOCTL used to trigger a stack overflow exploit.

This concludes the first part. In the next article we will talk about payloads. On this moment The only payload available is one designed to steal tokens, which will be used in the third part.

P.S. I understand that there are a lot of intricacies and problems that you may encounter. Since this series focuses on developing exploits, you will have to solve all the associated problems yourself. However, you can ask any questions you have in the comments.

chPF OELPFPTSCHE KHLBBOYS RP TBVPFE U PFMBDLPK SDTB U BCHBTYKOSHNY DBNRBNY RBNSFY. lBL RTBCHYMP, CHBN OHTSOP VKDEF ЪBDBFSH PDOP YЪ KHUFTPKUFCH RPDLBYULY, RETEYUYUMEOOSCHI CH ZHBKME /etc/fstab . uvtpu pvtbpch RBNSFY O KHUFTPKUFCHB, OE SCHMSAEYEUS KHUFTPKUFCHBNY RPDLBYULY, OBRTYNET, MEOFSHCH, CH DBOOSCHK NPNEOF OE RPDDETSYCHBAFUS.

Note: yURPMSHHKFE LPNBODH dumpon (8) DMS KHLBBOYS SDTH NEUFB, ZDE OHTsOP UPITBOSFSH BCHBTYKOSHCHE DBNRSCH. rPUME OBUFTPKLY RP LPNBODE swapon (8) TBDEMB RPDLBYULY DPMTSOB VSHFSH CHSHCHBOB RTPZTBNNNB dumpon . pVSHYUOP LFP CHSHRPMOSEPHUS ЪBDBOYEN RETENOOOPK dumpdev CH ZHBKME rc.conf (5). еUMY ЪБДБOB ьФБ RATENEOOBS, FP RPUME UVPS RTY RETCHPK NOPZPRPMSHЪPCHBFEMSHULPK RETEЪBZTHЪLE VHDEF BCHFPNBFYUEULY ЪBRHEEOOB RTPZTBNNNB savecore (8). pOB UPITBOIF BCHBTYKOSHCHK DBNR SDTB CH LBFBMPZ, ЪBDBOOSCHK CH RETENEOOOPK dumpdir ZHBKMB rc.conf . rP KHNPMYUBOYA LBFBMPZPN DMS BCHBTYKOSCHI DBNRPCH SCHMSEFUS /var/crash .

mYVP CHSC NPTSEFE ЪBDBFSH KHUFTPKUFCHP DMS UVTPUB PVTBB RBNSFY SCHOP YUETE RBTBNEFT dump CH UFTPLE config LPOZHYZHTBGYPOOPZP ZHBKMB CHBYEZP SDTB. fBLPK URPUPV YURPMSHЪPCHBFSH OE TELPNEODHEFUS Y PO DPMTSEO YURPMSHЪPCHBFSHUS, FPMSHLP EUMY CHSCH IPFYFE RPMKHYUBFSH BCHBTYKOSHCH PVTBYSH RBNSFY SDTB, LPFPTPPE BCHBTYKOP ЪBCHETYBEF UCHPA TBVPFH RTY ЪBZTHЪLE.

Note: dBMEE FETNYO gdb PYOBYUBEF PFMBDYUYL gdb , ЪBRHEEOOSCHK CH ``TETSINE PFMBDLY SDTB". RETEIPD CH LFPF TETSYN DPUFYZBEFUS ЪBRHULPN gdb U RBTBNEFTPN -k . h TETSYNE PFMBDLY SDTB gdb YЪNEOSEF UCHPЈ RTYZMBYEOYE ABOUT (kgdb) .

Tip: Eumi Chechi yurpmshhef FreeBSD Cetui 3 ymi tbooaa, Cheshchiki DPMTSOSH Cheshrpmeifsh Huyuye PFMBDPZP SDTB LPNBODPK STRIP, Hufbobchmychbfsh PFMSHYP PFMBDPUOP:

# cp kernel kernel.debug # strip -g kernel

bFPF YBZ OE FBL KhTS Y OEPVIPDYN, OP TELPNEODKHEN. (PhP FreeBSD 4th VPMEE RPJDOYI TEMYBI LFPF YBZ CHSHRPMOSEFUS BCHFPNBFYUEULY CH LPOGE RTPGEUUB RPUFTPEOOYS SDTB make .) lPZDB SDTP HUEYEOP, BCHFPNBFYUEULY YMY RTY RPNPEY LPNBOD CHCHYE, CHCH NPTSEFE KHUFBOPCHYFSH EZP PVSHYUOSCHN PVTBBPN, OVTTBCH make install .

ъBNEFSHFE, YuFP CH UFBTSHCHETUISI FreeBSD (DP 3.1, OE CHLMAYUBS LFPF TEMY), YURPMSHKHEFUS SDTB CH ZHTNBFE a.out, RPFPNH YI FBVMYGSH UYNCHPMPCH DPMTSOSCH TBURPMBZBFSHUS RPUFPSOOP CH RBNSFY. u VPMSHYPK FBVMYGEK UYNCHPMPCH CH OE HUEYOOOPN PFMBDPUOPN SDTE LFP YЪMYYOSS FTBFB. rPUMEDOYE TEMYYSH FreeBSD YURPMSHJHAF SDTB CH ZHTNBFE ELF, ZHE LFP OE SCHMSEFUS RTPVMENPK.

eUMY CHSH FEUFYTHEFE OPCHPE SDTP, ULBTSEN, OBVYTBS YNS OPCHPZP SDTB CH RTYZMBYYEOYY UBZTHYUYLB, OP CHBN OHTSOP ЪBZTHTSBFSH Y TBVPFBFSH U DTHZYN SDTPN, YUFPVSH UOPChB CHETOHFSHUS L OPTNBMSHOPNH ZHOLGYPOYTPCHBOYA, ЪBZTHTSBKFE EZP FPMSHLP CH PDOPRPMSHЪPCHBFEMSHULPN TETSYNE RTY RPNPEY ZHMBZB -s , KHLBSCCHBENPZP RTY ЪBZTHЪLE , B ЪBFEN CHSHRPMOYFE FBLYE YBZY:

# fsck -p # mount -a -t ufs # so your filesystem for /var/crash is writable # savecore -N /kernel.panicked /var/crash # exit # ...to multi-user

bFB RPUMEDPCHBFEMSHOPUFSH KHLBSCCHBEF RTPZTBNNE savecore (8) ABOUT YURPMSHЪPCHBOYE DTHZPZP SDTB DMS YЪCHMEYUEOYS UYNCHPMYUEULYI YNEO. YOBYUE POB VHDEF YURPMSHЪPCHBFSH SDTP, TBVPFBAEEE CH DBOOSHCHK NPNEOF Y, ULPTEE CHUEZP, OYUEZP OE UDEMBEF, RPFPNH YuFP BCBTYKOSHCHK PVTB RBNSFY YYNCHPMSCH SDTB VHDHF PFMYUBFSHUS.

b FERETSH, RPUME UVTPUB BCHBTYKOPZP DBNRB, RETEKDYFE CH LBFBMPZ /sys/compile/WHATEVER Y ЪBRKHUFYFE LPNBODH gdb -k . yЪ RTPZTBNNSH gdb UDEMBKFE CHPF SFP:

Symbol-file kernel.debug exec-file /var/crash/kernel.0 core-file /var/crash/vmcore.0 Y CHBMS - CHCH NPTSEFE PFMBTSYCHBFSH BCHBTYKOSHK DBNR, YURPMSHЪHS YUIPDOSCH FELUFSCH SDTB FPYuOP FBLCE, LBL CHSHCH LFP DEM BEFE AT MAVPC DTHZPK RTPZTBNNPK.

chPF TsKHTOBM LPNBOD UEBOUB TBVPFSH gdb, YMMAUFTYTHAEIK bfh RTPGEDHTH. dMYOOSCH UFTPLY VSHMY TBPTCHBOSH DMS KHMHYUYEOYS YUYFBVEMSHOPUFY Y DMS KHDPVUFCHB UFTPLY VSHCHMY RTPOKHNETPCHBOSHCH. CHUE PUFBMSHOPE SCHMSEFUS FTBUUYTPCHLPK PYYVLY, TEBMSHOP CHPOYLOKHCHYEK PE CHTENS TBVPFSCH OBD DTBKCHETPN LPOUPMY pcvt.

1:Script started on Fri Dec 30 23:15:22 1994 2: # cd /sys/compile/URIAH 3: # gdb -k kernel /var/crash/vmcore.1 4:Reading symbol data from /usr/src/ sys/compile/URIAH/kernel ...done. 5:IdlePTD 1f3000 6:panic: because you said to! 7:current pcb at 1e3f70 8:Reading in symbols for ../../i386/i386/machdep.c...done. 9: (kgdb) where 10:#0 boot (arghowto=256) (../../i386/i386/machdep.c line 767) 11:#1 0xf0115159 in panic () 12:#2 0xf01955bd in diediedie ( ) (../../i386/i386/machdep.c line 698) 13:#3 0xf010185e in db_fncall () 14:#4 0xf0101586 in db_command (-266509132, -266509516, -267381073) 15:#5 0x f0101711 in db_command_loop () 16:#6 0xf01040a0 in db_trap () 17:#7 0xf0192976 in kdb_trap (12, 0, -272630436, -266743723) 18:#8 0xf019d2eb in trap_fatal (...) 19:#9 0xf0 19ce60 in trap_pfault ( ...) 20:#10 0xf019cb2f in trap (...) 21:#11 0xf01932a1 in exception:calltrap () 22:#12 0xf0191503 in cnopen (...) 23:#13 0xf0132c34 in spec_open () 24: #14 0xf012d014 in vn_open () 25:#15 0xf012a183 in open () 26:#16 0xf019d4eb in syscall (...) 27: (kgdb) up 10 28:Reading in symbols for ../../i386/i386 /trap.c...done. 29:#10 0xf019cb2f in trap (frame=(tf_es = -260440048, tf_ds = 16, tf_\ 30:edi = 3072, tf_esi = -266445372, tf_ebp = -272630356, tf_isp = -27\ 31:2630396, t f_ebx = - 266427884, tf_edx = 12, tf_ecx = -266427884, tf\ 32:_eax = 64772224, tf_trapno = 12, tf_err = -272695296, tf_eip = -26\ 33:6672343, tf_cs = -26646936 8, tf_eflags = 66066, tf_esp = 3072, tf_\ 34:ss = -266427884)) (../../i386/i386/trap.c line 283) 35:283 (void) trap_pfault(&frame, FALSE); 36: (kgdb) frame frame->tf_ebp frame->tf_eip 37:Reading in symbols for ../../i386/isa/pcvt/pcvt_drv.c...done. 38:#0 0xf01ae729 in pcopen (dev=3072, flag=3, mode=8192, p=(struct p\ 39:roc *) 0xf07c0c00) (../../i386/isa/pcvt/pcvt_drv.c line 403) 40:403 return ((*linesw.l_open)(dev, tp)); 41: (kgdb) list 42:398 43:399 tp->t_state |= TS_CARR_ON; 44:400 tp->t_cflag |= CLOCAL; /* cannot be a modem (:-) */ 45:401 46:402 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200) 47:403 return ((*linesw.l_open)(dev, tp)); 48:404 #else 49:405 return ((*linesw.l_open)(dev, tp, flag)); 50:406 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */ 51:407 ) 52: (kgdb) print tp 53:Reading in symbols for ../../i386/i386/cons.c...done. 54:$1 = (struct tty *) 0x1bae 55: (kgdb) print tp->t_line 56:$2 = 1767990816 57: (kgdb) up 58:#1 0xf0191503 in cnopen (dev=0x00000000, flag=3, mode=8192 , p=(st\ 59:ruct proc *) 0xf07c0c00) (../../i386/i386/cons.c line 126) 60: return ((*cdevsw.d_open)(dev, flag, mode, p) ); 61: (kgdb) up 62:#2 0xf0132c34 in spec_open () 63: (kgdb) up 64:#3 0xf012d014 in vn_open () 65: (kgdb) up 66:#4 0xf012a183 in open () 67: (kgdb) up 68:#5 0xf019d4eb in syscall (frame=(tf_es = 39, tf_ds = 39, tf_edi =\ 69: 2158592, tf_esi = 0, tf_ebp = -272638436, tf_isp = -272629788, tf\ 70:_ebx = 7086 , tf_edx = 1, tf_ecx = 0, tf_eax = 5, tf_trapno = 582, \ 71:tf_err = 582, tf_eip = 75749, tf_cs = 31, tf_eflags = 582, tf_esp \ 72:= -272638456, tf_ss = 39)) (. ./../i386/i386/trap.c line 673) 73:673 error = (*callp->sy_call)(p, args, rval); 74: (kgdb) up 75:Initial frame selected; you cannot go up. 76: (kgdb) quit 77: # exit 78:exit 79: 80:Script done on Fri Dec 30 23:18:04 1994

lPNNEOFBTYY L CHSHCHYYERTYCHEDEOOPNH TSHTOBMKH:

UFTPLB 6:

ьФП DBNR, CHSFSHCHK RTY RPNPEY DDB (UNPFTY OITSE), RPPFPNH LPNNEOFBTYK L BCHBTYKOPNH PUFBOPCHH YNEEF YNEOOP CHYD ``because you said to!'' Y FTBUUYTPCHLB UFELB ZMHVPLB; PDOBLP YOBYUBMSHOPK RTYYUYOPK RETEIPDB CH DDB VSHMB BCHBTYKOBS PUFBOPCHLB RTY CHPOYLOPCHEOYA PYYVLY UFTBOIGSC RBNSFY.

UFTPLB 20:

lFP NEUFPOBIPTSDEOOYE ZHKHOLGYY trap() CH FTBUUYTPCHLE UFELB.

UFTPLB 36:

rTYOKHDIFEMSHOPE YURPMSHЪPCHBOIE OPChPK ZTBOYGSCH UFELB; FERTSH LFP OE OHTSOP. rTEDRPMBZBEFUS, YuFP ZTBOYGSCH UFELB KHLBSCCHBAF ABOUT RTBCHYMSHOP TBURPMPTSEOYE, DBCE CH UMHUBE BCHBTYKOPZP PUFBOPCHB. zMSDS ABOUT UFTPLH YUIPDOPZP LPDB 403, NPTsOP ULBBFSH, YuFP CHEUSHNB CHETPSFOP, YuFP MYVP CHYOPCHBF DPUFHR RP KHLBBFEMA ``tp"", MYVP VSHM CHSHCHIPD ЪB ZТBOYGSC NBUUYCHB.

UFTPLB 52:

rPIPTSE, YuFP CHYOPCHBF KHLBBFEMSH, OP ON SCHMSEFUS DPRKHUFYNSCHN BDTEUPN.

UFTPLB 56:

pDOBLP, PYUECHYDOP, UFP ON KHLBSCCHBEF ABOUT NHUPT, FBL UFP NSCH OBYMY OBYKH PYYVLH! (DMS FEI, LFP OE ЪOBLPN U LFPC YUBUFSHHA LPDB: tp->t_line UMHTSYF DMS ITBOEOYS TETSYNB LBOBMMB LPOUPMSHOPZP KHUFTPKUFCHB, Y LFP DPMTSOP VShchFSH DPUFBFPYuOP NBMEOSHLPE GEMPE YUYUMP. )

Kernel mode debuggers sit between the CPU and the operating system. This means that when you stop the kernel mode debugger, the operating system also stops completely. It's easy to see that bringing the operating system to a hard stop is useful when you're working on timers and timing issues. Still, with the exception of one debugger, which will be discussed below (in the “SoftlCE Debugger” section of this chapter), you cannot debug the code user mode using kernel mode debuggers.

There are not many kernel mode debuggers. Here are some of them: Windows 80386 Debugger (WDEB386), Kernel Debugger (1386KD), WinDBG and SoftlCE. Each of these debuggers is briefly described in the following sections.

Debugger WDBEB386

WDEB386 is a Windows 98 kernel mode debugger distributed as part of the Platform SDK. This debugger is only useful for developers writing Windows 98 virtual device drivers (VxD). Like most kernel mode debuggers for Windows operating systems, the WDEB386 debugger requires two machines to run and null modem cable. Two machines are needed because the part of the debugger that runs on the target machine has limited access to its hardware, so it sends its output to and receives commands from the other machine.

The WDEB386 debugger has an interesting history. It started out as an internal background tool for Microsoft during the Windows 3.0 era. It was difficult to use and did not have enough support for debugging source code and other nice properties that the Visual C++ and Visual Basic debuggers spoiled us with.

"Dot" (DOT) commands are the most important feature of the WDEB386. Through interrupt INT 41, the WDEB386 can be expanded to add commands. This extensibility allows VxD driver authors to create custom debugging commands that give them easy access to information in their virtual devices. Debug Windows version 98 supports a variety of DOT commands that allow you to observe the exact state of the operating system at any point in the debugging process.

Debugger I386KD

Windows 2000 differs from Windows 98 in that the actual working part of the kernel mode debugger is the NTOSKRNL part. EXE - file of the main operating kernel Windows systems 2000. This debugger is available in both free (release) and tested (debug) operating system configurations. To enable kernel mode debugging, set the bootloader option /DEBUG to BOOT. INI and, additionally, the bootloader option /DEBUGPORT, if you need to set the kernel mode debugger communication port to a value other than the default (COM1). I386KD runs on its own machine and communicates with Windows machine 2000 via a null modem cable.

Kernel mode debugger NTOSKRNL. The EXE does only enough to control the CPU so that the operating system can be debugged. Most of the debugging work - symbol processing, extended breakpoints and disassembly - is done on the 1386KD side. One Windows time The NT 4 Device Driver Kit (DDK) documented the protocol used in the null modem cable. However, Microsoft no longer documents it.

The power of the 1386KD is obvious when you look at all the commands it offers to access internal Windows state 2000. Knowledge of how device drivers work in Windows 2000 will help the programmer monitor the output of many commands. Despite all its power, i386KD is almost never used because it is a console application, which is very tedious to use for baseline debugging.

Sometimes I have a situation where Windows is waiting for loading time for the kernel debugger. You see the text "Windows start" but not the logo.

If I attach the debugger now, the Windows 7 logo animation plays. After that, the logo starts pulsing. At this point, the download process no longer progresses. CPU load is reduced to a minimum. I usually wait a few minutes, but nothing happens.

This doesn't always happen. However, if this happens, resetting the VM will not help. To fix this problem I need to use startup repair. Unfortunately, this takes forever.

Any ideas what I can do besides running startup repair?

Thank you in advance!

3

2 answers

To fix the problem you are facing, simply press F10 during boot. And remove/debug and related parameters. Then press enter.

Suggestion: Do not use /debug for the default boot menu option. Copy the boot configuration to a new entry. Then set it to debug mode. Windows doesn't know when you'll use the debugger. Therefore he must wait.