Skip to content

Commit d5a6c19

Browse files
authored
Merge pull request #88 from Wenzel/ci_build_windows_38
ci: build_windows based on Python 3.7
2 parents 65a8efc + 951beb3 commit d5a6c19

File tree

7 files changed

+60
-21
lines changed

7 files changed

+60
-21
lines changed

.github/workflows/ci.yml

+16-12
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@v1
1919

20-
- name: Set up Python 3.6 🐍
20+
- name: Set up Python 3.7 🐍
2121
uses: actions/setup-python@v1
2222
with:
23-
python-version: '3.6'
23+
python-version: '3.7'
2424

2525
- name: Install Nox
2626
run: python -m pip install nox==2020.8.22
@@ -35,10 +35,10 @@ jobs:
3535
steps:
3636
- uses: actions/checkout@v1
3737

38-
- name: Set up Python 3.6 🐍
38+
- name: Set up Python 3.7 🐍
3939
uses: actions/setup-python@v1
4040
with:
41-
python-version: '3.6'
41+
python-version: '3.7'
4242

4343
- name: Install Nox
4444
run: python -m pip install nox==2020.8.22
@@ -53,10 +53,10 @@ jobs:
5353
steps:
5454
- uses: actions/checkout@v1
5555

56-
- name: Set up Python 3.6 🐍
56+
- name: Set up Python 3.7 🐍
5757
uses: actions/setup-python@v1
5858
with:
59-
python-version: '3.6'
59+
python-version: '3.7'
6060

6161
- name: Build 🔨
6262
run: |
@@ -71,10 +71,10 @@ jobs:
7171
steps:
7272
- uses: actions/checkout@v1
7373

74-
- name: Set up Python 3.9 🐍
74+
- name: Set up Python 3.7 🐍
7575
uses: actions/setup-python@v1
7676
with:
77-
python-version: '3.9'
77+
python-version: '3.7'
7878

7979
- name: Install PyInstaller
8080
run: python -m pip install pyinstaller==4.0
@@ -93,17 +93,21 @@ jobs:
9393
name: checksec.exe
9494
path: dist/checksec.exe
9595

96+
# TODO: can't test rich output: UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-78: character maps to <undefined>
97+
- name: Smoke test
98+
run: ./dist/checksec.exe C:\Windows --json
99+
96100
test:
97101
needs: build
98102
runs-on: ubuntu-latest
99103

100104
steps:
101105
- uses: actions/checkout@v1
102106

103-
- name: Set up Python 3.6 🐍
107+
- name: Set up Python 3.7 🐍
104108
uses: actions/setup-python@v1
105109
with:
106-
python-version: '3.6'
110+
python-version: '3.7'
107111

108112
- name: Install Nox
109113
run: python -m pip install nox==2020.8.22
@@ -177,10 +181,10 @@ jobs:
177181
steps:
178182
- uses: actions/checkout@v1
179183

180-
- name: Set up Python 3.6 🐍
184+
- name: Set up Python 3.7 🐍
181185
uses: actions/setup-python@v1
182186
with:
183-
python-version: '3.6'
187+
python-version: '3.7'
184188

