I try to build libgd on my Solaris 10 (x86). In link stage, there is a core dump:
libtool: link: gcc -std=gnu99 -shared -Wl,-z -Wl,text -Wl,-h -Wl,libgd.so.3 -o .libs/libgd.so.3.0.0 .libs/gd.o .libs/gd_color.o .libs/gd_color_map.o .libs/gd_transform.o .libs/gdfx.o .libs/gd_security.o .libs/gd_gd.o .libs/gd_gd2.o .libs/gd_io.o .libs/gd_io_dp.o .libs/gd_gif_in.o .libs/gd_gif_out.o .libs/gd_io_file.o .libs/gd_io_ss.o .libs/gd_jpeg.o .libs/gd_png.o .libs/gd_ss.o .libs/gd_topal.o .libs/gd_wbmp.o .libs/gdcache.o .libs/gdfontg.o .libs/gdfontl.o .libs/gdfontmb.o .libs/gdfonts.o .libs/gdfontt.o .libs/gdft.o .libs/gdhelpers.o .libs/gdkanji.o .libs/gdtables.o .libs/gdxpm.o .libs/wbmp.o .libs/gd_filter.o .libs/gd_nnquant.o .libs/gd_rotate.o .libs/gd_matrix.o .libs/gd_interpolation.o .libs/gd_crop.o .libs/webpimg.o .libs/gd_webp.o .libs/gd_tiff.o .libs/gd_tga.o .libs/gd_bmp.o .libs/gd_xbm.o .libs/gd_color_match.o -R/usr/local/lib -R/usr/local/lib -R/usr/sfw/lib -R/usr/local/ssl/lib -R/usr/openwin/lib -R/usr/lib -R/usr/X11R6/lib -R/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.2/lib -L/usr/openwin/lib -L/usr/local/lib /usr/local/lib/libiconv.so -lz -lm /usr/local/lib/libpng12.so -L/usr/local/ssl/lib -L/usr/lib -L/usr/X11R6/lib -L/usr/local/BerkeleyDB.4.7/lib -L/usr/sfw/lib /usr/local/lib/libfreetype.so /usr/local/lib/libfontconfig.so -L/usr/local/BerkeleyDB.4.2/lib -lc
collect2: ld terminated with signal 8 [Arithmetic Exception], core dumped
make[2]: *** [libgd.la] Error 1
make[2]: Leaving directory `/data1/nan/libgd-2.1.0/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/data1/nan/libgd-2.1.0/src'
make: *** [all-recursive] Error 1
I use gdb to analyze the core dump:
Core was generated by `/usr/ccs/bin/ld -G -dy -z text -R/usr/local/lib -R/usr/local/lib -R/usr/sfw/lib'.
Program terminated with signal 8, Arithmetic exception.
[New process 92717 ]
#0 0xfeedd80c in process_cap () from /lib/libld.so.4
(gdb) bt
#0 0xfeedd80c in process_cap () from /lib/libld.so.4
#1 0xfeee002a in process_elf () from /lib/libld.so.4
#2 0xfeee0663 in ld32_process_ifl () from /lib/libld.so.4
#3 0xfeee0aa8 in ld32_process_open () from /lib/libld.so.4
#4 0xfeed9557 in process_files_com () from /lib/libld.so.4
#5 0xfeed96a4 in ld32_process_files () from /lib/libld.so.4
#6 0xfeedb58b in ld32_main () from /lib/libld.so.4
#7 0x08051a82 in main ()
From gdb, I can see the core occurs at 0xfeedd80c:
0xfeedd80c <process_cap+64>: div %esi
(gdb) i registers esi
esi 0x0 0
I can see the cause is dividing zero. But because I don't have the source code of ld, I can't analyse deeper. Could anyone give some clues on this issue? Thanks in advance!
Are you sure libm.so is the file being processed when the problem is
encountered? libm.so is a system library, and it's .SUNW_cap looks
fine (which is what I'd expect).
Oh wait, try 'LD_OPTIONS=-Dfiles,cap,details'. Perhaps the 'cap'
alone is telling you information in regards the last file where the
capabilities were processed. 'file' will tell you which file ld(1)
is presently working on.
And, a colleague just reminded me - capabilities sections can be created
using the Solaris link-editor, but if you take a relocatable object
with capabilities and reprocess it with gld (or perhaps objcopy?) you
might get an "invalid" capabilities section:
% elfdump -H foo.o
...
Object Capabilities:
index tag value
[0] CA_SUNW_HW_1 0x800 [ SSE ]
% gld -r foo.o -o bar.o
% elfdump -H bar.o
bar.o: .SUNW_cap: zero sh_entsize information, expected 0x8
Regardless, ld(1) shouldn't be falling over. I'll get that addressed.
Try setting 'LD_OPTIONS=-Dcap,details' and execute the link stage.
This should identify the file that is contributing the capabilities that are causing the issue. Inspect this input file with 'elfdump -H'.
If you can determine the questionable input file, also look at the capabilities section:
% elfdump -cN.SUNW_cap foo.o
Section Header[1]: sh_name: .SUNW_cap
sh_addr: 0xf4 sh_flags: [ SHF_ALLOC SHF_INFO_LINK ]
sh_size: 0xf8 sh_type: [ SHT_SUNW_cap ]
sh_offset: 0xf4 sh_entsize: 0x8 (31 entries)
Is it possible that the sh_entsize value is 0?
Related
I am trying to compile binaries with heap vulnerabilities to practice binary exploitation. To do so, I need an old version of the libc so that doesn't have all the security checks the modern ones do.
I have on my computer a glibc-2.3.2.so file and a ld-2.3.2.so file. I made a small test program -
7 int main()
8 {
9 char * first, *second;
10 first = malloc(0x40);
11 read(0,first,0x40);
12 free(first);
13 second = malloc(0x40);
14 ((void (*)())second)();
15
16 }
(The only thing not included are #include <stdlib.h> and #include <unistd.h>)
I turned the c file into a .o file with the command
gcc -c firstFit.c -m32
Then, I used g++ for the linking, specifying the old glibc.
g++ firstFit.o -o firstFit -Wl,--rpath=`pwd` -Wl,--dynamic-linker=`pwd`/ld-2.3.2.so -m32
It compiles just fine. However, when I try to run the file there is a floating point exception.
[1] 169605 floating point exception (core dumped) ./firstFit
I ran it under gdb to see where and
→ 0xf7fe9572 div DWORD PTR [ecx+0x164]
Using the gdb backtrace command
#0 0xf7fe9572 in ?? () from /home/zac/programming/cybersec/ctfPrepChalls/heap/ld-2.3.2.so
#1 0xf7ff6abd in ?? () from /home/zac/programming/cybersec/ctfPrepChalls/heap/ld-2.3.2.so
#2 0xf7fe8f13 in ?? () from /home/zac/programming/cybersec/ctfPrepChalls/heap/ld-2.3.2.so
#3 0xf7fe8c27 in ?? () from /home/zac/programming/cybersec/ctfPrepChalls/heap/ld-2.3.2.so
Why would ld be have a floating point error? How would I go about fixing this?
Help is appreciated
Then, I used g++ for the linking, specifying the old glibc.
g++ firstFit.o -o firstFit -Wl,--rpath=pwd -Wl,--dynamic-linker=pwd/ld-2.3.2.so -m32
One of the following two reasons very likely explains your crash:
You do not have complete installation of GLIBC-2.3.2 in your current directory.
In particular, g++ will link against libm.so.6, and if you end up using system libm.so.6 with $(pwd)/libc.so.6, you are very likely to have trouble (mixing bits of GLIBC which came from different builds is a no-no).
You link against system libstdc++.so.6, which has DT_GNU_HASH and no DT_HASH.
GLIBC-2.3.2 is old enough not to support GNU_HASH.
I expect the issue#2 is most likely explanation for SIGFPE.
You can confirm either of these by running
env LD_TRACE_LOADED_OBJECTS=1 ./firstFit
to find loaded objects (do not use ldd, it will lie to you), and looking at the output from:
readelf -d ./firstFit | grep HASH
readelf -d /path/to/libstdc++.so.6 | grep HASH
so, here is the program that only returns 0:
int main( void )
{
return 0;
}
compiling the program
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o"
Compilation finished successfully.
linking the program (using gcc, not g++)
gcc -ggdb3 -o "untitled1" "untitled1.o"
Compilation finished successfully.
running the program:
./untitled1
(nothing output)
Suggest: don't mix gcc and g++ for the same program
I was trying to learn how to use gdb on core dumps.
Here is the code:
int main()
{
return 1/0;
}
This is the gdb output, when I run gdb a.out core:
warning: exec file is newer than core file.
[New LWP 3121]
Core was generated by `./crash'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x00000000004004fc in ?? ()
(gdb) bt
#0 0x00000000004004fc in ?? ()
#1 0x0000000000400500 in ?? ()
#2 0x00007f6ea0945b97 in ?? ()
#3 0x0000000000000000 in ?? ()
What are ?? in the backtrace? How can I resolve them?
Those ?? are usually where the name of the function is displayed. GDB does not know the name of those functions and therefore displays ??.
Now, why is this happening? Depends. GCC compiles including symbols (e.g. function names and similar) by default. Most probably you are working with a stripped version, where symbols have been removed, or just with the wrong file.
As #zwol suggests, the line you see warning: exec file is newer than core file is an indication of the fact that something else is going on that you don't show in your question. You are working on a core dump file generated by the crashed executable, which is outdated.
I would suggest you to re-compile the program from scratch and make sure that you are opening the right file with GDB. First produce a new core dump by crashing the new program, then open it in GDB.
Assuming the following program.c:
int main(void) { return 1/0; }
This should work:
$ rm -f core
$ gcc program.c -o program
$ ./program
Floating point exception (core dumped)
$ gdb program core
Reading symbols from program...(no debugging symbols found)...done.
[New LWP 11896]
Core was generated by `./program'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x000055d24a4cd790 in main ()
(gdb) bt
#0 0x000055d24a4cd790 in main ()
(gdb)
NOTE: if you don't see (core dumped) when running the process that means that a core dump was not generated (which leaves you with the old one). If you are using Bash, try running the command ulimit -c unlimited before crashing the program.
What does ?? in gdb backtrace mean
It means that GDB has no idea to which code the addresses in backtrace: 0x04004fc, 0x0400500, etc. correspond.
and how to get the actual stack frames?
That depends on why this is happening. There are two common scenarios:
You are debugging the wrong executable.
One way this could happen is when you compile with optimization, e.g. gcc -O2 main.c -o crash, let the program dump core, then recompile with debugging (e.g. gcc -g main.c -o crash) and try to debug "old" core dump with "new" executable.
Don't do that. Instead, compile with optimization and debugging: gcc -O2 -g main.c -o crash.
P.S. This warning: warning: exec file is newer than core file is intended to warn you precisely about this case.
The other common cause is when you obtain a crash on a production system and try to debug it on a development one (given the addresses which you show this is unlikely to have happened here).
For that case, see this answer.
You did not compile with debug symbols - try adding -g to the compile line
I have a c project compiled with GCC.When I run my test.exe program ends with "test.exe has stopped working" but compiled successfully.How can I debug my program and how can find where is my mistake?
Technique 1:
I tried to printf("Successful 1..."),printf("Successful 2...") on the beginning of every single line of code but this method is frustrating.Are there tools(gdb...) to debug my code line by line for me?
printf("Successful 1...")
//code
printf("Successful 2...")
//code
How can I debug my program line by line with GDB?
Can I go to the error line directly with GDB?
Edit 1:
I use gdb and type run command and get following output which is not helpful(segmentation fault but where?):
Starting program: C:\Users\q\..././bin/test.exe
[New Thread 3292.0x22b8]
[New Thread 3292.0x1fb8]
Program received signal SIGSEGV, Segmentation fault.
0x7696e3e3 in ungetwc () from C:\WINDOWS\SysWOW64\msvcrt.dll
Edit 2:
How to debug using gdb? doesn't contain helpful answer to my question.Not possible duplicate of my answer
Edit 3:(bt method output)
I have program that contain 6 source and 6 header files.And every header and source files contain three and more than function pointers that perform some action.I tried debug with gdb bt and get following output:
#1 0x00000001 in ?? ()
#2 0x00000073 in ?? ()
#3 0x00000032 in ?? ()
#4 0x00000000 in ?? ()
My makefile:
all: compile run
compile :
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./bin/test ./lib/... .o ./lib/... .o ./lib/... .o ./lib/... .o ./lib/... .o ./src/test.c
run:
gdb ./bin/test.exe
Sometimes, if your bug is particularly bad, it overwrites the stack and demolishes all the clues that gdb (and particularly the bt command) would need in order to show you where you were.
In that case you can try something like this:
Start gdb, set a breakpoint on main, run your program, wait for the breakpoint to be hit.
Single-step through your program with the n command, which steps over, not down into, functions. (That is, each called function runs all at once; you're not single-stepping recursively down into each function.) Sooner or later one of your single-steps will step over a function which crashes. Now you've narrowed it down a bit.
Set a breakpoint on that function.
Rerun the program.
When you hit the breakpoint inside the troublesome function, again begin single-stepping. Sooner or later one of your single-steps will enter a sub-function which crashes. Now you've narrowed it down a bit more.
Continue in this fashion until you've located the actual line causing the crash.
You are getting segmentation fault and that is why your application is not running. Segmentation fault is a run time problem, even if your program compiles successfully.
In gdb after you get this:
Program received signal SIGSEGV, Segmentation fault.
type bt. The gdb's bt command will show you the back trace of your running program. It tells you which flow your program took and also the exact line which caused the segmentation fault and made your application crash.
The output of bt will be more 'readable' if you have built your application in debug mode. If you are using using gcc, you need to add -g flag to build in debug mode
I am trying to move on from my assembly file kernel stage to my C file kernel stage (finally...). But, I am having some trouble in the process of linking my compiled C kernel to my compiled assembly kernel entry program.
Here is the code for my kernel_entry.asm file.
[BITS 32] ; Starting in 32 bit protected mode
[EXTERN main] ; Extern to C file main function
call main ; Invoke main in our C kernel
jmp $ ; Jump here - Infinite loop
Here is the code for my kernel.c file.
void main() {
char* video_memory = (char*) 0xB8000;
*video_memory = 'X';
}
Here are the command lines I am using to compile them.
nasm -f elf -o kernel_entry.o kernel_entry.asm
gcc -ffreestanding -c kernel.c -o kernel.o
ld -o kernel.bin -Ttext 0x0500 kernel_entry.o kernel.o --oformat binary
The last command line gives me this error.
ld: i386 architecture of input file `kernel_entry.o' is incompatible with i386:x86-64 output
ld: warning: cannot find entry symbol _start; defaulting to 0000000000000500
Note: I am loading my kernel to the address and offset 0x0000:0x0500, which is why I use -Ttext 0x0500, I am unsure why the second ld warning appears but for now it seems unimportant (although if you offer any help in that regard it would be appreciated as well).
Can anyone tell me why I cannot link these files together? I am also running on Ubuntu dekstop 64 bit. Thank you in advance for any help you may give.
It looks as though you're compiling this code on a 64-bit system. As such, kernel.o is a 64-bit binary, and cannot be linked with the 32-bit kernel_entry.o.
Since you don't have any code in place to get the system into long mode, you probably want to compile the "kernel" as 32-bit code. Use -m32 to trigger this:
gcc -m32 -ffreestanding -c kernel.c -o kernel.o
^^^^
Hi I made a simple hello world C program and I am compiling it like this :
gcc -c hello.c
ld hello.o -lc -o out
I get a warning from ld : ld : _start not found defaulting to ....
I do an objdump -D hello.o and I cannot find the _start routine in the output.
What am I missing here ?
You're missing the crt* stuff which you will see if you link with gcc -v: crt1.o, crtend.o, crtn.o. Look at how gcc invokes collect2 (it's visible with gcc -v) and use the same options for ld.
main function is not the executable entry point: some initialization for standard library is done before main (because it's either impossible or illogical to do otherwise). Real entry point, which is _start by default, is in crt1.o which is always linked into your executable.
It's because you don't have a main function, also you can try
gcc -v hello.c -o hello
See if it compiles successfully.
On my system (Angstrom Linux, gcc 4.3.3), it happened due me installing libgcc-s-dev instead of libgcc-dev. No binary on the system contained _start string, I checked that. Installing libgcc-dev helped.