Skip to content

Commit b7c2625

Browse files
committed
Merge bitcoin/bitcoin#21664: contrib: use LIEF for macOS and Windows symbol & security checks
7fc5e86 test: install lief in CI (fanquake) 955140b contrib: consolidate PIE and NX security checks (fanquake) 2aa1631 contrib: use LIEF in PE symbol checks (fanquake) e93ac26 contrib: use LIEF in macOS symbol checks (fanquake) a632cbc contrib: use f strings in symbol-check.py (fanquake) 0f5d77c contrib: add PE PIE check to security checks (fanquake) 8e1f40d contrib: use LIEF for PE security checks (fanquake) a25b2e9 contrib: use LIEF for macOS security checks (fanquake) 7e7eae7 contrib: use f strings in security-check.py (fanquake) 2e7a9f7 guix: install LIEF in Guix container (fanquake) 465967b gitian: install LIEF in gitian container (fanquake) Pull request description: This PR is a proof of concept for using [LIEF](https://github.com/lief-project/LIEF) for the PE and MACHO symbol and security checks. It replaces our current approach of manually parsing the output of `objdump` & `otool`. If the consensus is that using LIEF is ok, then I also plan on replacing [pixie.py](https://github.com/bitcoin/bitcoin/blob/master/contrib/devtools/pixie.py), and using LIEF for all checks. LIEF for Linux is also currently blocked (on the next release, unless we want to build master) on one change for RISC-V that I [sent upstream](lief-project/LIEF#562). LIEF is seemingly well maintained, and is the basis for a number of other tools. It also has some very nice documentation; i.e the [Python API for ELF](https://lief.quarkslab.com/doc/latest/api/python/elf.html). It also has many builtins we can take advantage of. i.e [`is_pie`](https://lief.quarkslab.com/doc/latest/api/python/macho.html#lief.MachO.Binary.is_pie), [`has_nx`](https://lief.quarkslab.com/doc/latest/api/python/macho.html#lief.MachO.Binary.has_nx) etc. This means we can [consolidate some of our checks](bitcoin/bitcoin@9c5eeb5). If/when end up using LIEF for lightning then we can consolidate further, and cleanup these scripts. i.e to not parse the binary inside the checks, but once at the start of the script. Guix builds: ```bash # find guix-build-$(git rev-parse --short=12 HEAD)/output/ -type f -print0 | env LC_ALL=C sort -z | xargs -r0 sha256sum 963a08638c46f9a3d75cd4b0c155d1ca091bbeba27167291adcd3dca03fd4c3d guix-build-f51237d94d98/output/aarch64-linux-gnu/bitcoin-f51237d94d98-aarch64-linux-gnu-debug.tar.gz a3ce927c46b103789a010c41a6ebfafe4548d90ee7d88f2a735c9183b775da5c guix-build-f51237d94d98/output/aarch64-linux-gnu/bitcoin-f51237d94d98-aarch64-linux-gnu.tar.gz 2503ac8901068805d5e7251fd5cfeb7c1f8ba3528bdfcf3aa1e0c40bfd5c1cbc guix-build-f51237d94d98/output/arm-linux-gnueabihf/bitcoin-f51237d94d98-arm-linux-gnueabihf-debug.tar.gz 5798697e58e1788df85aa9e2e4d33fef0456169fcbd2521f13b3b5806ac0d84d guix-build-f51237d94d98/output/arm-linux-gnueabihf/bitcoin-f51237d94d98-arm-linux-gnueabihf.tar.gz 4185adebc6a0abe7241a3cd409a6ab7be031c26f1c4245e30bb5f87eef0925d2 guix-build-f51237d94d98/output/dist-archive/bitcoin-f51237d94d98.tar.gz 9b4b8756c5c84295eb6b61b6b32a07a8d07723fb38aaa8f519b6133935061bda guix-build-f51237d94d98/output/powerpc64-linux-gnu/bitcoin-f51237d94d98-powerpc64-linux-gnu-debug.tar.gz cbd821aa464a9c16f7979dbec1a5e66939e777a567f55f7081499a8d528d42c5 guix-build-f51237d94d98/output/powerpc64-linux-gnu/bitcoin-f51237d94d98-powerpc64-linux-gnu.tar.gz abed530a82e97e3cf621c90a13c0881b0e39ccce2a6f42a3ff80de76e2abc5f7 guix-build-f51237d94d98/output/powerpc64le-linux-gnu/bitcoin-f51237d94d98-powerpc64le-linux-gnu-debug.tar.gz 8b6d2bdd8b58ff1f6072bf8693abe3ce773ff3a7d8d2b7218207e69945b9d31b guix-build-f51237d94d98/output/powerpc64le-linux-gnu/bitcoin-f51237d94d98-powerpc64le-linux-gnu.tar.gz d99cc705032d22ae819975992216899ed960ba25871a05c8789d00b80418511f guix-build-f51237d94d98/output/riscv64-linux-gnu/bitcoin-f51237d94d98-riscv64-linux-gnu-debug.tar.gz 5240ca4f4ef7c62088185224ac319ad9a4a9b40075df10af18d8a6355bca32fb guix-build-f51237d94d98/output/riscv64-linux-gnu/bitcoin-f51237d94d98-riscv64-linux-gnu.tar.gz adc16eaee4b51e8615ce8b3be9f6c018698237df4ad6e0886cf0d4ab6bc9e5c4 guix-build-f51237d94d98/output/x86_64-apple-darwin18/bitcoin-f51237d94d98-osx-unsigned.dmg b188af0572ee682d74cc82c7e6e464115205fc130a457cfe19d42ac9ddd267f8 guix-build-f51237d94d98/output/x86_64-apple-darwin18/bitcoin-f51237d94d98-osx-unsigned.tar.gz e764062fde144e6fb5d6dd776c10fc2daa8d775831f7e43247d17a6c6e060c97 guix-build-f51237d94d98/output/x86_64-apple-darwin18/bitcoin-f51237d94d98-osx64.tar.gz dab3d26ac94c669140f7329d14e57ef02b0fe92b8a8f9d96c32a416adea0da0f guix-build-f51237d94d98/output/x86_64-linux-gnu/bitcoin-f51237d94d98-x86_64-linux-gnu-debug.tar.gz ca59d4379fbe2b9a52deebeaf88508e0eda4215f28d319aff0781289dd159712 guix-build-f51237d94d98/output/x86_64-linux-gnu/bitcoin-f51237d94d98-x86_64-linux-gnu.tar.gz 52b7c35321a85c4f6c95bf0e687574454b71ede9bec1c9cf17f37c578c888a94 guix-build-f51237d94d98/output/x86_64-w64-mingw32/bitcoin-f51237d94d98-win-unsigned.tar.gz a543895a00f8ffb3ba50ca68396d52ad5a18dd8efe38730e0049dd70d283a092 guix-build-f51237d94d98/output/x86_64-w64-mingw32/bitcoin-f51237d94d98-win64-debug.zip aec050d03c65268a986148500f7341cceb8c5f85287e0e3cde8933ce4b4dee32 guix-build-f51237d94d98/output/x86_64-w64-mingw32/bitcoin-f51237d94d98-win64-setup-unsigned.exe 57ba33ed6ee8d3a885e342471359301473e83037d5442895beb686921a4c50e9 guix-build-f51237d94d98/output/x86_64-w64-mingw32/bitcoin-f51237d94d98-win64.zip ``` Gitian builds: ```bash # macOS: 2f066e852bdd30ac46e5ecdf7619d19d408035c318a3edf0f1893ec2e25efb69 bitcoin-41a1b3d1b130-osx-unsigned.dmg 8cf8ac4d21740f490262453c330b5f4a5c5b8139dfc1b322efefce3f3b93d1b2 bitcoin-41a1b3d1b130-osx-unsigned.tar.gz cf1b84efdd9d2588a1ce9513580fb56b38bfafe60e18f8adbeedf03521c6c2b2 bitcoin-41a1b3d1b130-osx64.tar.gz 14995244b0bb3e80e7b79975c9c70fdfb3ee3c04fda3efd5358ce1c4efa3a312 src/bitcoin-41a1b3d1b130.tar.gz 93881069d5e1dc385c08895a7b035a94eb010325afc2776c99b6aafa21096eb8 bitcoin-core-osx-22-res.yml # Windows: 4d56dd7713121684b7eaa448679c65df2fd0aa5319bf8d12fb6cfa9f0b005cf7 bitcoin-f51237d94d98-win-unsigned.tar.gz 4558f4173152b084bcba25aa1a53c605208a70fe20392141b63cefb476528c85 bitcoin-f51237d94d98-win64-debug.zip b63feaca010e86d514cfe38d716e3c8a8b8058e4f969b868aaaeb8a8a3d3dc81 bitcoin-f51237d94d98-win64-setup-unsigned.exe de7d8586cc91ba391fe911853a99d9fd15fc6f9a60f9b91a0447940173aac67a bitcoin-f51237d94d98-win64.zip 4185adebc6a0abe7241a3cd409a6ab7be031c26f1c4245e30bb5f87eef0925d2 src/bitcoin-f51237d94d98.tar.gz 45efaca35b5fad0a04dfd06e44f7c00b990aa91c7bf2faea57e020d3491a6cf0 bitcoin-core-win-22-res.yml # Linux: 055d646c5f8cf4708008374546176012ff758566a2645a3a01e1a33eab1002fe bitcoin-f51237d94d98-aarch64-linux-gnu-debug.tar.gz bfc8b0efc36b0474c88546b12d2723c04b4dc629ae311082025c7e0b8f0d1aa9 bitcoin-f51237d94d98-aarch64-linux-gnu.tar.gz 9dfaa5acfffadad8942b32996458013a155d12ed07be76601f232233627b5cb9 bitcoin-f51237d94d98-arm-linux-gnueabihf-debug.tar.gz 54eb57905ff8513b9f628707b61aa4659c362fb2f6d17e0ee240b4da3674907d bitcoin-f51237d94d98-arm-linux-gnueabihf.tar.gz ad98d876616eff578ad8cfd17dfbabe48ed14200823579687d66694bae3d2fe3 bitcoin-f51237d94d98-powerpc64-linux-gnu-debug.tar.gz fe1b421dd1cb6e04d5dc5d341459dc15fa6e15b80906e5d8e0405cf43495e0f7 bitcoin-f51237d94d98-powerpc64-linux-gnu.tar.gz 9001d95cc7d2722d9d7dd83d9da8e5adf575fddf91b615b76b9bcfece30ecf6f bitcoin-f51237d94d98-powerpc64le-linux-gnu-debug.tar.gz 9e0650ad2aba70c0fd1608a077e95f335dc1bb4a79eab9b0b56ac87427a4fd4f bitcoin-f51237d94d98-powerpc64le-linux-gnu.tar.gz fbfde0134944d3dbd32991455b0a8abdd334853ab8a4c1a1a4c060d9de071c50 bitcoin-f51237d94d98-riscv64-linux-gnu-debug.tar.gz 2fa2cfddce98c44c65305326fc623a7f065129208337503d813a08d51580cb8a bitcoin-f51237d94d98-riscv64-linux-gnu.tar.gz b2d6caeee0e3c350a43165c39876ebed8e588958007af0d06996e341c7060683 bitcoin-f51237d94d98-x86_64-linux-gnu-debug.tar.gz bfdb827e75d43d61462513c9a843620b93c9160d9d246cad13278baaa07f64ea bitcoin-f51237d94d98-x86_64-linux-gnu.tar.gz 4185adebc6a0abe7241a3cd409a6ab7be031c26f1c4245e30bb5f87eef0925d2 src/bitcoin-f51237d94d98.tar.gz 34820a093916fa35b0fd98806a50092f46b20271af7422f43e2a4223ef6f9bb7 bitcoin-core-linux-22-res.yml ``` ACKs for top commit: laanwj: re-ACK 7fc5e86 Tree-SHA512: 0c30838413448ecfcf55e6273f607fdb01cb1acafa1d2762afad59360fca7d8efa78ec55064f50cba56cb2c9e98741e13665cba8e9b4b8e5b62b8a53f9bf8990
2 parents 00a9b06 + 7fc5e86 commit b7c2625

File tree

9 files changed

+90
-135
lines changed

9 files changed

+90
-135
lines changed

ci/test/00_setup_env_mac_host.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
export LC_ALL=C.UTF-8
88

99
export HOST=x86_64-apple-darwin18
10-
export PIP_PACKAGES="zmq"
10+
export PIP_PACKAGES="zmq lief"
1111
export GOAL="install"
1212
export BITCOIN_CONFIG="--with-gui --enable-reduce-exports --enable-external-signer"
1313
export CI_OS_NAME="macos"
1414
export NO_DEPENDS=1
1515
export OSX_SDK=""
1616
export CCACHE_SIZE=300M
17-
1817
export RUN_SECURITY_TESTS="true"

ci/test/00_setup_env_native_multiprocess.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ export LC_ALL=C.UTF-8
88

99
export CONTAINER_NAME=ci_native_multiprocess
1010
export DOCKER_NAME_TAG=ubuntu:20.04
11-
export PACKAGES="cmake python3 llvm clang"
11+
export PACKAGES="cmake python3 python3-pip llvm clang"
1212
export DEP_OPTS="DEBUG=1 MULTIPROCESS=1"
1313
export GOAL="install"
1414
export BITCOIN_CONFIG="--enable-external-signer --enable-debug CC=clang CXX=clang++" # Use clang to avoid OOM
1515
export TEST_RUNNER_ENV="BITCOIND=bitcoin-node"
1616
export RUN_SECURITY_TESTS="true"
17+
export PIP_PACKAGES="lief"

ci/test/04_install.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ if [[ $DOCKER_NAME_TAG == centos* ]]; then
6767
elif [ "$CI_USE_APT_INSTALL" != "no" ]; then
6868
${CI_RETRY_EXE} DOCKER_EXEC apt-get update
6969
${CI_RETRY_EXE} DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -y $PACKAGES $DOCKER_PACKAGES
70+
if [ -n "$PIP_PACKAGES" ]; then
71+
${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES
72+
fi
7073
fi
7174

7275
if [ "$CI_OS_NAME" == "macos" ]; then

contrib/devtools/security-check.py

Lines changed: 36 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,13 @@
66
Perform basic security checks on a series of executables.
77
Exit status will be 0 if successful, and the program will be silent.
88
Otherwise the exit status will be 1 and it will log which executables failed which checks.
9-
Needs `objdump` (for PE) and `otool` (for MACHO).
109
'''
11-
import subprocess
1210
import sys
13-
import os
1411
from typing import List, Optional
1512

13+
import lief
1614
import pixie
1715

18-
OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
19-
OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool')
20-
21-
def run_command(command) -> str:
22-
p = subprocess.run(command, stdout=subprocess.PIPE, check=True, universal_newlines=True)
23-
return p.stdout
24-
2516
def check_ELF_PIE(executable) -> bool:
2617
'''
2718
Check for position independent executable (PIE), allowing for address space randomization.
@@ -143,112 +134,59 @@ def check_ELF_separate_code(executable):
143134
return False
144135
return True
145136

146-
def get_PE_dll_characteristics(executable) -> int:
147-
'''Get PE DllCharacteristics bits'''
148-
stdout = run_command([OBJDUMP_CMD, '-x', executable])
149-
150-
bits = 0
151-
for line in stdout.splitlines():
152-
tokens = line.split()
153-
if len(tokens)>=2 and tokens[0] == 'DllCharacteristics':
154-
bits = int(tokens[1],16)
155-
return bits
156-
157-
IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020
158-
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040
159-
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100
160-
161137
def check_PE_DYNAMIC_BASE(executable) -> bool:
162138
'''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
163-
bits = get_PE_dll_characteristics(executable)
164-
return (bits & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE) == IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
139+
binary = lief.parse(executable)
140+
return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists
165141

166142
# Must support high-entropy 64-bit address space layout randomization
167143
# in addition to DYNAMIC_BASE to have secure ASLR.
168144
def check_PE_HIGH_ENTROPY_VA(executable) -> bool:
169145
'''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR'''
170-
bits = get_PE_dll_characteristics(executable)
171-
return (bits & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA) == IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
146+
binary = lief.parse(executable)
147+
return lief.PE.DLL_CHARACTERISTICS.HIGH_ENTROPY_VA in binary.optional_header.dll_characteristics_lists
172148

173149
def check_PE_RELOC_SECTION(executable) -> bool:
174150
'''Check for a reloc section. This is required for functional ASLR.'''
175-
stdout = run_command([OBJDUMP_CMD, '-h', executable])
176-
177-
for line in stdout.splitlines():
178-
if '.reloc' in line:
179-
return True
180-
return False
181-
182-
def check_PE_NX(executable) -> bool:
183-
'''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)'''
184-
bits = get_PE_dll_characteristics(executable)
185-
return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
186-
187-
def get_MACHO_executable_flags(executable) -> List[str]:
188-
stdout = run_command([OTOOL_CMD, '-vh', executable])
189-
190-
flags: List[str] = []
191-
for line in stdout.splitlines():
192-
tokens = line.split()
193-
# filter first two header lines
194-
if 'magic' in tokens or 'Mach' in tokens:
195-
continue
196-
# filter ncmds and sizeofcmds values
197-
flags += [t for t in tokens if not t.isdigit()]
198-
return flags
199-
200-
def check_MACHO_PIE(executable) -> bool:
201-
'''
202-
Check for position independent executable (PIE), allowing for address space randomization.
203-
'''
204-
flags = get_MACHO_executable_flags(executable)
205-
if 'PIE' in flags:
206-
return True
207-
return False
151+
binary = lief.parse(executable)
152+
return binary.has_relocations
208153

209154
def check_MACHO_NOUNDEFS(executable) -> bool:
210155
'''
211156
Check for no undefined references.
212157
'''
213-
flags = get_MACHO_executable_flags(executable)
214-
if 'NOUNDEFS' in flags:
215-
return True
216-
return False
217-
218-
def check_MACHO_NX(executable) -> bool:
219-
'''
220-
Check for no stack execution
221-
'''
222-
flags = get_MACHO_executable_flags(executable)
223-
if 'ALLOW_STACK_EXECUTION' in flags:
224-
return False
225-
return True
158+
binary = lief.parse(executable)
159+
return binary.header.has(lief.MachO.HEADER_FLAGS.NOUNDEFS)
226160

227161
def check_MACHO_LAZY_BINDINGS(executable) -> bool:
228162
'''
229163
Check for no lazy bindings.
230164
We don't use or check for MH_BINDATLOAD. See #18295.
231165
'''
232-
stdout = run_command([OTOOL_CMD, '-l', executable])
233-
234-
for line in stdout.splitlines():
235-
tokens = line.split()
236-
if 'lazy_bind_off' in tokens or 'lazy_bind_size' in tokens:
237-
if tokens[1] != '0':
238-
return False
239-
return True
166+
binary = lief.parse(executable)
167+
return binary.dyld_info.lazy_bind == (0,0)
240168

241169
def check_MACHO_Canary(executable) -> bool:
242170
'''
243171
Check for use of stack canary
244172
'''
245-
stdout = run_command([OTOOL_CMD, '-Iv', executable])
173+
binary = lief.parse(executable)
174+
return binary.has_symbol('___stack_chk_fail')
246175

247-
ok = False
248-
for line in stdout.splitlines():
249-
if '___stack_chk_fail' in line:
250-
ok = True
251-
return ok
176+
def check_PIE(executable) -> bool:
177+
'''
178+
Check for position independent executable (PIE),
179+
allowing for address space randomization.
180+
'''
181+
binary = lief.parse(executable)
182+
return binary.is_pie
183+
184+
def check_NX(executable) -> bool:
185+
'''
186+
Check for no stack execution
187+
'''
188+
binary = lief.parse(executable)
189+
return binary.has_nx
252190

253191
CHECKS = {
254192
'ELF': [
@@ -259,15 +197,16 @@ def check_MACHO_Canary(executable) -> bool:
259197
('separate_code', check_ELF_separate_code),
260198
],
261199
'PE': [
200+
('PIE', check_PIE),
262201
('DYNAMIC_BASE', check_PE_DYNAMIC_BASE),
263202
('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA),
264-
('NX', check_PE_NX),
203+
('NX', check_NX),
265204
('RELOC_SECTION', check_PE_RELOC_SECTION)
266205
],
267206
'MACHO': [
268-
('PIE', check_MACHO_PIE),
207+
('PIE', check_PIE),
269208
('NOUNDEFS', check_MACHO_NOUNDEFS),
270-
('NX', check_MACHO_NX),
209+
('NX', check_NX),
271210
('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS),
272211
('Canary', check_MACHO_Canary)
273212
]
@@ -285,24 +224,24 @@ def identify_executable(executable) -> Optional[str]:
285224
return None
286225

287226
if __name__ == '__main__':
288-
retval = 0
227+
retval: int = 0
289228
for filename in sys.argv[1:]:
290229
try:
291230
etype = identify_executable(filename)
292231
if etype is None:
293-
print('%s: unknown format' % filename)
232+
print(f'{filename}: unknown format')
294233
retval = 1
295234
continue
296235

297-
failed = []
236+
failed: List[str] = []
298237
for (name, func) in CHECKS[etype]:
299238
if not func(filename):
300239
failed.append(name)
301240
if failed:
302-
print('%s: failed %s' % (filename, ' '.join(failed)))
241+
print(f'{filename}: failed {" ".join(failed)}')
303242
retval = 1
304243
except IOError:
305-
print('%s: cannot open' % filename)
244+
print(f'{filename}: cannot open')
306245
retval = 1
307246
sys.exit(retval)
308247

contrib/devtools/symbol-check.py

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import os
1616
from typing import List, Optional
1717

18+
import lief
1819
import pixie
1920

2021
# Debian 8 (Jessie) EOL: 2020. https://wiki.debian.org/DebianReleases#Production_Releases
@@ -52,8 +53,6 @@
5253
'environ', '_environ', '__environ',
5354
}
5455
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
55-
OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
56-
OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool')
5756

5857
# Allowed NEEDED libraries
5958
ELF_ALLOWED_LIBRARIES = {
@@ -203,44 +202,22 @@ def check_ELF_libraries(filename) -> bool:
203202
ok = False
204203
return ok
205204

206-
def macho_read_libraries(filename) -> List[str]:
207-
p = subprocess.Popen([OTOOL_CMD, '-L', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
208-
(stdout, stderr) = p.communicate()
209-
if p.returncode:
210-
raise IOError('Error opening file')
211-
libraries = []
212-
for line in stdout.splitlines():
213-
tokens = line.split()
214-
if len(tokens) == 1: # skip executable name
215-
continue
216-
libraries.append(tokens[0].split('/')[-1])
217-
return libraries
218-
219205
def check_MACHO_libraries(filename) -> bool:
220206
ok: bool = True
221-
for dylib in macho_read_libraries(filename):
222-
if dylib not in MACHO_ALLOWED_LIBRARIES:
223-
print('{} is not in ALLOWED_LIBRARIES!'.format(dylib))
207+
binary = lief.parse(filename)
208+
for dylib in binary.libraries:
209+
split = dylib.name.split('/')
210+
if split[-1] not in MACHO_ALLOWED_LIBRARIES:
211+
print(f'{split[-1]} is not in ALLOWED_LIBRARIES!')
224212
ok = False
225213
return ok
226214

227-
def pe_read_libraries(filename) -> List[str]:
228-
p = subprocess.Popen([OBJDUMP_CMD, '-x', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
229-
(stdout, stderr) = p.communicate()
230-
if p.returncode:
231-
raise IOError('Error opening file')
232-
libraries = []
233-
for line in stdout.splitlines():
234-
if 'DLL Name:' in line:
235-
tokens = line.split(': ')
236-
libraries.append(tokens[1])
237-
return libraries
238-
239215
def check_PE_libraries(filename) -> bool:
240216
ok: bool = True
241-
for dylib in pe_read_libraries(filename):
217+
binary = lief.parse(filename)
218+
for dylib in binary.libraries:
242219
if dylib not in PE_ALLOWED_LIBRARIES:
243-
print('{} is not in ALLOWED_LIBRARIES!'.format(dylib))
220+
print(f'{dylib} is not in ALLOWED_LIBRARIES!')
244221
ok = False
245222
return ok
246223

@@ -275,7 +252,7 @@ def identify_executable(executable) -> Optional[str]:
275252
try:
276253
etype = identify_executable(filename)
277254
if etype is None:
278-
print('{}: unknown format'.format(filename))
255+
print(f'{filename}: unknown format')
279256
retval = 1
280257
continue
281258

@@ -284,9 +261,9 @@ def identify_executable(executable) -> Optional[str]:
284261
if not func(filename):
285262
failed.append(name)
286263
if failed:
287-
print('{}: failed {}'.format(filename, ' '.join(failed)))
264+
print(f'{filename}: failed {" ".join(failed)}')
288265
retval = 1
289266
except IOError:
290-
print('{}: cannot open'.format(filename))
267+
print(f'{filename}: cannot open')
291268
retval = 1
292269
sys.exit(retval)

contrib/gitian-descriptors/gitian-linux.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ packages:
2323
- "patch"
2424
- "pkg-config"
2525
- "python3"
26+
- "python3-pip"
2627
# Cross compilation HOSTS:
2728
# - arm-linux-gnueabihf
2829
- "binutils-arm-linux-gnueabihf"
@@ -99,6 +100,8 @@ script: |
99100
done
100101
}
101102
103+
pip3 install lief==0.11.4
104+
102105
# Faketime for depends so intermediate results are comparable
103106
export PATH_orig=${PATH}
104107
create_global_faketime_wrappers "2000-01-01 12:00:00"

contrib/gitian-descriptors/gitian-osx.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ packages:
2323
- "imagemagick"
2424
- "libz-dev"
2525
- "python3"
26+
- "python3-pip"
2627
- "python3-setuptools"
2728
- "fonts-tuffy"
2829
- "xorriso"
@@ -78,6 +79,8 @@ script: |
7879
done
7980
}
8081
82+
pip3 install lief==0.11.4
83+
8184
# Faketime for depends so intermediate results are comparable
8285
export PATH_orig=${PATH}
8386
create_global_faketime_wrappers "2000-01-01 12:00:00"

contrib/gitian-descriptors/gitian-win.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ packages:
2222
- "zip"
2323
- "ca-certificates"
2424
- "python3"
25+
- "python3-pip"
2526
remotes:
2627
- "url": "https://github.com/bitcoin/bitcoin.git"
2728
"dir": "bitcoin"
@@ -86,6 +87,8 @@ script: |
8687
done
8788
}
8889
90+
pip3 install lief==0.11.4
91+
8992
# Faketime for depends so intermediate results are comparable
9093
export PATH_orig=${PATH}
9194
create_global_faketime_wrappers "2000-01-01 12:00:00"

0 commit comments

Comments
 (0)