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