WinDbg -- debugging mixed x64 managed/unmanaged code - visual-studio

I'm using WinDbg (Native x64 -- NOT Itanium) to debug an x64 (unmanaged) application that loads both managed an unmanaged DLLs.
I'm trying to set a breakpoint in one of the unmanaged DLLs. When the breakpoint is hit and I step through, the instructions displayed are totally different from what they should be. I verified with two different disassemblers that WinDbg is not displaying the correct disassembly as I step through.
When attaching to the application, I get a line like this:
ModLoad: 00000000`XXXXXXXX 00000000`YYYYYYYY C:\MyDLL.DLL
I adjusted the addresses in the two disassemblers to reflect the base address XXXXXXXX.
What could be the problem?

Does uf modname!FuncName return the correct results? You can sometimes trick WinDbg if you unassemble / breakpoint at weird places. Remember, that x86/x64 is a variable-width instruction set, so if you start reading halfway through an instruction, the disassembler gets confused.

Somewhere i've noticed info that this may be related to improper entry point in your DLL. But I have no clue what to do with this information (i'm beginner).

Related

Why the DLL loaded in memory doesn't fully correspond to the original DLL file?

Please, correct me if I'm wrong anywhere...
What I want to do:
I want to find a certain function inside some DLL, which is being loaded by Windows service, during remote kernel debugging via WinDBG. (WinDBG plugin in IDA + VirtualKD + VMWare VM with Windows 10 x64).
I need to do it kernel mode, because I need to switch the processes and see all the memory
What I did:
I found an offset to the function in IDA (unfortunately, the DLL doesn't have debug symbols).
Connected to the VM in Kernel Mode.
Found the process of the service by iterating over the svchost-processes (!process 0 0 svchost.exe) and looking at CommandLine field in their PEBs (C:\Windows\system32\svchost.exe -k ...).
Switched to the process (.process /i <address>; g), refreshed the modules list (.reload)
Found the target DLL in user modules list and got its base address.
The problem:
The DLL loaded into memory doesn't fully correspond to the original DLL-file, so I can't find the function there.
When I jump to the address like <dll_base_address> + <function_offset> there is nothing there and around. But I found some other functions using this method, so it looks correct.
Then I tried to find the sequence of bytes belonging to the function according to the original DLL-file and also got nothing.
The function uses strings, which I found in data section, but there are no xrefs to them.
Looks like that function has completely disappeared...
What am I doing wrong?
P.S.: Also I dumped memory from <dll_start> to <dll_end> and compared it with the original file. Besides different jump addresses and offsets, sometimes the assembler code is completely missed...
It appeared that the memory pages were paged out. .pagein command did the trick
It appeared, that some memory pages were paged out (moved to secondary storage). This command loads the pages from secondary storage and they appear in disassembly:
.pagein /f /p <process_address> <memory_page_address>
See for more: The DLL is partly missed in remote kernel debugging

How does WinDbg itself work?

I have recently started windows driver development. I am wondering how does it actually debug my driver. The setup I have is --> Win7 as host, XP as guest on VMware, and I am debugging through serial port.
The research I have done:
I found only this link saying very few things that I am talking about.
I already know how debugger works on single OS, in that case debugger is also on the same OS, so it knows which process is running. That is understandable. But here, debugger is on entirely different OS, an entirely different environment. I just say file->open source files and I AM able to put breakpoints!! Moreover when I load driver, it actually breaks there. I mean why../How? How does XP's kernel comes to know(drivers are extension to kernel, atleast WDM, don't know about WDK) that there is source code of this driver? and that also outside its control(environment)? I mean I can have 10 files open with breakpoint in them, but it works beautifully, I am not able to fail/fool it.
So what I am thinking is like, whenever we add source to windbg on Win7, it creates the binary from that source, and whenever XP is going to load any binary, it checks if this is the binary that windbg is waiting for. what is confusing in above link is, Vikrant is saying that debugger asks kernel(XP) that it is willing to debug a process --> Bus HELLO... process is running on XP, and windbg on Win7 and does not know name or id of process. It has source code, but consider a case where there is a driver which is build out of 300 files, and just one, probably simplest file is open in windbg, how it matched that this source code is of the driver being run?
#Kjelll answer is correct. Here is the full scenario, including explanation to your comment:
PDB files have line information. This is a mapping from each (file,line) location to address (RVA - relative virtual address).
When you set a break point on a source file, WinDBG checks whether this source file correspond to a current address. If it is - it sets the breakpoint. Otherwise, it becomes a "future breakpoint" (not sure whether Microsoft uses this terminology).
When a new binary is a loaded, the agent on the client communicates with the host, informs it about the binary. At this point - WinDBG will try to allocate a PDB file.
WinDBG will start at the PDB location embedded within the file. You can see this value by using this command line: windbg -dump -pdbpath xxx.sys. This should explain how WinDBG will find a symbol file even if not on the .sympathy path (that I believe answers your comment to Kjell).
WinDBG will then search at the .sympathy.
Once symbol is find, it will look at all future breakpoint, and if applicable will set an actual breakpoint.
I think your link explain your question pretty well, but you have probably not realized what the mechanism of the pdb do for the debugger. The windbg on your host OS uses the pdb file to translate line nubers in the source files to addresses in your guest OS (xp) . Then the the debugger agent uses this address to set break points (Int 3) in the guest OS.This is much in the same way as a local debugger do to a local process.

