How to step C statements in GDB after going into bootmain() from bootasm.S in xv6? - c

I am using gdb to debug boot loader code in xv6. In bootasm.S, I can use gdb to debug assembly code as expected. Then at the end of bootasm.S, we will call bootmain (line 9168, call bootmain) and the execution will go into the bootmain function of the C code bootmain.c. Since it is a C code, I wish to step over the C statements instead of assembly. I know that the step command of gdb is for this purpose, but after I input 's', I received an error message: Cannot find bounds of current function. The same error shows up no matter I input 's' before or after the call bootmain instruction. So, is it possible to step C statements in gdb when the execution switches from an assembly source to a C source like the situation described above? If it is, how to do that? Thank you.
PS1: The list command only list the main() source of the kernel.
PS2: The remote terminal ran make qemu-gdb to start the QEMU, and the local terminal ran gdb kernel to start the debug session, following steps here. I think the C source code symbols like bootmain function should be included so I should be able to step the C code in it.
Thank you again for your help!

Related

Reversing share library written in C to extract port number with GDB

I am looking for help with GDB to reverse engineer shared library written in C that is preloaded in /etc/ld.so.preload.
Current library hooks accept() call if source port is correct it returns reverse shell back to user.
Strings command doesn't give out source port, so my target is to try to find it within GDB.
Program consist of two files headers.h where I have my definitions and variable #define SECRET_PORT 11111
source.c contains accept hook with reverse shell.
My problem is I cannot figure out a way how to retrieve PORT within GDB - I can load mylib.so within gdb and run: info functions to see whats inside - I can see accept function but when I try to disass accept I only get instructions that I barely can understand.
Problem when I run mylib it gives out SIGSEGV (maybe thats the reason I cannot see variables) there is no main function where to set break and if I do set it on function accept is still gives SIGSEGV error.
I tested with starti instead of run then I got Program stopped 0xSOMEADRESGOESHERE in deregister_tm_clones() I don't even know if this is correct way to test .so file. maybe there are some oser switches.
Im thinking I need to find a way how to set BP in HTONS() checking function where if statement compares source port and extract values from there but so far no luck.
p.s. when mylib is loaded in gdb there is message No debugging symbols found. So I cannot run like list accept or anything like that to view a source.
Compilation code gcc -Wall -shared -fPIC mylib.c -o mylib.so -ldl
Im thinking I need to find a way how to set BP in HTONS() checking function where if statement compares source port and extract values from there
You don't need to do that -- the instructions will be the same whether you run the application, or disassemble the function without running.
Compilation code ...
So you are trying to reverse-engineer the library for which you have a source?
That makes it very easy to find the constant you are looking for.
Start by setting the constant to easily recognizable value, e.g. 0x12131415. Compile the library and disassemble it. Look for your constant.
If you don't see it, save the disassembled output, and rebuild the library with a different value, e.g. 0xA1B1C1D1. Disassemble it again and compare to previous disassembled output. It should be easy to spot the difference.
P.S. If you really want to debug this library with a live process, do this:
gdb ./myprog
(gdb) set env LD_PRELOAD /path/to/mylib.so
(gdb) run
At this point, you should be able to set breakpoints and observe your library "in action".
Ok managed solve this with a help
when running GDB on shared library You will have to check hex value for 11111 and it should be 2B67 so in registers this will become something like 0x2b67 & it will be passed to htons() as check for source port.
So let's assume I didn't have the source code I could still run: gdb -q *.so
then: info functions and see with disass functionNameGoesHere where some accept / htons calls are made. Correct value should be found right above htons line.
Then decoded hex to dec and thats how You can find it.
This took some while to figure out as I coudn't set BP's.
Again thanks for input from community! Cheers

Finding line number info from a PC register value

I have a SPARC embedded executable built with debugging symbols. I ran this executable on a machine using a debug monitor, but without a debugger. The program crashed (segfault) and I found out the value of the PC register from the monitor (note: not a debugger). If I were using gdb at the time I would've known which line number it got stuck in. However, I wasn't using GDB at the time.
I want to find out what C line number the PC value corresponds to. What tool or gdb command can I use to find this out?
From this part of the documentation you can use the info command:
info line *0x63ff
That gets the line information for the code at address 0x63ff. Replace the address in the example with your own.

Daemon on embedded Linux device using Busybox be written in C or as a script

