-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.py
119 lines (86 loc) · 3.43 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env python3
import json
import os
import re
import shlex
import subprocess
import urllib.request
import colorama
import elftools.elf.elffile
def abort(message):
print(
f"{colorama.Style.BRIGHT}{colorama.Fore.RED}{message}{colorama.Style.RESET_ALL}"
)
raise SystemExit
def make_bright(text):
return f"{colorama.Style.BRIGHT}{text}{colorama.Style.RESET_ALL}"
def make_warning(text):
return f"{colorama.Fore.YELLOW}{text}{colorama.Style.RESET_ALL}"
def query_yes_no(question):
return input("{} (y/[N]) ".format(question)).lower() in ("y", "yes")
def extract_buildID(filepath):
out = subprocess.check_output(shlex.split("file {}".format(shlex.quote(filepath))))
try:
buildID = (
re.search(br"BuildID\[sha1\]\=(?P<buildID>[a-z0-9]+)", out)
.group("buildID")
.decode("ascii")
)
return buildID
except AttributeError:
return None
def get_libc_dbg_proper_filename(libc_filepath):
with open(libc_filepath, "rb") as f:
elf = elftools.elf.elffile.ELFFile(f)
data = elf.get_section_by_name(".gnu_debuglink").data()
libc_dbg_filename = data[: data.index(b"\0")].decode("ascii")
return libc_dbg_filename
def retrieve(url, dirpath=None):
if not dirpath:
with urllib.request.urlopen(url) as u:
return u.read()
else:
filepath, _ = urllib.request.urlretrieve(
url, filename=os.path.join(dirpath, os.path.basename(url))
)
return filepath
# ############################################################################ #
def dump(libc):
libc["realpath"] = os.path.realpath(
os.path.join(get_libcs_dirpath(), libc["relpath"])
)
print(json.dumps(libc, sort_keys=True, indent=4))
# ############################################################################ #
def get_libcs_dirpath():
# bowkin assumes either the directory `libcs` or a symlink to it can be found
# in the same directory of this script
libcs_dirpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "libcs")
return os.path.realpath(libcs_dirpath)
def get_libcs_db_filepath():
libcs_db_filepath = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "libcs.db"
)
return os.path.realpath(libcs_db_filepath)
# ############################################################################ #
def match(package_filepath):
package_filename = os.path.basename(package_filepath)
# Examples of supported packages:
# - libc6_2.23-0ubuntu10_amd64.deb
# - libc6_2.24-11+deb9u3_amd64.deb
# - libc6_2.28-8_i386.deb
# - glibc-2.23-3-x86_64.pkg.tar.xz
for pattern in (
r"libc6(?:-dbg)?_(?P<version>\d.\d+)-(?P<patch>\d+ubuntu.+?)_(?P<architecture>i386|amd64|armel|armhf|arm64).deb",
r"libc6(?:-dbg)?_(?P<version>\d.\d+)-(?P<patch>\d+\+deb.+?)_(?P<architecture>i386|amd64|armel|armhf|arm64).deb",
r"libc6(?:-dbg)?_(?P<version>\d.\d+)-(?P<patch>\d+)_(?P<architecture>i386|amd64|armel|armhf|arm64).deb",
r"glibc-(?P<version>\d.\d+)-(?P<patch>\d+)-(?P<architecture>i686|x86_64).pkg.tar.xz",
):
match = re.match(pattern, package_filename)
if match:
return match
else:
return None
def findall(pattern, url):
return re.findall(pattern, retrieve(url).decode("latin-1"))
def search(pattern, url):
return re.search(pattern, retrieve(url).decode("latin-1"))