Why does stepping every instruction crashes while launching the program works? [debugging]

I'm trying to follow the execution instructions of a simple program I compiled with C++ (it calculates some prime numbers then exits) in a debugger (ollydbg) but I have several questions:
Why the first instruction isn't the entry point of the "CODE" section? It is different
As soon as I "step over" a few instructions the debugger crashes and writes "Single step event at ntdll.someaddress, press shift+F7/F8/F9 to pass the exception to the program" and crashes. If I run the program without stepping the instructions it works fine and the program loads without problems
Why does this happen? This doesn't happen only with my program but with several others (almost every other 32 bit exe in my system)
If you're running OllyDbg under a 64-bit OS, that I believe you are out of luck, because OllyDbg doesn't support x86-64 Windows, not even as a debugger used to debug 32-bit apps. See this forum thread, it's from 2006, but I don't thing anything has changed since that. What they suggest is using a different debugger, for example the 64-bit version of WinDbg (which is a great debugger).
Why the first instruction isn't the entry point of the "CODE" section? It is different
You can set this in OllyDbg: Options - Debugging options - Events - "Make first pause at". You can start at the "system breakpoint", which is located in ntdll and is called even before the starting module's entry point is called.

Meaning of hex number in Windows crash dialog

Every now and then (ahem...) my code crashes on some system; quite often, my users send screenshots of Windows crash dialogs. For instance, I recently received this:
Unhandled win32 exception # 0x3a009598 in launcher2g.exe:
0xC00000005: Access violation writing location 0x00000000.
It's clear to me (due to the 0xc0000005 code as well as the written out error message) that I'm following a null pointer somewhere in my launcher2g.exe process. What's not clear to me is the significance of the '0x3a009598' number. Is this the code offset in the process' address space where the assembler instruction is stored which triggered the problem?
Under the assumption that 0x3a000000 is the position where the launcher2g.exe module was loaded into the process, I used the Visual Studio debugger to check the assembler code at 0x3a009598 but unfortunately that was just lots of 'int 3' instructions (this was a debug build, so there's lots of int 3 padding).
I always wondered how to make the most of these # 0x12345678 numbers - it would be great if somebody here could shed some light on it, or share some pointers to further explanations.
UPDATE: In case anybody finds this question in the future, here's a very interesting read I found which explains how to make sense of error messages as the one I quoted above: Finding crash information using the MAP file.
0x3a009598 would be the address of the x86 instruction that caused the crash.
The EXE typically gets loaded at its preferred load address - usually 0x04000000 iirc. So its probably bloody far away from 0x3a009598. Some DLL loaded by the process is probably located at this address.
Crash dumps are usually the most useful way to debug this kind of thing if you can get your users to generate and send them. You can load them with Visual Studio 2005 and up and get automatic symbol resolution of system dlls.
Next up, the .map files produced by your build process should help you determine the offending function - assuming you do manage to figure out which exe/dll module the crash was inside, and what its actual load address was.
On XP users can use DrWatsn32 to produce and send you crash dumps. On Vista and up, Windows Error Reporting writes the crash dumps to c:\users\\AppData\Local\Temp*.mdmp

Does the VS disassembly window show the whole EXE?

A client is running my company's program and it is halting before it gets anywhere. They sent this information from the Windows Event Log:
faulting module program.exe, version 1.2.3.4, fault address 0x00054321.
We don't have much else to go on so as a last ditch effort I've been trying to see if I can find where that position is in a disassembler. I run the program through Visual Studio, pause it, look at the Disassembly window and try scrolling to that address but all I get there is this:
00054321 ???
00054322 ???
00054323 ???
00054324 ???
00054325 ???
00054326 ???
00054327 ???
00054328 ???
00054329 ???
0005432A ???
Would this be because Visual Studio only disassembles part of the EXE near the pause position or something? It's hard for me to look through how much is actually disassembled because the scrollbar doesn't work fully. (I can't grab and move the scroll position; I have to scroll by line or by page.)
Thanks for any insight you may have!
The fault address could also be caused from a stack corruption problem, ie. the return address could be compromised and jumped back to the wrong address # 0x54321.
Also, depending on the tecnology used (Java, .NET) the code could change it's position between runs.
Visual studio makes a disassembly of the whole process space. ???? means that the position is not accessible.
You'd better need a stack-frame to see what's happening, from a core dump.
WinDbg may be your friend here, there you can load your executable and the symbols (.pdb), if you can get a (mini)dump as QbProg says that would definitely ease the search. But I have had experiences when it was easier doing this in WinDbg.
What are you expecting to see in the disassembly window? This approach is not going to work. If you are able to rebuild the exact same build configuration of that your client is running then you can enable the /MAP option in the project's link options. This will create a file that maps symbols to addresses and will allow you to see which function was executing when the crash occurred. You may have to do a bit of calculation to offset the raw mapped address against the address the module was loaded at on the client's PC.
As Fredrik says, WinDbg may be able to help too, especially if you can get a crash dump from your client's PC.

Resources