"bt full" stack trace in GDB shows the locals in each of the frame. Does it always show values of the locals at the entry of the function or the updated value of the locals when "bt full" is executed?
It shows the values of variables at the current point in each frame.
The way this works is that a variable's debugging information carries a description of the variable's location. gdb evaluates this description, then fetches the value from the location. Now, this can be complicated (variables can be in registers at one spot and in memory at another; or structures on the stack can be broken into their constituent parts; etc) -- but in the simple case this is just some location on the stack. So, if the variable is assigned to, the old value is overwritten.
However, if you are using a new-enough gcc and a new-enough gdb, you can in some cases see entry values for function arguments. An entry value might look like var#entry = 72. This means that the compiler was able to tell the debugger how to compute the value-at-entry. This is normally done by unwinding one frame and evaluating a DWARF expression that says how to compute the value given the state in the calling frame.
Related
Just a simple ask:
The (gdb) info locals command gives the list of local variables and their values.
Are these values initialized values or point in time of execution of that frame?
Can you provide any documentation around this?
Are these values initialized values or point in time of execution of that frame?
The latter. Documentation says:
"These are all variables (declared either static or automatic) accessible
at the point of execution of the selected frame."
I have read from Google that it is used for controlling buffer overruns at application level and it is called by CRT.
It also says that
" Essentially, on entry to an overrun-protected function, the cookie is put on the stack, and on exit, the value on the stack is compared against the global cookie. Any difference between them indicates that a buffer overrun has occurred and results in immediate termination of the program."
But I could not much understand how it works? Please help.
The "cookie" is basically nothing more than an arbitrary value.
So, the basic idea is that you write the chosen value on the stack before calling a function. Although it's probably not a very good value, let's arbitrarily chose 0x12345678 as the value.
Then it calls the function.
When the function returns, it goes back to the correct spot on the stack, and compares that value to 0x12345678. If the value has changed, this indicates that the function that was called wrote outside the area of the stack where it was allowed to write, so it (and that process in general) are deemed untrustworthy, and shut down.
In this case, instead of choosing 0x12345678, the system chooses a different value on a regular basis, such as every time the system is started. This means it's less likely to hit the correct value by accident -- it might happen to do so once, but if it's writing a specific value there, when the correct/chosen value changes, it'll end up writing the wrong value, and the problem will be detected.
It's probably also worth noting that this basic idea isn't particularly new. Just for example, back in the MS-DOS days, both Borland's and Microsoft's compilers would write some known value at the very bottom of the stack before calling main in your program. After main returned, they'd re-check that value. It would then print out an error message (right as the program exited) if the value didn't match what was expected.
It's exactly what the explanation says, but you can replace "cookie" with "some value". When the function is called, it puts some value on the stack. When the function returns, it checks it again to see if it changed.
The normal behavior of the function is to not touch the memory location. If the value there changed, it means that function code somehow overwrote it, and this means there was a buffer overflow.
I am debugging a runtime crash, with a stack trace that seems corrupted (see a related question from yesterday: Is the stack corrupted if the EBP frame pointer is NULL?).
Despite the corruption of the stack, I see many values on the stack that point to the exact locations of functions in the corresponding .map file. Furthermore, these functions are (for the most part, if not entirely) the expected functions that should appear on the stack in this case.
As one example (there are many), here is the stack value, and corresponding .map entry value:
0588fe5c: 005caa30 (stack address / value at that address)
0001:001c9a30 __ehhandler$?ProcessTAFRequest#TQueryThread##UAEXXZ 005caa30 f portable_source:UQueryThread.obj
(.map file entry indicating that address 005caa30 is the starting location of the function noted)
Assuming (likely incorrectly) that the stack is not corrupted except near the top, and that the function addresses I see somehow do correspond to the stack frames and corresponding EIP (return address) pointers, then my question is this: Why do I consistently see the exact value of the location of the functions in the .map file corresponding to the stack? In the past, a number of times I have walked through an uncorrupted stack trace, and always, the EIP pointers in the stack frames point near, but not at, the location of the corresponding functions listed in the .map file. (This makes sense, since the return address will typically be in the middle of a function, not at the start).
Can somebody please shed light?
Please see the back trace below, I donĀ“t think I have seen this before and I can not find any information in the documentation:
(gdb) bt
#0 0x000000007b44042c in Driver::setRec (this=0x1, message=#0x50)
I can't find it in documentation, but it looks like this is how gdb displays references to variables. According to backtrace, you were stopped at class method, accepting 1 parameter by reference with the following signature: Driver::setRec(message&).
Update:
It is not explicitly stated about # in C++ Expressions documentation. The only thing stated is:
In the parameter list shown when gdb displays a frame, the values of
reference variables are not displayed (unlike other variables); this
avoids clutter, since references are often used for large structures.
The address of a reference variable is always shown, unless you have
specified `set print address off'.
I dont know if this helps but from http://sources.redhat.com/gdb/download/onlinedocs/gdb.html#index-g_t_0040_0040_0040r_007b_002c-referencing-memory-as-an-array_007d-525
It is often useful to print out several successive objects of the same type in memory; a section of an array, or an array of dynamically determined size for which only a pointer exists in the program.
You can do this by referring to a contiguous span of memory as an artificial array, using the binary operator #'. The left operand of #' should be the first element of the desired array and be an individual object. The right operand should be the desired length of the array. The result is an array value whose elements are all of the type of the left argument. The first element is actually the left argument; the second element comes from bytes of memory immediately following those that hold the first element, and so on. Here is an example. If a program says
There for how I would interet this is 0x50 is a pointer address to the beginning of a string where the output message is. If I find more information on this I will update the post.
its for printing successive memory locations as array like output.
$gdb *memory#10
${1,2,3,4,5,6,7,8,9,10}
its a less powerful but easy to use memory inspection. if you want more power you should use the x (examine memory) command. consult
$info gdb
I'm currently making one of those game trainers as a small project. I've already ran into a problem; when you "go into a different level", the addresses for things such as fuel, cash, bullets, their addresses change. This would also happen say, if you were to restart the application.
How can I re-locate these addresses?
I feel like it's a fairly basic question, but it's one of those "it is or is not possible" questions to me. Should I just stop looking and forget the concept entirely? "Too hard?"
It's a bit hard to describe exactly how to do this since it heavily dependents on the program you're studying and whether the author went out if his way to make your life difficult. Note that I've only done this once but it worked reasonably well even if I only knew a little assembly.
What is probably happening is that the values are allocated on the heap using a call to malloc/new and everytime you change level they are cleaned up and re-allocated somewhere else. So the idea is to look at the assembly code of the program to find where the pointer returned by malloc is stored and figure out a way to reliably read the content of the pointer and find the value you're looking for.
First thing you'll want is a debugger like OllyDbg and a basic knowledge of assembly. After that, start by setting a read and write breakpoint on the variable you want to examine. Since you said that you can't tell exactly where the variable is, you'll have to pause the process while it's running and search the program's memory for the value. Hopefully you'll end up with only a few results to sift through but be suspicious of anything that is on the stack since it might just be a copy for a function call or for local use.
Once the breakpoint is set just run the program until a break occurs. Now all you have to do is look at the code and examine how the variable is being accessed. If it's being passed as a parameter, go examine the call site of the function. If it's being accessed through a pointer, make a note of it and start examining the pointer. If it's being accessed as an offset of a pointer, that means it's part of a data structure so make a note of it and start examining the other variable. And so on.
Stay focused on your variable and just keep examining the code until you eventually find the root which can be one of two things:
A global variable that has a static address. This is the easiest scenario since you have a static address hardcoded straight into the code that you can use to reliably walk through the data structures.
A stack allocated variable. This is trickier and I'm not entirely sure how to deal with this scenario reliably. It's possible that its address will have the same offset from the beginning of the stack most of the time but it might not. You could also walk the stack to find the corresponding function and its parameters but this a bit tricky to get right.
Once you have an address all that's left to do is use ReadProcessMemory to locate your variable using the information you found. For example, if the address you have represents a pointer to a data structure where at offset 0x40 your fuel value is stored, then you'll have to read the value at the address, add 0x40 to it and do another read on the result.
Note that the address is only valid as long as the executable doesn't change in any way. If it's recompiled or patched then you have to start over. I believe you'll also have to be careful about Windows' ASLR which might change the address around every time you start the program.
Comment box was too small to fit this so I'll put it here.
If it's esp plus a constant then I believe that this is a parameter and not a local variable (do confirm by checking the layout of the calling convention). If that's the case, then you should step the program until it returns to its caller, figure out how the parameter is being set (look for push instructions before the call instruction) and continue exploring from there. When I did this I had to unwind the stack once or twice before I found the global pointer to the data structure.
Also the esi register is not related to the stack (I had to look it up) so I'd check how it's being set. It could be that it contains the address of the data structure and the constant is the offset to the variable. If you figure out how the register is set you'll be that much closer to the pointer.