Skip to content

Commit

Permalink
Improve Windows compatibility of ofrak_core tests (#487)
Browse files Browse the repository at this point in the history
  • Loading branch information
alchzh authored Dec 12, 2024
1 parent 6242c09 commit fd7bab0
Show file tree
Hide file tree
Showing 50 changed files with 431 additions and 204 deletions.
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ ofrak_patch_maker/technical_docs/vbcc.pdf filter=lfs diff=lfs merge=lfs -text
ofrak_core/test_ofrak/components/assets/* filter=lfs diff=lfs merge=lfs -text
ofrak_core/test_ofrak/components/assets/README.md !filter !diff !merge text
ofrak_core/test_ofrak/components/assets/kernel_address_space_build.sh !filter !diff !merge text
ofrak_core/test_ofrak/components/assets/string_test.c !filter !diff !merge text
ofrak_tutorial/assets/* filter=lfs diff=lfs merge=lfs -text
docs/user-guide/gui/assets/* filter=lfs diff=lfs merge=lfs -text
ofrak_core/test_ofrak/components/assets/elf/* filter=lfs diff=lfs merge=lfs -text
ofrak_core/test_ofrak/components/assets/elf/edge-cases/* filter=lfs diff=lfs merge=lfs -text
frontend/public/themes/**/* filter=lfs diff=lfs merge=lfs -text
disassemblers/ofrak_angr/ofrak_angr_test/assets/* filter=lfs diff=lfs merge=lfs -text
ofrak_core/pytest_ofrak/elf/assets/* filter=lfs diff=lfs merge=lfs -text
ofrak_core/pytest_ofrak/elf/assets/*.c !filter !diff !merge text
ofrak_core/pytest_ofrak/elf/assets/Makefile !filter !diff !merge text
1 change: 1 addition & 0 deletions ofrak_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Fix bug where calling `Resource.remove_tag` on both a tag class and a class that inherits from that class causes a `KeyError` on resource save. ([#510](https://github.com/redballoonsecurity/ofrak/pull/510))
- Use PyPI version of `bincopy`, upgrade to version 20.0.0 ([#528](https://github.com/redballoonsecurity/ofrak/pull/528))
- Fix bugs on Windows arising from using `os.path` methods when only forward-slashes are acceptable ([#521](https://github.com/redballoonsecurity/ofrak/pull/521))
- Made some changes to OFRAK test suite to improve test coverage on Windows ([#487](https://github.com/redballoonsecurity/ofrak/pull/487))

### Changed
- By default, the ofrak log is now `ofrak-YYYYMMDDhhmmss.log` rather than just `ofrak.log` and the name can be specified on the command line ([#480](https://github.com/redballoonsecurity/ofrak/pull/480))
Expand Down
8 changes: 7 additions & 1 deletion ofrak_core/ofrak/component/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,14 @@ async def run(
# Check if the problem was that one of the dependencies is missing
missing_file = e.filename
for dep in self.external_dependencies:
if dep.tool == missing_file:
if missing_file:
if dep.tool == missing_file:
raise ComponentMissingDependencyError(self, dep)
# on Windows a filename is not provided from subprocess FileNotFoundError, so just
# assume the any missing tool we find is the problem
elif not await dep.is_tool_installed():
raise ComponentMissingDependencyError(self, dep)

raise
except CalledProcessError as e:
raise ComponentSubprocessError(e)
Expand Down
2 changes: 1 addition & 1 deletion ofrak_core/ofrak/core/ihex.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import re
import sys
from dataclasses import dataclass
from typing import List, Union, Tuple, Any
from typing import Any, List, Tuple, Union

from bincopy import BinFile

Expand Down
22 changes: 22 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

CC=gcc

default: program

program.o: program.c $(HEADERS)
$(CC) -c program.c -fno-asynchronous-unwind-tables -o program.o

program: program.o
$(CC) program.o -o program

program_no_reloc: program.o
$(CC) program.o -no-pie -o program_no_reloc

program_relocated: program_relocated.o
$(CC) program_relocated.o -o program_relocated

large_elf.o: large_elf.c $(HEADERS)
$(CC) -c large_elf.c -o large_elf.o

large_elf: large_elf.o
$(CC) large_elf.o -no-pie -o large_elf
3 changes: 3 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/large_elf
Git LFS file not shown
17 changes: 17 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/large_elf.c

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/large_elf.o
Git LFS file not shown
3 changes: 3 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/program
Git LFS file not shown
18 changes: 18 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/program.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

#include <stdio.h>

int foo();
int bar();

int main() {
printf("Hello, World!\n");
return foo();
}

int foo() {
return 12;
}

int bar() {
return 24;
}
3 changes: 3 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/program.o
Git LFS file not shown
3 changes: 3 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/program_no_reloc
Git LFS file not shown
8 changes: 8 additions & 0 deletions ofrak_core/pytest_ofrak/elf/assets/source_dir/patch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

int noop0();

int baz()
{
noop0();
return 36;
}
193 changes: 96 additions & 97 deletions ofrak_core/pytest_ofrak/elf/fixtures.py
Original file line number Diff line number Diff line change
@@ -1,165 +1,164 @@
import os
import subprocess

# import subprocess

import pytest

MAKEFILE_CONTENTS = """
CC=gcc

default: program
# MAKEFILE_CONTENTS = """
# CC=gcc

# default: program

# program.o: program.c $(HEADERS)
# $(CC) -c program.c -fno-asynchronous-unwind-tables -o program.o

program.o: program.c $(HEADERS)
$(CC) -c program.c -fno-asynchronous-unwind-tables -o program.o
# program: program.o
# $(CC) program.o -o program

program: program.o
$(CC) program.o -o program
# program_no_reloc: program.o
# $(CC) program.o -no-pie -o program_no_reloc

program_no_reloc: program.o
$(CC) program.o -no-pie -o program_no_reloc
# program_relocated: program_relocated.o
# $(CC) program_relocated.o -o program_relocated

program_relocated: program_relocated.o
$(CC) program_relocated.o -o program_relocated
# large_elf.o: large_elf.c $(HEADERS)
# $(CC) -c large_elf.c -o large_elf.o

large_elf.o: large_elf.c $(HEADERS)
$(CC) -c large_elf.c -o large_elf.o
# large_elf: large_elf.o
# $(CC) large_elf.o -no-pie -o large_elf
# """

large_elf: large_elf.o
$(CC) large_elf.o -no-pie -o large_elf
"""
# C_SOURCE_CONTENTS = """
# #include <stdio.h>

C_SOURCE_CONTENTS = """
#include <stdio.h>
# int foo();
# int bar();

int foo();
int bar();
# int main() {
# printf("Hello, World!\\n");
# return foo();
# }

int main() {
printf("Hello, World!\\n");
return foo();
}
# int foo() {
# return 12;
# }

int foo() {
return 12;
}
# int bar() {
# return 24;
# }

int bar() {
return 24;
}

# """

"""
# LARGE_SOURCE_CONTENTS_HEADER = """
# int foo();
# int bar();

LARGE_SOURCE_CONTENTS_HEADER = """
int foo();
int bar();
# int main() {
# return bar();
# }

int main() {
return bar();
}
# """

"""
# LARGE_SOURCE_CONTENTS_FOOTER = """

LARGE_SOURCE_CONTENTS_FOOTER = """
# int foo() {
# return 12;
# }

int foo() {
return 12;
}
# int bar() {
# return 24;
# }

int bar() {
return 24;
}

# """

"""
# PATCH_CONTENTS = """
# int noop0();

PATCH_CONTENTS = """
int noop0();
# int baz()
# {
# noop0();
# return 36;
# }
# """

int baz()
{
noop0();
return 36;
}
"""

# def create_noops():
# noops = []

def create_noops():
noops = []
# i = 0

i = 0
# for i in range(8000):
# instruction = f"int noop{i}(){{}}"
# noops.append(instruction)

for i in range(8000):
instruction = f"int noop{i}(){{}}"
noops.append(instruction)
# return noops

return noops

@pytest.fixture(scope="session")
def elf_test_directory():
return os.path.join(os.path.dirname(__file__), "assets")

@pytest.fixture
def elf_test_directory(tmpdir):
makefile_path = os.path.join(tmpdir, "Makefile")
c_source_path = os.path.join(tmpdir, "program.c")
large_source_path = os.path.join(tmpdir, "large_elf.c")
# makefile_path = os.path.join(tmpdir, "Makefile")
# c_source_path = os.path.join(tmpdir, "program.c")
# large_source_path = os.path.join(tmpdir, "large_elf.c")

patch_dir = os.path.join(tmpdir, "source_dir")
if not os.path.exists(patch_dir):
os.mkdir(patch_dir)
patch_path = os.path.join(patch_dir, "patch.c")
# patch_dir = os.path.join(tmpdir, "source_dir")
# if not os.path.exists(patch_dir):
# os.mkdir(patch_dir)
# patch_path = os.path.join(patch_dir, "patch.c")

noops = create_noops()
# noops = create_noops()

LARGE_SOURCE_CONTENTS = LARGE_SOURCE_CONTENTS_HEADER
for noop in noops:
LARGE_SOURCE_CONTENTS += noop
LARGE_SOURCE_CONTENTS += LARGE_SOURCE_CONTENTS_FOOTER
# LARGE_SOURCE_CONTENTS = LARGE_SOURCE_CONTENTS_HEADER
# for noop in noops:
# LARGE_SOURCE_CONTENTS += noop
# LARGE_SOURCE_CONTENTS += LARGE_SOURCE_CONTENTS_FOOTER

with open(makefile_path, "w") as f:
f.write(MAKEFILE_CONTENTS)
with open(c_source_path, "w") as f:
f.write(C_SOURCE_CONTENTS)
with open(large_source_path, "w") as f:
f.write(LARGE_SOURCE_CONTENTS)
with open(patch_path, "w") as f:
f.write(PATCH_CONTENTS)
# with open(makefile_path, "w") as f:
# f.write(MAKEFILE_CONTENTS)
# with open(c_source_path, "w") as f:
# f.write(C_SOURCE_CONTENTS)
# with open(large_source_path, "w") as f:
# f.write(LARGE_SOURCE_CONTENTS)
# with open(patch_path, "w") as f:
# f.write(PATCH_CONTENTS)

return tmpdir
# return tmpdir


@pytest.fixture
@pytest.fixture(scope="session")
def elf_object_file(elf_test_directory):
subprocess.run(["make", "-C", elf_test_directory, "program.o"])
return os.path.join(elf_test_directory, "program.o")


@pytest.fixture
@pytest.fixture(scope="session")
def elf_executable_file(elf_test_directory):
subprocess.run(["make", "-C", elf_test_directory, "program"])
return os.path.join(elf_test_directory, "program")


@pytest.fixture
@pytest.fixture(scope="session")
def elf_no_pie_executable_file(elf_test_directory):
subprocess.run(["make", "-C", elf_test_directory, "program_no_reloc"])
return os.path.join(elf_test_directory, "program_no_reloc")


@pytest.fixture
@pytest.fixture(scope="session")
def large_elf_source_file(elf_test_directory):
return os.path.join(elf_test_directory, "large_elf.c")


@pytest.fixture
@pytest.fixture(scope="session")
def large_elf_object_file(elf_test_directory):
subprocess.run(["make", "-C", elf_test_directory, "large_elf.o"])
return os.path.join(elf_test_directory, "large_elf.o")


@pytest.fixture
@pytest.fixture(scope="session")
def large_elf_file(elf_test_directory):
subprocess.run(["make", "-C", elf_test_directory, "large_elf"])
return os.path.join(elf_test_directory, "large_elf")


@pytest.fixture
@pytest.fixture(scope="session")
def patch_file(elf_test_directory):
return os.path.join(elf_test_directory, "source_dir", "patch.c")
2 changes: 1 addition & 1 deletion ofrak_core/pytest_ofrak/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def ofrak_id_service():

@pytest.fixture
def ofrak(ofrak_injector, ofrak_id_service):
ofrak = OFRAK(logging.INFO)
ofrak = OFRAK(logging.INFO, exclude_components_missing_dependencies=True)
ofrak.injector = ofrak_injector
ofrak.set_id_service(ofrak_id_service)

Expand Down
Loading

0 comments on commit fd7bab0

Please sign in to comment.