I wonder if there is any possibility to find files which are 32-bit ELF objects by using one single command in file system? I'm actually working in fedora 23 64 bit and can't locate any of those files but the exercise which I'm trying to do precisely says that it must be 32-bit ELF file. Thanks for any help.
7 Answers
All you need to do is check that the first 5 bytes in the file are 7f 45 4c 46 01 (that's what file
does). So you only need to read 5 bytes off every file:
PERLIO=:raw find . -type f -size +51c -exec perl -lne '
BEGIN{$/=\5};print $ARGV if $_ eq "\x7f\x45\x4c\x46\x01"; close ARGV' {} +
Here checking only regular files that are at least 52 bytes as that's the size of the ELF header for a 32 bit ELF file, though ELF files would generally be a lot bigger than that.
Do you mean something like the file
command used like this?
$ which ls
/bin/ls
$ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=cecbb9e27978d91bc6fe2cc4d46d0cd58deafdb2, stripped
$
You could do a find
command piped to file
as follows:
$ find /bin -type f -exec file '{}' \; | grep -c "ELF 32-bit LSB executable"
88
$ find /bin -type f -exec file '{}' \; 2>&1 | grep "ELF 32-bit LSB executable" | head -2
/bin/bzip2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=8ec5364bf1b5aae5a29b02aaa89db511e988f26a, stripped
/bin/more: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=2cf8c3651ba3e5dd6a053d40a969b4b7bca9cac0, stripped
$
You can use file
command and look for the keyword executable
in the output of this command. If found, grab the first 2 fields with awk
, i.e., $1
and $2
. there lies your answer. You can build a logic to do whatever you want to do with the 32-bit ELF files. Also you can look through the files in directories of your desire, in a loop.
You can use find
to get the files, then file
to get the file info and grep
to search for the string 32-bit
in the file
's output:
find /bin /usr/bin -type f -exec sh -c '{ file -L "$1" | grep -q 32-bit ;} \
&& echo "$1"' _ {} \;
Change/add location(s) to search to fit your need.
Example:
% find /usr/bin -type f -exec sh -c '{ file -L "$1" | grep -q 32-bit ;} && echo "$1"' _ {} \;
/usr/bin/unix2dos
/usr/bin/dos2unix
There are at least 3 ways to do it. Instead of printing all file names
I added | wc -l
at the end of every suggested command to prove that
they return the same:
use
find
in conjunction with-exec
:$ time find . -type f -exec file {} \; | grep -i "ELF 32" | wc -l 2872 real 0m7.422s user 0m5.095s sys 0m0.384s
use
find
in conjunction withxargs
- note that although it's much faster it's less safe asxargs
will run a given command even iffind
returns no results and-r
option used here is a GNU extension and is not specifiedPOSIX
:$ time find . -type f | xargs -r file | grep "ELF 32" | wc -l 2872 real 0m1.754s user 0m1.712s sys 0m0.052s
use
grep
to manually check header of each file.-r
here is to ignore symlinks:$ grep -l -a -m1 $'^\x7F\x45\x4c\x46\x01' -r . | wc -l 2872
Yes. Single-command recursive search for 32-bit ELF files:
$ scanelf -M32 -R /SEARCH/PATH
TYPE FILE
ET_DYN /SEARCH/PATH/library.so
ET_EXEC /SEARCH/PATH/executable
Also, suppressing banner and object type (printing only filepaths):
$ scanelf -M32 -RBF %F /SEARCH/PATH
/SEARCH/PATH/library.so
/SEARCH/PATH/executable