In WinDbg, can I use software breakpoints without having symbols? - debugging

I'm having trouble using software breakpoints in WinDbg in order to break in a given address.
It's a Visual C++ 6.0 MFC executable without symbols (belive me, I just can not generate the symbols).
Suppose my executable image is named image00400000. Using Software Breakpoints (bp):
0:000> bp image00400000 + 0x003ba1eb
0:000> bl
0 e 007ba1eb 0001 (0001) 0:**** image00400000+0x3ba1eb
0:000> g
I get the relative address (0x003ba1eb) from the .map file (this one I got it). I pick up a line which I'm sure that will be executed, but there is no stop at all...
Does anyone have any ideas? I'd appreciate them. Thank you!
PD: If there's anything left to explain or you need more info, just drop me a comment :-)

Sorry I'm not allowed to create comments yet (too new) to SO.
It is a bit tricky to be specific with the information available. I guess it is possible that the breakpoint address isn't calculated correctly. Given the situation I would attempt to calculate the breakpoint address as: Module start + code start + code offset from the map file. Maybe this is what you did (unless I got it wrong ;-) )
Also worth noting that the bp address needs to align on an instruction boundary. If it doesn't then it won't be set properly. This could be possible if you are having to guess at trying to get a breakpoint into a particular function.
It might be helpful to outline a little more about the condition under which you want the program to stop in the debugger.

To add symbols, you need to make a debug build
BUILD menu item
Set Active Configuration
Select the Debug Configuration, instead of the release configuration.
Rebuild everything, and your symbols should be there.

Related

MPLAB X + XC8 break at wrong line

I've encountered a very annoying problem that has cost a lot of time for several months now.
I have a project in MPLAB X. When I use a line-breakpoint it does not break on the right line at all when debugging my project.
I am using MPLAB X v4.15
This is what actually happens:
No matter where the breakpoint is, the debugger never breaks at the right place.
if I put a breakpoint somewhere, it always breaks at the wrong position
if I then restart the debugging it breaks at the same wrong position
If I change the breakpoint location, the position where the program actually breaks is different, but stays the same again when i restart the program.
Some more info:
Why does this happen?
Are there more people with this problem?
How do i solve this?
EDIT
Sadly, the solution suggested by K_Trenholm did not work for me. I put 3 "NOPs" in one function, but it didn't work as you suggested. See the picture below:
but what I got:
I would like to add that I tried various combinations of breakpoints for the NOPs. No matter what i do, the program always halts at the same PC for this case, seen in the picture above.
Thank you for your reply, it is very helpfull to even have ANY ideas on how to solve it.
If you have any other ideas, I would be very grateful if you would share them!
Two things come to mind:
1) Compiler optimizations can cause problems with breakpoint locations/values when debugging. When debugging, turn optimizations off (if possible, it looks like in your example you're bumping up on the ceiling in terms of code size).
2) Breakpoint "Skidding". See http://microchipdeveloper.com/tls0201:skid-effect#top-of-page
One way to work around this from what I've seen is to put a couple NOP instructions after the line where you plan on placing the breakpoint. This will ensure that any "skidding" will not execute more code.
The instruction where the break occurs will always execute completely, and anything pending in the pipeline will execute as well. For single cycle instructions, this adds a one instruction skid. For multiple cycle instructions and branches, it adds multiple cycles. So if you want to avoid
to jump the debugger into a subroutine you had to include some Nop behind the breakpoint.
example:
void main (void)
{
int x = 0;
x++1; //put Breakpoint here
Nop();
Nop();
Nop(); //Debugger will stop here
foo(x); //so foo() is not called
}
Depending on the MCU being used the debugger will introduce a 'skid effect' upon hitting a breakpoint. The debug session will execute up to two extra instructions before halting.

HEX Substraction in Windows ASM Shellcode returns wrong values

I'm working on some shellcoding, and have this weird result on my Windows VM. The idea is, starting from Zero, carve out some value. In this case, I need that the value is equals to: 0x50505353
(gdb) print /x 0 - 0x38383536 - 0x77777777
$1 = 0x50505353
In Python, GDB, OSX, Linux and everything else, this operation works as expected. On the Windows VM, when I perform the PUSH on OllyDBG or Immunity the result is: 0x52535051
So the question is, WHY? What I'm missing here?
This is the operation done in ASM:
AND EAX,65656565
AND EAX,1A1A1A1A
SUB EAX,38383536
SUB EAX,77777777
PUSH EAX
The first couple of AND transform EAX = 0x00000000. Then I can subtract from that. Just to be clear, I cannot use XOR on this test.
This is because you are not subtracting 0x38383536, you are subtracting 0x36353838, which gives the result you stated.
I just found the problem. When I do the calculations outside the Debugger, forgot the small detail that in order to use them in the shellcode, I should use the same values in reverse Endian Order.
Mental note: Always remember to check the order that you are working.
Thanks to all.
To be clear, are you saying error happens on the gdb command line as well as in your windows VM program? If gdb is giving rubbish then something is wrong with the VM.
Do you have gdb or another debugger working on the Windows VM? I'm a little confused about your runtime environment where you are seeing the error
If you have gdb where the error is occurring then here is how to debug.
If it is the program only then use stepi and info regs to see what is going on. The value of $eax before that last subtraction is likely the one of interest but check each instruction. If $eax has the correct value at the push then look around $sp in memory for the value. If it is still correct then follow the return from the function and look for the corresponding pop or stack read and check the value there. Perhaps the stack is getting corrupted before you actually print/use the value?

