How to revert changes to a kernel driver? - windows

So i installed a kernel driver on my windows machine but accidentally left a while(1) in there (I know pretty stupid) and now OS just hangs when i start it. Is there a way to revert the driver to an earlier stage or revert to "previous commit" like we do in git? i can see thought WinDbg that it just hangs there. Even though i can break into it I can't seem to make it move on from that infinite loop.

you'd typically have the below assembly controlling the while(1) loop. From inside the debugger change to assembly source mode and then alter rax register from 0 to 1. That should branch out the subsequent je.
xor eax,eax
cmp eax,1
je xyz
Generally, you'd have to change the driver's start type to "disabled" and fix up other registry entries if it is a filter to any other boot critical devices (eg upper/lower filter)

Related

How does an assembly debugger manipulates registers?

How does the debugger manipulate registers on a working CPU?
i am using nasm and afd with dosbox (don't know and can't use any alternative setup cuz my university requires this setup). running win 10.
really new to assembly. read this thread
but everything just went over my head. so please explain like i am 5. maybe some references to starters
The debugger built-in to DOSBOX is easy: it has a side-channel to access the entire machine state.
Under a multitasking OS, there are system calls like Linux ptrace that can manipulate the state of another process.
Under DOS, the debugger has to insert itself into a different region of memory than the program being debugged. The x86 ISA itself has debug features like TF in FLAGS (Trace Flag) for single stepping.
Once the debugger has control of the CPU (i.e. the CPU is executing debugger code), it can save the old values of registers somewhere (on the stack or in static locations).
It can restore them all (with mov instructions) and return to the program being debugged by using an iret that loads CS:IP and FLAGS from memory. SS:SP has to be valid for this to work (the return info will be right below the SS:SP of the process being debugged). So real-mode DOS debugging is "intrusive", and will clobber space below SS:SP. Unlike under a multitasking OS with virtual memory.
Another way to get back to the process being debugged without using any registers (i.e. after restoring everything) would be a far jmp cs:[mem] using an absolute addressing mode. But that can't restore FLAGS, so it won't work if you want to have TF set when you resume execution of the process being debugged.

Does the operating system assumes anything about callee-saved registers when control returns to it?

Does the operating system assumes anything about callee-saved registers when control returns to it?
I've wondered whether the OS, say Windows, assumes anything about the callee-saved registers like ebp, esi, edi?
In other words, does the OS require the value in any of these registers preserved, when control transfers back to it (ret in main)?
I cannot find anything specified, but I guess the answer is no (having looked at compiler generated code). Is there any documentation on the topic?
Windows 32 is designed to have process isolation.
Nothing* that a process does can cause another process (including) the operating system itself to fail.
For this reason it does not matter what you do with the registers upon exit.
The only exception is esp. If the stack pointer is messed up your application will terminate with a stack fault or access violation.
This will still not affect the OS however, it will merely terminate your app slightly early.
*Obviously this does not include the effects on the system by legitimate system calls, or the exploitation of bugs.
Note that the ret in main does not return control to the OS. Almost all Win32 c applications have a runtime library included. If so the ret in main returns to some initialization code that look like this:
//pseudo-init
do set up (setup command line params for main to read).
call main;
call Windows.ExitProcess();
Having a 'clean' exit to Windows is important to an application so it can clean up its own resources (close files etc). The OS does not really care. If an application does not clean up after itself, the OS will do the job for it.
Much worse than having a crashing up is a 'hung' one. If an application is stuck in an endless loop, or worse an endless loop that keeps claiming more and more resources then the system can be brought to its knees quite easily.

How to bypass isDebuggerPresent with x64dbg

I found a guide how to bypass it in ollydbg:
see here
But how to do that for an x64 application?
I have found following:
How must i manipulate this to don't get it detect the debugger?
You can do it the same way as described in the guide (i.e. by patching the code of IsDebuggerPresent).
Or you can set a breakpoint at the "movzx eax, byte ptr ds:[rax+2]" instruction, and when the program stops at the breakpoint, go to RAX+2 in the Dump pane and then change the byte from 1 to 0.

how to set a memory breakpoint in windbg kernel mode?

I would like to set a memory breakpoints on access in windbg in the kernel mode debugger
I want the debugger breaks everytime a specific module in usermode is hit with the kernel debugger.
but I've read somewhere its impossible to set it, in order to make a memory breakpoints I have to write a plugin to make it
I tried to use SDbgExt plugin with the !vprotect command, but it fails to set memory bp
If I have to write a plugin to allow memory bp in kernel mode It has to be a driver?
I've read some chapters in windows internals book, but it doesn't help me at all.
I couldn't find too much info how to start deal with it
You can set breakpoints on user mode addresses from kernel mode. The only thing you should take care is to switch to the right process with ".process /i " command
If it is a one-off breakpoint -- that is, you are content with process being destroyed by debugging -- zero out the entire module using e command (edit memory). Set the whole thing to cc (which is int 3 as far as I remember)... zeros will do as well. You will break as soon as you touch any of the module's code.
Next step, remember where you were (relative to the module) and set a proper breakpoint.
Hope that helps.
(editing) Do you have full symbols? If you do, did you try bm module!*
Sounds like you want to set a "breakpoint on access" but instead of specifying an address you want to specify a range? I have never seen it done in windbg. The BA breakpoints uses HW debug registers instead of inserting INTs like SW breakpoints so this is definitely HW platform specific.
I have done this on an ARM chipset once using a HW debugger. ETM on ARM allows you to set triggers on address ranges.

Assembly code breakpoint does not work as expected

I am developing a STM32F2 device using GCC 4.7.4 and a Lauterbach Combiprobe JTAG debugger. In my code, I have the following statement to always break at a certain spot for testing purposes:
asm volatile ("BKPT #0");
This is the only breakpoint. When I run the program, I can see that my program reaches the breakpoint, but I cannot step beyond this breakpoint using my JTAG debugger. Instead, I have to move the PC counter past this instruction to get the program to execute.
This was working in the past, but I am at a loss to figure out why the behavior is different now. Any clues or hints would be appreciated.
There are so many broken JTAG debuggers. Probably you installed an update for the JTAG adapter?
When you have GDB as Debugger you might check if you can add a macro set PC=PC+4 to a button or key. But if this is possible depends on your IDE.
There is no general rule what happens with the program counter if you have a breakpoint instruction in you application code. Some CPUs stop at the address containing the breakpoint instruction, others stop after the breakpoint instruction.
Since you use the tag "lauterbach" I assume you are using a TRACE32 debugger from Lauterbach.
If you think the debuggers behavior was different in the past, I think you should contact the Lauterbach support.
For now you can workaround the issue with the following TRACE32 command
Break.Set T:0x1000 /Program /CMD "Register.Set PP r(PP)+2"
(where 0x1000 stands for the address, where your BKPT instruction is located.)

Resources