185189
- name: Build 🔨
186190
run: |

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,12 @@ Check `--help` for more options (_JSON output_, _recursive walk_, _workers count
116116

117117
| | checksec.py | checksec.sh |
118118
|----------------------------|:-----------:|:-----------:|
119-
| Distributed workload |||
119+
| Cross-Platform support |||
120+
| Distributed workload |||
120121
| Scan file |||
121122
| Scan directory |||
122123
| Scan directory recursively |||
124+
| Specify libc path |||
123125
| Scan process |||
124126
| Scan process libs |||
125127
| Scan kernel config |||
@@ -144,6 +146,7 @@ Check `--help` for more options (_JSON output_, _recursive walk_, _workers count
144146

145147
| | checksec.py | winchecksec |
146148
|-----------------------------|:-----------:|:-----------:|
149+
| Cross-Platform support |||
147150
| Distributed workload |||
148151
| Scan file |||
149152
| Scan directory |||

checksec/__main__.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import os
1717
from concurrent.futures import ProcessPoolExecutor, as_completed
1818
from pathlib import Path
19-
from typing import Iterator, List, Union
19+
from typing import Iterator, List, Optional, Union
2020

2121
from docopt import docopt
2222

@@ -52,6 +52,18 @@ def checksec_file(filepath: Path) -> Union["ELFChecksecData", "PEChecksecData"]:
5252
return binary.checksec_state
5353

5454

55+
def worker_initializer(libc_path: Optional[Path] = None):
56+
"""Routine to initialize some context in a worker process"""
57+
# this function is used to set global object in the worker's process context
58+
# multiprocessing has different behaviors on Windows and Linux
59+
# on Windows, the global object __LIBC_OBJ in elf.py is found to be uninitialized,
60+
# even after we explicitely initialized it in the main function.
61+
#
62+
# this function ensures that the object is initialized with the libc_path passed as cmdline argument
63+
logging.debug("Worker %s: initializer", os.getpid())
64+
get_libc(libc_path)
65+
66+
5567
def main(args):
5668
filepath_list = [Path(entry) for entry in args["<file/directory>"]]
5769
debug = args["--debug"]
@@ -93,7 +105,9 @@ def main(args):
93105
check_output.enumerating_tasks_start()
94106
count = sum(1 for i in walk_filepath_list(filepath_list, recursive))
95107
check_output.enumerating_tasks_stop(count)
96-
with ProcessPoolExecutor(max_workers=workers) as pool:
108+
with ProcessPoolExecutor(
109+
max_workers=workers, initializer=worker_initializer, initargs=(libc_path,)
110+
) as pool:
97111
try:
98112
check_output.processing_tasks_start()
99113
future_to_checksec = {

checksec/elf.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from collections import namedtuple
23
from enum import Enum
34
from functools import lru_cache
@@ -48,12 +49,16 @@ def get_libc(libc_path: Optional[Path] = None) -> Optional["Libc"]:
4849
try:
4950
__LIBC_OBJ["libc"]
5051
except KeyError:
52+
logging.debug("Libc object not set")
5153
try:
5254
libc = Libc(libc_path)
53-
except (LibcNotFoundError, ErrorParsingFailed):
55+
except (LibcNotFoundError, ErrorParsingFailed) as e:
56+
logging.debug("Failed to init Libc object: %s", e)
5457
__LIBC_OBJ["libc"] = None
5558
else:
59+
logging.debug("Libc object initialized")
5660
__LIBC_OBJ["libc"] = libc
61+
logging.debug(__LIBC_OBJ)
5762
return __LIBC_OBJ["libc"]
5863

5964

@@ -79,6 +84,7 @@ def __init__(self, libpath: Path = None):
7984
libpath = Path(find_libc())
8085
if not libpath:
8186
raise LibcNotFoundError
87+
logging.debug("Initializing Libc from %s", libpath)
8288
self.libc = lief.parse(str(libpath))
8389
if not self.libc:
8490
raise ErrorParsingFailed(libpath)

checksec/output.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import logging
23
from abc import ABC, abstractmethod
34
from pathlib import Path
45
from typing import List, Union
@@ -137,6 +138,7 @@ def processing_tasks_start(self):
137138
self.process_task_id = self.process_bar.add_task("Checking", total=self.total)
138139

139140
def add_checksec_result(self, filepath: Path, checksec: Union[ELFChecksecData, PEChecksecData]):
141+
logging.debug("result for %s: %s", filepath, checksec)
140142
if isinstance(checksec, ELFChecksecData):
141143
row_res: List[str] = []
142144
# display results

checksec/utils.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from pathlib import Path
88

99
import lddwrap
10+
# cannot use is_elf because of circular dependency
11+
import lief
1012

1113

1214
class LibcNotFoundError(Exception):
@@ -37,11 +39,19 @@ def find_libc():
3739
# or other errors
3840
try:
3941
libc_path = find_libc_ldd()
40-
except FileNotFoundError:
42+
except (FileNotFoundError, RuntimeError):
4143
# test hardcoded paths
4244
logging.debug("Finding libc path: hardcoded paths")
4345
for maybe_libc in LIBC_PATH_POSSIBILITIES:
44-
if Path(maybe_libc).resolve().exists():
46+
logging.debug("Testing libc at %s", maybe_libc)
47+
maybe_libc_path = Path(maybe_libc)
48+
if maybe_libc_path.exists():
49+
# symlink
50+
if maybe_libc_path.is_symlink():
51+
dst = os.readlink(str(maybe_libc_path))
52+
logging.debug("Resolve symlink %s -> %s", maybe_libc_path, dst)
53+
maybe_libc_path = Path(dst)
54+
if lief.is_elf(str(maybe_libc_path)):
4555
libc_path = maybe_libc
4656
break
4757
if libc_path is None:

setup.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setuptools.setup(
1010
name="checksec.py",
11-
version="0.4.5",
11+
version="0.5.0",
1212
author="Mathieu Tarral",
1313
author_email="mathieu.tarral@protonmail.com",
1414
description="Checksec tool implemented in Python",
@@ -21,10 +21,10 @@
2121
"console_scripts": ["checksec = checksec.__main__:entrypoint"],
2222
},
2323
classifiers=[
24-
"Programming Language :: Python :: 3.6",
24+
"Programming Language :: Python :: 3.7",
2525
"Development Status :: 4 - Beta",
2626
"Typing :: Typed",
2727
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
2828
],
29-
python_requires=">=3.6",
29+
python_requires=">=3.7",
3030
)

0 commit comments

Comments
 (0)