diff options
| author | Glenn Smith <glenn@vector35.com> | 2023-01-11 16:07:24 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2023-01-11 16:07:24 -0500 |
| commit | 86968afc1d95c38eecd25319dd0a18649da2ae87 (patch) | |
| tree | 48d82fb916f921d8a08d93e353df6c19e5b4a370 | |
| parent | 938fe7902db474d457e5ebe466a8c67bcb433b5c (diff) | |
Docs for Import/Export header file
| -rw-r--r-- | docs/guide/type.md | 120 | ||||
| -rw-r--r-- | docs/img/import-header.png | bin | 0 -> 509733 bytes |
2 files changed, 120 insertions, 0 deletions
diff --git a/docs/guide/type.md b/docs/guide/type.md index 8beafdf6..2e5265fe 100644 --- a/docs/guide/type.md +++ b/docs/guide/type.md @@ -160,6 +160,109 @@ struct Header __packed }; ``` +### Import Header File + +If you already have a collection of headers containing types you want to use, you can import them directly. You can specify the compiler flags that would be used if a compiler were compiling a source file that uses this header. Specifically this means you can/should specify: +- `-isystem<path>` for various system header paths +- `-I<path>` for various user header paths +- `-D<macro>=<value>` for macro definitions +- `-x c -std=c99` to specify C99 mode +- Other Clang-compatible command-line flags are accepted (eg `-fms-extensions`, `-fms-compatibility`, etc) + +You can specify that types from system headers, accessed via `#include <header.h>`, will be in the results. Otherwise, only files from user headers, accessed via `#include "headere.h"` will be used. + +You can also specify Define Binary Ninja Macros, which makes the type parser include the various parser extensions that Binary Ninja allows in the Type View editors, eg `__packed`, `__padding`, `__syscall`, etc. You probably only want to use this option when importing a header file exported using [Export Header File](#export-header-file). + +After specifying the file(s) and flag(s), pressing Preview will give a list of all the types and functions defined in the file(s). You may check or uncheck the box next to any of the types/functions to control whether they will be imported to your analysis. + +If there were any parse errors, those will be shown instead of a list of types. Generally speaking, what this means is you're missing either header search paths or compile definitions. See the section below on [finding system headers](#finding-system-headers). + +Upon pressing Import, all the checked types/functions will be added to your analysis. Imported types will override any existing types you had defined, so they are disabled by default and indicated via the Exists Already column. Imported functions will replace signatures of any functions in your analysis whose name matches the one found in the header. + + + +#### Finding System Headers + +Since you need to specify the include paths for system headers, you will need to deduce them for the target platform of your analysis. Here are a few tricks that may help: + +##### Systems with GCC/Clang (macOS, Linux, etc) + +On these systems, you can run a command to print the default search path for compilation: + + gcc -Wp,-v -E - + clang -Wp,-v -E - + +For the directories printed by this command, you should include them with `-isystem<path>` in the order specified. + +For example (macOS, with Xcode 13): + + $ clang -Wp,-v -E - + clang -cc1 version 13.0.0 (clang-1300.0.29.3) default target arm64-apple-darwin21.6.0 + ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include" + ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks" + #include "..." search starts here: + #include <...> search starts here: + /usr/local/include + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/13.0.0/include + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory) + End of search list. + +From this example, the flags you want would be: (note: not including the framework directory line) + + -isystem/usr/local/include + -isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/13.0.0/include + -isystem/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include + -isystem/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include + +For example (Arch Linux): + + $ gcc -Wp,-v -E - + ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../x86_64-pc-linux-gnu/include" + #include "..." search starts here: + #include <...> search starts here: + /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include + /usr/local/include + /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed + /usr/include + End of search list. + +From this example, the flags you want would be: + + -isystem/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include + -isystem/usr/local/include + -isystem/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed + -isystem/usr/include + +##### For Windows + +For windows, there's no easy command to list all the include paths, so you have to piece them together from the Include Directory property in a Visual Studio project. You also want to include `-x c -std c99` since Windows headers include lots of C++ types that the type importer currently does not support. + +You will end up with something like the following for user mode: + + -x c -std c99 + -isystem"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include" + -isystem"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt" + -isystem"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared" + -isystem"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um" + +Or, for kernel mode: + + -x c -std c99 + -isystem"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include" + -isystem"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt" + -isystem"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared" + -isystem"C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\km" + +##### Cross-Platform Targets + +If you are analyzing a target that is for a different operating system, you need to both find the header include paths for that system, and copy (or mount) them to a location accessible by the computer running Binary Ninja. + +### Export Header File + +If you want to compile code using the structures you defined during your analysis, you can export all the types to a C-compatible header file that can be used via `#include` by a C compiler. You can also import this header in another analysis session via [Import Header File](#import-header-file), just be sure to enable Define Binary Ninja Macros when doing so. + ## Using the API Of course, like everything else in Binary Ninja, anything you can accomplish in the UI you can accomplish using the API. Manipulating types is no exception. Here are four common workflows for working with types as commented examples. @@ -438,6 +541,23 @@ current_function.parameter_vars[0].type = Type.pointer(bv.arch, Type.char()) >>> bv.get_data_var_at(here).type = Type.char() ``` +## Headers + +Importing a header goes through the same code path as parsing source directly. You will just have to read the file and specify the appropriate command-line arguments as an array. See [above](#import-header-file) for directions for choosing arguments. + +```python +>>> with open('C:\projects\stdafx.h', 'r') as f: +... TypeParser.default.parse_types_from_source(f.read(), 'stdafx.h', Platform['windows-x86_64'], [], ['--target=x86_64-pc-windows-msvc', '-x', 'c', '-std', 'c99', r'-isystemC:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include', r'-isystemC:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt', r'-isystemC:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared', r'-isystemC:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um']) +(<types: [...], variables: [...], functions: [...]>, []) +``` + +Exporting a header uses the `TypePrinter.print_all_types` api, and outputs a string. + +```python +>>> TypePrinter.default.print_all_types(bv.types.items(), bv) +'//------------------------------------------------------------------------------\n// Types for /bin/ls\n//\n// This header file generated by Binary Ninja\n//------------------------------------------------------------------------------\n\n#ifndef BN_TYPE_PARSER\n#include <stdint.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <stdbool.h>\n#include <wchar.h>\n\n#define __packed\n#define __noreturn\n#define __convention(name)\n...' +``` + ## Type Library Type Libraries are collections of type information (structs, enums, function types, etc.) stored in a file with the extension `.bntl`. diff --git a/docs/img/import-header.png b/docs/img/import-header.png Binary files differnew file mode 100644 index 00000000..f86b71e8 --- /dev/null +++ b/docs/img/import-header.png |
