I want to debug a specific process on a remote system and the only way i can do that is to use the kernel debugging method.
It works pretty good with just WINDBG, but i think ida can give me the extra edge i need for a better reversing experience.
So far debugging with windbg was successfull but now when i am using the windbg plugin in ida:
what i am actually experiencing is that i cant get the extra analysis from ida, all i can do is attach only to the process it self (only one available to attach to). and in the Modules window all i can see is the ntkrpamp.exe, which i assume is the kernel process.
i can use all WINDBG regular commands like !process 0 0, etc.. and can debug normally but nothing shows in the IDA window
I have never debugged dynamically using IDA but i can see it is possible..
could it work aswell in a kernel debugging session?
Edit:
I just noticed it is possible to analyze a model if i set a breakpoint with the windbg plugin and when IDA hits that breakpoint, this module is added to the IDA Modules windows.
It would be a lot easier if i could just analyze it without pre-putting a breakpoint on the specific module and waiting for it to hit.
Related
I've always wanted to know the inner-workings of Visual Studio's debugger and debuggers in general. How does it communicate and control your code, especially when it's running inside a host process or an external network server (attach to process)? Does the compiler or linker patch your code with callbacks so that the debugger is given control? If it indeed works this way, how do interpreted languages such as JavaScript containing no debug code work?
Generally speaking, Windows provides an API for writing debuggers that let you examine and modify memory in another process and to get notifications when exceptions happen in another process.
The debug process sits in a loop, waiting for notification from events from the process under inspection. To set a breakpoint, the debugger process modifies the code in the debugee to cause an exception (typically, an int 3 instruction for x86).
The compiler and linker work together to make the symbol information about a program available in a format that can be read by debuggers. On Windows, that's typically CodeView in a separate PDB file.
In the Unix-derived world, there's an API called ptrace that does essentially the same sorts of things as Windows debugging API.
For remote debugging, a small program is placed on the remote machine that communicates with and acts on behalf of the actual debugger running on the local machine.
For interpreted languages, like JavaScript, the debugger works with the interpreter to give the same sorts of functionality (inspecting memory, setting breakpoints, etc.).
Windows includes support for debuggers. A process has to enable debugger privilege, and once this is done that process can attach to any other process and debug it using windows debugger functions
http://msdn.microsoft.com/en-us/library/windows/desktop/ms679303(v=vs.85).aspx
For something like javascript, seems like you would need the equivalent of a javascript debugger.
In the case of a Visual Studio multi-process project, you typically have to switch which process the debugger is attached to in order to debug that process. I don't know if there's a way to have pending breakpoints set for multiple processes at the same time. There could be other debuggers that work better with multiple processes, but I haven't used such a tool.
I would like also ask about one thing: somewhere I've read that windbg supports multiple modes of debugging and one of those modes is some kind of kernel debugging where system is normally running and does not wait for windbg breakpoints etc. Is this local kernel debugging mode? Also if anybody can clarify very briefly the differences between Non invasive debugging and Dormant mode. I did not catch it from MSDN. Thank you
Debugging types
You can distinguish several times
a) between kernel debugging and user mode debugging (application debugging)
b) between live debugging (running system) and post mortem debugging (crash dump analysis)
c) between local debugging and remote debugging
so in total there are 8 combinations of debugging.
For local live kernel debugging you need to put the Windows kernel in debug mode. If you don't want that, you can get "pseudo"-live local kernel debugging with SysInternals LiveKd.
Noninvasive debugging
Noninvasive debugging is a subset of user mode debugging and best described by the article you already linked to (which is a copy of WinDbg help), which says:
With noninvasive debugging, you do not have as many debugging actions. However, you can minimize the debugger's interference with the target application. Noninvasive debugging is useful if the target application has stopped responding.
In noninvasive debugging, the debugger does not actually attach to the target application. The debugger suspends all of the target's threads and has access to the target's memory, registers, and other such information. However, the debugger cannot control the target.
Dormant mode
Dormant mode is when WinDbg is running but has not attached to any target. E.g. if you just start WinDbg without any command line options and you have not pressed F6 yet to attach to a process.
The task - when the application crashes, it is required to find the crash cause.
I saw recommendations to take the crash dump with AdPlus and then load it into WinDbg for analysis.
What I do is attach WinDbg to a process and wait for the program crash to debug once WinDbg shows the exception.
Is there any advantages in using AdPlus instead of directly attaching WinDbg to the process?
In your case, there's no advantage in creating a dump using AdPlus. If you can attach WinDbg and debug on the target machine, having the complete heap at hand, that's the best you can get.
In general, AdPlus is merely a VB script that wraps CDB, which is a console debugger. When you use it, CDB effectively debugs your program, the same way WinDbg does. The gain you get from using AdPlus is the easy configuration and notification options. Also, since it's designed to create dumps, it does that nicely - creates a per dump folder etc. But that's just convenience - as far as your basic need of finding the bug goes, in your case I'd stick with WinDbg.
I would say ADPlus is only better for non-technical person.
For developers, load process into WinDbg is much more convenient.
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
I keep wondering how does a debugger work? Particulary the one that can be 'attached' to already running executable. I understand that compiler translates code to machine language, but then how does debugger 'know' what it is being attached to?
The details of how a debugger works will depend on what you are debugging, and what the OS is. For native debugging on Windows you can find some details on MSDN: Win32 Debugging API.
The user tells the debugger which process to attach to, either by name or by process ID. If it is a name then the debugger will look up the process ID, and initiate the debug session via a system call; under Windows this would be DebugActiveProcess.
Once attached, the debugger will enter an event loop much like for any UI, but instead of events coming from the windowing system, the OS will generate events based on what happens in the process being debugged – for example an exception occurring. See WaitForDebugEvent.
The debugger is able to read and write the target process' virtual memory, and even adjust its register values through APIs provided by the OS. See the list of debugging functions for Windows.
The debugger is able to use information from symbol files to translate from addresses to variable names and locations in the source code. The symbol file information is a separate set of APIs and isn't a core part of the OS as such. On Windows this is through the Debug Interface Access SDK.
If you are debugging a managed environment (.NET, Java, etc.) the process will typically look similar, but the details are different, as the virtual machine environment provides the debug API rather than the underlying OS.
As I understand it:
For software breakpoints on x86, the debugger replaces the first byte of the instruction with CC (int3). This is done with WriteProcessMemory on Windows. When the CPU gets to that instruction, and executes the int3, this causes the CPU to generate a debug exception. The OS receives this interrupt, realizes the process is being debugged, and notifies the debugger process that the breakpoint was hit.
After the breakpoint is hit and the process is stopped, the debugger looks in its list of breakpoints, and replaces the CC with the byte that was there originally. The debugger sets TF, the Trap Flag in EFLAGS (by modifying the CONTEXT), and continues the process. The Trap Flag causes the CPU to automatically generate a single-step exception (INT 1) on the next instruction.
When the process being debugged stops the next time, the debugger again replaces the first byte of the breakpoint instruction with CC, and the process continues.
I'm not sure if this is exactly how it's implemented by all debuggers, but I've written a Win32 program that manages to debug itself using this mechanism. Completely useless, but educational.
In Linux, debugging a process begins with the ptrace(2) system call. This article has a great tutorial on how to use ptrace to implement some simple debugging constructs.
If you're on a Windows OS, a great resource for this would be "Debugging Applications for Microsoft .NET and Microsoft Windows" by John Robbins:
http://www.amazon.com/dp/0735615365
(or even the older edition: "Debugging Applications")
The book has has a chapter on how a debugger works that includes code for a couple of simple (but working) debuggers.
Since I'm not familiar with details of Unix/Linux debugging, this stuff may not apply at all to other OS's. But I'd guess that as an introduction to a very complex subject the concepts - if not the details and APIs - should 'port' to most any OS.
I think there are two main questions to answer here:
1. How the debugger knows that an exception occurred?
When an exception occurs in a process that’s being debugged, the debugger gets notified by the OS before any user exception handlers defined in the target process are given a chance to respond to the exception. If the debugger chooses not to handle this (first-chance) exception notification, the exception dispatching sequence proceeds further and the target thread is then given a chance to handle the exception if it wants to do so. If the SEH exception is not handled by the target process, the debugger is then sent another debug event, called a second-chance notification, to inform it that an unhandled exception occurred in the target process. Source
2. How the debugger knows how to stop on a breakpoint?
The simplified answer is: When you put a break-point into the program, the debugger replaces your code at that point with a int3 instruction which is a software interrupt. As an effect the program is suspended and the debugger is called.
Another valuable source to understand debugging is Intel CPU manual (Intel® 64 and IA-32 Architectures
Software Developer’s Manual). In the volume 3A, chapter 16, it introduced the hardware support of debugging, such as special exceptions and hardware debugging registers. Following is from that chapter:
T (trap) flag, TSS — Generates a debug exception (#DB) when an attempt is
made to switch to a task with the T flag set in its TSS.
I am not sure whether Window or Linux use this flag or not, but it is very interesting to read that chapter.
Hope this helps someone.
My understanding is that when you compile an application or DLL file, whatever it compiles to contains symbols representing the functions and the variables.
When you have a debug build, these symbols are far more detailed than when it's a release build, thus allowing the debugger to give you more information. When you attach the debugger to a process, it looks at which functions are currently being accessed and resolves all the available debugging symbols from here (since it knows what the internals of the compiled file looks like, it can acertain what might be in the memory, with contents of ints, floats, strings, etc.). Like the first poster said, this information and how these symbols work greatly depends on the environment and the language.