how to set a memory breakpoint in windbg kernel mode? - debugging

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.

Related

GDB does not break on a read access to an address caught by PIN

I've captured a read memory trace (i.e. addresses of all read accesses) of a program-run by Intel PIN, ASLR was off. I can capture it several times and the trace is still exactly the same.
Then I take an address from the trace (a specific address I am interested in), set a watchpoint in GDB by rwatch *0x7fffe309e643 but GDB does not notice the access. I'm doing this in the same terminal where the trace has been taken so it should access the same addresses; when I capture it then again, the trace is still very the same.
Do you have any ideas or hints why GDB does not catch it?
I have to note that the access very likely happens within a (C++) structure loaded from a Boost serialization and that the code has been compiled with -g3 -O1 flags (-O1 is really crucial for other reasons but a minimal example showed me that GDB breaks correctly even with -O1).
UPDATE:
As suggested, I tried PIN debugger (which actually utilizes GDB) but there is some problem with watchpoints. To present this problem, I made a minimal example.
int main()
{
unsigned char i = 4;
i++;
i = 3;
return 0;
}
I acquired a read memory trace with PIN and chose 0x7fffffffd89f (or similar) as the address of interest. Then I started PIN debugger and GDB in parallel terminals and connected GDB to PIN ((gdb) target remote :57946, as suggested by PIN). In GDB I set watchpoint (gdb) rwatch *0x7fffffffd89f and started execution but I get
Continuing.
Warning:
Could not insert hardware watchpoint 1.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
even though I only inserted a single watchpoint. I also tried to explicitly disable hardware breakpoints by set can-use-hw-watchpoints 0 but then it ran for an hour with no result and no processor load so I killed it.
Is there any other way how to set a functional watchpoint at a specific address when GDB is connected to PIN debugger? Note that there is no such problem with standalone GDB.
I use GDB 7.7.1, PIN 2.14-71313 and GCC 4.4.7, running Ubuntu 14.04.
The original problem would be likely solved then.
From pin user guide:
The "pin" Executable (Launcher)
The kit's root directory contains a "pin" executable. This is a 32-bit
launcher, used for launching Pin in 32 and 64 bit modes. The launcher
sets up the environment to find the libraries supplied with the kit.
It is likely that the environment is different when running pinbin, and therefore stack addresses will also be different (0x7fffe309e643 looks like a possible stack address) even without ASLR.
Your best bet is probably to use Pin application debugging interface.

Breakpoints not being hit in remote linux kernel debugging using gdb

I am trying to remotely debug a linux kernel running on an arm cortex-a9 target using jtag probe and gdb.
I can connect to the kernel and halt it with gdb. I am able to set breakpoints in the kernel code and gdb confirms there placement as well but the problem is that once I start the execution and issue a continue command, the breakpoints are never hit and the kernel continues to run....
Please help me out in this regard.
Thanks.
As pointed in this thread, you should set the breakpoints as hardware breakpoints, namely - using the hbreak command. Only then the breakpoints will be hit.
For anyone reading this, the debugger will not break with software breakpoints by default, see the relevant doc:
"If the architecture that you are using supports the kernel option CONFIG_STRICT_KERNEL_RWX, you should consider turning it off. This option will prevent the use of software breakpoints because it marks certain regions of the kernel’s memory space as read-only. If kgdb supports it for the architecture you are using, you can use hardware breakpoints if you desire to run with the CONFIG_STRICT_KERNEL_RWX option turned on, else you need to turn off this option."
at https://www.kernel.org/doc/html/v4.14/dev-tools/kgdb.html
Disable RWX and recompile, then software breakpoints should work (they started working normally here after this)
Is some cases, KASLR (Kernel Address Space Layout Randomization) can be the culprit.
Even though you setup hbreak, the actual code location can be different from the address seen from the .elf file when using KASLR, so either pass --append "nokaslr" to the kernel boot argument, or configure the kernel with RANDOMIZE_BASE=n. This applies for arm64 and x86_64. (maybe other architectures too).

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.)

ARM Gdb break on processor mode change

Im currently debugging Linux ARM kernel, and have always wondered if it is possible in gdb to break when the cpu mode change (usr, svc, abt etc). Currently, when i'm not sure which mode we are in, I usually have to look at the psr register multiple times, but maybe there is a more effective way, such as break on mode change?
I know I can put breakpoints on the exception vector, but that means I only detect mode changes to privileged mode and not the other way around. Maybe there is a command to check if the psr changes to 0x10(usr mode) ?
Thanks
All processes are scheduled in entry-common.S. This file has a macro named arch_ret_to_user. Define it to be a BKPT instruction, perhaps conditional on a global set via /proc.
You can not detect a switch to user mode generically using the CPU alone (you need support code), as the supervisor code can change anything. ETM may have some means if your CPU has the functionality.
There are also thread_nofity.h which has call-backs for when a user task is re-scheduled. You can hook this with your own logic if you don't need the debugger or put some breakpoint on a null(){} function which you only call from the notifier when the condition is meant.

DbgPrint in Memory Dump?

I have a driver that directly avoids the BSoD and turns the screen of Windows Vista into black with few colourful dots and stripes. I am finding a memory dump on the system afterwards and DbgView is wonderfully showing me a stack trace (stating that this might be a garbled stack and some parts might be incorrect). Pity is, the commands found in the stack are nowhere to be seen in the part of the code that is obviously breaking down the whole thing. (I can leave our the whole routine, but not parts of it.)
Does someone know a way to get debug messages either into the memory dump or out of the serial port to read them in an external debugger? (My testsystem stall if the debugger is connected, but this might be me not knowing enough on the how and why of remotely connected kernel debugging.)
I would like to get to know the point where my code fails, because browsing through code seems fine to me is getting a little futile and I could need a hint.
Description from MSDN on how to setup your debugging session.
The setup procedure is :
Setup 2 PCs, the first with your develop environment and the second which is the debug target. (Vista+Vista64 worked best for me)
Setup a debugger connection by either using a Firewire cable or a Null-Modem cable. (Null-Modem works almost always, but Firewire is better from a performance standpoint. USB is expensive and didn't work out of the box for me ...)
Setup the target computer to boot in 'debug' mode MSDN
Having WinDbg running and waiting for a kernel connection, boot the target computer in debug mode.
While boot up, WinDbg should print messages about the target system. Here you will see DbgPrint messages etc. (All DbgPrint is disabled per default in Vista (not in XP), and you must enable it link)
You can set breakpoints in modules in WinDbg by defining breakpoints.
PS: bcdedit sometimes fails to setup the debug mode. I have no clue why. But there seems a certain order in which you must tell it the debug parameters. Trying different combination's does work wonders ... .
You can use commands in WinDbg when you break into the process. A couple of interesting ones :
lm displays all modules currently loaded
lm m pattern displays all modules satisfying the search condition (e.g. "lm m kernel32*"
x module_name!function_name_pattern lists the symbols in the module (e.g. "kernel32!Create*")
bl lists all currently set breakpoints
bp module_name!function_name sets a breakpoint at the start of the function specified.
bc * deletes all breakpoints
.hh bp displays the help for "bp"
.reload /u x.sys reloads the x.sys module debug settings. (this is helpful when you want to rebuild your project, and get a 'could not create x.pdb ...' message).
Enable all DbgPrint output under Vista :
enable_dbg_print_vista.reg
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
"DEFAULT"=dword:0000000f

Resources