Skip to content

Commit

Permalink
Improve sample hex output
Browse files Browse the repository at this point in the history
Closes #47
  • Loading branch information
senier committed May 25, 2024
1 parent dfc9cbe commit 96b567b
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
8 changes: 2 additions & 6 deletions cobrafuzz/fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,8 @@ def _write_sample(self, buf: bytes, prefix: str = "crash-") -> None:
logging.info("Crash dir created (%s)", self._crash_dir)

crash_path = self._crash_dir / (prefix + m.hexdigest())

with crash_path.open("wb") as f:
f.write(buf)
logging.info("sample was written to %s", crash_path)
if len(buf) < 200:
logging.info("sample = %s", buf.hex())
crash_path.write_bytes(buf)
logging.info(util.hexdump(title=f"Sample written to {crash_path.name}:", data=buf))

def _initialize_process(self, wid: int) -> tuple[MPProcess, mp.Queue[Update]]:
queue: mp.Queue[Update] = self._mp_ctx.Queue()
Expand Down
11 changes: 11 additions & 0 deletions cobrafuzz/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,14 @@ def disable_logging() -> Iterator[None]:
yield
finally:
logging.disable(previous_level)


def hexdump(title: str, data: bytes) -> str:
length = 16
result = [title]
for i in range(0, len(data), length):
chunk = data[i : i + length]
hex_chunk = " ".join(f"{b:02x}" for b in chunk)
ascii_chunk = "".join(chr(b) if 32 <= b < 127 else "." for b in chunk)
result.append(f"{i:08x}: {hex_chunk:<{length*3}} {ascii_chunk}")
return "\n".join(result)
10 changes: 4 additions & 6 deletions tests/unit/test_fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import dill # type: ignore[import-untyped]
import pytest

from cobrafuzz import fuzzer, simplifier, state as st
from cobrafuzz import fuzzer, simplifier, state as st, util
from tests import utils


Expand Down Expand Up @@ -102,7 +102,7 @@ def test_write_sample(
assert artifact.is_file()
with artifact.open("rb") as af:
assert af.read() == sample
assert length >= 200 or f"sample = {sample.hex()}" in caplog.text
assert util.hexdump(title="", data=sample) in caplog.text


def test_regression_valid(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
Expand Down Expand Up @@ -464,8 +464,7 @@ def test_start_error(
assert caplog.record_tuples == [
("root", logging.INFO, "START units: 1, workers: 1, seeds: 0"),
("root", logging.INFO, "Test error message"),
("root", logging.INFO, f"sample was written to {tmp_path / filename}"),
("root", logging.INFO, "sample = 6465616462656566"),
("root", logging.INFO, util.hexdump(title=f"Sample written to {filename}:", data=data)),
("root", logging.INFO, "Found 1 crashes, stopping."),
]

Expand Down Expand Up @@ -522,8 +521,7 @@ def simplify(self) -> None:
("root", logging.INFO, "START units: 1, workers: 1, seeds: 0"),
("root", logging.INFO, "Test error message"),
("root", logging.INFO, f"Crash dir created ({crash_path})"),
("root", logging.INFO, f"sample was written to {crash_path / filename}"),
("root", logging.INFO, "sample = 6465616462656566"),
("root", logging.INFO, util.hexdump(title=f"Sample written to {filename}:", data=data)),
("root", logging.INFO, "Found 1 crashes, stopping."),
]

Expand Down
32 changes: 32 additions & 0 deletions tests/unit/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,35 @@ def test_non_adaptive_choice() -> None:
c.append(2)
assert c._population == [1, 2]
assert c._distribution is None


@pytest.mark.parametrize(
("title", "data", "expected"),
[
("", b"", ""),
(
"some title",
b"x",
"some title\n00000000: 78 x",
),
(
"some other title",
b"xy",
"some other title\n00000000: 78 79 xy",
),
(
"title:",
b"0123456780123456",
"title:\n00000000: 30 31 32 33 34 35 36 37 38 30 31 32 33 34 35 36 0123456780123456",
),
(
"title:",
b"012345678012345678",
"title:\n"
"00000000: 30 31 32 33 34 35 36 37 38 30 31 32 33 34 35 36 0123456780123456\n"
"00000010: 37 38 78",
),
],
)
def test_hexdump(title: str, data: bytes, expected: str) -> None:
assert util.hexdump(title, data) == expected

0 comments on commit 96b567b

Please sign in to comment.