Should a daemon on an embedded device using Busybox be written in C or as a script?
All the examples I have seen use #! /bin/ash at the top of the file and that is for scripting? But in the device I'm writing to has only complied C files (I think) and symbolic links in /usr/bin.
Every way I try to compile a C file with #include </bin/ash> (e.g. gcc -Wall -o daemon_busybox daemon_busybox.c) I get error after error report in /bin/ash:
/bin/ash:174:1: error: stray ‘\213’ in program
/bin/ash:174:1: error: stray ‘\10’ in program
/bin/ash:174:1: error: stray ‘\273’ in program
/bin/ash:174:1: error: stray ‘\204’ in program
/bin/ash:174:1: error: stray ‘\342’ in program
Note I have set this: /bin/ash -> busybox
Any ideas which way I should go?
Update:
I've been given the task trying to see if a daemon can be run on a small device that runs Linux (2.6.35-at-alpha4) and Java (SE Embedded Runtime Environment) with very limited memory (i.e. a 10 second wait to get java -version to report back).
Two weeks ago I didn't know much about daemons — only knew the word. So, this is all new to me.
On my development machine I have built two different daemon files, one in C and one as a script. Both run very nicely on my Linux machine.
But because of the very small size of the target device there is only busybox (no /lib/lsb/init-functions). So I'm trying to build a 3rd daemon file. I believe it should be written in C for this device, but all examples for busybox point to scripting.
Once your question is edited so that the file name you're trying to #include is visible, the problem becomes self-evident:
#include </bin/ash>
This tries to make the C compiler include the binary of busybox (via the symlink /bin/ash) into the code to be compiled. The average binary is not a valid C source file; this is doomed to failure.
Perhaps you simply need to drop that line — the C compiler stands a better chance of working if it is given header files and source files to compile. Maybe there's more work needed; we don't have enough information to help there.
Many daemons are written as C programs, but a carefully written shell script could be used instead.
Personally, I would like to do this as a script (I've never liked C). But on the device everything in the /usr/sbin folder looks like a C file. So, the conservative coder in me says C is the way to go. I know: ask the guys developed the device — but they're long gone. Right now my daemon is just a test (i.e. printf("Hello World\n"); ). I'm trying to get printf passed to Busybox. But so far I cannot get this file to compile. I just need a simple daemon in C to start.
OK; your C code for that should be just:
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
return 0;
}
Save it in hw_daemon.c. Compile it using:
gcc -o hw_daemon hw_daemon.c
If that won't compile, then you've not got a workable C development environment for the target machine. If that will compile, you should be able to run it with:
./hw_daemon
and you should see the infamous 'Hello World' message appear.
If that does not work, then you can go with the script version instead, in a file hw_script.sh:
#!/bin/ash
printf "Hello World\n"
You should be able to run that with:
Predicted output — not output observed on a machine.
$ ash hw_script.sh
Hello World
$ chmod +x hw_script.sh
$ ./hw_script.sh
Hello World
$
If neither of those works at all, then you've got major problems on the system (maybe Busybox doesn't provide a printf command workalike, for example, and you need to use echo "Hello World" instead of the printf).

How do you debug a C program on Windows?

I've never used a debugger and the time has come to give them a try. MinGW appears to come with GDB which I've been trying to use. Supposdly running gdb from the command line and typing run myprog.exe starts the debugger but when I do this I get
Starting program: C:\MinGW\bin\myprog.exe MyProg.exe
[New Thread 1828.0xd8c]
Error opening file.
[Inferior 1 (process 1828) exited with code 02]
How to proceed or what's an easier way?
In particular I'm trying to flush out undefined behavior.
Since your program terminates, you'll need to set a breakpoint to see anything. Try break main before the run line. Then you can do commands line next (next line), step (step into/outof function calls), print expression (where expression can be a variable name or a function-call or a calculation), display expression (same as print, but prints just before each prompt). At any given point you can type backtrace to get a call stack. You can even type up and down to move up the callstack, so you can print higher local variables.
Well, the easiest way would be to use an IDE, actually. You might want to give code::blocks a try - very easy to use, configures everything for you on installation (just make sure to pick a compiler - don't worry, it'll prompt you) and there, you're all set and ready to go. As it's multi-platform, it doesn't really lock you into windows either, and gives you very powerful (and, I guess more importantly, convenient) possibilities of graphical debugging.
pass the binary with gdb
gdb <binary>
then set breakpoint to main
gdb) break main
Then run your program in gdb
gdb) run
then break point hits use 'n' or 'next' to step to different lines
gdb) n
Use 's' for stepping into function and 'p' printing var value
Example :
gdb) s <fun_name>
gdb) p x
I would suggest , as a beginner start off with Visual Studio. It has a very good and easy to use debugger. Just create a break point in the line from which you want to start debugging (click on the left bar beside the line or right click and create a break point). Once your break points are set you can just simply run the program in debug mode and the execution of the program will halt in the point where the break was created.
At this point you should be able to view all valuable information about the execution of the program. You can use F10 to continue the execution step or F11 to step inside the execution tree.
The debugger as many other advanced features like break on condition , hit count etc but you can start off with it's basic functionality.
If I compiled a program like this:
gcc -o my-prog -g myprog.c
I could then debug the executable my-prog it like this:
gdb my-prog
The -g option tells gcc to generate full debugging info. Other compilers will have their own versions of this option (e.g. the MSVC cl command has the /Zi option).
Since you're having issues running the gdb on your program, it might be worth checking if it was compiled with debugging info in the first place. The debugging info is usually generated in the same location as where you compiled your program.

How Can I debug a C program on Linux?

I am writing a C language program on Linux and compiling it using GCC.
I also use a Make file.
I want to debug my program. I don't want to debug a single file, I want to debug the whole program.
How can I do it?
Compile your code with the -g flag, and then use the gdb debugger. Documentation for gdb is here, but in essence:
gcc -g -o prog myfile.c another.c
and then:
gdb prog
If you want a user-friendly GUI for gdb, take a look at DDD or Insight.
I guess that you are building from the command line.
You might want to consider an IDE (Integrated Development Environment), such as KDevelop or Eclipse, etc (hint - Eclipse ... ECLPISE ... E C L I PS E).
Use an IDE to edit your code, refactor your code, examine your code - class tree, click a variable, class or function to jump to declaration, etc, etc
And - of course - to debug:
run your code in the IDE
set breakpoints to stop at particular lines
or just step through, a line at a time
examine the call stack to see how you go there
examine the current values of variables, to understand your problem
change the values of those variables and run to see what happens
and more, more, more
p.s as wasatz mentioned- DDD is great - for visualizing the contents of arrays/matrices, and - imo - especially if you have linked lists
You can use gdb-based simple and useful GUI "Nemiver". It can debug your whole module comprising many source files.
Try cgdb
cgdb is a lightweight curses (terminal-based) interface to the GNU Debugger (GDB). In addition to the standard gdb console, cgdb provides a split screen view that displays the source code as it executes. The keyboard interface is modeled after vim, so vim users should feel at home using cgdb.
github repository

Resources