Skip to content

Commit

Permalink
Add local libc database provider for libcdb (#2356)
Browse files Browse the repository at this point in the history
* Add local libc database provider for libcdb

* Remove unnecessary assert

* Add docstring for local_libcdb

* Suppress warning output while `context.libdb` sets default

* Testing the local system's libc first

* Set falsely `context.lcoal_libcdb` to turn off local libc-database integration

* Fix docstring

* Make path check in validator

* Fix doctests

* Add CHANGELOG
  • Loading branch information
the-soloist committed Mar 1, 2024
1 parent 000c31c commit 3b4b261
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ The table below shows which release corresponds to each branch, and what date th

## 4.14.0 (`dev`)

- [#2356][2356] Add local libc database provider for libcdb

[2356]: https://github.com/Gallopsled/pwntools/pull/2356

## 4.13.0 (`beta`)

Expand Down
6 changes: 6 additions & 0 deletions pwnlib/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ def STDERR(v):
"""Sends logging to ``stderr`` by default, instead of ``stdout``"""
context.log_console = sys.stderr

def LOCAL_LIBCDB(v):
"""Sets path to local libc-database via ``context.local_libcdb``, e.g.
``LOCAL_LIBCDB='/path/to/libc-databse'``"""
context.local_libcdb = v

hooks = {
'LOG_LEVEL': LOG_LEVEL,
'LOG_FILE': LOG_FILE,
Expand All @@ -170,6 +175,7 @@ def STDERR(v):
'NOASLR': NOASLR,
'NOPTRACE': NOPTRACE,
'STDERR': STDERR,
'LOCAL_LIBCDB': LOCAL_LIBCDB,
}

def initialize():
Expand Down
27 changes: 27 additions & 0 deletions pwnlib/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ class ContextType(object):
'endian': 'little',
'gdbinit': "",
'kernel': None,
'local_libcdb': "/var/lib/libc-database",
'log_level': logging.INFO,
'log_file': _devnull(),
'log_console': sys.stdout,
Expand Down Expand Up @@ -1071,6 +1072,32 @@ def log_console(self, stream):
stream = open(stream, 'wt')
return stream

@_validator
def local_libcdb(self, path):
"""
Sets path to local libc-database, get more information for libc-database:
https://github.com/niklasb/libc-database
Works in :attr:`pwnlib.libcdb` when searching by local database provider.
The default value is ``/var/lib/libc-database``.
Sets `context.local_libcdb` to empty string or `None` will turn off local libc-database integration.
Examples:
>>> context.local_libcdb = pwnlib.data.elf.path
>>> context.local_libcdb = 'foobar'
Traceback (most recent call last):
...
AttributeError: 'foobar' does not exist, please download libc-database first
"""

if not os.path.isdir(path):
raise AttributeError("'%s' does not exist, please download libc-database first" % path)

return path

@property
def mask(self):
return (1 << self.bits) - 1
Expand Down
19 changes: 18 additions & 1 deletion pwnlib/libcdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from pwnlib.context import context
from pwnlib.elf import ELF
from pwnlib.filesystem.path import Path
from pwnlib.log import getLogger
from pwnlib.tubes.process import process
from pwnlib.util.fiddling import enhex
Expand Down Expand Up @@ -126,7 +127,23 @@ def provider_local_system(hex_encoded_id, hash_type):
return local_libc.data
return None

PROVIDERS = [provider_local_system, provider_libcdb, provider_libc_rip]
# Offline search https://github.com/niklasb/libc-database for hash type
def provider_local_database(hex_encoded_id, hash_type):
if not context.local_libcdb:
return None

localdb = Path(context.local_libcdb)
if not localdb.is_dir():
return None

log.debug("Searching local libc database, %s: %s", hash_type, hex_encoded_id)
for libc_path in localdb.rglob("*.so"):
if hex_encoded_id == HASHES[hash_type](libc_path):
return read(libc_path)

return None

PROVIDERS = [provider_local_system, provider_local_database, provider_libcdb, provider_libc_rip]

def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
assert hash_type in HASHES, hash_type
Expand Down

0 comments on commit 3b4b261

Please sign in to comment.