Retrieve executable from core dump - linux

I want to retrieve the executable from a core dump and the output of any linux package used to get this information should contain execfn in it's output.
Here are the following things which I have tried so far :
$ file kms
kms: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/test', real uid: 1000440000, effective uid: 1000440000, real gid: 0, effective gid: 0, execfn: '/test', platform: 'x86_64'
The file command only works for specific cores and it's not a generic solution because some core dump gives following output.
$ file ss
ss: ELF 64-bit LSB core file x86-64, version 1 (SYSV), too many program header sections (6841)
gdb command doesn't work for all core dumps in the same manner. The output using gdb command is inconsistent. The output received by gdb command for some core dump is not the same as strings command.
$gdb kms
Core was generated by `/test'.
I even tried strings package and I think it gives proper output but the format doesn't contain execfn for it to be used in my solution
$ strings kms | grep ^/ | tail -1
/test
Can anyone please suggest any linux package which will help me in retrieving executable from core dump which contains execfn in it's output.

Try running the file(1) command on your core(5) file. But that requires your core file to be complete. See below and gcore(1) with strace(1) and ptrace(2).
If your ELF executable (see elf(5)) was built with DWARF debugging information then you should have enough information in your core file. See also gdb(1) and this answer.
DWARF debugging information is obtained by compiling and linking your program -if it was compiled with GCC (or with Clang) so using a recent gcc, g++, gfortran, clang, clang++ command - with the -g (or -g2 ....) flag.
Be aware of setrlimit(2). You may need to use the ulimit builtin of GNU bash (see bash(1) and the documentation of GNU bash...), or the limit builtin of zsh to increase the core size file limit.
If your core dump limit size (i.e. RLIMIT_CORE for setrlimit) is too small, it is preferable to raise it and run again your program. A good developer could disable core dumps in an executable. My guess (perhaps wrong) is that a too small core limit size might be consistent with your observations.
If your interactive Unix shell is something else that /bin/bash (e.g. fish) be sure to read its documentation. See also passwd(5), ps(1) -to be used as ps $$, pstree(1), top(1).
See also proc(5). You might try cat /proc/$$/limits or /bin/cat /self/limits in your terminal before running your program there. Perhaps /bin/cat /proc/version could be needed to understand more.
Your Linux kernel can also be configured to avoid core dumps. Ask for details on kernelnewbies and read more about SE Linux. Some Linux kernels accept gzcat /proc/config.gz as root, but other don't, to query their configuration. You could need root access with sudo(8) or su(1). See credentials(7).
On Linux, you might be interested by Ian Taylor libbacktrace. RefPerSys and GCC are using it.

Related

Understanding Linux readelf "program interpreter" - how is this set at compile time?

I am building some software (swupdate) that has the traditional 'kbuild' (kconfig / menuconfig) mechanism, and thus has an intermediate binary mconf that it builds before it brings up the text-menu system.
I'm using a third-party "productivity layer" tool to invoke the menuconfig (PetaLinux, a wrapper around Yocto), but the binary that results is not usable:
$ scripts/kconfig/mconf
bash: scripts/kconfig/mconf: No such file or directory
I figured out that this weird behaviour is due to the following:
$ readelf -a scripts/kconfig/mconf | grep interpreter
[Requesting program interpreter: /scratch/jenkins-BUILDS-eSDK-2021.2_stable-pipeline-build-89_VersalFullPrime/build/tmp/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2]
Note the long path to a ld-linux-x86-64.so, which I don't have on my system in that location. This path looks like it's leaked into the build from the PetaLinux environment, somehow.
What it should look like is:
$ readelf -a scripts/kconfig/mconf | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
Incidentally, I got that binary by building mconf manually, with a command like this:
make -C <path/to/source> O=<path/to/build> menuconfig
...
HOSTCC scripts/kconfig/mconf.o
...
Anyway, that's all details, and my actual question is this - where can I find information about how the "program interpreter" is set by the compiler or linker? Where do you think it's going wrong? Is there an environment variable that can affect this behaviour?

View source for standard Linux commands e.g. cat, ls, cd

I would like to view the source code for a Linux command to see what is actually going on inside each command. When I attempt to open the commands in /bin in a text/hex editor, I get a bunch of garbage. What is the proper way to view the source on these commands?
Thanks in advance,
Geoff
EDIT:
I should have been more specific. Basically I have a command set that was written by someone who I can no longer reach. I would like to see what his command was actually doing, but without a way to 'disassemble' the command, I am dead in the water. I was hoping for a way to do this within the OS.
Many of the core Linux commands are part of the GNU core utils. The source can be found online here
The file you are opening is the binary executables which are the stuff the kernel passes to the CPU. These files are made using a compiler that takes in the source code you and I understand and turns it via a number of stages into this CPU friendly format.
You can find out the system calls that are being made using strace
strace your_command
Most likely you can download the source code with your distribution's package manager. For example, on Debian and related distros (Ubuntu included), first find which package the command belongs to:
$ dpkg -S /bin/cat
coreutils: /bin/cat
The output tells you that /bin/cat is in the coreutils package. Now you can download the source code:
apt-get source coreutils
This question is related to reverse engineering.
Some keyword is static analysis and dynamic analysis
use gdb to check that the binary file have symbol table inside or not. (if binary compile with debugging flag, you can get the source code and skip below step)
observe program behavior by strace/ltrace.
write seudo-code by use objdump/ida-pro or other disassembler.
run it by gdb to dynamic analysis and correct the seudo-code.
A normal binary file can be reverted back to source code if you want and have time. Conversely, an abnormal program is not easy to do this, but it only appear on specific ctf competition. (Some special skill like strip/objcopy/packer ... etc)
You can see assembly code of /bin/cat with:
objdump -d /bin/cat
Then analyze it and see what command can be launch.
Another way of approaching is strings /bin/cat, it is usefull make a initial idea and then reverse it.
You can get the source code of every linux command online anyway :D

How do I detect the OS Name in Perl to a particular version?

I have tried to look for an answer on how this may be done but I cannot seem to find one.
I am aware that to find the OS name in perl you can use
$^O
However in Linux and Solaris, no matter what OS version you are on it will just return either Solaris or Linux. I would like it to show up as Solaris10 or Solaris11. Is there a way to get this? I know if you enter
uname -r
you can get the version number (5.10 in Solaris for example).
Any thoughts on how this could be done?
Thank you =)
The POSIX module in perl provides the uname call, so:
use POSIX qw(uname);
my #uname = uname();
print $uname[0] . " " . $uname[2];
This provides the information from the running system, not from the system that performed the build (which is where the Config results come from).
In general, though, this information is the kernel release, and not the marketing version of the product, so for example, this wouldn't tell you if it's a Linux Mint system, just that it's a Linux system running the 3.2.foo kernel.
For lsb based Linux systems, the lsb_release command can give this information e.g. on a linux system I have:
natsu ~> lsb_release -r
Release: 12.04
natsu ~> lsb_release -i
Distributor ID: Ubuntu
This information is in the /etc/lsb-release file.
For Solaris, the release information is in the /etc/release file. The first line contains the name of the operating system e.g. Solaris 10 9/10. There are multiple lines in this file, and it's more of a free-form text field.
use Config;
print "$_\n" for #Config{qw(myuname osname osvers)};
From perldoc Config,
The Config module contains all the information that was available to the Configure program at Perl build time.
myuname
The output of uname -a if available, otherwise the hostname. The whole thing is then lower-cased and slashes and single quotes are removed.
osname
This variable contains the operating system name (e.g. sunos, solaris, hpux, etc.). It can be useful later on for setting defaults. Any spaces are replaced with underscores. It is set to a null string if we can't figure it out.
osvers
This variable contains the operating system version (e.g. 4.1.3, 5.2, etc.). It is primarily used for helping select an appropriate hints file, but might be useful elsewhere for setting defaults. It is set to '' if we can't figure it out. We try to be flexible about how much of the version number to keep, e.g. if 4.1.1, 4.1.2, and 4.1.3 are essentially the same for this package, hints files might just be os_4.0 or os_4.1, etc., not keeping separate files for each little release.

How to run binary file in Linux

I have a file called commanKT and want to run it in a Linux terminal. Can someone help by giving the command to run this file? I tried ./commonRT but I'm getting the error:
"bash: ./commonrt: cannot execute binary file"
[blackberry#BuildMc MainApp]$ ls -al commonKT
-rwxrwxr-x. 1 sijith sijith 10314053 Feb 27 16:49 commonKT
To execute a binary, use: ./binary_name.
If you get an error:
bash: ./binary_name: cannot execute binary file
it'll be because it was compiled using a tool chain that was for a different target to that which you're attempting to run the binary on.
For example, if you compile 'binary_name.c' with arm-none-linux-gnueabi-gcc and try run the generated binary on an x86 machine, you will get the aforementioned error.
To execute a binary or .run file in Linux from the shell, use the dot forward slash friend
./binary_file_name
and if it fails say because of permissions, you could try this before executing it
chmod +x binary_file_name
# then execute it
./binary_file_name
Hope it helps
The volume it's on is mounted noexec.
:-) If not typo, why are you using ./commonRT instead of ./commonKT ??
It is possible that you compiled your binary with incompatible architecture settings on your build host vs. your execution host.
Can you please have a look at the enabled target settings via
g++ {all-your-build-flags-here} -Q -v --help=target
on your build host? In particular, the COLLECT_GCC_OPTIONS variable may give you valuable debug info. Then have a look at the CPU capabilities on your execution host via
cat /proc/cpuinfo | grep -m1 flags
Look out for mismatches such as -msse4.2 [enabled] on your build host but a missing sse4_2 flag in the CPU capabilities.
If that doesn't help, please provide the output of ldd commonKT on both build and execution host.
This is an answer to #craq :
I just compiled the file from C source and set it to be executable with chmod. There were no warning or error messages from gcc.
I'm a bit surprised that you had to 'set it to executable' -- my gcc always sets the executable flag itself. This suggests to me that gcc didn't expect this to be the final executable file, or that it didn't expect it to be executable on this system.
Now I've tried to just create the object file, like so:
$ gcc -c -o hello hello.c
$ chmod +x hello
(hello.c is a typical "Hello World" program.) But my error message is a bit different:
$ ./hello
bash: ./hello: cannot execute binary file: Exec format error`
On the other hand, this way, the output of the file command is identical to yours:
$ file hello
hello: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
Whereas if I compile correctly, its output is much longer.
$ gcc -o hello hello.c
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=131bb123a67dd3089d23d5aaaa65a79c4c6a0ef7, not stripped
What I am saying is: I suspect it has something to do with the way you compile and link your code. Maybe you can shed some light on how you do that?
The only way that works for me (extracted from here):
chmod a+x name_of_file.bin
Then run it by writing
./name_of_file.bin
If you get a permission error you might have to launch your application with root privileges:
sudo ./name_of_file.bin
Or, the file is of a filetype and/or architecture that you just cannot run with your hardware and/or there is also no fallback binfmt_misc entry to handle the particular format in some other way. Use file(1) to determine.
your compilation option -c makes your compiling just compilation and assembly, but no link.
If it is not a typo, as pointed out earlier, it could be wrong compiler options like compiling 64 bit under 32 bit. It must not be a toolchain.
full path for binary file. For example: /home/vitaliy2034/binary_file_name. Or
use directive "./+binary_file_name".
'./' in unix system it return full path to directory, in which you open terminal(shell).
I hope it helps.
Sorry, for my english language)
1st login with su
su <user-name>
enter password
Password: xxxxxx
Then executer command/file, it should run.

equivalent of dumpstabs -s solaris command in linux

what is the equivalent of dumpstabs -s solaris command in linux?
Regards
ven
I guess this should do the same:
objdump -g
Or maybe
readelf --debug-dump
for ELF files. You can give various options to that last command (see man readelf).
Edit: After reading the manual of objdump, I found the -G option to show the STABS (I guess this is what you want). The manual mentions the following:
This is only useful on systems (such as Solaris 2.0) in which ".stab" debugging symbol-table entries are carried in an ELF section.
So maybe what you want just isn't possible on Linux.

Resources