]>
Commit | Line | Data |
---|---|---|
6566e5f2 MT |
1 | #!/bin/bash |
2 | ||
3 | # Check if a file is an ELF binary | |
4 | # | |
5 | function file_is_elf() { | |
6 | local file=${1} | |
7 | ||
520f0ed3 | 8 | file "${file}" 2>/dev/null | grep -q "ELF" |
6566e5f2 MT |
9 | } |
10 | ||
11 | # Check if a file is a script. | |
12 | # If the first line starts with #! this is sufficient. | |
13 | # | |
14 | function file_is_script() { | |
15 | local file=${1} | |
16 | ||
520f0ed3 | 17 | file ${file} 2>/dev/null | egrep -q ":.* (commands|script)" |
63029754 MT |
18 | } |
19 | ||
20 | # Check if file is an 64-bit binary. | |
21 | function file_is_64bit() { | |
22 | local file=${1} | |
6566e5f2 | 23 | |
63029754 | 24 | file -L ${file} 2>/dev/null | grep -q "ELF 64-bit" |
6566e5f2 MT |
25 | } |
26 | ||
27 | # Get the interpreter of a file. | |
28 | # | |
29 | function file_get_interpreter() { | |
30 | local file=${1} | |
31 | ||
32 | if file_is_elf ${file}; then | |
1df83d33 | 33 | file_get_elf_interpreter ${file} |
6566e5f2 | 34 | elif file_is_script ${file}; then |
1df83d33 | 35 | file_get_script_interpreter ${file} |
6566e5f2 MT |
36 | fi |
37 | } | |
38 | ||
39 | # Hidden function that gets the interpreter from an ELF file. | |
40 | # | |
1df83d33 | 41 | function file_get_elf_interpreter() { |
6566e5f2 MT |
42 | local file=${1} |
43 | ||
520f0ed3 MT |
44 | local interp=$(readelf -l ${file} 2>/dev/null | \ |
45 | grep "program interpreter" | tr -d "]" | awk '{ print $NF }') | |
693077b4 MT |
46 | |
47 | # Only return real file names. Debugging files do not | |
48 | # have those starting with a /. | |
49 | if [ "${interp:0:1}" = "/" ]; then | |
50 | echo "${interp}" | |
51 | return | |
52 | fi | |
6566e5f2 MT |
53 | } |
54 | ||
55 | # Hidden fucntion that gets the interpreter from a script file. | |
56 | # | |
1df83d33 | 57 | function file_get_script_interpreter() { |
6566e5f2 MT |
58 | local file=${1} |
59 | ||
60 | # If the file is not executeable, no interpreter will be needed | |
61 | [ -x "${file}" ] || return | |
62 | ||
63 | local first_line=$(head -n1 ${file}) | |
64 | ||
77099310 MT |
65 | # Return nothing if no shebang was found. |
66 | [ "${first_line:0:2}" = "#!" ] || return | |
67 | ||
6566e5f2 MT |
68 | first_line="${first_line:2:${#first_line}}" |
69 | ||
70 | # Choose the first argument and strip any parameters if available | |
71 | local interpreter | |
72 | for interpreter in ${first_line}; do | |
77099310 MT |
73 | # Skip interpreters that do that have an absolute path. |
74 | [ "${interpreter:0:1}" = "/" ] || break | |
75 | ||
6566e5f2 MT |
76 | echo "${interpreter}" |
77 | return | |
78 | done | |
79 | } | |
80 | ||
81 | # Check if a file is statically linked. | |
82 | # | |
83 | function file_is_static() { | |
84 | local file=${1} | |
85 | ||
520f0ed3 | 86 | file ${file} 2>/dev/null | grep -q "statically linked" |
6566e5f2 MT |
87 | } |
88 | ||
89 | # Get NEEDED from a file. | |
90 | # | |
91 | function file_get_needed() { | |
92 | local file=${1} | |
93 | ||
520f0ed3 | 94 | local out=$(readelf -d ${file} 2>/dev/null | grep NEEDED | \ |
63029754 MT |
95 | tr -d "[]" | awk '{ print $NF }') |
96 | ||
97 | echo "${out}$(file_is_64bit ${file})" | |
6566e5f2 MT |
98 | } |
99 | ||
100 | # Get RPATH from a file. | |
101 | # | |
102 | function file_get_rpath() { | |
103 | local file=${1} | |
104 | ||
520f0ed3 | 105 | readelf -d ${file} 2>/dev/null | grep RPATH | \ |
6566e5f2 MT |
106 | tr -d "[]" | awk '{ print $NF }' |
107 | } | |
108 | ||
109 | # Get SONAME from a file. | |
110 | # | |
111 | function file_get_soname() { | |
112 | local file=${1} | |
113 | ||
63029754 | 114 | objdump -p ${file} 2>/dev/null | awk '/SONAME/ { print $2 }' |
6566e5f2 MT |
115 | } |
116 | ||
117 | # Check if a file is a shared object. | |
118 | # | |
119 | function file_is_shared_object() { | |
120 | local file=${1} | |
121 | ||
520f0ed3 | 122 | file ${file} 2>/dev/null | grep -q "shared object" |
6566e5f2 MT |
123 | } |
124 | ||
125 | # Check if a file has the canary. | |
126 | # | |
127 | function file_has_canary() { | |
128 | local file=${1} | |
129 | ||
520f0ed3 | 130 | readelf -s ${file} 2>/dev/null | grep -q "__stack_chk_fail" |
6566e5f2 MT |
131 | } |
132 | ||
133 | # Check if a file has an executeable stack. | |
134 | # | |
135 | function file_has_execstack() { | |
136 | local file=${1} | |
137 | ||
520f0ed3 | 138 | readelf -h ${file} 2>/dev/null | grep -qE "Type:[[:space:]]*EXEC" |
6566e5f2 MT |
139 | } |
140 | ||
141 | # Check if a file has NX. | |
142 | # | |
143 | function file_has_nx() { | |
144 | local file=${1} | |
145 | ||
520f0ed3 | 146 | readelf -l ${file} 2>/dev/null | grep "GNU_STACK" | grep -q "RWE" |
6566e5f2 MT |
147 | [ $? != 0 ] |
148 | } | |
149 | ||
150 | # Check if a file is partly RELRO. | |
151 | # | |
152 | function file_is_relro_partly() { | |
153 | local file=${1} | |
154 | ||
520f0ed3 | 155 | readelf -l ${file} 2>/dev/null | grep -q "GNU_RELRO" |
6566e5f2 MT |
156 | } |
157 | ||
158 | # Check if a file is fully RELRO. | |
159 | # | |
160 | function file_is_relro_full() { | |
161 | local file=${1} | |
162 | ||
163 | if file_is_relro_partly ${file}; then | |
520f0ed3 | 164 | readelf -d ${file} 2>/dev/null | grep -q "BIND_NOW" |
6566e5f2 MT |
165 | return $? |
166 | fi | |
167 | return 1 | |
168 | } | |
169 | ||
170 | # Find all ELF files. | |
171 | # | |
172 | function find_elf_files() { | |
173 | local dir | |
174 | local dirs | |
175 | local prefix | |
176 | ||
177 | while [ $# -gt 0 ]; do | |
178 | case "${1}" in | |
179 | --prefix=*) | |
180 | prefix="${1#--prefix=}/" | |
181 | ;; | |
182 | *) | |
183 | dirs="${dirs} ${1}" | |
184 | ;; | |
185 | esac | |
186 | shift | |
187 | done | |
188 | ||
189 | local file | |
190 | local files | |
191 | ||
192 | for dir in ${dirs}; do | |
193 | dir="${prefix}${dir}" | |
3fee3333 | 194 | for file in $(find ${dir} -type f -not -name "*.ko" 2>/dev/null); do |
1b51609b MT |
195 | case "${file}" in |
196 | # Skip kernel modules. | |
197 | */lib/modules/*) | |
198 | continue | |
199 | ;; | |
200 | esac | |
201 | ||
6566e5f2 MT |
202 | if file_is_elf ${file} && ! file_is_static ${file}; then |
203 | files="${files} ${file}" | |
204 | fi | |
205 | done | |
206 | done | |
207 | ||
208 | echo ${files} | |
209 | } | |
210 | ||
211 | function filter_startfiles() { | |
212 | local file=${1} | |
213 | ||
214 | grep -qE "crt[1in]\.o$" <<<${file} | |
215 | } |