How do I debug a jump to a bad address?

I am currently debugging some assembly code using GDB and am stuck on the following problem. Somehow or other, I've ended up at a bogus instruction address, probably because either I called a bogus function pointer, or I mangled the return address on the parent stack frame.
GDB is fantastic and stops the program exactly when it detects this has happened. However, what it doesn't tell me is the instruction address that sent me to this bogus address. So now I am stuck. I know that I am now at a bogus address, but I have no way of knowing how I got here. What I think I need is a list of the last n values that $rip has taken on. But I cannot find any way of doing that in GDB's documentation and am pretty sure it is not possible.
So I would appreciate it if anyone else had any great tips on low-level debugging they could share. Thanks!
-Patrick
I think GDB's trace might helps
https://sourceware.org/gdb/onlinedocs/gdb/Tracepoints.html
When your code crash, the trap is raised and the instruction pointer jump to the trap table, the jump depends on the trap raised.
You want to determine which instruction causes this trap, so you can execute the command backtrace (bt) to show the latest exectuted functions before the jump to the trap table. When you identify the function, execute step by step to idenfy the instruction which causes the error.
If you are using a target with gdb in remote mode, you need to give gdb a strong symbol table to allow the awareness of the whole code symbols.

LLDB Break at Address

I apologize for the likely trivial question but I am running into a wall as Google gives me the same non-applicable answers over and over.
I am trying to set a breakpoint in LLDB. After reading the documentation, the options available to me are to either stop on a certain line in the source or on a certain symbol.
What I want to do is set a breakpoint on a certain memory location.
Not read-or-write to that memory location either but simply breaking when the instruction at that location is about to be executed.
In Pseudocode:
break 0x00010000
breaks when EIP points to 0x00010000.
How can I do this?
breakpoint set has an address option; you would type help breakpoint set to see all of them. For your specific example,
(lldb) br s -a 0x10000
(You can always use shorter versions of command names in lldb that are unambiguous so typing out breakpoint set isn't necessary)
The alternative is to use "process launch --stop-at-entry ...". This will allow you to set breakpoints after the program is launched and then "continue" will let you stop on your first breakpoint. Interestingly (testing in Ubuntu) using --stop-at-entry takes a lot longer to start (~3 seconds). I need to use this on OS X and maybe it will be quicker there.

Is there a cap on the number of modules WinDbg can see?

Does anyone know if there is a cap on the number of DLLs WinDbg can see ? I believe Visual Studio was once capped at 500 but I can't find a source for this claim outside of some second hand accounts at work.
I'm trying to debug a hairy scenario and WinDbg's stack trace is incomplete. According to Process Explorer, the module I'm interested in is loaded but it doesn't show up in the output of 'lm' in WinDbg.
Suspiciously, said output is exactly 500 modules long, even though I know there are many more than that loaded, leading me to believe WinDbg isn't seeing DLLs beyond the first 500. Can anyone confirm ? Or suggest some other reason why a loaded module might not show up in 'lm' ?
Edit: upon further investigation, I was able to get WinDbg to load see the module I needed by attaching the debugger earlier, before that module was loaded.
It seems to me that, upon attaching to a process, the debugger engine will only see the first 500 dlls but will process subsequent loads correctly. I would still love confirmation from a WinDbg expert though, or better yet, a bypass to process more than 500 modules when attaching !
There is a registry key controlling the number of debugger messages a debugger can see.
When you increase the value to e.g. 2048 you can see all loaded dlls.
Here is the relevant key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
DWORD DebuggerMaxModuleMsgs = e.g. 2048
I have expired that due to corruption in the module list windbg has not displayed all modules.
Here is a script (found in the Windbg help file) which I have used on 32 bits xp userdumps.
when hunting for modules not found in the lm output.
You can also try the !dlls in windbg.
$$ run with: $$>< C:\DbgScripts\walkLdr.txt
$$
$$ Get module list LIST_ENTRY in $t0.
r? $t0 = &#$peb->Ldr->InLoadOrderModuleList
$$ Iterate over all modules in list.
.for (r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)#$t0;
(#$t1 != 0) & (#$t1 != #$t0);
r? $t1 = (ntdll!_LDR_DATA_TABLE_ENTRY*)#$t1->InLoadOrderLinks.Flink)
{
$$ Get base address in $Base.
as /x ${/v:$Base} ##c++(#$t1->DllBase)
$$ Get full name into $Mod.
as /msu ${/v:$Mod} ##c++(&#$t1->FullDllName)
.block
{
.echo ${$Mod} at ${$Base}
}
ad ${/v:$Base}
ad ${/v:$Mod}
}

Resources