Reading variables while debugging with GDB (C) - c

I am beginner with GDB debbuging. I need read variables in GDB, I use the command info variable and get this information:
0x000007c4 variable1.0
0x000007c8 variable2.1
I set a breakpoint inside the variables function and these are defined how type long *. How can I read the value inside these correctly? I tried with show, display, print $variable1, p/x variable and so on commands.
Sorry for my grammar, i am not native speaker.

To view the contents of memory use gdb's x/FMT ADDRESS command e.g. x/d 0x000007c4 (to display an integer sized object from address 0x000007c4 and format it in decimal).
The info variables command in gdb will list all global and static variables and their program addresses. You don't describe the language or implementation you're using, but in C the variable name "variable1.0" is not valid. Therefore it must have been created by some link editor or the compiler in a post-process. Therefore the symbol may not exist in debug information and is only accessible by directly viewing the contents of memory, which is why the gdb p command doesn't work (there is no valid expression to show you that variable because it's not a variable, but just a symbol at an address).

Related

How to set a global variable value in C to shell environment variable?

While porting U-Boot on a specific hardware,
a function has to parse a header to get OS entry point to jump into it.
Say, the function get's the os entry point into a global 'C' variable uint32_t osentry.
How to set this value to U-Boot shell command 'go'?
I see U-Boot go (shell) command, has to be set as go $entry
In few examples, I see the entry is fixed address set as shell environment value.
Whereas, for me it is in a global 'C' variable.
How to set a global variable value in C to shell environment variable?
Use the env_set_addr() function to set an environment variable for use as an address from an ordinary program variable.
From include/common.h:
/**
* env_set_addr - Set an environment variable to an address in hex
*
* #varname: Environment variable to set
* #addr: Value to set it to
* #return 0 if ok, 1 on error
*/
ADDENDUM
For some reason, I could n't find this function in the code base I use.
You neglect to mention what version of U-Boot that you are using.
env_set() and its friends were apparently introduced in version 2017.09 to replace setenv() and its friends.
I used similar setenv(), after formatting with sprintf.
Since version 2011.12 the simple setenv() has been augmented with setenv_addr() and/or setenv_hex(), which will convert the unsigned long integer to a string of hex digits for you.
If you are still using a version of U-Boot older than 2011.12, then you will have to do what you describe.

How/when memory is assigned to global variables in C

I am aware of C memory layout and binary formation process.
I have a doubt/query regarding the phase when and who assigns address to global variables.
extern int dummy; //Declared in some other file
int * pTest = &dummy;
This code compiles well. Here pTest will have address of dummy only if address is assigned to it.
I want to know in which phase (compilation or linker) does dummy variable gets address?
The compiler says:
int *pTest = &<where is dummy?>;
The linker says:
int *pTest= &<dummy is here>;
The loader says:
int *pTest= <dummy is at 0x1234>;
This somewhat simplified explanation tries to convey the following:
The compiler identifies that an external variable dummy is used
The linker identifies where and in which module this variable resides
But only once the executable program is placed in memory is the actual location of the variable known and the loader puts this actual address in all the places where dummy is used.
the actual process is actually a bit different.
The compiler saves the information in the object file about the the assignment and the external object reference.
The linker depending on the actual hardware IS and implementation calculates the absolute address ( if the code will be placed at the fixed address - for example the embedded uC project) or same virtual and sets the entry in the relocation table (If the code is position independent) and the loaded is changing this virtuall address to the correct one during the program loading and start-up.

How to tell apart imported function vs imported global variable in a DLL's PE header?

I'm writing a small tool that should be able to inspect an arbitrary process of interest and check if any of its statically linked functions were trampolined. (An example of a trampoline could be what Microsoft Detours does to a process.)
For that I parse the PE header of the target process and retrieve all of its imported DLLs with all imported functions in them. Then I can compare the following between DLLs on disk and the DLLs loaded in the target process memory:
A. Entries in the Import Address Table for each imported function.
B. First N bytes of each function's machine code.
And if any of the above do not match, this will most certainly mean that a trampoline was applied to a particular function (or WinAPI.)
This works well, except of one situation when a target process can import a global variable instead of a function. For example _acmdln is such global variable. You can still find it in msvcrt.dll and use it as such:
//I'm not sure why you'd want to do it this way,
//but it will give you the current command line.
//So just to prove the concept ...
HMODULE hMod = ::GetModuleHandle(L"msvcrt.dll");
char* pVar = (char*)::GetProcAddress(hMod, "_acmdln");
char* pCmdLine = pVar ? *(char**)pVar : NULL;
So, what this means for my trampoline checking tool is that I need to differentiate between an imported function (WinAPI) and a global variable. Any idea how?
PS. If I don't do that, my algorithm that I described above will compare a global variable's "code bytes" as if it was a function, which is just a pointer to a command line that will most certainly be different, and then flag it as a trampolined function.
PS2. Not exactly my code, but a similar way to parse PE header can be found here. (Search for DumpImports function for extracting DLL imports.)
Global variables will be in the .data section not the .text section, in addition the section will not have execute permissions if it's not a function. Therefore you can use both of these characteristics to filter.

LLDB print a variable named class

I have a C programm in which a variable called class is used.
I'm trying to debug it with LLDB but I'm encountering the following problem:
(lldb) print class
error: warning: declaration does not declare anything
error: declaration of anonymous class must be a definition
error: 1 errors parsing expression
I believe this problem occurs because class is a reserved keyword in C++ and LLDB interprets the code passed to print as C++. Is there still a way to print the content of my variable?
(Please do not advise me to rename the variable, I would have come up with this myself, if it was possible)
The problem is that the lldb expression parser uses C++ references to implement the job of finding & extracting results from the expressions we run. So we currently have to compile the expressions as C++ expressions, and as you guessed, you can't use "class" in a C++ expression. At some point, we have to teach clang how to do "C with references" and then we'll be able to compile & execute real C expressions.
However, provided you have debug information for "class", you can print the value of the variable using the "frame variable" command, i.e.:
(lldb) frame variable class
The "frame variable" command does not use the expression parser, it goes directly to the debug information, extracts the type & location of the variable, and prints that directly. So it doesn't suffer this restriction. If "class" is a global variable, not a frame local, use target variable instead.
frame variable does support a limited set of "expression-like" features, you can say:
(lldb) frame variable class.member
or
(lldb) frame variable *class
but you can't use it to call functions or pass the variable to a function call.
If you need to do that you can run the command:
(lldb) frame variable -L class
which will print the location of the variable. Usually that's some address, in which case you can use
(TypeOfClass *) <Address From Frame Variable>
in your expression in place of "class". If the location turns out to be a register, then use "$" appropriately cast in your expression. If you are going to use the variable in a number of expressions, remember you can do:
(lldb) expr TypeOfClass *$class = (TypeOfClass *) <Address From Frame Variable>
and then just use $class in your subsequent expressions. If you got super-motivated, you could even write a Python command that automates these steps...

Reading static variable from a binary

I am trying to read the value of a static variable in C like:
int variable = value;
The thing is that I only have the binary, and the code with a fake value (it is for a lecture, where we study security aspects of software development).
I have been trying to read the value using the GDB, and
(gdb)info variables
which just gives me a list of the variables (including the one I'm looking for) and what seems to be an address, so I would like to know if there is a way to read the value using GDB?
In GDB, use the 'print' command:
print variable
Voila!

Resources