Skip to content

Commit 4ac98cd

Browse files
authored
Add offline parameter for libcdb.search_by_hash series function (#2360)
* Add offline parameter * Add CHANGELOG * Rename `offline` to `offline_only`
1 parent 75cc3c3 commit 4ac98cd

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ The table below shows which release corresponds to each branch, and what date th
7171

7272
## 4.14.0 (`dev`)
7373

74+
- [#2360][2360] Add offline parameter for `search_by_hash` series function
7475
- [#2356][2356] Add local libc database provider for libcdb
7576
- [#2374][2374] libcdb.unstrip_libc: debug symbols are fetched only if not present
7677

78+
[2360]: https://github.com/Gallopsled/pwntools/pull/2360
7779
[2356]: https://github.com/Gallopsled/pwntools/pull/2356
7880
[2374]: https://github.com/Gallopsled/pwntools/pull/2374
7981

pwnlib/libcdb.py

+34-12
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,12 @@ def provider_local_database(hex_encoded_id, hash_type):
143143

144144
return None
145145

146-
PROVIDERS = [provider_local_system, provider_local_database, provider_libcdb, provider_libc_rip]
146+
PROVIDERS = {
147+
"offline": [provider_local_system, provider_local_database],
148+
"online": [provider_libcdb, provider_libc_rip]
149+
}
147150

148-
def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
151+
def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True, offline_only=False):
149152
assert hash_type in HASHES, hash_type
150153

151154
# Ensure that the libcdb cache directory exists
@@ -157,8 +160,12 @@ def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
157160
if cache is None:
158161
return None
159162

163+
providers = PROVIDERS["offline"]
164+
if not offline_only:
165+
providers += PROVIDERS["online"]
166+
160167
# Run through all available libc database providers to see if we have a match.
161-
for provider in PROVIDERS:
168+
for provider in providers:
162169
data = provider(hex_encoded_id, hash_type)
163170
if data and data.startswith(b'\x7FELF'):
164171
break
@@ -607,7 +614,7 @@ def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as
607614
selected_libc = _handle_multiple_matching_libcs(matching_libcs)
608615
return search_by_build_id(selected_libc['buildid'], unstrip=unstrip)
609616

610-
def search_by_build_id(hex_encoded_id, unstrip=True):
617+
def search_by_build_id(hex_encoded_id, unstrip=True, offline_only=False):
611618
"""
612619
Given a hex-encoded Build ID, attempt to download a matching libc from libcdb.
613620
@@ -616,6 +623,10 @@ def search_by_build_id(hex_encoded_id, unstrip=True):
616623
Hex-encoded Build ID (e.g. 'ABCDEF...') of the library
617624
unstrip(bool):
618625
Try to fetch debug info for the libc and apply it to the downloaded file.
626+
offline_only(bool):
627+
Both offline and online providers are used by default. When pass
628+
`offline_only=True`, libcdb enable an exclusive offline search mode,
629+
which will disable online providers.
619630
620631
Returns:
621632
Path to the downloaded library on disk, or :const:`None`.
@@ -631,9 +642,9 @@ def search_by_build_id(hex_encoded_id, unstrip=True):
631642
>>> hex(ELF(filename).symbols.read)
632643
'0xeef40'
633644
"""
634-
return search_by_hash(hex_encoded_id, 'build_id', unstrip)
645+
return search_by_hash(hex_encoded_id, 'build_id', unstrip, offline_only)
635646

636-
def search_by_md5(hex_encoded_id, unstrip=True):
647+
def search_by_md5(hex_encoded_id, unstrip=True, offline_only=False):
637648
"""
638649
Given a hex-encoded md5sum, attempt to download a matching libc from libcdb.
639650
@@ -642,6 +653,10 @@ def search_by_md5(hex_encoded_id, unstrip=True):
642653
Hex-encoded md5sum (e.g. 'ABCDEF...') of the library
643654
unstrip(bool):
644655
Try to fetch debug info for the libc and apply it to the downloaded file.
656+
offline_only(bool):
657+
Both offline and online providers are used by default. When pass
658+
`offline_only=True`, libcdb enable an exclusive offline search mode,
659+
which will disable online providers.
645660
646661
Returns:
647662
Path to the downloaded library on disk, or :const:`None`.
@@ -657,9 +672,9 @@ def search_by_md5(hex_encoded_id, unstrip=True):
657672
>>> hex(ELF(filename).symbols.read)
658673
'0xeef40'
659674
"""
660-
return search_by_hash(hex_encoded_id, 'md5', unstrip)
675+
return search_by_hash(hex_encoded_id, 'md5', unstrip, offline_only)
661676

662-
def search_by_sha1(hex_encoded_id, unstrip=True):
677+
def search_by_sha1(hex_encoded_id, unstrip=True, offline_only=False):
663678
"""
664679
Given a hex-encoded sha1, attempt to download a matching libc from libcdb.
665680
@@ -668,6 +683,10 @@ def search_by_sha1(hex_encoded_id, unstrip=True):
668683
Hex-encoded sha1sum (e.g. 'ABCDEF...') of the library
669684
unstrip(bool):
670685
Try to fetch debug info for the libc and apply it to the downloaded file.
686+
offline_only(bool):
687+
Both offline and online providers are used by default. When pass
688+
`offline_only=True`, libcdb enable an exclusive offline search mode,
689+
which will disable online providers.
671690
672691
Returns:
673692
Path to the downloaded library on disk, or :const:`None`.
@@ -683,10 +702,9 @@ def search_by_sha1(hex_encoded_id, unstrip=True):
683702
>>> hex(ELF(filename).symbols.read)
684703
'0xeef40'
685704
"""
686-
return search_by_hash(hex_encoded_id, 'sha1', unstrip)
687-
705+
return search_by_hash(hex_encoded_id, 'sha1', unstrip, offline_only)
688706

689-
def search_by_sha256(hex_encoded_id, unstrip=True):
707+
def search_by_sha256(hex_encoded_id, unstrip=True, offline_only=False):
690708
"""
691709
Given a hex-encoded sha256, attempt to download a matching libc from libcdb.
692710
@@ -695,6 +713,10 @@ def search_by_sha256(hex_encoded_id, unstrip=True):
695713
Hex-encoded sha256sum (e.g. 'ABCDEF...') of the library
696714
unstrip(bool):
697715
Try to fetch debug info for the libc and apply it to the downloaded file.
716+
offline_only(bool):
717+
Both offline and online providers are used by default. When pass
718+
`offline_only=True`, libcdb enable an exclusive offline search mode,
719+
which will disable online providers.
698720
699721
Returns:
700722
Path to the downloaded library on disk, or :const:`None`.
@@ -710,7 +732,7 @@ def search_by_sha256(hex_encoded_id, unstrip=True):
710732
>>> hex(ELF(filename).symbols.read)
711733
'0xeef40'
712734
"""
713-
return search_by_hash(hex_encoded_id, 'sha256', unstrip)
735+
return search_by_hash(hex_encoded_id, 'sha256', unstrip, offline_only)
714736

715737

716738

0 commit comments

Comments
 (0)