mirror of
https://github.com/lifting-bits/mcsema
synced 2026-06-08 15:31:09 +00:00
d42db800a4
* Parse flavors * Batch folder is now created/deleted properly * Shared libraries as symlinks in special dir * Simple README file * Get binary info * Simple cfg retrieval * Lifter has path to cfg as argument * Flags for eventual evaluation * Check policy and presence of cfg file * Print results of getting the cfgs * Check of batch sanity fix * run_test cli parsing * Add abi_libraries directory parsing * Shared libraries directory parsing * Lift and recompile * Before actual test implementation * Playground for testing * Actual testing * Split test cases on per binary bases * Add some commits * Result print * Enhance README.txt * Populate.py to copy needed binaries * Add short decsription of populate.py * Support flavor all * add ida frontend implementation * Basic tag files * Basic inputs * Missing comma * Change inputs handling * Separate function for copy files * Naming convention * Handle missing test case class * Create bin if it is missing * Create so_dir if it is missing * Remove not used cmd argument * Add several more test_suites * ida frontend lift function can now be selected * Smarter tests * BasicTest does not need setUp * Prevent system-wide installed binaries from being run instead of tested * Simple comment * Pass rest of are passed to lift * Fix parser error with unspecified lift_args * Variable name * Change default interpreter to python3 * Fix optional argument parsing for the subsequent lift * typo in mcsema-disass * More details in README * Simplify usage of IDA frontend * ida frontend stores logs * Add script to compile programs and generate tags if desired * Year on copyright * Add hello world src examples of tests. * Add test addition example to README * Correct extension for log files * Basic linker flags * Fix crash if file in bin is missing when tag is present * Bunch of test files * Empty runs * Test_suite name should have maxsplit=1 * Dynamically create test_suites for src programs from definitions * Define cases * Stdin * Split tests into another file * WIP: stdin from string * Another string to be matched if binary is pie * Fix typo in test case * Add color support * Improve stdout output * Add wrappers to make colors more use friendly * Move object representation of test results into separate file * Add magneta * Cleaner verbose output * Log partial results, so they can be dumped into file later for comparison * Replace usage of internals of color.Colors * Refactor how constants are hidden in Colors * Add load/save test results into json * Simple printer of multiple results * result_data.compare() now takes formatter as argument which handles all printing * result_data compare() code cleanup * Missing closing bracket in get_cfg * Test cases now correctly process stdin * Add option to save log as json * Move global variable input_dir into correct module * Add missing suites for files compiled from sources * Compile does not crash when tags are not being stubbed * Fix passing stdin into Popen - input is bytes instead of str * Some tests no longer print floats * populate: Add color support * run_tests: Multithread support * run_tests: Introduces option to specify number of threads to use * get_cfg: Introduces option to specify number of threads to use * Update README with compile.py information * Change --lib_dir to --runtime_lib to avoid llvm version problems * WIP: Set default compiler to clang-8 * Logs are now stored inside batch_name_cfg/logs * Fix bug in log file filename generation * get_cfg: If all is specified as flavor, even empty tag files are selected * Changed run_tests.py --libc_dir to --abi_lib_dir to match mcsema-lift naming conventions * run_test: Timeout is now set to 5sec per test * run_tests: timeout is static attribute of BaseTest. * run_tests: Expand grep tests * run_tests: timeout is now logged as type of test result * src: Add test for global ctors/dtors. * src: Compile script can now use user-defined compilators * run: Add runners for global ctor/dtor tests. * compile: TAGS can now be specified as first line in src file * src: Add TAGS to source files * compile: Source files can now contain more complex header * compile: Config is now responsible for whole process * src: reflect changes in compile script * Missing copyright header * Add util script * populate: Reflect changes in tags structure * get_cfg: Replace flavors by tags to be consistent * get_cfg: Reflect changes in tags structure * run: Parse configs * run: Rework lift to use class instead of random stuff everywhere * run: Removed unittest * run: Remove tests.py * src: Add headers to src tests * run: Obliterate last remnants of tests.py * Update README to reflect changes * Change README from plaintext to markdown * Update .remill_commit_id * Update .remill_commit_id
154 lines
5.0 KiB
Markdown
154 lines
5.0 KiB
Markdown
New attempt to create a better test suite. In development process, use at your own peril.
|
|
|
|
# Use:
|
|
|
|
|
|
1) You can use `populate.py` to copy binaries to be tested from `/bin` or `/usr/bin`.
|
|
Directory that contains configs is iterated and each binary that has present at least one config file is searched for.
|
|
In case it is not found error is written on standard output, but the script continues with the rest.
|
|
|
|
Example:
|
|
|
|
```
|
|
./populate.py
|
|
> not_exists not found anywhere
|
|
> Found /bin/echo
|
|
> Found /bin/grep
|
|
```
|
|
|
|
2) In case you want to try your own sources you can use `compile.py` which compiles all sources from `src` directory. If option `--stub_tags` is used, the corresponding tag files are created.
|
|
|
|
3) First create a batch of cfg file using `get_cfg.py` -- you can select tags to run only subset of all tests (they are specified in `tags` directory).
|
|
+ tag all will get cfg for every file with at least one config present
|
|
+ there are several policies that allows modification of already existing batches
|
|
|
|
Example:
|
|
|
|
```
|
|
# Every file present in the `bin` directory will be lifted
|
|
# into cfg file.
|
|
# If a batch with name first_batch is present it will be deleted.
|
|
|
|
python get_cfg.py --disass dyninst --tags all
|
|
--batch first_batch --batch_policy D
|
|
|
|
# Lifts all missing files that have tags C.
|
|
# In case some file has already present cfg,
|
|
# it is not replaced
|
|
|
|
python get_cfg.py --disass dyninst --tags C
|
|
--batch first_batch --batch_policy C
|
|
|
|
# Updates all files with tag echo, leaves rest of the batch untouched
|
|
|
|
python get_cfg.py --disass dyninst --tags echo
|
|
--batch first_batch --batch_policy U
|
|
```
|
|
|
|
4) Once batch is created `run_tests.py` can be run.
|
|
|
|
# Config/Test files (tags/):
|
|
|
|
Directory tags (name to be changed) contains two types of files (beware, whitespaces are used as delimiters, therefore they matter):
|
|
|
|
1) `binary.kind.config`, which has following internal structure:
|
|
|
|
```
|
|
TAGS: one two ...
|
|
LIFT_OPTS: +one +two 87 !three
|
|
```
|
|
|
|
`TAGS` specify tags of this config, while `LIFT_OPTS` represent specific lift options. Options prefixed by `+` are added and prefix `!` means that the options is not used even though it would normally be by default.
|
|
One binary can have multiple config files.
|
|
|
|
At the moment each config should contain exactly one of the following two tags: `c`, `cpp`. They are later used to determine which compiler to use when recompiling.
|
|
|
|
2) `binary.test`, which has following internal structure:
|
|
|
|
```
|
|
TEST: cmd_option1 ...
|
|
STDIN: -Fpath/to/file/ or string
|
|
FILES: Not implemented yet
|
|
TEST: ...
|
|
...
|
|
```
|
|
|
|
For simple test cases it is easier to write this kind of test specification than the one used in python sources.
|
|
|
|
`STDIN:` after file is optional and so is `FILES:`. If value of `STDIN:` is prefixed by F corresponding file is loaded (it can be relative to the root of test dir) and used as stdin.
|
|
|
|
# src/
|
|
|
|
Files presented in `src` are meant to be compiled by `compile.py` and can have special header:
|
|
```
|
|
/* TAGS: ... */
|
|
/* CC_OPTS: ... */
|
|
/* LD_OPTS: ... */
|
|
/* LIFT_OPTS: kind1 ... */
|
|
/* LIFT_OPTS: kind2 ... */
|
|
...
|
|
/* TEST: */
|
|
/* STDIN: */
|
|
...
|
|
```
|
|
Everything except `CC_OPTS:` and `LD_OPTS:` is used to generated appropriate `.config/.test` files. `CC_OPTS:` and `LD_OPTS:` are forwarded to the compiler.
|
|
|
|
# Complex tests
|
|
|
|
Not every test can be described by simple "language" of the `.test` files, therefore it is needed to have a way to define those more complex ones.
|
|
In `run_tests.py` a global array `g_complex_test` is present, which is used to store more advanced configurations. It has following data type:
|
|
|
|
```
|
|
{ str : [ TestDetails ] }
|
|
```
|
|
The structure is rather intuitive -- each binary has one entry and can have multiple test cases stored in array of `TestDetails`. `TestDetails` currently have following options:
|
|
```
|
|
cmd (set in __init___): array of command line arguments
|
|
files: files that are used by the program
|
|
-> it is needed to copy them into appropriate location
|
|
check: files that are output of the program
|
|
-> it is needed to compare them
|
|
```
|
|
As usual, files can be specified by relative paths from root directory of tests.
|
|
|
|
|
|
|
|
# Directory structure:
|
|
|
|
```
|
|
get_cfg.py # script to create new cfg files
|
|
run_tests.py # runs the selected batches
|
|
populate.py # tries to copy binaries from `/bin` or `/usr/bin` based on tags files
|
|
bin
|
|
|- base_test
|
|
|- ... rest of tested binaries
|
|
|
|
tags
|
|
|- base_test.default.config
|
|
|- ... for each binary at least one config file
|
|
|- base.test
|
|
|- .. optional test files
|
|
|
|
# Folders containing cfg files (there may be a reason you want to have several,
|
|
# for example compare frontends or have cfgs of some special flavor)
|
|
batch1_cfg
|
|
|- base_test.cfg
|
|
|- ...
|
|
|
|
batch2_cfg
|
|
|- base_test.cfg
|
|
|- ...
|
|
|
|
# Symlinks to shared libraries used by original binaries
|
|
# Links themselves are created by get_cfg.py
|
|
shared_libs
|
|
|- libc.so
|
|
|- ...
|
|
|
|
# Inputs for the run_tests.py
|
|
inputs
|
|
|- input1.txt
|
|
|- program1
|
|
|- ...
|
|
```
|