I was trying to debug a program that has a corrupted stack and seems too big (it has multiple threads) to manually debug. So I was wondering if there was a way to print out the symbols that correspond to the addresses on the stack after the corruption to try and get a better idea of how it got there.
I noticed the "info symbol" command (which normally prints out the symbol at a given address) only accepts one address at a time. So, I tried to write a script to do what I wanted, but when I tried to store the addresses in convenience variables so I could iterate through the stack manually, the info symbol command wouldn't work.
I know on WinDBG there is the dds command which does what I'm looking for, but I have not been able to find an equivalent in GDB. Does anyone know an equivalent?
x command with a flag will decode memory as address and will try to lookup for the symbols
given code:
int func3(int a)
{
return a+a;
}
int func2(int b)
{
return func3(b+b);
}
int func1(int c)
{
return func2(c+c);
}
int main(int argc, char** argv)
{
return func1(argc);
}
and breakpoint at func3 output will be:
(gdb) x /16ga $rsp
0x7fffffffe150: 0x7fffffffe168 0x5555555545fa <func2+23>
0x7fffffffe160: 0x2000000c2 0x7fffffffe180
0x7fffffffe170: 0x555555554613 <func1+23> 0x100000000
0x7fffffffe180: 0x7fffffffe1a0 0x55555555462e <main+25>
0x7fffffffe190: 0x7fffffffe288 0x100000000
0x7fffffffe1a0: 0x555555554630 <__libc_csu_init> 0x7ffff7a05b97 <__libc_start_main+231>
0x7fffffffe1b0: 0x1 0x7fffffffe288
0x7fffffffe1c0: 0x100008000 0x555555554615
This might not answer your question but could help you with identifying the place where you have the stack corruption. Have you tried compiling with -fstack-protectorxxx flags on ?
https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Stack_corruption
Related
I have been working on this simply hobbyist OS, and I have decided to add some C++ support. Here is the simple script I wrote. When I compile it, I get this message:
cp.o: In function `caller':
test.cpp:(.text+0x3a): undefined reference to `__stack_chk_fail'
Here is the script:
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
// Code here
}
int caller() {
CPP caller;
caller.test();
return CPP.a;
}
Try it like this.
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
CPP::a = 4;
}
int caller() {
CPP caller;
caller.test();
return caller.a;
}
int main(){
int called = caller();
std::cout << called << std::endl;
return 0;
}
It seems to me that the linker you are using can't find the library containing a security function crashing the program upon detecting stack smashing. (It may be that the compiler doesn't include the function declaration for some reason? I am not familiar who actually defies this specific function.) Try compiling with -fno-stack-protector or equivalent.
What is the compiler used? A workaround might be defining the function as something like exit(1); or similar. That would produce the intended effect yet fix the problem for now.
I created a test program to show how this actually plays out. Test program:
int main(){
int a[50]; // To have the compiler manage the stack
return 0;
}
With only -O0 as the flag ghidra decompiles this to:
undefined8 main(void){
long in_FS_OFFSET;
if (*(long *)(in_FS_OFFSET + 0x28) != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
With -fno-stack-protector:
undefined8 main(void){
return 0;
}
The array was thrown out by ghidra in decompilation, but we see that the stack protection is missing if you use the flag. There are also some messed up parts of this in ghidra (e.g. int->undefined8), but this is standard in decompilation.
Consequences of using the flag
Compiling without stack protection is not good per se, but it shouldn't affect you in much. If you write some code (that the compiler shouts you about) you can create a buffer overflowable program, which should not be that big of an issue in my optinion.
Alternative
Alternatively have a look at this. They are talking about embedded systems, but the topic seems appropriate.
Why is the code there
Look up stack smashing, but to my knowledge I will try to explain. When the program enters a function (main in this case) it stores the location of the next instruction in the stack.
If you write an OS you probably know what the stack is, but for completeness: The stack is just some memory onto which you can push and off which you can pop data. You always pop the last pushed thing off the stack. C++ and other languages also use the stack as a way to store local variables. The stack is at the end of memory and when you push something, the new thing will be further forward rather than back, it fills up 'backwards'.
You can initialise buffers as a local variable e.g. char[20]. If you filled the buffer without checking the length you might overfill this, and overwrite things in the stack other than the buffer. The return address of the next instruction is in the stack as well. So if we have a program like this:
int test(){
int a;
char buffer[20];
int c;
// someCode;
}
Then the stack will look something like this at someCode:
[ Unused space, c, buffer[0], buffer[1] ..., buffer[19], a, Return Address, variables of calling function ]
Now if I filled the buffer without checking the length I can overwrite a (which is a problem as I can modify how the program runs) or even the return address (which is a major flaw as I might be able to execute malicious shellcode, by injecting it into the buffer). To avoid this compilers insert a 'stack cookie' between a and the return address. If that variable is changed then the program should terminate before calling return, and that is what __stack_chk_fail() is for. It seems that it is defined in some library as well so you might not be able use this, despite technically the compiler being the one that uses this.
I'm trying to use GDB to debug my C++ program.
I'm thinking if it's possible to pass arguments to a function while using GDB.
For example, I have such a program as below:
#include <iostream>
void func(int a)
{
std::cout << a << std::endl;
}
int main(int argc, char **argv)
{
func(2222);
return EXIT_SUCCESS;
}
I set a breakpoint at the line func(2222) in the function main. My question is: is it possible to set another argument to the function func, instead of 2222, while using GDB on this program?
You can change the value a inside the function func()).
For that you can use:
assign a = $value_you_want
Example
b func # set breakpoint
c # continue
assign a = 2 # breakpoint gets hit, change value from a = 222 to a = 2
Yes. You can evaluate expressions while debugging. You can use either call <expr> or print <expr>, but the expression must be known at the time of breakpoint.
In your example, you could do:
gdb ./test
(gdb) b main
...
(gdb) r
...
(gdb) call func(11)
11
More info about call/print: https://sourceware.org/gdb/onlinedocs/gdb/Calling.html
I don't think it's possible to change the value passed to the function before the call of func(2222). However, you are able to modify the values of the parameter after GDB has stepped into the function, before another code execution.
My favorite way to debug with GDB is within Visual Studio Code, it provides a GUI on top of all the GDB commands, and makes using advanced GDB debugging much easier. And you can set a new value for the variable simply by clicking on it. You can see an example below.
I have FreeRTOS running on ARM processor and I don't have dump_stack() available to me... I am trying to check the call-chain and badly missing dump_stack()... I was googling a bit, and found something close to what i was looking for, using GCC(/GDB) _Unwind_Backtrace() utility but it only prints the address of stack_frame. It doesn't provide mapping to meaningful symbol (like function names). Any help is really appreciated.
#include <stdio.h>
#include <unwind.h>
#include <stdint.h>
static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg)
{
uintptr_t pc = _Unwind_GetIP(context);
if (pc) {
printf("unwind got pc ...0x%x\n", pc);
}
return _URC_NO_REASON;
}
ssize_t unwind_backtrace()
{
_Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, 0);
return rc == _URC_END_OF_STACK ? 0 : -1;
}
void func_1()
{
int ret = unwind_backtrace();
printf("unwind_backtrace return ...%d\n", ret);
}
void func_2()
{
func_1();
}
int main()
{
func_2();
return 0;
}
Result:
unwind got pc ...0x40076b
unwind got pc ...0x400796
unwind got pc ...0x4007bd
unwind got pc ...0x400819
unwind got pc ...0x67314b15
unwind got pc ...0x400649
unwind_backtrace return ...0
All the IDEs I use (and I use a lot) show me the stack trace in a window - but only for the currently executing task. If I want to see the trace for all the tasks I need a fully thread aware FreeRTOS plug-in of the type provided by Segger, IAR and Code Confidence.
It doesn't provide mapping to meaningful symbol
The "standard" way to perform this mapping is by using addr2line. Something like:
addr2line -fe a.out 0x40076b 0x400796 0x4007bd ...
Update:
I want on the fly convert ...
Well, you should have asked for that then.
It's a simple matter of writing code. You need to write code that will map address ranges to symbol names (just like addr2line does).
On an ELF platform, this is actually quite simple: read Elf32_Syms from .symtab section to build address to symbol map, and look up your addresses in that map. You'll also need to read corresponding symbol names from .strtab section (Elf32_Sym.st_name is the offset into .strtab).
since I am using embedded system, I need to store a specific function in an external memory location in the address 0x840140
Here is the function:
//The function that I want to set its address to 0x840140
float myfunction(float x,float y) {
float z;
z=x+y;
return z;
}
void main() {
float w;
//Calling the function
w=myfunction(5.5,10.5);
}
Xilinx "MicroBlaze" seems to be using a GNU CC based compiler, which means it (probably) using the gnu ld linker. It has a fairly extensive scripting language, so different sections of code, for example, can be located at different locations.
If you don't want ALL of your code to be located as one lump, you will need to "set" a section for the function in question, e.g:
void myfunction (void) __attribute__ ((section ("at840000.text")));
then use text.at840000 to tell the linker where you want the code to be placed.
Something like this:
SECTIONS {
at840000.text 0x840000 { * }
}
(I'm not 100% sure about the exact syntax here, but something along those lines)
Disclaimer: I have no never tried this.
It might be possible using a linker script. This article places code at a specific address for building a kernel. Check the section about "The linking part".
Are you sure you want the function stored in a specific memory location? You probably want just the function result.
void main() {
float *w = (float*)0x840140;
//Calling the function
*w=myfunction(5.5,10.5);
}
This will put the float returned by myFunction() in the correct memory location.
Given knowledge of the prototype of a function and its address in memory, is it possible to call this function from another process or some piece of code that knows nothing but the prototype and memory address? If possible, how can a returned type be handled back in the code?
On modern operating systems, each process has its own address space and addresses are only valid within a process. If you want to execute code in some other process, you either have to inject a shared library or attach your program as a debugger.
Once you are in the other program's address space, this code invokes a function at an arbitrary address:
typedef int func(void);
func* f = (func*)0xdeadbeef;
int i = f();
Yes - you're describing a function pointer. Here's a simple example;
int (*func)(void) = (int (*)(void))0x12345678;
int x = func();
It probably won't work between processes - in most operating systems, processes don't have access to each other's memory.
When you need a direct call:
((void(*)(void))0x1234)();
All previous answers are nice but much too long:
int i = ((int (*)(void))0xdeadbeef)();
// ========== --> addr of the function to call
// ============= --> type of the function to call
// ========================= --> ... we get a ptr to that fct
// ============================= --> ... and we call the function
In most OP, every process has its own memory, so you can't.
Sample code:
a.c:
#include <stdio.h>
int r() {return 2;}
int main() {
printf("%p\n",r);
while(1);
}
b.c:
#include <stdio.h>
int main() {
int a,(*b)();
scanf("%p",&b);
a=b();
printf("%d\n",a);
return 0;
}
this get segmentation fault.
It is definitely possible, but there are restrictions. Each process will have its own block of memory which other processes can't interfere with. Now, you will notice, I wrote it is definitely possible, this is through DLL injection (or code injection).
We can use the typedef keyword to achieve this. Now, I see you've marked the answer as 'Answered' and it seems you've gotten on fine, this is just a notice for anyone else that may be interested.