Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d005663ac7 | ||
|
|
3354b45db2 | ||
|
|
4c32abd74e | ||
|
|
105fbbb714 | ||
|
|
c7c5a9fc4f | ||
|
|
7fe429a5f0 | ||
|
|
811a871fdf | ||
|
|
9a78a15cee | ||
|
|
8254a43863 | ||
|
|
27a280e09e | ||
|
|
3ce19013f5 | ||
|
|
934b2b7b95 | ||
|
|
f8db8a714c | ||
|
|
05eee7a67f | ||
|
|
fe8ccaa92d | ||
|
|
d377a74997 | ||
|
|
479149510a | ||
|
|
2f136969fc | ||
|
|
52199f0518 | ||
|
|
9ec12e299e | ||
|
|
298468c530 | ||
|
|
8107947d82 | ||
|
|
0a470d7420 | ||
|
|
37ab8a7ef0 | ||
|
|
e0dd3363ec | ||
|
|
6bc9a38587 | ||
|
|
3cc572c3bb | ||
|
|
4c9c42c483 | ||
|
|
1c02380920 | ||
|
|
cfd60bd66a | ||
|
|
c8e6eff6ef | ||
|
|
1937d455ec | ||
|
|
5916c8d2b9 | ||
|
|
6a4edfdf2f | ||
|
|
f0fcff7f0b | ||
|
|
9e8d4d5242 | ||
|
|
1d228ed1e5 | ||
|
|
e5a4126dde | ||
|
|
b68429c52d | ||
|
|
b492a5cf34 | ||
|
|
5da76859ef | ||
|
|
fb73059abb | ||
|
|
372512fc18 | ||
|
|
a426b86d75 | ||
|
|
cac3d8fb3f | ||
|
|
aa7586881c | ||
|
|
a0a312030e | ||
|
|
f3754eb210 | ||
|
|
884e229971 | ||
|
|
3174463a64 | ||
|
|
a931521fa8 | ||
|
|
d41866b597 | ||
|
|
a01d9d8d0e | ||
|
|
5da7ef8723 | ||
|
|
2f08559f17 | ||
|
|
0e340dd897 | ||
|
|
916d51868b | ||
|
|
d05b3499b6 | ||
|
|
46d05fc76b | ||
|
|
d61a93b42e | ||
|
|
3437f545bf | ||
|
|
45bb1b0db1 | ||
|
|
469c7d00f1 | ||
|
|
2a95290b7e | ||
|
|
d5b1aa3866 | ||
|
|
f5f9641a8c | ||
|
|
afee9061d9 | ||
|
|
f09dd83eac | ||
|
|
c6416faefc | ||
|
|
1f7c8f7dc3 | ||
|
|
daec9c3ff5 | ||
|
|
e608952ef4 | ||
|
|
17c244a396 | ||
|
|
bb59f8e685 | ||
|
|
6e058369f0 | ||
|
|
8093e32b76 | ||
|
|
2d00880302 | ||
|
|
673aae77ff | ||
|
|
7e4f53f1a3 | ||
|
|
648c1634c4 | ||
|
|
fdea2d1662 | ||
|
|
1c637e3dde | ||
|
|
34bf0f5880 | ||
|
|
f1bec5a714 | ||
|
|
815ba98c26 | ||
|
|
5f6908d286 | ||
|
|
2f21a83aee | ||
|
|
e367104b07 | ||
|
|
8856a904c1 | ||
|
|
6bf76c99e6 | ||
|
|
59c1b1f797 | ||
|
|
49617fb66c | ||
|
|
d0b10c2cf9 | ||
|
|
6822a9ffc5 | ||
|
|
5a136fe72c | ||
|
|
d89b211807 | ||
|
|
888b83fc25 | ||
|
|
5bbd1db78e | ||
|
|
44e9b9f03f | ||
|
|
4d55e3f6d7 | ||
|
|
e0c8a9a47d | ||
|
|
3cc74890ce | ||
|
|
b9881acbde | ||
|
|
753779b0c9 | ||
|
|
c1190ff78f | ||
|
|
707d9669b0 | ||
|
|
fc65d29434 | ||
|
|
ac4df39892 | ||
|
|
d9153dad43 | ||
|
|
663c457579 | ||
|
|
0329c63b14 | ||
|
|
222bc2bb35 | ||
|
|
1ce7a456f2 | ||
|
|
af0d738b4c | ||
|
|
0b1567438a | ||
|
|
2d82cd19e6 | ||
|
|
4130bdf127 | ||
|
|
38b8e4a191 | ||
|
|
83bc9ca17d | ||
|
|
cb3a013963 | ||
|
|
7b033b9015 | ||
|
|
5f8f75cae8 | ||
|
|
cad40b6cdc | ||
|
|
0c74c540ce | ||
|
|
b09d043b26 | ||
|
|
b3bab67254 | ||
|
|
84a0691cac | ||
|
|
42c0a08910 | ||
|
|
ce6e49f6aa | ||
|
|
0802130a61 | ||
|
|
e4880ee9bb | ||
|
|
b3be170559 | ||
|
|
2f1c7a6fe0 | ||
|
|
415680ad41 | ||
|
|
d5099fa16e | ||
|
|
a80d770619 | ||
|
|
11a8ade305 | ||
|
|
b0e8f9d274 | ||
|
|
1177cbb56c | ||
|
|
d22542bd4a | ||
|
|
c71b0cbc87 | ||
|
|
ed6a59a878 | ||
|
|
d2b15cd295 | ||
|
|
5602aa1e84 | ||
|
|
93253ef1d3 | ||
|
|
e7d2824ada | ||
|
|
3d3a2c1503 | ||
|
|
c457dcff11 | ||
|
|
0fb5f726b8 | ||
|
|
ec1f0e5184 | ||
|
|
3db4f48c96 | ||
|
|
1ee1f04d9f | ||
|
|
1c038d2aea | ||
|
|
ad8111dd07 | ||
|
|
71b451d833 | ||
|
|
b5182ec963 | ||
|
|
1acd918396 | ||
|
|
1e8ca39b4d | ||
|
|
19ab30f42c | ||
|
|
5934632c9a | ||
|
|
1ca94b13a0 | ||
|
|
7b9de7b6c3 | ||
|
|
3f51514f64 | ||
|
|
20a0227742 | ||
|
|
ab1e2bb1e8 | ||
|
|
5257787eb0 | ||
|
|
b784c6449a | ||
|
|
57b10a2eec | ||
|
|
f4835af59f | ||
|
|
28508c36bc | ||
|
|
823272a6cd | ||
|
|
90a9262d48 | ||
|
|
ac2a412d71 | ||
|
|
be381b97b7 | ||
|
|
00341b040e | ||
|
|
3c0bd971a5 | ||
|
|
d7dc3e8ee0 | ||
|
|
8d7f5e06a5 | ||
|
|
c7bc5f65e2 | ||
|
|
e6305498dc | ||
|
|
4ab6992632 | ||
|
|
76093f3a39 | ||
|
|
cf7d1ccca5 | ||
|
|
234ecccefc | ||
|
|
d1595d7949 | ||
|
|
85939c66a1 | ||
|
|
7a4664a795 | ||
|
|
1c419a2c92 | ||
|
|
3d0ce7545e | ||
|
|
e9a680377e | ||
|
|
340c0ec674 | ||
|
|
2cf8334aa0 | ||
|
|
69876ad0d9 | ||
|
|
e09ecffb8f | ||
|
|
0947d84c73 | ||
|
|
1182334831 | ||
|
|
f308f19af5 | ||
|
|
1a94b7437b | ||
|
|
d335521fda | ||
|
|
70caa0db77 | ||
|
|
f9b6b77101 | ||
|
|
9233847d66 | ||
|
|
07a94b09da | ||
|
|
0d91852ac0 | ||
|
|
f0ff7ee3b4 | ||
|
|
d18c174062 | ||
|
|
8835d034e0 | ||
|
|
f714ffc14b | ||
|
|
e23553c613 | ||
|
|
2775086371 | ||
|
|
421a732e8a | ||
|
|
56603ca2f6 | ||
|
|
da362e6a35 | ||
|
|
807947f7e0 | ||
|
|
a920267cba | ||
|
|
478de7829b | ||
|
|
d9e1137cb9 | ||
|
|
f8ca472f7d | ||
|
|
d3e6a7986e | ||
|
|
3e9d44510a | ||
|
|
497b0c012e | ||
|
|
57a0b95070 | ||
|
|
e216760b76 | ||
|
|
80e04d4b43 | ||
|
|
164bd1f160 | ||
|
|
7c3369add4 | ||
|
|
47467ec03f | ||
|
|
82b9718f31 | ||
|
|
2d7805d86e | ||
|
|
53a656aba3 | ||
|
|
cd3553733b | ||
|
|
19cd0cbc38 | ||
|
|
1a6638f644 | ||
|
|
5cfdb05540 | ||
|
|
835132af6c | ||
|
|
255cd71927 | ||
|
|
ac033c4bd0 | ||
|
|
401486a6b8 | ||
|
|
a2484a43b3 | ||
|
|
38ec1e378b | ||
|
|
5537c2552f | ||
|
|
98240b8210 | ||
|
|
9c2e9facc9 | ||
|
|
418e4756d7 | ||
|
|
373317efc3 | ||
|
|
bc1a98bb3b | ||
|
|
1b964afe28 | ||
|
|
b1ac356f2c | ||
|
|
d41f9b7aa2 | ||
|
|
305fdd7204 | ||
|
|
f5b7164f45 | ||
|
|
daa95b0530 | ||
|
|
6269d5d9bc | ||
|
|
991586a1ed | ||
|
|
0f2deb05c9 | ||
|
|
dfcad82f44 | ||
|
|
43830eacb1 | ||
|
|
6933e5ecab | ||
|
|
cb421fb41c | ||
|
|
db9c1bd4db | ||
|
|
25bddf6019 | ||
|
|
bed43eb08c | ||
|
|
3cb815ce5d | ||
|
|
48d241cefa | ||
|
|
f5a4f6b272 | ||
|
|
21cdf9bac1 | ||
|
|
c47df2999e | ||
|
|
1cc1b60bf9 | ||
|
|
2274e39c00 | ||
|
|
d15b1c7dc6 | ||
|
|
e9764969d5 | ||
|
|
1915b921de | ||
|
|
b000c38366 | ||
|
|
a8b11cf158 | ||
|
|
032780721e | ||
|
|
9626dda2ba | ||
|
|
2c8b087757 | ||
|
|
324d102afa | ||
|
|
c9f36fc09e | ||
|
|
e3015ebbf7 | ||
|
|
94575d302a | ||
|
|
eb6611bca1 | ||
|
|
b4eb53e0fc | ||
|
|
2ad74fed83 | ||
|
|
ec3920229a | ||
|
|
d35a0ad211 | ||
|
|
966e456616 | ||
|
|
7897f7b09d | ||
|
|
762d77f11c | ||
|
|
aca974e752 | ||
|
|
6fa0be53dc | ||
|
|
0e4f68093e | ||
|
|
0dfd129b47 | ||
|
|
8c0c4c48ff | ||
|
|
dfa8c70336 | ||
|
|
c5193a4817 | ||
|
|
fee8f64a03 | ||
|
|
96fcacf722 | ||
|
|
4384b3aba3 | ||
|
|
492f16baf8 | ||
|
|
b3d9008614 | ||
|
|
f02175670b | ||
|
|
c9340c36e9 | ||
|
|
66fb8e54fa | ||
|
|
ce04422eda | ||
|
|
311ed4f125 | ||
|
|
5e0fd64160 | ||
|
|
7b217e964a | ||
|
|
4ed300ac71 | ||
|
|
3fb34c778b | ||
|
|
4db4e3d62c | ||
|
|
986536909b | ||
|
|
6ff62e6303 | ||
|
|
03b153ba17 | ||
|
|
80e790d9a7 | ||
|
|
d91e91d6b9 | ||
|
|
d795497828 | ||
|
|
bc6a8514e3 | ||
|
|
3dbce30ac9 | ||
|
|
57671447c6 | ||
|
|
7c8a0c7c05 | ||
|
|
9ecdfca369 | ||
|
|
fe9edfb041 | ||
|
|
d68e913e09 | ||
|
|
884e1046e5 | ||
|
|
cc601d961f | ||
|
|
1ec74f52a9 | ||
|
|
b7d8074351 | ||
|
|
29635eb4db | ||
|
|
3172dd1992 | ||
|
|
4fa7229678 | ||
|
|
767fe8253a | ||
|
|
ff51a337c5 | ||
|
|
9ac21a5841 | ||
|
|
b17fb37c21 | ||
|
|
9ae756af30 | ||
|
|
88a4d550cd | ||
|
|
d336834b11 | ||
|
|
12e80c5b1d | ||
|
|
8da5388b94 | ||
|
|
69219fdbe7 | ||
|
|
f0610149b0 | ||
|
|
d1382c1863 | ||
|
|
347b1b9c8f | ||
|
|
be0ee74c14 | ||
|
|
35de7f3592 | ||
|
|
92be25bb62 | ||
|
|
1502b48a17 | ||
|
|
1f190a9fa1 | ||
|
|
7ac083bb73 | ||
|
|
3d86f07199 | ||
|
|
daa4b238f4 | ||
|
|
978dcc3b1a | ||
|
|
1fafa1745b | ||
|
|
d295ee4d8b | ||
|
|
f986c6dd17 | ||
|
|
cfdcc42fcd | ||
|
|
22894bef5b | ||
|
|
59eea4c1fc | ||
|
|
07b7d33d06 | ||
|
|
702f4e51b8 | ||
|
|
62700dfd05 | ||
|
|
bff40d626c | ||
|
|
87cfc06382 | ||
|
|
6c2e39cfc0 | ||
|
|
70c842f726 | ||
|
|
e1844d4ecc | ||
|
|
25dbebb658 | ||
|
|
658297344b | ||
|
|
cb71d0d640 | ||
|
|
6f21d3902a | ||
|
|
14f941bab4 | ||
|
|
2e94b01eb8 | ||
|
|
3847142f1e | ||
|
|
83bdf9c8d4 | ||
|
|
7f01c7e580 | ||
|
|
6fe77f843b | ||
|
|
136aeff77e | ||
|
|
63d5500ee7 | ||
|
|
1e40f986b8 | ||
|
|
76df01f96a | ||
|
|
cf890cee8d | ||
|
|
cb2a0948d4 | ||
|
|
cbf06a5033 | ||
|
|
4396aec5e9 | ||
|
|
d6f11cf5cd | ||
|
|
bc5a0c7254 | ||
|
|
05989e1dac | ||
|
|
b4e355f532 | ||
|
|
0ab32ac170 | ||
|
|
61d2923941 | ||
|
|
9f6c798506 | ||
|
|
872a518693 | ||
|
|
10a0da37e7 | ||
|
|
cd639a011e | ||
|
|
ab3b10bfa1 | ||
|
|
8b659ba3ec | ||
|
|
91bc6dfd6e | ||
|
|
007646df14 | ||
|
|
9b647bdd58 | ||
|
|
188a1231a0 | ||
|
|
f155e94363 | ||
|
|
bedb668860 | ||
|
|
d09a8d53cd | ||
|
|
d19b32f006 | ||
|
|
a0e7d68f3b | ||
|
|
ef3694ba7e | ||
|
|
dfc7fb6016 | ||
|
|
e4ceecd6c4 | ||
|
|
9c4204a358 | ||
|
|
e46f1ded86 | ||
|
|
f36b5a5410 | ||
|
|
28d64ba71b | ||
|
|
64d13d63e6 | ||
|
|
3b012a0a7f | ||
|
|
b19a17ee89 | ||
|
|
b5fd54aab4 | ||
|
|
f23d3bccd4 | ||
|
|
a89d452efa | ||
|
|
b0502c94d0 | ||
|
|
38e5565568 | ||
|
|
986b7d0177 | ||
|
|
6c0f19af19 | ||
|
|
1efd1a3857 | ||
|
|
0291fe7236 | ||
|
|
71e6942309 | ||
|
|
66a54c6d92 | ||
|
|
a037769500 | ||
|
|
59298ccdc7 | ||
|
|
81feabd209 |
+118
@@ -0,0 +1,118 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
Standard: c++17
|
||||
|
||||
# Column limit
|
||||
ColumnLimit: 83
|
||||
|
||||
# Indentation
|
||||
IndentWidth: 2
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
ContinuationIndentWidth: 4
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: false
|
||||
IndentPPDirectives: BeforeHash
|
||||
NamespaceIndentation: None
|
||||
IndentWrappedFunctionNames: true
|
||||
IndentAccessModifiers: false
|
||||
|
||||
# Access modifiers at same level as class members
|
||||
AccessModifierOffset: 0
|
||||
|
||||
# Constructor initializers: colon at end of line, each initializer on new line
|
||||
BreakConstructorInitializers: AfterColon
|
||||
PackConstructorInitializers: Never
|
||||
|
||||
# Inheritance
|
||||
BreakInheritanceList: BeforeColon
|
||||
|
||||
# Pointer/Reference alignment: attached to type
|
||||
PointerAlignment: Left
|
||||
ReferenceAlignment: Pointer
|
||||
DerivePointerAlignment: false
|
||||
|
||||
# Spacing
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
|
||||
# Alignment
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveDeclarations: false
|
||||
|
||||
# Short forms
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortCaseExpressionOnASingleLine: true
|
||||
|
||||
# Packing
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
|
||||
# Namespaces
|
||||
CompactNamespaces: false
|
||||
FixNamespaceComments: false
|
||||
|
||||
# Empty lines
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
MaxEmptyLinesToKeep: 2
|
||||
|
||||
# Ternary operators stay at end of line
|
||||
BreakBeforeTernaryOperators: false
|
||||
|
||||
# Misc
|
||||
Cpp11BracedListStyle: true
|
||||
ReflowComments: true
|
||||
InsertBraces: true
|
||||
InsertNewlineAtEOF: true
|
||||
|
||||
BreakTemplateDeclarations: Yes
|
||||
BreakBeforeCloseBracketBracedList: true
|
||||
BreakBeforeCloseBracketFunction: true
|
||||
BreakBeforeTemplateCloser: true
|
||||
|
||||
EnumTrailingComma: Insert
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: true
|
||||
AcrossComments: true
|
||||
BreakAfterReturnType: ExceptShortType
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterControlStatement: MultiLine
|
||||
|
||||
RemoveEmptyLinesInUnwrappedLines: true
|
||||
RemoveSemicolon: true
|
||||
QualifierAlignment: Left
|
||||
|
||||
|
||||
# Includes - preserve existing order
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
|
||||
IncludeCategories:
|
||||
- Regex: '^((<|")(spdlog|nanobind|catch2|utf8)/)'
|
||||
Priority: 3
|
||||
- Regex: '<[[:alnum:].]+>'
|
||||
Priority: 4
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
@@ -0,0 +1,4 @@
|
||||
api/python/**
|
||||
third-party/**
|
||||
src/runtime/osx/utils.h
|
||||
tests/test_define_conflicts.cpp
|
||||
@@ -0,0 +1,76 @@
|
||||
Checks: [
|
||||
-*,
|
||||
bugprone-*,
|
||||
performance-*,
|
||||
portability-*,
|
||||
cppcoreguidelines-*,
|
||||
misc-*,
|
||||
clang-taidy-*,
|
||||
modernize-*,
|
||||
|
||||
-clang-taidy-avoid-implicit-enum-to-integer-conversion,
|
||||
-clang-taidy-avoid-high-cyclomatic-complexity,
|
||||
|
||||
-modernize-use-trailing-return-type,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-avoid-c-arrays,
|
||||
|
||||
# `modernize-avoid-c-style-cast` also rejects the functional-style suggested by
|
||||
# `clang-taidy-avoid-static-integer-cast` (caught by -Wold-style-cast though)
|
||||
-modernize-avoid-c-style-cast,
|
||||
|
||||
-modernize-use-ranges,
|
||||
-modernize-use-constraints,
|
||||
-modernize-use-designated-initializers,
|
||||
-modernize-use-integer-sign-comparison,
|
||||
-modernize-use-string-view,
|
||||
|
||||
-bugprone-derived-method-shadowing-base-method,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-signed-bitwise,
|
||||
-bugprone-signed-char-misuse,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
-cppcoreguidelines-avoid-const-or-ref-data-members,
|
||||
-cppcoreguidelines-avoid-do-while,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-explicit-constructor,
|
||||
-cppcoreguidelines-macro-to-enum,
|
||||
-cppcoreguidelines-macro-usage,
|
||||
-cppcoreguidelines-missing-std-forward,
|
||||
-cppcoreguidelines-narrowing-conversions,
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||
-cppcoreguidelines-pro-type-const-cast,
|
||||
-cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
-cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
-cppcoreguidelines-pro-type-union-access,
|
||||
-cppcoreguidelines-special-member-functions,
|
||||
-cppcoreguidelines-use-enum-class,
|
||||
-misc-const-correctness,
|
||||
-misc-explicit-constructor,
|
||||
-misc-include-cleaner,
|
||||
-misc-misplaced-const,
|
||||
-misc-no-recursion,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-misc-override-with-different-visibility,
|
||||
-misc-static-assert,
|
||||
-misc-use-anonymous-namespace,
|
||||
-misc-use-internal-linkage,
|
||||
-performance-enum-size,
|
||||
-performance-no-int-to-ptr,
|
||||
-portability-avoid-pragma-once,
|
||||
]
|
||||
|
||||
CheckOptions:
|
||||
bugprone-unused-return-value.CheckedReturnTypes: '^::std::error_code$;^::std::error_condition$;^::std::errc$;^::std::expected$;^::LIEF::result$'
|
||||
bugprone-unused-return-value.AllowCastToVoid: true
|
||||
|
||||
HeaderFilterRegex: '.*'
|
||||
ExcludeHeaderFilterRegex: '(builds|build|api/rust/include|utils/ordinals_lookup_tables_std|utils/ordinals_lookup_tables)/*'
|
||||
@@ -0,0 +1,70 @@
|
||||
Documentation:
|
||||
CommentFormat: Doxygen
|
||||
Diagnostics:
|
||||
Includes:
|
||||
IgnoreHeader:
|
||||
- spdlog/fmt/.*
|
||||
- nanobind/stl/.*
|
||||
- third-party/.*
|
||||
ClangTidy:
|
||||
FastCheckFilter: Strict
|
||||
Add: [
|
||||
bugprone-*,
|
||||
performance-*,
|
||||
portability-*,
|
||||
cppcoreguidelines-*,
|
||||
modernize-*,
|
||||
misc-*,
|
||||
clang-taidy-*,
|
||||
]
|
||||
Remove: [
|
||||
bugprone-easily-swappable-parameters,
|
||||
bugprone-narrowing-conversions,
|
||||
bugprone-reserved-identifier,
|
||||
bugprone-signed-char-misuse,
|
||||
cppcoreguidelines-avoid-c-arrays,
|
||||
cppcoreguidelines-avoid-const-or-ref-data-members,
|
||||
cppcoreguidelines-avoid-do-while,
|
||||
cppcoreguidelines-avoid-magic-numbers,
|
||||
cppcoreguidelines-explicit-constructor,
|
||||
cppcoreguidelines-missing-std-forward,
|
||||
cppcoreguidelines-narrowing-conversions,
|
||||
cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
cppcoreguidelines-owning-memory,
|
||||
cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||
cppcoreguidelines-pro-type-const-cast,
|
||||
cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-pro-type-union-access,
|
||||
misc-explicit-constructor,
|
||||
misc-misplaced-const,
|
||||
misc-no-recursion,
|
||||
misc-non-private-member-variables-in-classes,
|
||||
misc-use-anonymous-namespace,
|
||||
misc-use-internal-linkage,
|
||||
misc-static-assert,
|
||||
modernize-avoid-c-arrays,
|
||||
modernize-concat-nested-namespaces,
|
||||
modernize-make-unique,
|
||||
modernize-use-nodiscard,
|
||||
modernize-use-noexcept,
|
||||
modernize-use-trailing-return-type,
|
||||
performance-enum-size,
|
||||
performance-no-int-to-ptr,
|
||||
]
|
||||
---
|
||||
If:
|
||||
PathMatch:
|
||||
- api/rust/include/LIEF/.*
|
||||
CompileFlags:
|
||||
Remove: [-std=gnu++17]
|
||||
Add: [-std=gnu++20]
|
||||
|
||||
---
|
||||
If:
|
||||
PathMatch:
|
||||
- include/LIEF/.*
|
||||
PathExclude:
|
||||
- api/rust/.*
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
[paths]
|
||||
source =
|
||||
tests/
|
||||
|
||||
[run]
|
||||
branch = True
|
||||
relative_files = True
|
||||
omit =
|
||||
*/api/python/*
|
||||
*/tests/utils.py
|
||||
*/tests/conftest.py
|
||||
*/tests/run_pytest.py
|
||||
; Require LIEF extended
|
||||
*/tests/coff/test_disassembler.py
|
||||
*/tests/api/test_demangle.py
|
||||
*/tests/dwarf/*
|
||||
*/tests/objc/*
|
||||
*/tests/assembly/*
|
||||
*/tests/pdb/*
|
||||
*/tests/dyld-shared-cache/*
|
||||
|
||||
[report]
|
||||
; Regexes for lines to exclude from consideration
|
||||
exclude_also =
|
||||
; Don't complain about missing debug-only code:
|
||||
def __repr__
|
||||
if self\.debug
|
||||
|
||||
; Don't complain if tests don't hit defensive assertion code:
|
||||
raise AssertionError
|
||||
raise NotImplementedError
|
||||
raise RuntimeError
|
||||
|
||||
; Don't complain if non-runnable code isn't run:
|
||||
if 0:
|
||||
if __name__ == .__main__.:
|
||||
if lief.__extended__:
|
||||
if stderr:
|
||||
if not file.exists():
|
||||
|
||||
; Don't complain about these markers
|
||||
@pytest\.mark\.lief_extended
|
||||
@pytest\.mark\.slow
|
||||
@@ -1,138 +0,0 @@
|
||||
# Launch Docker CI when committing
|
||||
# Inspired from https://medium.com/@zypherman/my-experiences-with-travis-ci-7f5ea26a87c0
|
||||
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import logging
|
||||
import pprint
|
||||
import os
|
||||
|
||||
LOG_LEVEL = logging.INFO
|
||||
|
||||
logging.getLogger().addHandler(logging.StreamHandler())
|
||||
logging.getLogger().setLevel(LOG_LEVEL)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
AUTH_TOKEN = os.getenv("TRAVIS_TOKEN", sys.argv[1] if len(sys.argv) > 1 else None)
|
||||
|
||||
if not AUTH_TOKEN:
|
||||
logger.error("No token found!")
|
||||
sys.exit(1)
|
||||
|
||||
LIEF_ID = 12579556
|
||||
DOCKER_ID = 15139981
|
||||
|
||||
ENDPOINT = 'https://api.travis-ci.org'
|
||||
|
||||
LIEF = f"{ENDPOINT}/repo/{LIEF_ID}"
|
||||
DOCKER = f"{ENDPOINT}/repo/{DOCKER_ID}"
|
||||
|
||||
DOCKER_ENV_VARS_ENDPOINT = f"{DOCKER}/env_vars"
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'User-Agent': 'API Explorer',
|
||||
'Travis-API-Version': '3',
|
||||
'Authorization': f'token {AUTH_TOKEN}'
|
||||
}
|
||||
|
||||
def last_docker_build():
|
||||
response = requests.get(f"{DOCKER}/branch/master", headers=headers)
|
||||
|
||||
if not response.ok:
|
||||
logging.error("Error while getting last_docker_build")
|
||||
sys.exit(1)
|
||||
|
||||
href = response.json()["last_build"]["@href"]
|
||||
build_info = requests.get(f"{ENDPOINT}{href}", headers=headers)
|
||||
|
||||
if not build_info.ok:
|
||||
logging.error("Error while getting build_info")
|
||||
sys.exit(1)
|
||||
|
||||
return build_info.json()
|
||||
|
||||
|
||||
|
||||
def trigger_build():
|
||||
response = requests.get(f"{DOCKER}/branch/master", headers=headers)
|
||||
build_info = last_docker_build()
|
||||
|
||||
pprint.pprint(build_info)
|
||||
|
||||
# Get last build info
|
||||
last_build_id = build_info["id"]
|
||||
last_build_status = build_info["state"]
|
||||
|
||||
# Create env variables
|
||||
env_vars = [
|
||||
{
|
||||
"env_var.name": "TRIGGER_COMMIT",
|
||||
"env_var.value": os.getenv("TRAVIS_COMMIT"),
|
||||
"env_var.public": False,
|
||||
},
|
||||
{
|
||||
"env_var.name": "TRIGGER_REPO",
|
||||
"env_var.value": os.getenv("TRAVIS_REPO_SLUG"),
|
||||
"env_var.public": False,
|
||||
},
|
||||
{
|
||||
"env_var.name": "TRIGGER_ACTION",
|
||||
"env_var.value": "build-doc",
|
||||
"env_var.public": False,
|
||||
},
|
||||
{
|
||||
"env_var.name": "DEPENDENT_BUILD",
|
||||
"env_var.value": "true",
|
||||
"env_var.public": False,
|
||||
},
|
||||
]
|
||||
|
||||
env_vars_results = requests.get(DOCKER_ENV_VARS_ENDPOINT, headers=headers)
|
||||
if not env_vars_results.ok:
|
||||
logger.error("Error while getting Docker env variables")
|
||||
sys.exit(1)
|
||||
env_vars_remote = env_vars_results.json()["env_vars"]
|
||||
|
||||
# Set env variables
|
||||
for env_var in env_vars:
|
||||
remote_var = next(filter(lambda v : v["name"] == env_var["env_var.name"], env_vars_remote), None)
|
||||
if remote_var:
|
||||
r = requests.patch(f"{DOCKER}/env_var/{remote_var['id']}", data=json.dumps(env_var), headers=headers)
|
||||
if not r.ok:
|
||||
logger.error(f"Error while setting variable: '{remote_var['name']}'")
|
||||
sys.exit(1)
|
||||
else:
|
||||
result = requests.post(DOCKER_ENV_VARS_ENDPOINT, data=json.dumps(env_var), headers=headers)
|
||||
if not result.ok:
|
||||
logger.error(f"Error while setting variable: '{env_var['env_var.name']}'")
|
||||
sys.exit(1)
|
||||
|
||||
# (Re)Start build
|
||||
result = requests.post(f"{ENDPOINT}/build/{last_build_id}/restart", headers=headers)
|
||||
if not result.ok:
|
||||
logger.error("Error while restarting the build")
|
||||
sys.exit(1)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
is_pull_request = not (os.getenv("TRAVIS_PULL_REQUEST", "false") == "false")
|
||||
|
||||
if is_pull_request:
|
||||
logger.info("Skipping pull request build...")
|
||||
return 0
|
||||
|
||||
return trigger_build()
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -1,5 +1,10 @@
|
||||
name: 'Android'
|
||||
on: push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
build-sdk:
|
||||
@@ -9,7 +14,7 @@ jobs:
|
||||
arch: ['arm', 'arm64']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get Date
|
||||
@@ -18,7 +23,7 @@ jobs:
|
||||
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: android-${{ runner.os }}-${{ matrix.arch }}-${{ steps.get-date.outputs.date }}
|
||||
@@ -38,7 +43,7 @@ jobs:
|
||||
-v $HOME/.ccache:/ccache \
|
||||
--rm liefproject/android-${ARCH} bash /work/scripts/docker/android-sdk-${ARCH}
|
||||
- name: 'Upload Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: android-sdk-${{ matrix.arch }}
|
||||
path: build/*.tar.gz
|
||||
@@ -48,11 +53,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-sdk
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/artifacts
|
||||
- name: Display artifacts
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
name: 'Linux x86-64'
|
||||
on: push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
linux-sdk:
|
||||
@@ -19,7 +24,7 @@ jobs:
|
||||
ACTIONS_CACHE_URL: "${{ env.ACTIONS_CACHE_URL }}"
|
||||
options: --user 1001:1001
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get Date
|
||||
@@ -32,7 +37,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p /home/pylief/.ccache/tmp
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /home/pylief/.ccache
|
||||
key: linux-x86-64-${{ runner.os }}-sdk-${{ steps.get-date.outputs.date }}
|
||||
@@ -71,13 +76,13 @@ jobs:
|
||||
cd /tmp/build/linux-x86-64
|
||||
cpack --config $GITHUB_WORKSPACE/cmake/cpack.config.cmake
|
||||
- name: 'Upload SDK Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: linux-x86-64-sdk
|
||||
path: /tmp/build/linux-x86-64/*.tar.gz
|
||||
retention-days: 3
|
||||
- name: 'Upload Install Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: linux-x86-64-install
|
||||
path: /install
|
||||
@@ -96,7 +101,7 @@ jobs:
|
||||
PYTEST_ADDOPTS: "--color=yes"
|
||||
options: --user 1001:1001
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get Date
|
||||
@@ -105,7 +110,7 @@ jobs:
|
||||
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: linux-x86-64-${{ runner.os }}-test-${{ steps.get-date.outputs.date }}
|
||||
@@ -186,9 +191,9 @@ jobs:
|
||||
options: --user 1001:1001
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']
|
||||
python-version: ['3.12', '3.13', '3.14']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get Date
|
||||
@@ -201,14 +206,14 @@ jobs:
|
||||
run: |
|
||||
mkdir -p /home/pylief/.ccache/tmp
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /home/pylief/.ccache
|
||||
key: linux-x86-64-${{ runner.os }}-${{ matrix.python-version }}-${{ steps.get-date.outputs.date }}
|
||||
restore-keys: |
|
||||
linux-x86-64-${{ runner.os }}-${{ matrix.python-version }}
|
||||
- name: Download LIEF install dir
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: linux-x86-64-install
|
||||
path: /install
|
||||
@@ -231,7 +236,7 @@ jobs:
|
||||
auditwheel repair -w $GITHUB_WORKSPACE/dist {} \;
|
||||
ls -alh $GITHUB_WORKSPACE/dist
|
||||
- name: 'Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: linux-x86-64-python${{ matrix.python-version }}-wheel
|
||||
path: dist/*.whl
|
||||
@@ -241,11 +246,11 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
needs: [pywheels]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: linux-x86-64-*
|
||||
merge-multiple: true
|
||||
|
||||
+24
-21
@@ -1,14 +1,19 @@
|
||||
name: 'macOS'
|
||||
on: push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
python-test-version: '3.10'
|
||||
python-test-version: '3.13'
|
||||
|
||||
jobs:
|
||||
osx-sdk:
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install system dependencies
|
||||
@@ -24,7 +29,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p $RUNNER_TEMP/.ccache
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ runner.temp }}/.ccache
|
||||
key: osx-${{ runner.os }}-sdk-${{ steps.get-date.outputs.date }}
|
||||
@@ -42,19 +47,19 @@ jobs:
|
||||
run: |
|
||||
bash scripts/osx/package_sdk.sh
|
||||
- name: 'Upload SDK Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: osx-sdk
|
||||
path: build/*.tar.gz
|
||||
retention-days: 3
|
||||
- name: 'Upload install artifact [arm64]'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: osx-arm64-install
|
||||
path: install/arm64
|
||||
retention-days: 1
|
||||
- name: 'Upload install artifact [x64]'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: osx-x64-install
|
||||
path: install/x64
|
||||
@@ -63,11 +68,11 @@ jobs:
|
||||
runs-on: macos-14
|
||||
if: "!contains(github.event.commits[0].message, '[skip-test]')"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ env.python-test-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.python-test-version }}
|
||||
- name: Install system dependencies
|
||||
@@ -83,7 +88,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p $RUNNER_TEMP/.ccache
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ runner.temp }}/.ccache
|
||||
key: osx-${{ runner.os }}-test-${{ steps.get-date.outputs.date }}
|
||||
@@ -93,7 +98,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
- name: Build Python 3.10 with tests
|
||||
- name: Build Python 3.13 with tests
|
||||
shell: bash
|
||||
env:
|
||||
LIEF_SAMPLES_DIR: "/tmp/samples"
|
||||
@@ -128,15 +133,15 @@ jobs:
|
||||
needs: osx-sdk
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']
|
||||
python-version: ['3.12', '3.13', '3.14']
|
||||
arch: ['x64', 'arm64']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install system dependencies
|
||||
@@ -153,14 +158,14 @@ jobs:
|
||||
run: |
|
||||
mkdir -p $RUNNER_TEMP/.ccache
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ runner.temp }}/.ccache
|
||||
key: osx-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.python-version }}-${{ steps.get-date.outputs.date }}
|
||||
restore-keys: |
|
||||
osx-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.python-version }}
|
||||
- name: Download LIEF install dir
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: osx-${{ matrix.arch }}-install
|
||||
path: ~/lief-${{ matrix.arch }}-install
|
||||
@@ -178,7 +183,7 @@ jobs:
|
||||
run: |
|
||||
python -m pip -vv wheel --wheel-dir=dist/ api/python
|
||||
- name: 'Upload Python wheel artifact - ${{ matrix.python-version }}'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: osx-wheel-${{ matrix.arch }}-${{ matrix.python-version }}
|
||||
path: dist/*.whl
|
||||
@@ -188,11 +193,11 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
needs: [wheels]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: osx-*
|
||||
merge-multiple: true
|
||||
@@ -217,5 +222,3 @@ jobs:
|
||||
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
|
||||
liefproject/deploy \
|
||||
python3 /src/.github/deploy.py --skip-sdk /runner_tmp/artifacts
|
||||
|
||||
|
||||
|
||||
+23
-20
@@ -2,18 +2,18 @@ name: LIEF PR
|
||||
on: [pull_request, workflow_dispatch]
|
||||
|
||||
env:
|
||||
python-osx-version: '3.10'
|
||||
python-win-version: '3.10'
|
||||
python-osx-version: '3.12'
|
||||
python-win-version: '3.12'
|
||||
|
||||
jobs:
|
||||
osx:
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.python-osx-version }}
|
||||
- name: Install system dependencies
|
||||
@@ -31,31 +31,31 @@ jobs:
|
||||
python -m pip install -e api/python
|
||||
python tests/dl_samples.py ${LIEF_SAMPLES_DIR}
|
||||
python tests/run_pytest.py
|
||||
python tests/run_tools_check.py ${BUILD_DIR}
|
||||
ctest --output-on-failure --test-dir ${BUILD_DIR}
|
||||
python tests/run_tools_check.py ${LIEF_BUILD_DIR}
|
||||
ctest --output-on-failure --test-dir ${LIEF_BUILD_DIR}
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build & Test
|
||||
shell: bash
|
||||
env:
|
||||
PYTHON_VERSION: 39
|
||||
PYTHON_VERSION: 312
|
||||
run: |
|
||||
docker run --rm \
|
||||
-e PYTHON_VERSION=$PYTHON_VERSION \
|
||||
-e PYTHON_BINARY=/opt/python/cp39-cp39/bin/python3.9 \
|
||||
-e PYTHON_BINARY=/opt/python/cp312-cp312/bin/python3.12 \
|
||||
-v $GITHUB_WORKSPACE:/src \
|
||||
liefproject/manylinux_2_28_x86_64 \
|
||||
bash /src/scripts/docker/test-linux-x64
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python ${{ env.python-win-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.python-win-version }}
|
||||
architecture: x64
|
||||
@@ -73,17 +73,20 @@ jobs:
|
||||
echo ("LIEF_BUILD_DIR=" + $env:RUNNER_TEMP + "/lief-build") >> $env:GITHUB_ENV
|
||||
echo ("PYLIEF_CONF=" + $env:GITHUB_WORKSPACE + "/scripts/windows/py-x64-test.toml") >> $env:GITHUB_ENV
|
||||
- name: Build Python ${{ env.python-win-version }}
|
||||
shell: cmd
|
||||
shell: pwsh
|
||||
run: |
|
||||
python -m pip install -r tests/requirements.txt
|
||||
python -m pip install api/python
|
||||
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
|
||||
- name: Run tests
|
||||
timeout-minutes: 20
|
||||
shell: cmd
|
||||
python tests/dl_samples.py $env:LIEF_SAMPLES_DIR
|
||||
- name: Run tests - unittests
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd %GITHUB_WORKSPACE%
|
||||
cd $env:GITHUB_WORKSPACE
|
||||
ctest --output-on-failure --test-dir $env:LIEF_BUILD_DIR
|
||||
Exit $LASTEXITCODE
|
||||
- name: Run tests - python
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd $env:GITHUB_WORKSPACE
|
||||
python tests/run_pytest.py
|
||||
ctest --output-on-failure --test-dir %BUILD_DIR%
|
||||
|
||||
|
||||
Exit $LASTEXITCODE
|
||||
|
||||
@@ -3,15 +3,18 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'master'
|
||||
- 'release-**'
|
||||
- 'release/**'
|
||||
tags:
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
python-test-version: '3.10'
|
||||
python-version: '3.9'
|
||||
python-test-version: '3.13'
|
||||
python-version: '3.13'
|
||||
CLICOLOR_FORCE: "1"
|
||||
FORCE_COLOR: "1"
|
||||
GCC_COLORS: "yes"
|
||||
COLORTERM: "truecolor"
|
||||
TERM: "screen-256color"
|
||||
CLICOLOR: "1"
|
||||
|
||||
jobs:
|
||||
build-sdk:
|
||||
@@ -24,14 +27,15 @@ jobs:
|
||||
SCCACHE_CACHE_SIZE: 2G
|
||||
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.python-version }}
|
||||
architecture: ${{ matrix.arch }}
|
||||
- run: python -m pip install setuptools
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
choco install ninja
|
||||
@@ -45,7 +49,7 @@ jobs:
|
||||
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- name: Setup sccache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
continue-on-error: false
|
||||
with:
|
||||
path: ${{ vars.SCCACHE_DIR }}
|
||||
@@ -58,13 +62,13 @@ jobs:
|
||||
run: |
|
||||
python ./scripts/windows/package_sdk.py
|
||||
- name: 'Upload SDK artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: windows-${{ matrix.arch }}-sdk
|
||||
path: build/*.zip
|
||||
retention-days: 3
|
||||
- name: 'Upload install artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: windows-${{ matrix.arch }}-install
|
||||
path: ${{ runner.temp }}/lief-install
|
||||
@@ -84,11 +88,11 @@ jobs:
|
||||
SCCACHE_CACHE_SIZE: 2G
|
||||
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ env.python-test-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ env.python-test-version }}
|
||||
architecture: ${{ matrix.arch }}
|
||||
@@ -105,7 +109,7 @@ jobs:
|
||||
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- name: Setup sccache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
continue-on-error: false
|
||||
with:
|
||||
path: ${{ vars.SCCACHE_DIR }}
|
||||
@@ -131,23 +135,30 @@ jobs:
|
||||
echo ("LIEF_SAMPLES_DIR=" + $env:RUNNER_TEMP + "/samples") >> $env:GITHUB_ENV
|
||||
echo ("LIEF_BUILD_DIR=" + $env:RUNNER_TEMP + "/lief-build") >> $env:GITHUB_ENV
|
||||
- name: Build Python ${{ env.python-test-version }}
|
||||
shell: cmd
|
||||
shell: pwsh
|
||||
run: |
|
||||
python -m pip install -r tests/requirements.txt
|
||||
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
|
||||
python tests/dl_samples.py $env:LIEF_SAMPLES_DIR
|
||||
python -m pip -vvv install --user api/python
|
||||
Exit $LASTEXITCODE
|
||||
- name: Download samples
|
||||
shell: cmd
|
||||
shell: pwsh
|
||||
run: |
|
||||
python -m pip install -r tests/requirements.txt
|
||||
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
|
||||
- name: Run tests
|
||||
timeout-minutes: 20
|
||||
shell: cmd
|
||||
python tests/dl_samples.py $env:LIEF_SAMPLES_DIR
|
||||
- name: Run unittests
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd %GITHUB_WORKSPACE%
|
||||
cd $env:GITHUB_WORKSPACE
|
||||
ctest --output-on-failure --test-dir $env:LIEF_BUILD_DIR
|
||||
Exit $LASTEXITCODE
|
||||
- name: Run Python tests
|
||||
timeout-minutes: 20
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd $env:GITHUB_WORKSPACE
|
||||
python tests/run_pytest.py
|
||||
ctest --output-on-failure --test-dir %LIEF_BUILD_DIR%/
|
||||
Exit $LASTEXITCODE
|
||||
- name: sccache stats
|
||||
run: sccache --show-stats
|
||||
- name: stop sccache server
|
||||
@@ -157,18 +168,18 @@ jobs:
|
||||
needs: build-sdk
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']
|
||||
python-version: ['3.12', '3.13', '3.14']
|
||||
arch: ['x86', 'x64']
|
||||
fail-fast: false
|
||||
env:
|
||||
SCCACHE_CACHE_SIZE: 2G
|
||||
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: ${{ matrix.arch }}
|
||||
@@ -186,7 +197,7 @@ jobs:
|
||||
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- name: Save sccache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
continue-on-error: false
|
||||
with:
|
||||
path: ${{ vars.SCCACHE_DIR }}
|
||||
@@ -194,7 +205,7 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.arch }}-sccache-${{ matrix.python-version }}
|
||||
- name: Download LIEF install dir
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: windows-${{ matrix.arch }}-install
|
||||
path: ~/lief-${{ matrix.arch }}-install
|
||||
@@ -215,11 +226,11 @@ jobs:
|
||||
run: |
|
||||
chcp 65001 #set code page to utf-8
|
||||
- name: Build Python ${{ matrix.python-version }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
python -m pip -vvv wheel --wheel-dir=dist/ ./api/python
|
||||
shell: cmd
|
||||
- name: 'Upload Python artifacts [${{ matrix.python-version }}]'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: windows-${{ matrix.arch }}-wheel-${{ matrix.python-version }}
|
||||
path: dist/*.whl
|
||||
@@ -230,11 +241,11 @@ jobs:
|
||||
#needs: [build-sdk, wheels]
|
||||
needs: [wheels]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: windows-*
|
||||
merge-multiple: true
|
||||
@@ -255,4 +266,3 @@ jobs:
|
||||
-e LIEF_S3_KEY=$LIEF_S3_KEY \
|
||||
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
|
||||
liefproject/deploy python3 /src/.github/deploy.py --skip-sdk /runner_tmp/artifacts
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
name: LIEF Windows Quick
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
- '!master'
|
||||
- '!main'
|
||||
- '!release-**'
|
||||
- '!release/**'
|
||||
tags-ignore:
|
||||
- "**"
|
||||
|
||||
env:
|
||||
python-version: '3.12'
|
||||
|
||||
jobs:
|
||||
quick-test:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64, x86]
|
||||
fail-fast: false
|
||||
env:
|
||||
SCCACHE_CACHE_SIZE: 2G
|
||||
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ env.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ env.python-version }}
|
||||
architecture: ${{ matrix.python-version }}
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
choco install ninja
|
||||
choco install sccache
|
||||
python -m pip install --upgrade pip
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
vsversion: "2022"
|
||||
- name: Get Date
|
||||
id: get-date
|
||||
run: |
|
||||
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- name: Save sccache
|
||||
uses: actions/cache@v4
|
||||
continue-on-error: false
|
||||
with:
|
||||
path: ${{ vars.SCCACHE_DIR }}
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-quick-${{ steps.get-date.outputs.date }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.arch }}-quick
|
||||
- name: Start sccache server
|
||||
run: sccache --start-server
|
||||
- name: Set env variables
|
||||
run: |
|
||||
chcp 65001 #set code page to utf-8
|
||||
echo ("LIEF_SAMPLES_DIR=" + $env:RUNNER_TEMP + "/samples") >> $env:GITHUB_ENV
|
||||
- name: Build Python ${{ env.python-version }}
|
||||
shell: cmd
|
||||
run: |
|
||||
python -m pip install -r tests/requirements.txt
|
||||
python -m pip -vvv install api/python
|
||||
- name: Download samples
|
||||
shell: cmd
|
||||
run: |
|
||||
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
timeout-minutes: 20
|
||||
run: |
|
||||
python ./tests/run_pytest.py
|
||||
- name: sccache stats
|
||||
run: sccache --show-stats
|
||||
- name: sccache server
|
||||
run: sccache --stop-server || true
|
||||
@@ -11,3 +11,5 @@ api/rust/cargo/target/*
|
||||
api/rust/examples/target/*
|
||||
tools/target/*
|
||||
plugins/ghidra/bin/
|
||||
api/python/tests/lib/
|
||||
dev-scripts/
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
Authors:
|
||||
|
||||
Romain Thomas <me@romainthomas.fr> - Quarkslab
|
||||
Romain Thomas <me@romainthomas.fr>
|
||||
|
||||
+3
-6
@@ -4,13 +4,10 @@ Acknowledgements
|
||||
LIEF makes use of the following open source projects:
|
||||
|
||||
- mbedTLS - https://tls.mbed.org/
|
||||
- pybind11 - https://github.com/pybind/pybind11
|
||||
- nanobind - https://github.com/wjakob/nanobind
|
||||
- json - https://nlohmann.github.io/json/
|
||||
- rang - https://agauniyal.github.io/rang/
|
||||
- easyloggingpp - https://github.com/muflihun/easyloggingpp
|
||||
- Catch - https://github.com/philsquared/Catch
|
||||
- yamlcpp - https://github.com/jbeder/yaml-cpp
|
||||
- filesystem - https://github.com/wjakob/filesystem
|
||||
- spdlog - https://github.com/gabime/spdlog
|
||||
- Catch2 - https://github.com/catchorg/Catch2
|
||||
- utf8-cpp - https://sourceforge.net/projects/utfcpp/
|
||||
- llvm - http://llvm.org/ - For the formats enums and structures
|
||||
- virtualbox - https://www.virtualbox.org/ - For the PE 'LoadConfiguration' structures
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
see doc/sphinx/changelog.rst
|
||||
|
||||
see doc/sphinx/changelog.md
|
||||
|
||||
+95
-88
@@ -1,17 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(LIEF LANGUAGES C CXX)
|
||||
|
||||
enable_language(C)
|
||||
enable_language(CXX)
|
||||
|
||||
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
# Enable https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Modules
|
||||
@@ -19,7 +8,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCCompilerFlag)
|
||||
include(ExternalProject)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
find_package(Git)
|
||||
@@ -35,7 +23,7 @@ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git"
|
||||
AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND Git_FOUND)
|
||||
include(LIEFGit)
|
||||
else()
|
||||
set(LIEF_VERSION_MAJOR 1)
|
||||
set(LIEF_VERSION_MAJOR 2)
|
||||
set(LIEF_VERSION_MINOR 0)
|
||||
set(LIEF_VERSION_PATCH 0)
|
||||
endif()
|
||||
@@ -67,8 +55,8 @@ message(STATUS "Caching: ${LIEF_USE_CCACHE}")
|
||||
if(LIEF_USE_CCACHE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_FOUND})
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_FOUND})
|
||||
message(STATUS "Found ccache: ${CCACHE_FOUND}")
|
||||
else()
|
||||
find_program(SCCACHE_FOUND sccache)
|
||||
@@ -96,6 +84,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
|
||||
endif()
|
||||
|
||||
set(LIEF_EXTRA_FLAGS)
|
||||
|
||||
message(STATUS "LIEF_EXTRA_FLAGS: ${LIEF_EXTRA_FLAGS}")
|
||||
message(STATUS "CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
message(STATUS "CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
@@ -120,31 +111,58 @@ include(GNUInstallDirs)
|
||||
add_library(LIB_LIEF src/Object.cpp)
|
||||
add_subdirectory(src)
|
||||
|
||||
if(NOT LIEF_PY_LIEF_EXT)
|
||||
if (LIEF_EXTRA_FLAGS)
|
||||
target_compile_options(LIB_LIEF PRIVATE ${LIEF_EXTRA_FLAGS})
|
||||
endif()
|
||||
|
||||
if(LIEF_PRECOMPILED)
|
||||
find_package(lief-extended QUIET)
|
||||
if (NOT lief-extended_FOUND)
|
||||
find_package(LIEF REQUIRED)
|
||||
endif()
|
||||
else()
|
||||
add_library(LIEF::LIEF ALIAS LIB_LIEF)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT LIEF_OPT_MBEDTLS_EXTERNAL)
|
||||
set_source_files_properties(${mbedtls_src_files} PROPERTIES GENERATED TRUE)
|
||||
target_sources(LIB_LIEF PRIVATE ${mbedtls_src_files})
|
||||
target_compile_definitions(LIB_LIEF PRIVATE -DMBEDTLS_NO_PLATFORM_ENTROPY)
|
||||
|
||||
target_include_directories(LIB_LIEF SYSTEM PRIVATE
|
||||
${MBEDTLS_INCLUDE_DIRS}
|
||||
"${MBEDTLS_SOURCE_DIR}/library"
|
||||
)
|
||||
if (LIEF_PYTHON_FREE_THREADED)
|
||||
target_compile_definitions(LIB_LIEF PRIVATE
|
||||
# these must be set at LIB_LIEF compile time to be forwarded to MbedTLS
|
||||
-DMBEDTLS_THREADING_C
|
||||
-DMBEDTLS_THREADING_ALT
|
||||
)
|
||||
endif()
|
||||
|
||||
add_dependencies(LIB_LIEF lief_mbed_tls)
|
||||
target_compile_definitions(LIB_LIEF PRIVATE
|
||||
-DTF_PSA_CRYPTO_USER_CONFIG_FILE="${CMAKE_CURRENT_SOURCE_DIR}/config/mbedtls/psa_config.h"
|
||||
)
|
||||
else()
|
||||
find_package(MbedTLS REQUIRED)
|
||||
find_package(MbedTLS 4.0.0 EXACT REQUIRED)
|
||||
target_link_libraries(LIB_LIEF PRIVATE
|
||||
MbedTLS::mbedcrypto MbedTLS::mbedx509)
|
||||
MbedTLS::tfpsacrypto MbedTLS::mbedx509)
|
||||
if (LIEF_PYTHON_FREE_THREADED)
|
||||
message(WARNING "Python free-threading requires the external MbedTLS to have \
|
||||
been built with threading support. LIEF cannot enforce this.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(LIB_LIEF PRIVATE
|
||||
-DMBEDTLS_CONFIG_FILE="${CMAKE_CURRENT_SOURCE_DIR}/config/mbedtls/config.h"
|
||||
-DMBEDTLS_X509_USE_C
|
||||
-DMBEDTLS_PK_PARSE_C
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(LIB_LIEF PRIVATE bcrypt)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
target_link_libraries(LIB_LIEF PRIVATE ws2_32)
|
||||
if (LIEF_IMPORT_SUFFIX)
|
||||
@@ -153,11 +171,8 @@ if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/bigobj)
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug AND UNIX)
|
||||
target_compile_options(LIB_LIEF PRIVATE -g -O0)
|
||||
target_compile_options(LIB_LIEF PRIVATE /bigobj)
|
||||
target_compile_options(LIB_LIEF PUBLIC /Zc:__cplusplus)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS OR LIEF_FORCE_API_EXPORTS)
|
||||
@@ -200,7 +215,6 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/config.h.in"
|
||||
|
||||
set(LIEF_PUBLIC_INCLUDE_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/api/c/include/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||
|
||||
set(LIEF_PRIVATE_INCLUDE_DIR
|
||||
@@ -215,21 +229,18 @@ target_include_directories(LIB_LIEF
|
||||
PUBLIC "$<BUILD_INTERFACE:${LIEF_PUBLIC_INCLUDE_DIR}>"
|
||||
PRIVATE "${LIEF_PRIVATE_INCLUDE_DIR}")
|
||||
|
||||
target_precompile_headers(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lief-pch.hpp
|
||||
)
|
||||
|
||||
if(LIEF_ENABLE_JSON)
|
||||
if(LIEF_OPT_NLOHMANN_JSON_EXTERNAL)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
target_link_libraries(LIB_LIEF PRIVATE nlohmann_json::nlohmann_json)
|
||||
else()
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/internal/nlohmann/json.hpp
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/internal/nlohmann
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBJSON_SOURCE_DIR}/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/internal/nlohmann/
|
||||
DEPENDS lief_libjson)
|
||||
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/internal/nlohmann/json.hpp)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/internal/nlohmann)
|
||||
file(COPY ${LIBJSON_SOURCE_DIR}/
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/internal/nlohmann/)
|
||||
|
||||
target_include_directories(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/)
|
||||
@@ -242,7 +253,6 @@ if(LIEF_FROZEN_ENABLED)
|
||||
find_package(frozen REQUIRED)
|
||||
target_link_libraries(LIB_LIEF PRIVATE frozen::frozen)
|
||||
else()
|
||||
add_dependencies(LIB_LIEF lief_frozen)
|
||||
target_include_directories(LIB_LIEF
|
||||
PRIVATE "${FROZEN_INCLUDE_DIR}")
|
||||
endif()
|
||||
@@ -257,37 +267,22 @@ if(LIEF_EXTERNAL_EXPECTED)
|
||||
find_package(tl-expected REQUIRED)
|
||||
target_link_libraries(LIB_LIEF PUBLIC tl::expected)
|
||||
else()
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/expected.hpp
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${EXPECTED_SRC_DIR}/include/tl/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/
|
||||
DEPENDS lief_expected)
|
||||
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/expected.hpp)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/)
|
||||
file(COPY ${EXPECTED_SRC_DIR}/include/tl/
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/)
|
||||
endif()
|
||||
|
||||
|
||||
# =======================================
|
||||
# utfcpp
|
||||
# =======================================
|
||||
|
||||
if(LIEF_OPT_UTFCPP_EXTERNAL)
|
||||
find_package(utf8cpp REQUIRED)
|
||||
target_link_libraries(LIB_LIEF PRIVATE utf8cpp::utf8cpp)
|
||||
else()
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/internal/utfcpp/utf8.h
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/internal/
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${UTFCPP_INCLUDE_DIR}/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/internal/utfcpp
|
||||
DEPENDS lief_utfcpp)
|
||||
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/internal/utfcpp/utf8.h)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/internal/)
|
||||
file(COPY ${UTFCPP_INCLUDE_DIR}/
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/internal/utfcpp)
|
||||
endif()
|
||||
|
||||
# =======================================
|
||||
@@ -301,16 +296,9 @@ if(LIEF_EXTERNAL_SPAN)
|
||||
"$<BUILD_INTERFACE:${LIEF_EXTERNAL_SPAN_DIR}>")
|
||||
endif()
|
||||
else()
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/span.hpp
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${TCB_SPAN_SRC_DIR}/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/
|
||||
DEPENDS lief_span)
|
||||
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/span.hpp)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/)
|
||||
file(COPY ${TCB_SPAN_SRC_DIR}/
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/)
|
||||
endif()
|
||||
|
||||
target_link_libraries(LIB_LIEF PRIVATE lief_spdlog)
|
||||
@@ -329,9 +317,31 @@ set_target_properties(LIB_LIEF
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
C_VISIBILITY_PRESET hidden)
|
||||
|
||||
if (LIEF_CLANG_TIDY)
|
||||
find_program(CLANG_TIDY_EXE NAMES "clang-tidy" REQUIRED)
|
||||
cmake_path(GET CLANG_TIDY_EXE PARENT_PATH CLANG_TIDY_DIR)
|
||||
|
||||
set(CLANG_TIDY_COMMAND
|
||||
"${CLANG_TIDY_EXE}"
|
||||
"--use-color"
|
||||
"--load=${CLANG_TIDY_DIR}/clang-taidy.so"
|
||||
"--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy-core.yaml"
|
||||
)
|
||||
if (LIEF_CLANG_TIDY_WARN_ERR)
|
||||
list(APPEND CLANG_TIDY_COMMAND "--warnings-as-errors=*")
|
||||
endif()
|
||||
|
||||
set_target_properties(LIB_LIEF PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
|
||||
|
||||
if (TARGET LIB_LIEF_RUNTIME)
|
||||
set_target_properties(LIB_LIEF_RUNTIME
|
||||
PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
set_property(TARGET LIB_LIEF APPEND
|
||||
PROPERTY LINK_FLAGS "-Wl,--gc-sections -Wl,--exclude-libs,ALL")
|
||||
target_link_options(LIB_LIEF PRIVATE -Wl,--gc-sections -Wl,--exclude-libs,ALL)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(LIB_LIEF PUBLIC -D_GLIBCXX_USE_CXX11_ABI=1)
|
||||
@@ -341,19 +351,20 @@ target_compile_definitions(LIB_LIEF PUBLIC -D_GLIBCXX_USE_CXX11_ABI=1)
|
||||
set(SANITIZER_FLAGS -fno-omit-frame-pointer -g -O1)
|
||||
if(LIEF_ASAN)
|
||||
message(STATUS "Address sanitizer enabled")
|
||||
list(APPEND SANITIZER_FLAGS -fsanitize=address)
|
||||
list(APPEND SANITIZER_FLAGS
|
||||
-fsanitize=address
|
||||
-fsanitize-address-use-after-scope
|
||||
-fsanitize-address-use-after-return=runtime
|
||||
)
|
||||
|
||||
set_property(TARGET LIB_LIEF
|
||||
APPEND PROPERTY LINK_FLAGS -fsanitize=address)
|
||||
target_link_libraries(LIB_LIEF INTERFACE libclang_rt.asan.so)
|
||||
target_link_options(LIB_LIEF PUBLIC -fsanitize=address)
|
||||
endif()
|
||||
|
||||
if(LIEF_LSAN)
|
||||
message(STATUS "Leak sanitizer enabled")
|
||||
list(APPEND SANITIZER_FLAGS -fsanitize=leak)
|
||||
|
||||
set_property(TARGET LIB_LIEF
|
||||
APPEND PROPERTY LINK_FLAGS -fsanitize=leak)
|
||||
target_link_options(LIB_LIEF PUBLIC -fsanitize=leak)
|
||||
|
||||
target_link_libraries(LIB_LIEF INTERFACE lsan)
|
||||
endif()
|
||||
@@ -362,21 +373,16 @@ if(LIEF_TSAN)
|
||||
message(STATUS "Thread sanitizer enabled")
|
||||
list(APPEND SANITIZER_FLAGS -fsanitize=thread)
|
||||
|
||||
set_property(TARGET LIB_LIEF
|
||||
APPEND PROPERTY LINK_FLAGS -fsanitize=thread)
|
||||
|
||||
target_link_libraries(LIB_LIEF INTERFACE tsan)
|
||||
target_link_options(LIB_LIEF PUBLIC -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
if(LIEF_USAN)
|
||||
message(STATUS "Undefined sanitizer enabled")
|
||||
list(APPEND SANITIZER_FLAGS -fsanitize=undefined,null,alignment)
|
||||
|
||||
set_property(TARGET LIB_LIEF
|
||||
APPEND PROPERTY LINK_FLAGS -fsanitize=undefined,null,alignment)
|
||||
target_link_options(LIB_LIEF PUBLIC -fsanitize=undefined,null,alignment)
|
||||
|
||||
target_link_libraries(LIB_LIEF PUBLIC ubsan -fsanitize=undefined,null,alignment)
|
||||
target_link_libraries(LIB_LIEF PUBLIC ubsan)
|
||||
endif()
|
||||
|
||||
set(LIEF_SANITIZER OFF)
|
||||
@@ -389,15 +395,12 @@ if(LIEF_SANITIZER)
|
||||
target_compile_options(LIB_LIEF PUBLIC ${SANITIZER_FLAGS})
|
||||
add_subdirectory(tests/sanitizer)
|
||||
endif()
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Fuzzing options
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
if(LIEF_FUZZING)
|
||||
set(FUZZING_FLAGS -fno-omit-frame-pointer -g -O2 -fsanitize=fuzzer-no-link)
|
||||
set(FUZZING_LINKER_FLAGS -fsanitize=fuzzer-no-link)
|
||||
set_property(TARGET LIB_LIEF
|
||||
APPEND PROPERTY LINK_FLAGS ${FUZZING_LINKER_FLAGS})
|
||||
target_link_options(LIB_LIEF PUBLIC -fsanitize=fuzzer-no-link)
|
||||
|
||||
target_compile_options(LIB_LIEF PRIVATE ${FUZZING_FLAGS})
|
||||
target_link_libraries(LIB_LIEF PUBLIC pthread)
|
||||
@@ -451,6 +454,10 @@ if(LIEF_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(LIEF_COMPILE_DOC_EXAMPLES)
|
||||
add_subdirectory(doc/code/cpp)
|
||||
endif()
|
||||
|
||||
# Post-build operations
|
||||
# ======================
|
||||
if(BUILD_SHARED_LIBS AND CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
|
||||
@@ -17,19 +17,20 @@ modify and abstract ELF, PE and MachO formats.
|
||||
|
||||
**Main features**:
|
||||
|
||||
* **Parsing**: LIEF can parse [ELF](https://lief.re/doc/latest/formats/elf/index.html), [PE](https://lief.re/doc/latest/formats/pe/index.html), [MachO](https://lief.re/doc/latest/formats/macho/index.html), [COFF](https://lief.re/doc/latest/formats/coff/index.html), OAT, DEX, VDEX, ART and provides an user-friendly API to access to internals.
|
||||
* **Modify**: LIEF can use to modify some parts of these formats (adding a section, changing a symbol's name, ...)
|
||||
* **Parsing**: LIEF can parse [ELF](https://lief.re/doc/latest/formats/elf/index.html), [PE](https://lief.re/doc/latest/formats/pe/index.html), [MachO](https://lief.re/doc/latest/formats/macho/index.html), [COFF](https://lief.re/doc/latest/formats/coff/index.html), OAT, DEX, VDEX, ART and provides a user-friendly API to access their internals.
|
||||
* **Modify**: LIEF can be used to modify some parts of these formats (adding a section, changing a symbol's name, ...)
|
||||
* **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.
|
||||
* **API**: LIEF can be used in [C++](https://lief.re/doc/latest/doxygen/), Python, [Rust](https://lief-rs.s3.fr-par.scw.cloud/doc/latest/lief/index.html), C and
|
||||
* **API**: You can use LIEF via [C++](https://lief.re/doc/latest/doxygen/), Python, [Rust](https://lief-rs.s3.fr-par.scw.cloud/doc/latest/lief/index.html), and
|
||||
[Node.js](https://github.com/Piebald-AI/node-lief) (unofficial, AI-generated)
|
||||
|
||||
**Extended features**:
|
||||
|
||||
* [**Runtime**](https://lief.re/doc/latest/runtime/intro.html)
|
||||
* [**DWARF/PDB** Support](https://lief.re/doc/latest/extended/debug_info/index.html)
|
||||
* [**Objective-C** Metadata](https://lief.re/doc/latest/extended/objc/index.html)
|
||||
* [**Dyld Shared Cache**](https://lief.re/doc/latest/extended/dsc/index.html) with support for extracting Dylib
|
||||
* [**Disassembler**](https://lief.re/doc/latest/extended/disassembler/index.html): AArch64, x86/x86-64, ARM, RISC-V, Mips, PowerPC, eBPF
|
||||
* [**Assembler**](https://lief.re/doc/latest/extended/assembler/index.html): AArch64, x86/x86-64
|
||||
* [**Assembler**](https://lief.re/doc/latest/extended/assembler/index.html): AArch64, x86/x86-64, RISC-V
|
||||
|
||||
**Plugins**:
|
||||
|
||||
@@ -48,7 +49,7 @@ modify and abstract ELF, PE and MachO formats.
|
||||
# Content
|
||||
|
||||
- [About](#about)
|
||||
- [Download / Install](#downloads--install)
|
||||
- [Downloads / Install](#downloads--install)
|
||||
- [Getting started](#getting-started)
|
||||
- [Blog](https://lief.re/blog/)
|
||||
- [Documentation](#documentation)
|
||||
@@ -66,33 +67,39 @@ modify and abstract ELF, PE and MachO formats.
|
||||
- [ELF Coredump](https://lief.re/doc/latest/tutorials/12_elf_coredump.html)
|
||||
- [PE Authenticode](https://lief.re/doc/latest/tutorials/13_pe_authenticode.html)
|
||||
- [Contact](#contact)
|
||||
- [About](#about)
|
||||
- [About](#about-1)
|
||||
- [Authors](#authors)
|
||||
- [License](#license)
|
||||
- [Bibtex](#bibtex)
|
||||
- [BibTeX](#bibtex)
|
||||
|
||||
## Downloads / Install
|
||||
|
||||
## C++
|
||||
### C++
|
||||
|
||||
```cmake
|
||||
find_package(LIEF REQUIRED)
|
||||
target_link_libraries(my-project LIEF::LIEF)
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "my-awesome-project"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
lief = "0.17.3"
|
||||
lief = "1.0.0"
|
||||
```
|
||||
|
||||
## Python
|
||||
### Homebrew
|
||||
|
||||
```console
|
||||
brew install lief
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
To install the latest **version** (release):
|
||||
|
||||
@@ -103,7 +110,7 @@ pip install lief
|
||||
To install nightly build:
|
||||
|
||||
```console
|
||||
pip install [--user] --force-reinstall --index-url https://lief.s3-website.fr-par.scw.cloud/latest lief==1.0.0.dev0
|
||||
pip install [--user] --force-reinstall --index-url https://lief.s3-website.fr-par.scw.cloud/latest lief==2.0.0.dev0
|
||||
```
|
||||
|
||||
### Packages
|
||||
@@ -112,13 +119,13 @@ pip install [--user] --force-reinstall --index-url https://lief.s3-website.fr-pa
|
||||
- **Nightly**:
|
||||
* SDK: https://lief.s3-website.fr-par.scw.cloud/latest/sdk
|
||||
* Python Wheels: https://lief.s3-website.fr-par.scw.cloud/latest/lief
|
||||
- **v0.17.3**: https://github.com/lief-project/LIEF/releases/tag/0.17.3
|
||||
- **v1.0.0**: https://github.com/lief-project/LIEF/releases/tag/1.0.0
|
||||
|
||||
Here are guides to install or integrate LIEF:
|
||||
|
||||
* [Python](https://lief.re/doc/latest/installation.html#python)
|
||||
* [Visual Studio](https://lief.re/doc/latest/installation.html#visual-studio-integration)
|
||||
* [XCode](https://lief.re/doc/latest/installation.html#xcode-integration)
|
||||
* [Xcode](https://lief.re/doc/latest/installation.html#xcode-integration)
|
||||
* [CMake](https://lief.re/doc/latest/installation.html#cmake-integration)
|
||||
|
||||
## Getting started
|
||||
@@ -134,15 +141,14 @@ for section in binary.sections:
|
||||
print(section.name, section.virtual_address)
|
||||
|
||||
# PE
|
||||
binary = lief.parse("C:\\Windows\\explorer.exe")
|
||||
|
||||
if rheader := pe.rich_header:
|
||||
binary = lief.parse(r"C:\Windows\explorer.exe")
|
||||
if (rheader := binary.rich_header) is not None:
|
||||
print(rheader.key)
|
||||
|
||||
# Mach-O
|
||||
binary = lief.parse("/usr/bin/ls")
|
||||
for fixup in binary.dyld_chained_fixups:
|
||||
print(fixup)
|
||||
if (fixups := binary.dyld_chained_fixups) is not None:
|
||||
print(fixups)
|
||||
```
|
||||
|
||||
### Rust
|
||||
@@ -163,27 +169,30 @@ if let Some(Binary::PE(pe)) = Binary::parse(path.as_str()) {
|
||||
### C++
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <LIEF/LIEF.hpp>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// ELF
|
||||
if (std::unique_ptr<const LIEF::ELF::Binary> elf = LIEF::ELF::Parser::parse("/bin/ls")) {
|
||||
for (const LIEF::ELF::Section& section : elf->sections()) {
|
||||
std::cout << section->name() << ' ' << section->virtual_address() << '\n';
|
||||
std::cout << section.name() << ' ' << section.virtual_address() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// PE
|
||||
if (std::unique_ptr<const LIEF::PE::Binary> pe = LIEF::PE::Parser::parse("C:\\Windows\\explorer.exe")) {
|
||||
if (const LIEF::PE::RichHeader* rheader : pe->rich_header()) {
|
||||
if (const LIEF::PE::RichHeader* rheader = pe->rich_header()) {
|
||||
std::cout << rheader->key() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// Mach-O
|
||||
if (std::unique_ptr<LIEF::MachO::FatBinary> macho = LIEF::MachO::Parser::parse("/bin/ls")) {
|
||||
for (const LIEF::MachO::DyldChainedFixups& fixup : macho->dyld_chained_fixups()) {
|
||||
std::cout << fixup << '\n';
|
||||
for (const LIEF::MachO::Binary& bin : *macho) {
|
||||
if (const LIEF::MachO::DyldChainedFixups* fixups = bin.dyld_chained_fixups()) {
|
||||
std::cout << *fixups << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,25 +201,6 @@ int main(int argc, char** argv) {
|
||||
|
||||
```
|
||||
|
||||
### C (Limited API)
|
||||
|
||||
```cpp
|
||||
#include <LIEF/LIEF.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Elf_Binary_t* elf = elf_parse("/usr/bin/ls");
|
||||
|
||||
Elf_Section_t** sections = elf->sections;
|
||||
|
||||
for (size_t i = 0; sections[i] != NULL; ++i) {
|
||||
printf("%s\n", sections[i]->name);
|
||||
}
|
||||
|
||||
elf_binary_destroy(elf);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Main documentation](https://lief.re/doc/latest/index.html)
|
||||
@@ -230,9 +220,9 @@ Romain Thomas ([@rh0main](https://www.romainthomas.fr/)) - Formerly at [Quarksla
|
||||
|
||||
### License
|
||||
|
||||
LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.17.3/LICENSE).
|
||||
[Apache 2.0](https://github.com/lief-project/LIEF/blob/1.0.0/LICENSE).
|
||||
|
||||
### Bibtex
|
||||
### BibTeX
|
||||
|
||||
```bibtex
|
||||
@MISC {LIEF,
|
||||
@@ -243,5 +233,3 @@ LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/
|
||||
year = "2017"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@ if (LIEF_PYTHON_API)
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
|
||||
if(LIEF_C_API)
|
||||
add_subdirectory(c)
|
||||
endif()
|
||||
|
||||
if(LIEF_RUST_API)
|
||||
add_subdirectory(rust)
|
||||
endif()
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
if(LIEF_ELF)
|
||||
add_subdirectory(ELF)
|
||||
endif()
|
||||
|
||||
if(LIEF_PE)
|
||||
add_subdirectory(PE)
|
||||
endif()
|
||||
|
||||
if(LIEF_MACHO)
|
||||
add_subdirectory(MachO)
|
||||
endif()
|
||||
|
||||
target_sources(LIB_LIEF PRIVATE logging.cpp)
|
||||
target_include_directories(LIB_LIEF PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>")
|
||||
@@ -1,115 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <cstring>
|
||||
#include "LIEF/ELF/Binary.h"
|
||||
#include "LIEF/ELF/Section.h"
|
||||
#include "LIEF/ELF/Segment.h"
|
||||
#include "LIEF/ELF/Header.h"
|
||||
#include "LIEF/ELF/Symbol.h"
|
||||
|
||||
#include "LIEF/ELF/Parser.hpp"
|
||||
#include "LIEF/ELF/Binary.hpp"
|
||||
|
||||
#include "Section.hpp"
|
||||
#include "Segment.hpp"
|
||||
#include "DynamicEntry.hpp"
|
||||
#include "Symbol.hpp"
|
||||
#include "Header.hpp"
|
||||
#include "Binary.hpp"
|
||||
|
||||
using namespace LIEF::ELF;
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
void init_c_binary(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
c_binary->handler = reinterpret_cast<void*>(binary);
|
||||
c_binary->type = static_cast<uint32_t>(binary->type());
|
||||
c_binary->interpreter = nullptr;
|
||||
if (binary->has_interpreter()) {
|
||||
const std::string& interp = binary->interpreter();
|
||||
c_binary->interpreter = static_cast<char*>(malloc((interp.size() + 1) * sizeof(char)));
|
||||
std::memcpy(
|
||||
reinterpret_cast<void*>(const_cast<char*>(c_binary->interpreter)),
|
||||
reinterpret_cast<const void*>(interp.data()),
|
||||
interp.size());
|
||||
reinterpret_cast<char*>(const_cast<char*>(c_binary->interpreter))[interp.size()] = '\0';
|
||||
}
|
||||
|
||||
init_c_header(c_binary, binary);
|
||||
init_c_sections(c_binary, binary);
|
||||
init_c_segments(c_binary, binary);
|
||||
init_c_dynamic_symbols(c_binary, binary);
|
||||
init_c_symtab_symbols(c_binary, binary);
|
||||
init_c_dynamic_entries(c_binary, binary);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Elf_Binary_t* elf_parse(const char *file) {
|
||||
Binary* binary = Parser::parse(file).release();
|
||||
|
||||
if (binary == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* c_binary = static_cast<Elf_Binary_t*>(malloc(sizeof(Elf_Binary_t)));
|
||||
memset(c_binary, 0, sizeof(Elf_Binary_t));
|
||||
init_c_binary(c_binary, binary);
|
||||
return c_binary;
|
||||
}
|
||||
|
||||
// Binary Methods
|
||||
// ==============
|
||||
|
||||
int elf_binary_save_header(Elf_Binary_t* binary) {
|
||||
Header& hdr = reinterpret_cast<Binary*>(binary->handler)->header();
|
||||
|
||||
hdr.file_type(LIEF::ELF::Header::FILE_TYPE(binary->header.file_type));
|
||||
hdr.machine_type(LIEF::ELF::ARCH(binary->header.machine_type));
|
||||
hdr.object_file_version(LIEF::ELF::Header::VERSION(binary->header.object_file_version));
|
||||
hdr.program_headers_offset(binary->header.program_headers_offset);
|
||||
hdr.section_headers_offset(binary->header.section_headers_offset);
|
||||
hdr.processor_flag(binary->header.processor_flags);
|
||||
hdr.header_size(binary->header.header_size);
|
||||
hdr.program_header_size(binary->header.program_header_size);
|
||||
hdr.numberof_segments(binary->header.numberof_segments);
|
||||
hdr.section_header_size(binary->header.section_header_size);
|
||||
hdr.numberof_sections(binary->header.numberof_sections);
|
||||
hdr.section_name_table_idx(binary->header.name_string_table_idx);
|
||||
hdr.entrypoint(binary->header.entrypoint);
|
||||
|
||||
//TODO: identity
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void elf_binary_destroy(Elf_Binary_t* binary) {
|
||||
destroy_sections(binary);
|
||||
destroy_segments(binary);
|
||||
destroy_dynamic_symbols(binary);
|
||||
destroy_symtab_symbols(binary);
|
||||
destroy_dynamic_entries(binary);
|
||||
|
||||
if (binary->interpreter != nullptr) {
|
||||
free(const_cast<char*>(binary->interpreter));
|
||||
}
|
||||
|
||||
delete reinterpret_cast<Binary*>(binary->handler);
|
||||
free(binary);
|
||||
|
||||
}
|
||||
//}
|
||||
@@ -1,9 +0,0 @@
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
Symbol.cpp
|
||||
Section.cpp
|
||||
Segment.cpp
|
||||
DynamicEntry.cpp
|
||||
Header.cpp
|
||||
Binary.cpp
|
||||
utils.cpp
|
||||
)
|
||||
@@ -1,219 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "DynamicEntry.hpp"
|
||||
|
||||
#include "LIEF/ELF/DynamicEntryFlags.hpp"
|
||||
#include "LIEF/ELF/DynamicSharedObject.hpp"
|
||||
#include "LIEF/ELF/DynamicEntryLibrary.hpp"
|
||||
#include "LIEF/ELF/DynamicEntryRpath.hpp"
|
||||
#include "LIEF/ELF/DynamicEntryRunPath.hpp"
|
||||
#include "LIEF/ELF/DynamicEntryArray.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
|
||||
void init_c_dynamic_entries(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
Binary::it_dynamic_entries dyn_entries = binary->dynamic_entries();
|
||||
c_binary->dynamic_entries = static_cast<Elf_DynamicEntry_t**>(
|
||||
malloc((dyn_entries.size() + 1) * sizeof(Elf_DynamicEntry_t**)));
|
||||
|
||||
for (size_t i = 0; i < dyn_entries.size(); ++i) {
|
||||
DynamicEntry& entry = dyn_entries[i];
|
||||
switch(entry.tag()) {
|
||||
case DynamicEntry::TAG::NEEDED:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_Library_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_Library_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
e->name = reinterpret_cast<DynamicEntryLibrary*>(&entry)->name().c_str();
|
||||
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::SONAME:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_SharedObject_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_SharedObject_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
e->name = reinterpret_cast<DynamicSharedObject*>(&entry)->name().c_str();
|
||||
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::RPATH:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_Rpath_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_Rpath_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
e->rpath = reinterpret_cast<DynamicEntryRpath*>(&entry)->rpath().c_str();
|
||||
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::RUNPATH:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_RunPath_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_RunPath_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
e->runpath = reinterpret_cast<DynamicEntryRunPath*>(&entry)->runpath().c_str();
|
||||
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::INIT_ARRAY:
|
||||
case DynamicEntry::TAG::FINI_ARRAY:
|
||||
case DynamicEntry::TAG::PREINIT_ARRAY:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_Array_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_Array_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
const std::vector<uint64_t>& array = reinterpret_cast<DynamicEntryArray*>(&entry)->array();
|
||||
e->array = static_cast<uint64_t*>(malloc((array.size() + 1) * sizeof(uint64_t)));
|
||||
for (size_t i = 0; i < array.size(); ++i) {
|
||||
e->array[i] = array[i];
|
||||
}
|
||||
e->array[array.size()] = 0;
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::FLAGS:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_Flags_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_Flags_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
const DynamicEntryFlags::flags_list_t& flags = reinterpret_cast<DynamicEntryFlags*>(&entry)->flags();
|
||||
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::FLAGS_1:
|
||||
{
|
||||
auto* e = static_cast<Elf_DynamicEntry_Flags_t*>(
|
||||
malloc(sizeof(Elf_DynamicEntry_Flags_t)));
|
||||
|
||||
e->tag = static_cast<uint64_t>(entry.tag());
|
||||
e->value = entry.value();
|
||||
const DynamicEntryFlags::flags_list_t& flags = reinterpret_cast<DynamicEntryFlags*>(&entry)->flags();
|
||||
c_binary->dynamic_entries[i] = reinterpret_cast<Elf_DynamicEntry_t*>(e);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
c_binary->dynamic_entries[i] =
|
||||
static_cast<Elf_DynamicEntry_t*>(malloc(sizeof(Elf_DynamicEntry_t)));
|
||||
c_binary->dynamic_entries[i]->tag = static_cast<uint64_t>(entry.tag());
|
||||
c_binary->dynamic_entries[i]->value = entry.value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c_binary->dynamic_entries[dyn_entries.size()] = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_dynamic_entries(Elf_Binary_t* c_binary) {
|
||||
|
||||
Elf_DynamicEntry_t **dynamic_entries = c_binary->dynamic_entries;
|
||||
for (size_t idx = 0; dynamic_entries[idx] != nullptr; ++idx) {
|
||||
switch(DynamicEntry::TAG(dynamic_entries[idx]->tag)) {
|
||||
case DynamicEntry::TAG::NEEDED:
|
||||
{
|
||||
free(reinterpret_cast<Elf_DynamicEntry_Library_t*>(dynamic_entries[idx]));
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::SONAME:
|
||||
{
|
||||
free(reinterpret_cast<Elf_DynamicEntry_SharedObject_t*>(dynamic_entries[idx]));
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::RPATH:
|
||||
{
|
||||
free(reinterpret_cast<Elf_DynamicEntry_Rpath_t*>(dynamic_entries[idx]));
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::RUNPATH:
|
||||
{
|
||||
free(reinterpret_cast<Elf_DynamicEntry_RunPath_t*>(dynamic_entries[idx]));
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::INIT_ARRAY:
|
||||
case DynamicEntry::TAG::FINI_ARRAY:
|
||||
case DynamicEntry::TAG::PREINIT_ARRAY:
|
||||
{
|
||||
Elf_DynamicEntry_Array_t* entry_array=reinterpret_cast<Elf_DynamicEntry_Array_t*>(dynamic_entries[idx]);
|
||||
free(entry_array->array);
|
||||
free(entry_array);
|
||||
break;
|
||||
}
|
||||
|
||||
case DynamicEntry::TAG::FLAGS:
|
||||
{
|
||||
Elf_DynamicEntry_Flags_t* entry_flags=reinterpret_cast<Elf_DynamicEntry_Flags_t*>(dynamic_entries[idx]);
|
||||
free(entry_flags);
|
||||
break;
|
||||
}
|
||||
case DynamicEntry::TAG::FLAGS_1:
|
||||
{
|
||||
Elf_DynamicEntry_Flags_t* entry_flags=reinterpret_cast<Elf_DynamicEntry_Flags_t*>(dynamic_entries[idx]);
|
||||
free(entry_flags);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
free(dynamic_entries[idx]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
free(c_binary->dynamic_entries);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Header.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
|
||||
void init_c_header(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
const Header& hdr = binary->header();
|
||||
c_binary->header.file_type = static_cast<uint32_t>(hdr.file_type());
|
||||
c_binary->header.machine_type = static_cast<uint32_t>(hdr.machine_type());
|
||||
c_binary->header.object_file_version = static_cast<uint32_t>(hdr.object_file_version());
|
||||
c_binary->header.program_headers_offset = hdr.program_headers_offset();
|
||||
c_binary->header.section_headers_offset = hdr.section_headers_offset();
|
||||
c_binary->header.processor_flags = hdr.processor_flag();
|
||||
c_binary->header.header_size = hdr.header_size();
|
||||
c_binary->header.program_header_size = hdr.program_header_size();
|
||||
c_binary->header.numberof_segments = hdr.numberof_segments();
|
||||
c_binary->header.section_header_size = hdr.section_header_size();
|
||||
c_binary->header.numberof_sections = hdr.numberof_sections();
|
||||
c_binary->header.name_string_table_idx = hdr.section_name_table_idx();
|
||||
c_binary->header.entrypoint = hdr.entrypoint();
|
||||
const Header::identity_t& ident = hdr.identity();
|
||||
std::copy(std::begin(ident), std::end(ident), c_binary->header.identity);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Section.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
void init_c_sections(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
Binary::it_sections sections = binary->sections();
|
||||
|
||||
c_binary->sections = static_cast<Elf_Section_t**>(
|
||||
malloc((sections.size() + 1) * sizeof(Elf_Section_t**)));
|
||||
|
||||
for (size_t i = 0; i < sections.size(); ++i) {
|
||||
Section& b_section = sections[i];
|
||||
c_binary->sections[i] = static_cast<Elf_Section_t*>(malloc(sizeof(Elf_Section_t)));
|
||||
span<const uint8_t> section_content = b_section.content();
|
||||
|
||||
c_binary->sections[i]->name = b_section.fullname().c_str();
|
||||
c_binary->sections[i]->flags = b_section.flags();
|
||||
c_binary->sections[i]->type = static_cast<uint32_t>(b_section.type());
|
||||
c_binary->sections[i]->virtual_address = b_section.virtual_address();
|
||||
c_binary->sections[i]->offset = b_section.file_offset();
|
||||
c_binary->sections[i]->original_size = b_section.original_size();
|
||||
c_binary->sections[i]->link = b_section.link();
|
||||
c_binary->sections[i]->info = b_section.information();
|
||||
c_binary->sections[i]->alignment = b_section.alignment();
|
||||
c_binary->sections[i]->entry_size = b_section.entry_size();
|
||||
c_binary->sections[i]->size = section_content.size();
|
||||
c_binary->sections[i]->entropy = b_section.entropy();
|
||||
c_binary->sections[i]->content = !section_content.empty() ?
|
||||
const_cast<uint8_t*>(section_content.data()) : nullptr;
|
||||
}
|
||||
c_binary->sections[sections.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_sections(Elf_Binary_t* c_binary) {
|
||||
|
||||
Elf_Section_t **sections = c_binary->sections;
|
||||
for (size_t idx = 0; sections[idx] != nullptr; ++idx) {
|
||||
free(sections[idx]);
|
||||
}
|
||||
free(c_binary->sections);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Segment.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
|
||||
void init_c_segments(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
Binary::it_segments segments = binary->segments();
|
||||
c_binary->segments = static_cast<Elf_Segment_t**>(
|
||||
malloc((segments.size() + 1) * sizeof(Elf_Segment_t**)));
|
||||
for (size_t i = 0; i < segments.size(); ++i) {
|
||||
Segment& segment = segments[i];
|
||||
|
||||
span<const uint8_t> segment_content = segment.content();
|
||||
|
||||
c_binary->segments[i] = static_cast<Elf_Segment_t*>(malloc(sizeof(Elf_Segment_t)));
|
||||
c_binary->segments[i]->type = static_cast<uint32_t>(segment.type());
|
||||
c_binary->segments[i]->flags = static_cast<uint32_t>(segment.flags());
|
||||
c_binary->segments[i]->virtual_address = segment.virtual_address();
|
||||
c_binary->segments[i]->virtual_size = segment.virtual_size();
|
||||
c_binary->segments[i]->offset = segment.file_offset();
|
||||
c_binary->segments[i]->alignment = segment.alignment();
|
||||
c_binary->segments[i]->size = segment_content.size();
|
||||
c_binary->segments[i]->content = !segment_content.empty() ?
|
||||
const_cast<uint8_t*>(segment_content.data()) : nullptr;
|
||||
}
|
||||
|
||||
c_binary->segments[segments.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
void destroy_segments(Elf_Binary_t* c_binary) {
|
||||
Elf_Segment_t **segments = c_binary->segments;
|
||||
for (size_t idx = 0; segments[idx] != nullptr; ++idx) {
|
||||
free(segments[idx]);
|
||||
}
|
||||
free(c_binary->segments);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Symbol.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
|
||||
void init_c_dynamic_symbols(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
Binary::it_dynamic_symbols dyn_symb = binary->dynamic_symbols();
|
||||
|
||||
c_binary->dynamic_symbols = static_cast<Elf_Symbol_t**>(
|
||||
malloc((dyn_symb.size() + 1) * sizeof(Elf_Symbol_t**)));
|
||||
|
||||
for (size_t i = 0; i < dyn_symb.size(); ++i) {
|
||||
Symbol& b_sym = dyn_symb[i];
|
||||
c_binary->dynamic_symbols[i] = static_cast<Elf_Symbol_t*>(malloc(sizeof(Elf_Symbol_t)));
|
||||
c_binary->dynamic_symbols[i]->name = b_sym.name().c_str();
|
||||
c_binary->dynamic_symbols[i]->type = static_cast<uint32_t>(b_sym.type());
|
||||
c_binary->dynamic_symbols[i]->binding = static_cast<uint32_t>(b_sym.binding());
|
||||
c_binary->dynamic_symbols[i]->other = b_sym.other();
|
||||
c_binary->dynamic_symbols[i]->shndx = b_sym.shndx();
|
||||
c_binary->dynamic_symbols[i]->value = b_sym.value();
|
||||
c_binary->dynamic_symbols[i]->size = b_sym.size();
|
||||
c_binary->dynamic_symbols[i]->information = b_sym.information();
|
||||
c_binary->dynamic_symbols[i]->is_exported = b_sym.is_exported();
|
||||
c_binary->dynamic_symbols[i]->is_imported = b_sym.is_imported();
|
||||
}
|
||||
c_binary->dynamic_symbols[dyn_symb.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void init_c_symtab_symbols(Elf_Binary_t* c_binary, Binary* binary) {
|
||||
Binary::it_symtab_symbols static_symb = binary->symtab_symbols();
|
||||
|
||||
c_binary->symtab_symbols = static_cast<Elf_Symbol_t**>(
|
||||
malloc((static_symb.size() + 1) * sizeof(Elf_Symbol_t**)));
|
||||
|
||||
for (size_t i = 0; i < static_symb.size(); ++i) {
|
||||
Symbol& b_sym = static_symb[i];
|
||||
c_binary->symtab_symbols[i] = static_cast<Elf_Symbol_t*>(malloc(sizeof(Elf_Symbol_t)));
|
||||
c_binary->symtab_symbols[i]->name = b_sym.name().c_str();
|
||||
c_binary->symtab_symbols[i]->type = static_cast<uint32_t>(b_sym.type());
|
||||
c_binary->symtab_symbols[i]->binding = static_cast<uint32_t>(b_sym.binding());
|
||||
c_binary->symtab_symbols[i]->other = b_sym.other();
|
||||
c_binary->symtab_symbols[i]->shndx = b_sym.shndx();
|
||||
c_binary->symtab_symbols[i]->value = b_sym.value();
|
||||
c_binary->symtab_symbols[i]->size = b_sym.size();
|
||||
c_binary->symtab_symbols[i]->information = b_sym.information();
|
||||
c_binary->symtab_symbols[i]->is_exported = b_sym.is_exported();
|
||||
c_binary->symtab_symbols[i]->is_imported = b_sym.is_imported();
|
||||
}
|
||||
c_binary->symtab_symbols[static_symb.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_dynamic_symbols(Elf_Binary_t* c_binary) {
|
||||
Elf_Symbol_t **dynamic_symbols = c_binary->dynamic_symbols;
|
||||
for (size_t idx = 0; dynamic_symbols[idx] != nullptr; ++idx) {
|
||||
free(dynamic_symbols[idx]);
|
||||
}
|
||||
free(c_binary->dynamic_symbols);
|
||||
}
|
||||
|
||||
|
||||
void destroy_symtab_symbols(Elf_Binary_t* c_binary) {
|
||||
Elf_Symbol_t **symtab_symbols = c_binary->symtab_symbols;
|
||||
for (size_t idx = 0; symtab_symbols[idx] != nullptr; ++idx) {
|
||||
free(symtab_symbols[idx]);
|
||||
}
|
||||
free(c_binary->symtab_symbols);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_ELF_SYMBOL_CPP_C_API_
|
||||
#define LIEF_ELF_SYMBOL_CPP_C_API_
|
||||
|
||||
#include "LIEF/ELF/Binary.h"
|
||||
#include "LIEF/ELF/Binary.hpp"
|
||||
|
||||
#include "LIEF/ELF/Symbol.h"
|
||||
#include "LIEF/ELF/Symbol.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
|
||||
void init_c_dynamic_symbols(Elf_Binary_t* c_binary, Binary* binary);
|
||||
void init_c_symtab_symbols(Elf_Binary_t* c_binary, Binary* binary);
|
||||
|
||||
void destroy_dynamic_symbols(Elf_Binary_t* c_binary);
|
||||
void destroy_symtab_symbols(Elf_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "LIEF/MachO/Binary.h"
|
||||
|
||||
#include "LIEF/MachO/Binary.hpp"
|
||||
|
||||
#include "Binary.hpp"
|
||||
#include "Section.hpp"
|
||||
#include "Header.hpp"
|
||||
#include "Symbol.hpp"
|
||||
#include "Segment.hpp"
|
||||
#include "LoadCommand.hpp"
|
||||
|
||||
|
||||
using namespace LIEF::MachO;
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
void init_c_binary(Macho_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
c_binary->handler = reinterpret_cast<void*>(binary);
|
||||
c_binary->imagebase = binary->imagebase();
|
||||
init_c_header(c_binary, binary);
|
||||
init_c_commands(c_binary, binary);
|
||||
init_c_symbols(c_binary, binary);
|
||||
init_c_sections(c_binary, binary);
|
||||
init_c_segments(c_binary, binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void macho_binaries_destroy(Macho_Binary_t** binaries) {
|
||||
for (size_t i = 0; binaries[i] != nullptr; ++i) {
|
||||
destroy_sections(binaries[i]);
|
||||
destroy_commands(binaries[i]);
|
||||
destroy_symbols(binaries[i]);
|
||||
destroy_segments(binaries[i]);
|
||||
|
||||
delete reinterpret_cast<Binary*>(binaries[i]->handler);
|
||||
free(binaries[i]);
|
||||
}
|
||||
free(binaries);
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
Parser.cpp
|
||||
LoadCommand.cpp
|
||||
Segment.cpp
|
||||
Symbol.cpp
|
||||
Section.cpp
|
||||
Header.cpp
|
||||
Binary.cpp
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Header.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
void init_c_header(Macho_Binary_t* c_binary, Binary* binary) {
|
||||
Header& header = binary->header();
|
||||
c_binary->header.magic = static_cast<uint32_t>(header.magic());
|
||||
c_binary->header.cpu_type = static_cast<enum LIEF_MACHO_CPU_TYPES>(header.cpu_type());
|
||||
c_binary->header.cpu_subtype = header.cpu_subtype();
|
||||
c_binary->header.file_type = static_cast<enum LIEF_MACHO_FILE_TYPES>(header.file_type());
|
||||
c_binary->header.nb_cmds = header.nb_cmds();
|
||||
c_binary->header.sizeof_cmds = header.sizeof_cmds();
|
||||
c_binary->header.flags = header.flags();
|
||||
c_binary->header.reserved = header.reserved();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "LoadCommand.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
void init_c_commands(Macho_Binary_t* c_binary, Binary* binary) {
|
||||
Binary::it_commands commands = binary->commands();
|
||||
|
||||
c_binary->commands = static_cast<Macho_Command_t**>(
|
||||
malloc((commands.size() + 1) * sizeof(Macho_Command_t**)));
|
||||
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
LoadCommand& cmd = commands[i];
|
||||
|
||||
c_binary->commands[i] = static_cast<Macho_Command_t*>(malloc(sizeof(Macho_Command_t)));
|
||||
const span<const uint8_t> cmd_content = cmd.data();
|
||||
auto* content = static_cast<uint8_t*>(malloc(cmd_content.size() * sizeof(uint8_t)));
|
||||
std::copy(
|
||||
std::begin(cmd_content),
|
||||
std::end(cmd_content),
|
||||
content);
|
||||
|
||||
c_binary->commands[i]->command = static_cast<enum LIEF_MACHO_LOAD_COMMAND_TYPES>(cmd.command());
|
||||
c_binary->commands[i]->size = cmd.size();
|
||||
c_binary->commands[i]->data = content;
|
||||
c_binary->commands[i]->offset = cmd.command_offset();
|
||||
}
|
||||
|
||||
c_binary->commands[commands.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_commands(Macho_Binary_t* c_binary) {
|
||||
Macho_Command_t **commands = c_binary->commands;
|
||||
for (size_t idx = 0; commands[idx] != nullptr; ++idx) {
|
||||
free(commands[idx]->data);
|
||||
free(commands[idx]);
|
||||
}
|
||||
free(c_binary->commands);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_MACHO_LOAD_COMMAND_CPP_C_API_
|
||||
#define LIEF_MACHO_LOAD_COMMAND_CPP_C_API_
|
||||
|
||||
#include "LIEF/MachO/Binary.h"
|
||||
#include "LIEF/MachO/Binary.hpp"
|
||||
|
||||
#include "LIEF/MachO/LoadCommand.h"
|
||||
#include "LIEF/MachO/LoadCommand.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
|
||||
void init_c_commands(Macho_Binary_t* c_binary, Binary* binary);
|
||||
void destroy_commands(Macho_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,52 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <cstring>
|
||||
|
||||
#include "LIEF/MachO/Binary.h"
|
||||
#include "LIEF/MachO/Parser.hpp"
|
||||
#include "LIEF/MachO/FatBinary.hpp"
|
||||
|
||||
#include "Binary.hpp"
|
||||
|
||||
using namespace LIEF::MachO;
|
||||
|
||||
Macho_Binary_t** macho_parse(const char *file) {
|
||||
FatBinary* fat = Parser::parse(file).release();
|
||||
if (fat == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t nb_bin = fat->size();
|
||||
|
||||
auto** c_macho_binaries = static_cast<Macho_Binary_t**>(
|
||||
malloc((fat->size() + 1) * sizeof(Macho_Binary_t**)));
|
||||
|
||||
for (size_t i = 0; i < nb_bin; ++i) {
|
||||
Binary* binary = fat->at(i);
|
||||
if (binary != nullptr) {
|
||||
c_macho_binaries[i] = static_cast<Macho_Binary_t*>(malloc(sizeof(Macho_Binary_t)));
|
||||
init_c_binary(c_macho_binaries[i], binary);
|
||||
}
|
||||
}
|
||||
|
||||
fat->release_all_binaries();
|
||||
|
||||
c_macho_binaries[nb_bin] = nullptr;
|
||||
delete fat;
|
||||
|
||||
return c_macho_binaries;
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Section.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
void init_c_sections(Macho_Binary_t* c_binary, Binary* binary) {
|
||||
Binary::it_sections sections = binary->sections();
|
||||
|
||||
c_binary->sections = static_cast<Macho_Section_t**>(
|
||||
malloc((sections.size() + 1) * sizeof(Macho_Section_t**)));
|
||||
|
||||
for (size_t i = 0; i < sections.size(); ++i) {
|
||||
const Section& section = sections[i];
|
||||
|
||||
c_binary->sections[i] = static_cast<Macho_Section_t*>(malloc(sizeof(Macho_Section_t)));
|
||||
span<const uint8_t> section_content = section.content();
|
||||
auto* content = static_cast<uint8_t*>(malloc(section_content.size() * sizeof(uint8_t)));
|
||||
std::copy(std::begin(section_content), std::end(section_content),
|
||||
content);
|
||||
|
||||
c_binary->sections[i]->name = section.fullname().c_str();
|
||||
c_binary->sections[i]->alignment = section.alignment();
|
||||
c_binary->sections[i]->relocation_offset = section.relocation_offset();
|
||||
c_binary->sections[i]->numberof_relocations = section.numberof_relocations();
|
||||
c_binary->sections[i]->flags = section.raw_flags();
|
||||
c_binary->sections[i]->type = static_cast<enum LIEF_MACHO_MACHO_SECTION_TYPES>(section.type());
|
||||
c_binary->sections[i]->reserved1 = section.reserved1();
|
||||
c_binary->sections[i]->reserved2 = section.reserved2();
|
||||
c_binary->sections[i]->reserved3 = section.reserved3();
|
||||
c_binary->sections[i]->virtual_address = section.virtual_address();
|
||||
c_binary->sections[i]->offset = section.offset();
|
||||
c_binary->sections[i]->size = section_content.size();
|
||||
c_binary->sections[i]->content = content;
|
||||
c_binary->sections[i]->entropy = section.entropy();
|
||||
}
|
||||
|
||||
c_binary->sections[sections.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void destroy_sections(Macho_Binary_t* c_binary) {
|
||||
Macho_Section_t **sections = c_binary->sections;
|
||||
for (size_t idx = 0; sections[idx] != nullptr; ++idx) {
|
||||
free(sections[idx]->content);
|
||||
free(sections[idx]);
|
||||
}
|
||||
free(c_binary->sections);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_MACHO_SECTION_CPP_C_API_
|
||||
#define LIEF_MACHO_SECTION_CPP_C_API_
|
||||
|
||||
#include "LIEF/MachO/Binary.h"
|
||||
#include "LIEF/MachO/Binary.hpp"
|
||||
|
||||
#include "LIEF/MachO/Section.h"
|
||||
#include "LIEF/MachO/Section.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
|
||||
void init_c_sections(Macho_Binary_t* c_binary, Binary* binary);
|
||||
void destroy_sections(Macho_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Segment.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
void init_c_segments(Macho_Binary_t* c_binary, Binary* binary) {
|
||||
Binary::it_segments segments = binary->segments();
|
||||
|
||||
c_binary->segments = static_cast<Macho_Segment_t**>(
|
||||
malloc((segments.size() + 1) * sizeof(Macho_Segment_t**)));
|
||||
|
||||
for (size_t i = 0; i < segments.size(); ++i) {
|
||||
SegmentCommand& segment = segments[i];
|
||||
|
||||
c_binary->segments[i] = static_cast<Macho_Segment_t*>(malloc(sizeof(Macho_Segment_t)));
|
||||
span<const uint8_t> segment_content = segment.content();
|
||||
auto* content = static_cast<uint8_t*>(malloc(segment_content.size() * sizeof(uint8_t)));
|
||||
std::copy(
|
||||
std::begin(segment_content),
|
||||
std::end(segment_content),
|
||||
content);
|
||||
|
||||
c_binary->segments[i]->name = segment.name().c_str();
|
||||
c_binary->segments[i]->virtual_address = segment.virtual_address();
|
||||
c_binary->segments[i]->virtual_size = segment.virtual_size();
|
||||
c_binary->segments[i]->file_size = segment.file_size();
|
||||
c_binary->segments[i]->file_offset = segment.file_offset();
|
||||
c_binary->segments[i]->max_protection = segment.max_protection();
|
||||
c_binary->segments[i]->init_protection = segment.init_protection();
|
||||
c_binary->segments[i]->numberof_sections = segment.numberof_sections();
|
||||
c_binary->segments[i]->flags = segment.flags();
|
||||
c_binary->segments[i]->content = content;
|
||||
c_binary->segments[i]->size = segment_content.size();
|
||||
c_binary->segments[i]->sections = nullptr; //TODO
|
||||
}
|
||||
|
||||
c_binary->segments[segments.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_segments(Macho_Binary_t* c_binary) {
|
||||
Macho_Segment_t **segments = c_binary->segments;
|
||||
for (size_t idx = 0; segments[idx] != nullptr; ++idx) {
|
||||
free(segments[idx]->content);
|
||||
free(segments[idx]);
|
||||
}
|
||||
free(c_binary->segments);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_MACHO_SEGMENT_CPP_C_API_
|
||||
#define LIEF_MACHO_SEGMENT_CPP_C_API_
|
||||
|
||||
#include "LIEF/MachO/Binary.h"
|
||||
#include "LIEF/MachO/Binary.hpp"
|
||||
|
||||
#include "LIEF/MachO/Segment.h"
|
||||
#include "LIEF/MachO/SegmentCommand.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
|
||||
void init_c_segments(Macho_Binary_t* c_binary, Binary* binary);
|
||||
void destroy_segments(Macho_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Symbol.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
void init_c_symbols(Macho_Binary_t* c_binary, Binary* binary) {
|
||||
Binary::it_symbols symbols = binary->symbols();
|
||||
|
||||
c_binary->symbols = static_cast<Macho_Symbol_t**>(
|
||||
malloc((symbols.size() + 1) * sizeof(Macho_Symbol_t**)));
|
||||
|
||||
for (size_t i = 0; i < symbols.size(); ++i) {
|
||||
const Symbol& symbol = symbols[i];
|
||||
|
||||
c_binary->symbols[i] = static_cast<Macho_Symbol_t*>(malloc(sizeof(Macho_Symbol_t)));
|
||||
|
||||
c_binary->symbols[i]->name = symbol.name().c_str();
|
||||
c_binary->symbols[i]->type = symbol.raw_type();
|
||||
c_binary->symbols[i]->numberof_sections = symbol.numberof_sections();
|
||||
c_binary->symbols[i]->description = symbol.description();
|
||||
c_binary->symbols[i]->value = symbol.value();
|
||||
}
|
||||
|
||||
c_binary->symbols[symbols.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_symbols(Macho_Binary_t* c_binary) {
|
||||
Macho_Symbol_t **symbols = c_binary->symbols;
|
||||
for (size_t idx = 0; symbols[idx] != nullptr; ++idx) {
|
||||
free(symbols[idx]);
|
||||
}
|
||||
free(c_binary->symbols);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <cstring>
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
|
||||
#include "LIEF/PE/Parser.hpp"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "Binary.hpp"
|
||||
#include "DosHeader.hpp"
|
||||
#include "Header.hpp"
|
||||
#include "OptionalHeader.hpp"
|
||||
#include "Section.hpp"
|
||||
#include "DataDirectory.hpp"
|
||||
#include "Import.hpp"
|
||||
|
||||
using namespace LIEF::PE;
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_binary(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
c_binary->handler = reinterpret_cast<void*>(binary);
|
||||
|
||||
init_c_dos_header(c_binary, binary);
|
||||
init_c_header(c_binary, binary);
|
||||
init_c_optional_header(c_binary, binary);
|
||||
init_c_sections(c_binary, binary);
|
||||
init_c_data_directories(c_binary, binary);
|
||||
init_c_imports(c_binary, binary);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Pe_Binary_t* pe_parse(const char *file) {
|
||||
Binary* binary = Parser::parse(file).release();
|
||||
|
||||
if (binary == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* c_binary = static_cast<Pe_Binary_t*>(malloc(sizeof(Pe_Binary_t)));
|
||||
std::memset(c_binary, 0, sizeof(Pe_Binary_t));
|
||||
init_c_binary(c_binary, binary);
|
||||
|
||||
return c_binary;
|
||||
}
|
||||
|
||||
void pe_binary_destroy(Pe_Binary_t* binary) {
|
||||
destroy_sections(binary);
|
||||
destroy_data_directories(binary);
|
||||
destroy_imports(binary);
|
||||
delete reinterpret_cast<Binary*>(binary->handler);
|
||||
free(binary);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
target_sources(LIB_LIEF PRIVATE
|
||||
Binary.cpp
|
||||
DosHeader.cpp
|
||||
Header.cpp
|
||||
OptionalHeader.cpp
|
||||
Section.cpp
|
||||
DataDirectory.cpp
|
||||
Import.cpp
|
||||
ImportEntry.cpp
|
||||
)
|
||||
@@ -1,54 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "DataDirectory.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
void init_c_data_directories(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
Binary::it_data_directories data_directories = binary->data_directories();
|
||||
|
||||
c_binary->data_directories = static_cast<Pe_DataDirectory_t**>(
|
||||
malloc((data_directories.size() + 1) * sizeof(Pe_DataDirectory_t**)));
|
||||
|
||||
for (size_t i = 0; i < data_directories.size(); ++i) {
|
||||
|
||||
c_binary->data_directories[i] = static_cast<Pe_DataDirectory_t*>(malloc(sizeof(Pe_DataDirectory_t)));
|
||||
c_binary->data_directories[i]->rva = data_directories[i].RVA();
|
||||
c_binary->data_directories[i]->size = data_directories[i].size();
|
||||
}
|
||||
c_binary->data_directories[data_directories.size()] = nullptr;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_data_directories(Pe_Binary_t* c_binary) {
|
||||
|
||||
Pe_DataDirectory_t **data_directories = c_binary->data_directories;
|
||||
for (size_t idx = 0; data_directories[idx] != nullptr; ++idx) {
|
||||
free(data_directories[idx]);
|
||||
}
|
||||
free(c_binary->data_directories);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_DATA_DIRECTORY_CPP_C_API
|
||||
#define LIEF_PE_DATA_DIRECTORY_CPP_C_API
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/DataDirectory.h"
|
||||
#include "LIEF/PE/DataDirectory.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_data_directories(Pe_Binary_t* c_binary, Binary* binary);
|
||||
void destroy_data_directories(Pe_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "DosHeader.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
void init_c_dos_header(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
const DosHeader& dos_header = binary->dos_header();
|
||||
c_binary->dos_header.magic = dos_header.magic();
|
||||
c_binary->dos_header.used_bytes_in_last_page = dos_header.used_bytes_in_last_page();
|
||||
c_binary->dos_header.file_size_in_pages = dos_header.file_size_in_pages();
|
||||
c_binary->dos_header.numberof_relocation = dos_header.numberof_relocation();
|
||||
c_binary->dos_header.header_size_in_paragraphs = dos_header.header_size_in_paragraphs();
|
||||
c_binary->dos_header.minimum_extra_paragraphs = dos_header.minimum_extra_paragraphs();
|
||||
c_binary->dos_header.maximum_extra_paragraphs = dos_header.maximum_extra_paragraphs();
|
||||
c_binary->dos_header.initial_relative_ss = dos_header.initial_relative_ss();
|
||||
c_binary->dos_header.initial_sp = dos_header.initial_sp();
|
||||
c_binary->dos_header.checksum = dos_header.checksum();
|
||||
c_binary->dos_header.initial_ip = dos_header.initial_ip();
|
||||
c_binary->dos_header.initial_relative_cs = dos_header.initial_relative_cs();
|
||||
c_binary->dos_header.addressof_relocation_table = dos_header.addressof_relocation_table();
|
||||
c_binary->dos_header.overlay_number = dos_header.overlay_number();
|
||||
c_binary->dos_header.oem_id = dos_header.oem_id();
|
||||
c_binary->dos_header.oem_info = dos_header.oem_info();
|
||||
c_binary->dos_header.addressof_new_exeheader = dos_header.addressof_new_exeheader();
|
||||
|
||||
const DosHeader::reserved_t& reserved = dos_header.reserved();
|
||||
std::copy(
|
||||
std::begin(reserved),
|
||||
std::end(reserved),
|
||||
c_binary->dos_header.reserved);
|
||||
|
||||
|
||||
const DosHeader::reserved2_t& reserved2 = dos_header.reserved2();
|
||||
std::copy(
|
||||
std::begin(reserved2),
|
||||
std::end(reserved2),
|
||||
c_binary->dos_header.reserved2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_DOS_HEADER_CPP_C_API_
|
||||
#define LIEF_PE_DOS_HEADER_CPP_C_API_
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/DosHeader.h"
|
||||
#include "LIEF/PE/DosHeader.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_dos_header(Pe_Binary_t* c_binary, Binary* binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Header.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_header(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
const Header& header = binary->header();
|
||||
|
||||
const Header::signature_t& signature = header.signature();
|
||||
|
||||
c_binary->header.machine = static_cast<enum LIEF_PE_MACHINE_TYPES>(header.machine());
|
||||
c_binary->header.numberof_sections = header.numberof_sections();
|
||||
c_binary->header.time_date_stamp = header.time_date_stamp();
|
||||
c_binary->header.pointerto_symbol_table = header.pointerto_symbol_table();
|
||||
c_binary->header.numberof_symbols = header.numberof_symbols();
|
||||
c_binary->header.sizeof_optional_header = header.sizeof_optional_header();
|
||||
c_binary->header.characteristics = static_cast<uint16_t>(header.characteristics());
|
||||
|
||||
std::copy(std::begin(signature), std::end(signature),
|
||||
c_binary->header.signature);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const char* lief_pe_header_machine_str(enum LIEF_PE_MACHINE_TYPES e) {
|
||||
return LIEF::PE::to_string(static_cast<LIEF::PE::Header::MACHINE_TYPES>(e));
|
||||
}
|
||||
|
||||
const char* lief_pe_header_characteristics_str(enum LIEF_PE_HEADER_CHARACTERISTICS e) {
|
||||
return LIEF::PE::to_string(static_cast<LIEF::PE::Header::CHARACTERISTICS>(e));
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_HEADER_CPP_C_API_
|
||||
#define LIEF_PE_HEADER_CPP_C_API_
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/Header.h"
|
||||
#include "LIEF/PE/Header.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_header(Pe_Binary_t* c_binary, Binary* binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Import.hpp"
|
||||
#include "ImportEntry.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_imports(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
if (!binary->has_imports()) {
|
||||
c_binary->imports = nullptr;
|
||||
}
|
||||
|
||||
Binary::it_imports imports = binary->imports();
|
||||
|
||||
c_binary->imports = static_cast<Pe_Import_t**>(
|
||||
malloc((imports.size() + 1) * sizeof(Pe_Import_t**)));
|
||||
|
||||
for (size_t i = 0; i < imports.size(); ++i) {
|
||||
Import& imp = imports[i];
|
||||
c_binary->imports[i] = static_cast<Pe_Import_t*>(malloc(sizeof(Pe_Import_t)));
|
||||
|
||||
c_binary->imports[i]->name = imp.name().c_str();
|
||||
c_binary->imports[i]->forwarder_chain = imp.forwarder_chain();
|
||||
c_binary->imports[i]->timedatestamp = imp.forwarder_chain();
|
||||
c_binary->imports[i]->import_address_table_rva = imp.import_address_table_rva();
|
||||
c_binary->imports[i]->import_lookup_table_rva = imp.import_lookup_table_rva();
|
||||
c_binary->imports[i]->entries = nullptr;
|
||||
init_c_import_entries(c_binary->imports[i], imp);
|
||||
}
|
||||
|
||||
c_binary->imports[imports.size()] = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void destroy_imports(Pe_Binary_t* c_binary) {
|
||||
if (c_binary->imports == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pe_Import_t **imports = c_binary->imports;
|
||||
for (size_t idx = 0; imports[idx] != nullptr; ++idx) {
|
||||
destroy_import_entries(imports[idx]);
|
||||
free(imports[idx]);
|
||||
}
|
||||
free(c_binary->imports);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_IMPORT_CPP_C_API_
|
||||
#define LIEF_PE_IMPORT_CPP_C_API_
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/Import.h"
|
||||
#include "LIEF/PE/Import.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_imports(Pe_Binary_t* c_binary, Binary* binary);
|
||||
void destroy_imports(Pe_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ImportEntry.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_import_entries(Pe_Import_t* c_import, Import& imp) {
|
||||
|
||||
Import::it_entries entries = imp.entries();
|
||||
|
||||
c_import->entries = static_cast<Pe_ImportEntry_t**>(
|
||||
malloc((entries.size() + 1) * sizeof(Pe_ImportEntry_t**)));
|
||||
|
||||
for (size_t i = 0; i < entries.size(); ++i) {
|
||||
ImportEntry& import_entry = entries[i];
|
||||
c_import->entries[i] = static_cast<Pe_ImportEntry_t*>(malloc(sizeof(Pe_ImportEntry_t)));
|
||||
|
||||
c_import->entries[i]->is_ordinal = import_entry.is_ordinal();
|
||||
c_import->entries[i]->name = import_entry.is_ordinal() ? nullptr : import_entry.name().c_str();
|
||||
c_import->entries[i]->ordinal = import_entry.is_ordinal() ? import_entry.ordinal() : 0;
|
||||
c_import->entries[i]->hint_name_rva = import_entry.hint_name_rva();
|
||||
c_import->entries[i]->hint = import_entry.hint();
|
||||
c_import->entries[i]->iat_value = import_entry.iat_value();
|
||||
c_import->entries[i]->data = import_entry.data();
|
||||
c_import->entries[i]->iat_address = import_entry.iat_address();
|
||||
}
|
||||
|
||||
c_import->entries[entries.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void destroy_import_entries(Pe_Import_t* c_import) {
|
||||
Pe_ImportEntry_t **entries = c_import->entries;
|
||||
for (size_t idx = 0; entries[idx] != nullptr; ++idx) {
|
||||
free(entries[idx]);
|
||||
}
|
||||
free(c_import->entries);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_IMPORT_ENTRY_CPP_C_API_
|
||||
#define LIEF_PE_IMPORT_ENTRY_CPP_C_API_
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/ImportEntry.h"
|
||||
#include "LIEF/PE/ImportEntry.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_import_entries(Pe_Import_t* c_import, Import& imp);
|
||||
void destroy_import_entries(Pe_Import_t* c_import);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "OptionalHeader.hpp"
|
||||
#include "LIEF/PE/OptionalHeader.h"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_optional_header(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
const OptionalHeader& optional_header = binary->optional_header();
|
||||
c_binary->optional_header.magic = static_cast<uint16_t>(optional_header.magic());
|
||||
c_binary->optional_header.major_linker_version = optional_header.major_linker_version();
|
||||
c_binary->optional_header.minor_linker_version = optional_header.minor_linker_version();
|
||||
c_binary->optional_header.sizeof_code = optional_header.sizeof_code();
|
||||
c_binary->optional_header.sizeof_initialized_data = optional_header.sizeof_initialized_data();
|
||||
c_binary->optional_header.sizeof_uninitialized_data = optional_header.sizeof_uninitialized_data();
|
||||
c_binary->optional_header.addressof_entrypoint = optional_header.addressof_entrypoint();
|
||||
c_binary->optional_header.baseof_code = optional_header.baseof_code();
|
||||
if (optional_header.magic() == PE_TYPE::PE32) {
|
||||
c_binary->optional_header.baseof_data = optional_header.baseof_data();
|
||||
} else {
|
||||
c_binary->optional_header.baseof_data = 0;
|
||||
}
|
||||
c_binary->optional_header.imagebase = optional_header.imagebase();
|
||||
c_binary->optional_header.section_alignment = optional_header.section_alignment();
|
||||
c_binary->optional_header.file_alignment = optional_header.file_alignment();
|
||||
c_binary->optional_header.major_operating_system_version = optional_header.major_operating_system_version();
|
||||
c_binary->optional_header.minor_operating_system_version = optional_header.minor_operating_system_version();
|
||||
c_binary->optional_header.major_image_version = optional_header.major_image_version();
|
||||
c_binary->optional_header.minor_image_version = optional_header.minor_image_version();
|
||||
c_binary->optional_header.major_subsystem_version = optional_header.major_subsystem_version();
|
||||
c_binary->optional_header.minor_subsystem_version = optional_header.minor_subsystem_version();
|
||||
c_binary->optional_header.win32_version_value = optional_header.win32_version_value();
|
||||
c_binary->optional_header.sizeof_image = optional_header.sizeof_image();
|
||||
c_binary->optional_header.sizeof_headers = optional_header.sizeof_headers();
|
||||
c_binary->optional_header.checksum = optional_header.checksum();
|
||||
c_binary->optional_header.subsystem = static_cast<enum LIEF_PE_SUBSYSTEM>(optional_header.subsystem());
|
||||
c_binary->optional_header.dll_characteristics = optional_header.dll_characteristics();
|
||||
c_binary->optional_header.sizeof_stack_reserve = optional_header.sizeof_stack_reserve();
|
||||
c_binary->optional_header.sizeof_stack_commit = optional_header.sizeof_stack_commit();
|
||||
c_binary->optional_header.sizeof_heap_reserve = optional_header.sizeof_heap_reserve();
|
||||
c_binary->optional_header.sizeof_heap_commit = optional_header.sizeof_heap_commit();
|
||||
c_binary->optional_header.loader_flags = optional_header.loader_flags();
|
||||
c_binary->optional_header.numberof_rva_and_size = optional_header.numberof_rva_and_size();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const char* lief_pe_subsytem_str(enum LIEF_PE_SUBSYSTEM e) {
|
||||
return LIEF::PE::to_string(static_cast<LIEF::PE::OptionalHeader::SUBSYSTEM>(e));
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_OPTIONAL_HEADER_CPP_C_API_
|
||||
#define LIEF_PE_OPTIONAL_HEADER_CPP_C_API_
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/OptionalHeader.h"
|
||||
#include "LIEF/PE/OptionalHeader.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_optional_header(Pe_Binary_t* c_binary, Binary* binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,71 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Section.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
void init_c_sections(Pe_Binary_t* c_binary, Binary* binary) {
|
||||
|
||||
Binary::it_sections sections = binary->sections();
|
||||
|
||||
c_binary->sections = static_cast<Pe_Section_t**>(
|
||||
malloc((sections.size() + 1) * sizeof(Pe_Section_t**)));
|
||||
|
||||
for (size_t i = 0; i < sections.size(); ++i) {
|
||||
Section& b_section = sections[i];
|
||||
c_binary->sections[i] = static_cast<Pe_Section_t*>(malloc(sizeof(Pe_Section_t)));
|
||||
span<const uint8_t> section_content = b_section.content();
|
||||
uint8_t* content = nullptr;
|
||||
|
||||
if (!section_content.empty()) {
|
||||
content = static_cast<uint8_t*>(malloc(section_content.size() * sizeof(uint8_t)));
|
||||
std::copy(std::begin(section_content), std::end(section_content),
|
||||
content);
|
||||
}
|
||||
|
||||
c_binary->sections[i]->name = b_section.fullname().c_str();
|
||||
c_binary->sections[i]->virtual_address = b_section.virtual_address();
|
||||
c_binary->sections[i]->size = b_section.size();
|
||||
c_binary->sections[i]->offset = b_section.offset();
|
||||
c_binary->sections[i]->virtual_size = b_section.virtual_size();
|
||||
c_binary->sections[i]->pointerto_relocation = b_section.pointerto_relocation();
|
||||
c_binary->sections[i]->pointerto_line_numbers = b_section.pointerto_line_numbers();
|
||||
c_binary->sections[i]->characteristics = b_section.characteristics();
|
||||
c_binary->sections[i]->content = content;
|
||||
c_binary->sections[i]->content_size = section_content.size();
|
||||
c_binary->sections[i]->entropy = b_section.entropy();
|
||||
}
|
||||
c_binary->sections[sections.size()] = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy_sections(Pe_Binary_t* c_binary) {
|
||||
|
||||
Pe_Section_t **sections = c_binary->sections;
|
||||
for (size_t idx = 0; sections[idx] != nullptr; ++idx) {
|
||||
free(sections[idx]->content);
|
||||
free(sections[idx]);
|
||||
}
|
||||
free(c_binary->sections);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_SECTION_CPP_C_API_
|
||||
#define LIEF_PE_SECTION_CPP_C_API_
|
||||
|
||||
#include "LIEF/PE/Binary.h"
|
||||
#include "LIEF/PE/Binary.hpp"
|
||||
|
||||
#include "LIEF/PE/Section.h"
|
||||
#include "LIEF/PE/Section.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
void init_c_sections(Pe_Binary_t* c_binary, Binary* binary);
|
||||
void destroy_sections(Pe_Binary_t* c_binary);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,26 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_ELF_H_
|
||||
#define C_LIEF_ELF_H_
|
||||
|
||||
#include "LIEF/ELF/Binary.h"
|
||||
#include "LIEF/ELF/Symbol.h"
|
||||
#include "LIEF/ELF/Section.h"
|
||||
#include "LIEF/ELF/Header.h"
|
||||
#include "LIEF/ELF/DynamicEntry.h"
|
||||
#include "LIEF/ELF/utils.h"
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_C_ELF_BINARY_H
|
||||
#define LIEF_C_ELF_BINARY_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/ELF/enums.h"
|
||||
|
||||
#include "LIEF/ELF/Section.h"
|
||||
#include "LIEF/ELF/Segment.h"
|
||||
#include "LIEF/ELF/Header.h"
|
||||
#include "LIEF/ELF/DynamicEntry.h"
|
||||
#include "LIEF/ELF/Symbol.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** LIEF::ELF::Binary C Handler */
|
||||
struct Elf_Binary_t {
|
||||
void* handler;
|
||||
const char* interpreter;
|
||||
uint32_t type;
|
||||
Elf_Header_t header;
|
||||
Elf_Section_t **sections;
|
||||
Elf_Segment_t **segments;
|
||||
Elf_DynamicEntry_t **dynamic_entries;
|
||||
Elf_Symbol_t **dynamic_symbols;
|
||||
Elf_Symbol_t **symtab_symbols;
|
||||
};
|
||||
|
||||
typedef struct Elf_Binary_t Elf_Binary_t;
|
||||
|
||||
/** Wrapper for LIEF::ELF::Parser::parse */
|
||||
LIEF_API Elf_Binary_t* elf_parse(const char *file);
|
||||
|
||||
LIEF_API void elf_binary_destroy(Elf_Binary_t* binary);
|
||||
|
||||
/** Update LIEF::ELF::Header object */
|
||||
LIEF_API int elf_binary_save_header(Elf_Binary_t* binary);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,77 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_C_ELF_DYNAMIC_ENTRY_H
|
||||
#define LIEF_C_ELF_DYNAMIC_ENTRY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Elf_DynamicEntry_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
struct Elf_DynamicEntry_Library_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
struct Elf_DynamicEntry_SharedObject_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
struct Elf_DynamicEntry_Array_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
uint64_t* array;
|
||||
};
|
||||
|
||||
struct Elf_DynamicEntry_Rpath_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
const char* rpath;
|
||||
};
|
||||
|
||||
struct Elf_DynamicEntry_RunPath_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
const char* runpath;
|
||||
};
|
||||
|
||||
struct Elf_DynamicEntry_Flags_t {
|
||||
uint64_t tag;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
typedef struct Elf_DynamicEntry_t Elf_DynamicEntry_t;
|
||||
typedef struct Elf_DynamicEntry_Library_t Elf_DynamicEntry_Library_t;
|
||||
typedef struct Elf_DynamicEntry_SharedObject_t Elf_DynamicEntry_SharedObject_t;
|
||||
typedef struct Elf_DynamicEntry_Array_t Elf_DynamicEntry_Array_t;
|
||||
typedef struct Elf_DynamicEntry_Rpath_t Elf_DynamicEntry_Rpath_t;
|
||||
typedef struct Elf_DynamicEntry_RunPath_t Elf_DynamicEntry_RunPath_t;
|
||||
typedef struct Elf_DynamicEntry_Flags_t Elf_DynamicEntry_Flags_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_C_ELF_HEADER_H
|
||||
#define LIEF_C_ELF_HEADER_H
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/ELF/enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Elf_Header_t {
|
||||
uint8_t identity[LIEF_EI_NIDENT];
|
||||
uint32_t file_type;
|
||||
uint32_t machine_type;
|
||||
uint32_t object_file_version;
|
||||
uint64_t entrypoint;
|
||||
uint64_t program_headers_offset;
|
||||
uint64_t section_headers_offset;
|
||||
uint32_t processor_flags;
|
||||
uint32_t header_size;
|
||||
uint32_t program_header_size;
|
||||
uint32_t numberof_segments;
|
||||
uint32_t section_header_size;
|
||||
uint32_t numberof_sections;
|
||||
uint32_t name_string_table_idx;
|
||||
};
|
||||
|
||||
typedef struct Elf_Header_t Elf_Header_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_C_ELF_SECTION_H
|
||||
#define LIEF_C_ELF_SECTION_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Elf_Section_t {
|
||||
const char* name;
|
||||
uint32_t flags;
|
||||
uint32_t type;
|
||||
uint64_t virtual_address;
|
||||
uint64_t offset;
|
||||
uint64_t original_size;
|
||||
uint32_t link;
|
||||
uint32_t info;
|
||||
uint64_t alignment;
|
||||
uint64_t entry_size;
|
||||
uint64_t size;
|
||||
uint8_t* content;
|
||||
double entropy;
|
||||
};
|
||||
|
||||
typedef struct Elf_Section_t Elf_Section_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_C_ELF_SYMBOL_H
|
||||
#define LIEF_C_ELF_SYMBOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LIEF/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Elf_Symbol_t {
|
||||
const char* name;
|
||||
uint32_t type;
|
||||
uint32_t binding;
|
||||
uint8_t information;
|
||||
uint8_t other;
|
||||
uint16_t shndx;
|
||||
uint64_t value;
|
||||
uint64_t size;
|
||||
uint8_t is_exported; /**< Whether or not the symbol is exported */
|
||||
uint8_t is_imported; /**< Whether or not the symbol is imported */
|
||||
};
|
||||
|
||||
typedef struct Elf_Symbol_t Elf_Symbol_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_MACHO_H_
|
||||
#define C_LIEF_MACHO_H_
|
||||
|
||||
#include "LIEF/MachO/Binary.h"
|
||||
#include "LIEF/MachO/Symbol.h"
|
||||
#include "LIEF/MachO/Segment.h"
|
||||
#include "LIEF/MachO/Section.h"
|
||||
#include "LIEF/MachO/LoadCommand.h"
|
||||
#include "LIEF/MachO/Header.h"
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_MACHO_BINARY_H_
|
||||
#define C_LIEF_MACHO_BINARY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/MachO/Header.h"
|
||||
#include "LIEF/MachO/LoadCommand.h"
|
||||
#include "LIEF/MachO/Symbol.h"
|
||||
#include "LIEF/MachO/Section.h"
|
||||
#include "LIEF/MachO/Segment.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief LIEF::MachO::Binary C Handler */
|
||||
struct Macho_Binary_t {
|
||||
void* handler;
|
||||
uint64_t imagebase;
|
||||
Macho_Header_t header;
|
||||
Macho_Command_t** commands;
|
||||
Macho_Symbol_t** symbols;
|
||||
Macho_Section_t** sections;
|
||||
Macho_Segment_t** segments;
|
||||
|
||||
};
|
||||
|
||||
typedef struct Macho_Binary_t Macho_Binary_t;
|
||||
|
||||
/** @brief Wrapper on LIEF::MachO::Parser::parse */
|
||||
LIEF_API Macho_Binary_t** macho_parse(const char *file);
|
||||
|
||||
LIEF_API void macho_binaries_destroy(Macho_Binary_t** binaries);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_MACHO_HEADER_H_
|
||||
#define C_LIEF_MACHO_HEADER_H_
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/MachO/enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Macho_Header_t {
|
||||
uint32_t magic;
|
||||
enum LIEF_MACHO_CPU_TYPES cpu_type;
|
||||
uint32_t cpu_subtype;
|
||||
enum LIEF_MACHO_FILE_TYPES file_type;
|
||||
uint32_t nb_cmds;
|
||||
uint32_t sizeof_cmds;
|
||||
uint32_t flags;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
typedef struct Macho_Header_t Macho_Header_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_MACHO_SECTION_H_
|
||||
#define C_LIEF_MACHO_SECTION_H_
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/MachO/enums.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Macho_Section_t {
|
||||
|
||||
const char* name;
|
||||
uint32_t alignment;
|
||||
uint32_t relocation_offset;
|
||||
uint32_t numberof_relocations;
|
||||
uint32_t flags;
|
||||
enum LIEF_MACHO_MACHO_SECTION_TYPES type;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
uint32_t reserved3;
|
||||
uint64_t virtual_address;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
uint8_t* content;
|
||||
double entropy;
|
||||
};
|
||||
|
||||
typedef struct Macho_Section_t Macho_Section_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,48 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_MACHO_SEGMENT_H_
|
||||
#define C_LIEF_MACHO_SEGMENT_H_
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/MachO/enums.h"
|
||||
#include "LIEF/MachO/Section.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Macho_Segment_t {
|
||||
const char* name;
|
||||
uint64_t virtual_address;
|
||||
uint64_t virtual_size;
|
||||
uint64_t file_size;
|
||||
uint64_t file_offset;
|
||||
uint32_t max_protection;
|
||||
uint32_t init_protection;
|
||||
uint32_t numberof_sections;
|
||||
uint32_t flags;
|
||||
uint8_t* content;
|
||||
uint64_t size;
|
||||
Macho_Section_t** sections;
|
||||
};
|
||||
|
||||
typedef struct Macho_Segment_t Macho_Segment_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef LIEF_MACHO_C_ENUMS_H_
|
||||
#define LIEF_MACHO_C_ENUMS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _LIEF_EN
|
||||
#undef _LIEF_EN
|
||||
#endif
|
||||
|
||||
#ifdef _LIEF_EN_2
|
||||
#undef _LIEF_EN_2
|
||||
#endif
|
||||
|
||||
#ifdef _LIEF_EI
|
||||
#undef _LIEF_EI
|
||||
#endif
|
||||
|
||||
#define _LIEF_EN(N) LIEF_MACHO_##N
|
||||
#define _LIEF_EN_2(N, TYPE) LIEF_MACHO_##N
|
||||
#define _LIEF_EI(X) LIEF_MACHO_##X
|
||||
|
||||
#include "LIEF/MachO/enums.inc"
|
||||
|
||||
#undef _LIEF_EN
|
||||
#undef _LIEF_EN_2
|
||||
#undef _LIEF_EI
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,58 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_PE_BINARY_H_
|
||||
#define C_LIEF_PE_BINARY_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/enums.h"
|
||||
|
||||
#include "LIEF/PE/DosHeader.h"
|
||||
#include "LIEF/PE/Header.h"
|
||||
#include "LIEF/PE/OptionalHeader.h"
|
||||
#include "LIEF/PE/DataDirectory.h"
|
||||
#include "LIEF/PE/Section.h"
|
||||
#include "LIEF/PE/Import.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief LIEF::PE::Binary C Handler */
|
||||
struct Pe_Binary_t {
|
||||
void* handler;
|
||||
Pe_DosHeader_t dos_header;
|
||||
Pe_Header_t header;
|
||||
Pe_OptionalHeader_t optional_header;
|
||||
Pe_DataDirectory_t** data_directories;
|
||||
Pe_Section_t** sections;
|
||||
Pe_Import_t** imports;
|
||||
};
|
||||
|
||||
typedef struct Pe_Binary_t Pe_Binary_t;
|
||||
|
||||
/** Wrapper on LIEF::PE::Parser::parse */
|
||||
LIEF_API Pe_Binary_t* pe_parse(const char *file);
|
||||
|
||||
LIEF_API void pe_binary_destroy(Pe_Binary_t* binary);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License",;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_PE_DATA_DIRECTORY_H
|
||||
#define C_LIEF_PE_DATA_DIRECTORY_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/PE/enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum LIEF_PE_DATA_DIRECTORY {
|
||||
LIEF_PE_DATA_DIR_EXPORT_TABLE = 0,
|
||||
LIEF_PE_DATA_DIR_IMPORT_TABLE,
|
||||
LIEF_PE_DATA_DIR_RESOURCE_TABLE,
|
||||
LIEF_PE_DATA_DIR_EXCEPTION_TABLE,
|
||||
LIEF_PE_DATA_DIR_CERTIFICATE_TABLE,
|
||||
LIEF_PE_DATA_DIR_BASE_RELOCATION_TABLE,
|
||||
LIEF_PE_DATA_DIR_DEBUG,
|
||||
LIEF_PE_DATA_DIR_ARCHITECTURE,
|
||||
LIEF_PE_DATA_DIR_GLOBAL_PTR,
|
||||
LIEF_PE_DATA_DIR_TLS_TABLE,
|
||||
LIEF_PE_DATA_DIR_LOAD_CONFIG_TABLE,
|
||||
LIEF_PE_DATA_DIR_BOUND_IMPORT,
|
||||
LIEF_PE_DATA_DIR_IAT,
|
||||
LIEF_PE_DATA_DIR_DELAY_IMPORT_DESCRIPTOR,
|
||||
LIEF_PE_DATA_DIR_CLR_RUNTIME_HEADER,
|
||||
LIEF_PE_DATA_DIR_RESERVED,
|
||||
|
||||
LIEF_PE_DATA_DIR_NONE,
|
||||
};
|
||||
|
||||
struct Pe_DataDirectory_t {
|
||||
uint32_t rva;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
typedef struct Pe_DataDirectory_t Pe_DataDirectory_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_PE_DOS_HEADER_H_
|
||||
#define C_LIEF_PE_DOS_HEADER_H_
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/ELF/enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Pe_DosHeader_t {
|
||||
uint16_t magic ;
|
||||
uint16_t used_bytes_in_last_page;
|
||||
uint16_t file_size_in_pages;
|
||||
uint16_t numberof_relocation;
|
||||
uint16_t header_size_in_paragraphs;
|
||||
uint16_t minimum_extra_paragraphs;
|
||||
uint16_t maximum_extra_paragraphs;
|
||||
uint16_t initial_relative_ss;
|
||||
uint16_t initial_sp;
|
||||
uint16_t checksum;
|
||||
uint16_t initial_ip;
|
||||
uint16_t initial_relative_cs;
|
||||
uint16_t addressof_relocation_table;
|
||||
uint16_t overlay_number;
|
||||
uint16_t reserved[4];
|
||||
uint16_t oem_id;
|
||||
uint16_t oem_info;
|
||||
uint16_t reserved2[10];
|
||||
uint32_t addressof_new_exeheader;
|
||||
};
|
||||
|
||||
typedef struct Pe_DosHeader_t Pe_DosHeader_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,95 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_PE_HEADER_H
|
||||
#define C_LIEF_PE_HEADER_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum LIEF_PE_MACHINE_TYPES {
|
||||
LIEF_PE_MACHINE_UNKNOWN = 0x0,
|
||||
LIEF_PE_MACHINE_AM33 = 0x1D3, /**< Matsushita AM33 */
|
||||
LIEF_PE_MACHINE_AMD64 = 0x8664, /**< AMD x64 */
|
||||
LIEF_PE_MACHINE_ARM = 0x1C0, /**< ARM little endian */
|
||||
LIEF_PE_MACHINE_ARMNT = 0x1C4, /**< ARMv7 Thumb mode only */
|
||||
LIEF_PE_MACHINE_ARM64 = 0xAA64, /**< ARMv8 in 64-bits mode */
|
||||
LIEF_PE_MACHINE_EBC = 0xEBC, /**< EFI byte code */
|
||||
LIEF_PE_MACHINE_I386 = 0x14C, /**< Intel 386 or later */
|
||||
LIEF_PE_MACHINE_IA64 = 0x200, /**< Intel Itanium processor family */
|
||||
LIEF_PE_MACHINE_M32R = 0x9041, /**< Mitsubishi M32R little endian */
|
||||
LIEF_PE_MACHINE_MIPS16 = 0x266, /**< MIPS16 */
|
||||
LIEF_PE_MACHINE_MIPSFPU = 0x366, /**< MIPS with FPU */
|
||||
LIEF_PE_MACHINE_MIPSFPU16 = 0x466, /**< MIPS16 with FPU */
|
||||
LIEF_PE_MACHINE_POWERPC = 0x1F0, /**< Power PC little endian */
|
||||
LIEF_PE_MACHINE_POWERPCFP = 0x1F1, /**< Power PC with floating point */
|
||||
LIEF_PE_MACHINE_POWERPCBE = 0x1F2, /**< Power PC big endian */
|
||||
LIEF_PE_MACHINE_R4000 = 0x166, /**< MIPS with little endian */
|
||||
LIEF_PE_MACHINE_RISCV32 = 0x5032, /**< RISC-V 32-bit address space */
|
||||
LIEF_PE_MACHINE_RISCV64 = 0x5064, /**< RISC-V 64-bit address space */
|
||||
LIEF_PE_MACHINE_RISCV128 = 0x5128, /**< RISC-V 128-bit address space */
|
||||
LIEF_PE_MACHINE_SH3 = 0x1A2, /**< Hitachi SH3 */
|
||||
LIEF_PE_MACHINE_SH3DSP = 0x1A3, /**< Hitachi SH3 DSP */
|
||||
LIEF_PE_MACHINE_SH4 = 0x1A6, /**< Hitachi SH4 */
|
||||
LIEF_PE_MACHINE_SH5 = 0x1A8, /**< Hitachi SH5 */
|
||||
LIEF_PE_MACHINE_THUMB = 0x1C2, /**< ARM or Thumb */
|
||||
LIEF_PE_MACHINE_WCEMIPSV2 = 0x169 /**< MIPS little-endian WCE v2 */
|
||||
};
|
||||
|
||||
enum LIEF_PE_HEADER_CHARACTERISTICS {
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_INVALID = 0x0000,
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_RELOCS_STRIPPED = 0x0001, /**< The file does not contain base relocations and must be loaded at its preferred base. If this cannot be done, the loader will error.*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_EXECUTABLE_IMAGE = 0x0002, /**< The file is valid and can be run.*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_LINE_NUMS_STRIPPED = 0x0004, /**< COFF line numbers have been stripped. This is deprecated and should be 0*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_LOCAL_SYMS_STRIPPED = 0x0008, /**< COFF symbol table entries for local symbols have been removed. This is deprecated and should be 0.*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_AGGRESSIVE_WS_TRIM = 0x0010, /**< Aggressively trim working set. This is deprecated and must be 0.*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_LARGE_ADDRESS_AWARE = 0x0020, /**< Image can handle > 2GiB addresses. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_BYTES_REVERSED_LO = 0x0080, /**< Little endian: the LSB precedes the MSB in memory. This is deprecated and should be 0.*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_32BIT_MACHINE = 0x0100, /**< Machine is based on a 32bit word architecture. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_DEBUG_STRIPPED = 0x0200, /**< Debugging info has been removed. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_REMOVABLE_RUN_FROM_SWAP = 0x0400, /**< If the image is on removable media, fully load it and copy it to swap. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_NET_RUN_FROM_SWAP = 0x0800, /**< If the image is on network media, fully load it and copy it to swap. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_SYSTEM = 0x1000, /**< The image file is a system file, not a user program.*/
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_DLL = 0x2000, /**< The image file is a DLL. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_UP_SYSTEM_ONLY = 0x4000, /**< This file should only be run on a uniprocessor machine. */
|
||||
LIEF_PE_HEADER_CHARACTERISTICS_BYTES_REVERSED_HI = 0x8000 /**< Big endian: the MSB precedes the LSB in memory. This is deprecated */
|
||||
};
|
||||
|
||||
struct Pe_Header_t {
|
||||
uint8_t signature[4];
|
||||
enum LIEF_PE_MACHINE_TYPES machine;
|
||||
uint16_t numberof_sections;
|
||||
uint32_t time_date_stamp;
|
||||
uint32_t pointerto_symbol_table;
|
||||
uint32_t numberof_symbols;
|
||||
uint16_t sizeof_optional_header;
|
||||
uint16_t characteristics;
|
||||
};
|
||||
|
||||
typedef struct Pe_Header_t Pe_Header_t;
|
||||
|
||||
LIEF_API const char* lief_pe_header_machine_str(enum LIEF_PE_MACHINE_TYPES e);
|
||||
LIEF_API const char* lief_pe_header_characteristics_str(enum LIEF_PE_HEADER_CHARACTERISTICS e);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_PE_OPTIONAL_HEADER_H
|
||||
#define C_LIEF_PE_OPTIONAL_HEADER_H
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/PE/enums.h"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum LIEF_PE_DLL_CHARACTERISTICS {
|
||||
LIEF_PE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, /**< ASLR with 64 bit address space. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040, /**< DLL can be relocated at load time. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080, /**< Code integrity checks are enforced. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, /**< Image is NX compatible. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200, /**< Isolation aware, but do not isolate the image. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_NO_SEH = 0x0400, /**< Does not use structured exception handling (SEH). No SEH handler may be called in this image. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_NO_BIND = 0x0800, /**< Do not bind the image. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000, /**< Image should execute in an AppContainer. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000, /**< A WDM driver. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000, /**< Image supports Control Flow Guard. */
|
||||
LIEF_PE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 /**< Terminal Server aware. */
|
||||
};
|
||||
|
||||
enum LIEF_PE_SUBSYSTEM {
|
||||
LIEF_PE_SUBSYSTEM_UNKNOWN = 0, /**< An unknown subsystem. */
|
||||
LIEF_PE_SUBSYSTEM_NATIVE = 1, /**< Device drivers and native Windows processes */
|
||||
LIEF_PE_SUBSYSTEM_WINDOWS_GUI = 2, /**< The Windows GUI subsystem. */
|
||||
LIEF_PE_SUBSYSTEM_WINDOWS_CUI = 3, /**< The Windows character subsystem. */
|
||||
LIEF_PE_SUBSYSTEM_OS2_CUI = 5, /**< The OS/2 character subsytem. */
|
||||
LIEF_PE_SUBSYSTEM_POSIX_CUI = 7, /**< The POSIX character subsystem. */
|
||||
LIEF_PE_SUBSYSTEM_NATIVE_WINDOWS = 8, /**< Native Windows 9x driver. */
|
||||
LIEF_PE_SUBSYSTEM_WINDOWS_CE_GUI = 9, /**< Windows CE. */
|
||||
LIEF_PE_SUBSYSTEM_EFI_APPLICATION = 10, /**< An EFI application. */
|
||||
LIEF_PE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, /**< An EFI driver with boot services. */
|
||||
LIEF_PE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, /**< An EFI driver with run-time services. */
|
||||
LIEF_PE_SUBSYSTEM_EFI_ROM = 13, /**< An EFI ROM image. */
|
||||
LIEF_PE_SUBSYSTEM_XBOX = 14, /**< XBOX. */
|
||||
LIEF_PE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16, /**< A BCD application. */
|
||||
LIEF_PE_SUBSYSTEM_XBOX_CODE_CATALOG = 17,
|
||||
};
|
||||
|
||||
struct Pe_OptionalHeader_t {
|
||||
uint16_t magic;
|
||||
uint8_t major_linker_version;
|
||||
uint8_t minor_linker_version;
|
||||
uint32_t sizeof_code;
|
||||
uint32_t sizeof_initialized_data;
|
||||
uint32_t sizeof_uninitialized_data;
|
||||
uint32_t addressof_entrypoint;
|
||||
uint32_t baseof_code;
|
||||
uint32_t baseof_data;
|
||||
uint64_t imagebase;
|
||||
uint32_t section_alignment;
|
||||
uint32_t file_alignment;
|
||||
uint16_t major_operating_system_version;
|
||||
uint16_t minor_operating_system_version;
|
||||
uint16_t major_image_version;
|
||||
uint16_t minor_image_version;
|
||||
uint16_t major_subsystem_version;
|
||||
uint16_t minor_subsystem_version;
|
||||
uint32_t win32_version_value;
|
||||
uint32_t sizeof_image;
|
||||
uint32_t sizeof_headers;
|
||||
uint32_t checksum;
|
||||
enum LIEF_PE_SUBSYSTEM subsystem;
|
||||
uint32_t dll_characteristics;
|
||||
uint64_t sizeof_stack_reserve;
|
||||
uint64_t sizeof_stack_commit;
|
||||
uint64_t sizeof_heap_reserve;
|
||||
uint64_t sizeof_heap_commit;
|
||||
uint32_t loader_flags;
|
||||
uint32_t numberof_rva_and_size;
|
||||
};
|
||||
|
||||
typedef struct Pe_OptionalHeader_t Pe_OptionalHeader_t;
|
||||
|
||||
LIEF_API const char* lief_pe_subsytem_str(enum LIEF_PE_SUBSYSTEM e);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,89 +0,0 @@
|
||||
/* Copyright 2017 - 2026 R. Thomas
|
||||
* Copyright 2017 - 2026 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef C_LIEF_PE_SECTION_H_
|
||||
#define C_LIEF_PE_SECTION_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "LIEF/PE/enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum LIEF_PE_SECTION_CHARACTERISTICS {
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_TYPE_NO_PAD = 0x00000008,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_CNT_CODE = 0x00000020,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_CNT_INITIALIZED_DATA = 0x00000040,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_CNT_UNINITIALIZED_DATA = 0x00000080,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_LNK_OTHER = 0x00000100,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_LNK_INFO = 0x00000200,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_LNK_REMOVE = 0x00000800,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_LNK_COMDAT = 0x00001000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_GPREL = 0x00008000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_PURGEABLE = 0x00010000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_16BIT = 0x00020000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_LOCKED = 0x00040000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_PRELOAD = 0x00080000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_1BYTES = 0x00100000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_2BYTES = 0x00200000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_4BYTES = 0x00300000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_8BYTES = 0x00400000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_16BYTES = 0x00500000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_32BYTES = 0x00600000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_64BYTES = 0x00700000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_128BYTES = 0x00800000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_256BYTES = 0x00900000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_512BYTES = 0x00A00000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_1024BYTES = 0x00B00000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_2048BYTES = 0x00C00000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_4096BYTES = 0x00D00000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_ALIGN_8192BYTES = 0x00E00000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_LNK_NRELOC_OVFL = 0x01000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_DISCARDABLE = 0x02000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_NOT_CACHED = 0x04000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_NOT_PAGED = 0x08000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_SHARED = 0x10000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_EXECUTE = 0x20000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_READ = 0x40000000,
|
||||
LIEF_PE_SECTION_CHARACTERISTICS_MEM_WRITE = 0x80000000
|
||||
};
|
||||
|
||||
|
||||
struct Pe_Section_t {
|
||||
const char* name;
|
||||
uint64_t virtual_address;
|
||||
uint64_t size;
|
||||
uint64_t offset;
|
||||
|
||||
uint32_t virtual_size;
|
||||
uint32_t pointerto_relocation;
|
||||
uint32_t pointerto_line_numbers;
|
||||
uint32_t characteristics;
|
||||
|
||||
uint8_t* content;
|
||||
uint64_t content_size;
|
||||
double entropy;
|
||||
|
||||
};
|
||||
|
||||
typedef struct Pe_Section_t Pe_Section_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef LIEF_PE_C_ENUMS_H_
|
||||
#define LIEF_PE_C_ENUMS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _LIEF_EN(N) LIEF_PE_##N
|
||||
#define _LIEF_EN_2(N, TYPE) LIEF_PE_##N
|
||||
#define _LIEF_EI(X) LIEF_PE_##X
|
||||
|
||||
#include "LIEF/PE/enums.inc"
|
||||
|
||||
#undef _LIEF_EN
|
||||
#undef _LIEF_EN_2
|
||||
#undef _LIEF_EI
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
+43
-12
@@ -1,5 +1,4 @@
|
||||
|
||||
if (LIEF_PY_LIEF_EXT)
|
||||
if (LIEF_PRECOMPILED)
|
||||
if (LIEF_PY_LIEF_EXT_SHARED)
|
||||
find_package(LIEF REQUIRED COMPONENTS SHARED)
|
||||
else()
|
||||
@@ -14,17 +13,12 @@ endif()
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
if (LIEF_EXTERNAL_NANOBIND)
|
||||
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
|
||||
find_package(nanobind REQUIRED)
|
||||
else()
|
||||
set(NANOBIND_VERSION 2.11.0.r10.g5f0a380)
|
||||
set(NANOBIND_SHA256 SHA256=4494b2b580b400e98e4d847b6a9e2a3aeb99581ac7545f6efaa52605335fa806)
|
||||
set(NANOBIND_VERSION 3.0.1)
|
||||
set(NANOBIND_SHA256 SHA256=20111f42e0608e4e518bbe6095bdf64ef74d1d21bad22cb6f2aa3aff013e4443)
|
||||
set(NANOBIND_URL "${THIRD_PARTY_DIRECTORY}/nanobind-${NANOBIND_VERSION}.zip"
|
||||
CACHE STRING "URL to the Nanobind")
|
||||
FetchContent_Declare(nanobind
|
||||
@@ -48,14 +42,26 @@ set(NANOBIND_OPT
|
||||
NOMINSIZE
|
||||
)
|
||||
|
||||
if (LIEF_PYTHON_STABLE_ABI)
|
||||
message(STATUS "Stable ABI enabled")
|
||||
list(APPEND NANOBIND_OPT STABLE_ABI)
|
||||
endif()
|
||||
|
||||
if (LIEF_PYTHON_FREE_THREADED)
|
||||
message(STATUS "Free threading enabled")
|
||||
list(APPEND NANOBIND_OPT FREE_THREADED)
|
||||
endif()
|
||||
|
||||
if (LIEF_PYTHON_STATIC)
|
||||
list(APPEND NANOBIND_OPT NB_EXT_STATIC)
|
||||
list(APPEND NANOBIND_OPT NB_EXT_STATIC ON)
|
||||
endif()
|
||||
|
||||
nanobind_add_module(
|
||||
pyLIEF
|
||||
${NANOBIND_OPT}
|
||||
|
||||
NB_SUPPRESS_WARNINGS
|
||||
|
||||
src/pyLIEF.cpp
|
||||
)
|
||||
|
||||
@@ -71,12 +77,21 @@ set_target_properties(pyLIEF PROPERTIES
|
||||
OUTPUT_NAME "_lief"
|
||||
)
|
||||
|
||||
|
||||
if (LIEF_EXTRA_FLAGS)
|
||||
target_compile_options(pyLIEF PRIVATE ${LIEF_EXTRA_FLAGS})
|
||||
endif()
|
||||
|
||||
if (MSVC AND NOT CLANG_CL AND NOT LIEF_EXTERNAL_SPDLOG)
|
||||
target_compile_definitions(pyLIEF PRIVATE FMT_UNICODE=0)
|
||||
endif()
|
||||
|
||||
target_link_libraries(pyLIEF PUBLIC ${LIEF_TARGET} lief_spdlog)
|
||||
|
||||
target_precompile_headers(pyLIEF PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pylief-pch.hpp
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(pyLIEF PROPERTIES
|
||||
MACOSX_RPATH ON
|
||||
@@ -102,7 +117,11 @@ endif()
|
||||
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(pyLIEF PUBLIC ${PYTHON_LIBRARIES})
|
||||
target_link_libraries(pyLIEF PUBLIC ${PYTHON_LIBRARIES} bcrypt)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
target_link_libraries(pyLIEF PUBLIC Python::Module)
|
||||
endif()
|
||||
|
||||
if(SKBUILD)
|
||||
@@ -113,8 +132,20 @@ if(SKBUILD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LIEF_ASAN)
|
||||
target_link_libraries(pyLIEF INTERFACE libclang_rt.asan.so)
|
||||
endif()
|
||||
|
||||
if (LIEF_TSAN)
|
||||
target_link_libraries(pyLIEF INTERFACE libclang_rt.tsan.so)
|
||||
endif()
|
||||
|
||||
if (LIEF_PYTHON_STATIC)
|
||||
install(TARGETS nanobind-static pyLIEF
|
||||
set(NANOBIND_TARGET nanobind-static)
|
||||
if (LIEF_PYTHON_STABLE_ABI)
|
||||
set(NANOBIND_TARGET nanobind-static-abi3)
|
||||
endif()
|
||||
install(TARGETS ${NANOBIND_TARGET} pyLIEF
|
||||
DESTINATION lib/python-${Python_VERSION})
|
||||
|
||||
install(
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# About
|
||||
|
||||
The purpose of this project is to provide a cross-platform library that can parse, modify and
|
||||
abstract ELF, PE and MachO formats.
|
||||
|
||||
Main features:
|
||||
|
||||
> - **Parsing**: LIEF can parse ELF, PE, MachO, OAT, DEX, VDEX, ART and provides a user-friendly API to access format internals.
|
||||
> - **Modify**: LIEF enables to modify some parts of these formats
|
||||
> - **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.
|
||||
> - **API**: LIEF can be used in C++, Python and Rust
|
||||
|
||||
LIEF Extended:
|
||||
|
||||
> - DWARF/PDB Support
|
||||
> - Objective-C Metadata
|
||||
> - dyld shared cache
|
||||
|
||||
Checkout: <https://lief.re/doc/latest/extended/intro.html> for the details
|
||||
|
||||
# Getting Started
|
||||
|
||||
```console
|
||||
$ pip install lief
|
||||
```
|
||||
|
||||
```python
|
||||
import lief
|
||||
|
||||
elf = lief.ELF.parse("/bin/ls")
|
||||
for section in elf.sections:
|
||||
print(section.name, len(section.content))
|
||||
|
||||
pe = lief.PE.parse("cmd.exe")
|
||||
for imp in pe.imports:
|
||||
print(imp.name)
|
||||
|
||||
fat = lief.MachO.parse("/bin/dyld")
|
||||
for macho in fat:
|
||||
for sym in macho.symbols:
|
||||
print(sym)
|
||||
```
|
||||
|
||||
# Documentation
|
||||
|
||||
- [Main documentation](https://lief.re/doc/latest/index.html)
|
||||
- [API](https://lief.re/doc/latest/api/python/index.html)
|
||||
|
||||
# Contact
|
||||
|
||||
- **Mail**: contact at lief.re
|
||||
- **Discord**: [LIEF](https://discord.gg/jGQtyAYChJ)
|
||||
|
||||
# Authors
|
||||
|
||||
Romain Thomas [@rh0main](https://x.com/rh0main)
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.15.1/LICENSE)
|
||||
@@ -1,65 +0,0 @@
|
||||
About
|
||||
=====
|
||||
|
||||
The purpose of this project is to provide a cross platform library that can parse, modify and
|
||||
abstract ELF, PE and MachO formats.
|
||||
|
||||
Main features:
|
||||
|
||||
* **Parsing**: LIEF can parse ELF, PE, MachO, OAT, DEX, VDEX, ART and provides an user-friendly API to access to format internals.
|
||||
* **Modify**: LIEF enables to modify some parts of these formats
|
||||
* **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.
|
||||
* **API**: LIEF can be used in C, C++, Python and Rust
|
||||
|
||||
LIEF Extended:
|
||||
|
||||
* DWARF/PDB Support
|
||||
* Objective-C Metadata
|
||||
* dyld shared cache
|
||||
|
||||
Checkout: https://lief.re/doc/latest/extended/intro.html for the details
|
||||
|
||||
Getting Started
|
||||
================
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install lief
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import lief
|
||||
|
||||
elf = lief.ELF.parse("/bin/ls")
|
||||
for section in elf.sections:
|
||||
print(section.name, len(section.content))
|
||||
|
||||
pe = lief.PE.parse("cmd.exe")
|
||||
for imp in pe.imports:
|
||||
print(imp.name)
|
||||
|
||||
fat = lief.MachO.parse("/bin/dyld")
|
||||
for macho in fat:
|
||||
for sym in macho.symbols:
|
||||
print(sym)
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
* `Main documentation <https://lief.re/doc/latest/index.html>`_
|
||||
* `API <https://lief.re/doc/latest/api/python/index.html>`_
|
||||
|
||||
Contact
|
||||
=======
|
||||
|
||||
* **Mail**: contact at lief.re
|
||||
* **Discord**: `LIEF <https://discord.gg/jGQtyAYChJ>`_
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Romain Thomas `@rh0main <https://x.com/rh0main>`_
|
||||
|
||||
----
|
||||
|
||||
LIEF is provided under the `Apache 2.0 license <https://github.com/lief-project/LIEF/blob/0.15.1/LICENSE>`_
|
||||
+132
-77
@@ -1,32 +1,39 @@
|
||||
from __future__ import annotations
|
||||
from pydantic_core import ErrorDetails, core_schema, CoreSchema
|
||||
from pydantic import BaseModel, ValidationError, Field, GetCoreSchemaHandler
|
||||
from typing import Any, Optional, Union, List
|
||||
from pathlib import Path
|
||||
import tomli
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sysconfig
|
||||
from pathlib import Path
|
||||
from typing import Annotated, Any, Literal
|
||||
|
||||
from typing_extensions import Annotated
|
||||
import tomli
|
||||
from pydantic import BaseModel, Field, GetCoreSchemaHandler, ValidationError
|
||||
from pydantic_core import CoreSchema, ErrorDetails, core_schema
|
||||
from scikit_build_core._logging import rich_print
|
||||
|
||||
from scikit_build_core.settings.skbuild_read_settings import rich_print
|
||||
|
||||
def cmake_serialize(field: Any):
|
||||
if isinstance(field, bool):
|
||||
return "ON" if field else "OFF"
|
||||
return field
|
||||
|
||||
|
||||
class EnvStringValidator:
|
||||
def _get_env_string(self, string: str) -> str:
|
||||
winpy_architecture = os.getenv("LIEF_TARGET_ARCHITECTURE", "")
|
||||
if winpy_architecture == "x86_64":
|
||||
winpy_architecture = "amd64"
|
||||
formatted = string.format(
|
||||
python_version=os.getenv("LIEF_TARGET_PYTHON_VERSION", ""),
|
||||
python_version_alt=os.getenv("LIEF_TARGET_PYTHON_VERSION", "").replace('.', ''),
|
||||
architecture=os.getenv("LIEF_TARGET_ARCHITECTURE", ""),
|
||||
winpy_architecture=winpy_architecture,
|
||||
ci_project_dir=os.getenv("CI_PROJECT_DIR", ""),
|
||||
python_version=os.getenv("LIEF_TARGET_PYTHON_VERSION", ""),
|
||||
python_version_alt=os.getenv("LIEF_TARGET_PYTHON_VERSION", "").replace(
|
||||
".", ""
|
||||
),
|
||||
architecture=os.getenv("LIEF_TARGET_ARCHITECTURE", ""),
|
||||
winpy_architecture=winpy_architecture,
|
||||
ci_project_dir=os.getenv("CI_PROJECT_DIR", ""),
|
||||
stable_abi=os.getenv("LIEF_STABLE_ABI", ""),
|
||||
free_threaded=os.getenv("LIEF_FREE_THREADED", ""),
|
||||
runtime=os.getenv("LIEF_RUNTIME", "false"),
|
||||
)
|
||||
return formatted
|
||||
|
||||
@@ -37,26 +44,33 @@ class EnvStringValidator:
|
||||
self._get_env_string, handler(source_type)
|
||||
)
|
||||
|
||||
|
||||
EnvString = Annotated[str, EnvStringValidator()]
|
||||
|
||||
|
||||
class BuildConfig(BaseModel):
|
||||
build_type: EnvString = Field("Release", alias="type")
|
||||
cache: bool = True
|
||||
ninja: bool = False
|
||||
stable_abi: bool | EnvString = Field(False, alias="stable-abi")
|
||||
free_threaded: bool | EnvString | None = Field(None, alias="free-threaded")
|
||||
default_target: str = Field("pyLIEF", alias="default-target")
|
||||
parallel_jobs: int = Field(0, alias="parallel-jobs")
|
||||
compilation_flags: List[str] = Field([], alias="compilation-flags")
|
||||
build_dir: Optional[EnvString] = Field(None, alias="build-dir")
|
||||
extra_targets: Union[List[EnvString], EnvString] = Field(None, alias="extra-targets")
|
||||
extra_cmake: Union[List[EnvString], EnvString] = Field(None, alias="extra-cmake-opt")
|
||||
lief_install_dir: Optional[EnvString] = Field(None, alias="lief-install-dir")
|
||||
compilation_flags: list[str] = Field([], alias="compilation-flags")
|
||||
lief_extra_compilation_flags: list[str] = Field(
|
||||
[], alias="lief-extra-compilation-flags"
|
||||
)
|
||||
build_dir: EnvString | None = Field(None, alias="build-dir")
|
||||
extra_targets: list[EnvString] | EnvString = Field([], alias="extra-targets")
|
||||
extra_cmake: list[EnvString] | EnvString = Field([], alias="extra-cmake-opt")
|
||||
lief_install_dir: EnvString | None = Field(None, alias="lief-install-dir")
|
||||
py_api: EnvString = Field("", alias="py-api")
|
||||
c_compiler: Optional[EnvString] = Field(None, alias="c-compiler")
|
||||
cxx_compiler: Optional[EnvString] = Field(None, alias="cxx-compiler")
|
||||
c_compiler: EnvString | None = Field(None, alias="c-compiler")
|
||||
cxx_compiler: EnvString | None = Field(None, alias="cxx-compiler")
|
||||
|
||||
@property
|
||||
def targets(self) -> List[str]:
|
||||
default_targets: List[str] = [self.default_target]
|
||||
def targets(self) -> list[str]:
|
||||
default_targets: list[str] = [self.default_target]
|
||||
if self.extra_targets is not None:
|
||||
if isinstance(self.extra_targets, str):
|
||||
default_targets.append(self.extra_targets)
|
||||
@@ -65,10 +79,8 @@ class BuildConfig(BaseModel):
|
||||
|
||||
return default_targets
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
out: List[str] = [
|
||||
f"-DLIEF_USE_CCACHE={cmake_serialize(self.cache)}"
|
||||
]
|
||||
def cmake_dump(self) -> list[str]:
|
||||
out: list[str] = [f"-DLIEF_USE_CCACHE={cmake_serialize(self.cache)}"]
|
||||
|
||||
if self.extra_cmake is not None:
|
||||
if isinstance(self.extra_cmake, str):
|
||||
@@ -78,66 +90,82 @@ class BuildConfig(BaseModel):
|
||||
|
||||
if self.lief_install_dir is not None:
|
||||
lief_cmake_dir = Path(self.lief_install_dir) / "lib" / "cmake" / "LIEF"
|
||||
lief_dir = lief_cmake_dir.expanduser().resolve().absolute()
|
||||
out.extend((
|
||||
"-DLIEF_PY_LIEF_EXT=on",
|
||||
"-DLIEF_INSTALL=off",
|
||||
f"-DLIEF_DIR={lief_dir.as_posix()}"
|
||||
))
|
||||
lief_dir = lief_cmake_dir.expanduser().resolve()
|
||||
|
||||
if not lief_dir.is_dir():
|
||||
raise RuntimeError(f"Invalid install dir: {lief_cmake_dir}")
|
||||
|
||||
out.extend(
|
||||
(
|
||||
"-DLIEF_PY_LIEF_EXT=on",
|
||||
"-DLIEF_INSTALL=off",
|
||||
f"-DLIEF_DIR={lief_dir.as_posix()}",
|
||||
)
|
||||
)
|
||||
|
||||
if self.c_compiler is not None:
|
||||
out.append(
|
||||
f"-DCMAKE_C_COMPILER={self.c_compiler}"
|
||||
)
|
||||
out.append(f"-DCMAKE_C_COMPILER={self.c_compiler}")
|
||||
|
||||
if self.cxx_compiler is not None:
|
||||
out.append(
|
||||
f"-DCMAKE_CXX_COMPILER={self.cxx_compiler}"
|
||||
)
|
||||
out.append(f"-DCMAKE_CXX_COMPILER={self.cxx_compiler}")
|
||||
|
||||
if len(self.compilation_flags) > 0:
|
||||
flags = " ".join(self.compilation_flags)
|
||||
out.extend((
|
||||
f'-DCMAKE_CXX_FLAGS={flags}',
|
||||
f'-DCMAKE_C_FLAGS={flags}',
|
||||
))
|
||||
out.extend(
|
||||
(
|
||||
f"-DCMAKE_CXX_FLAGS={flags}",
|
||||
f"-DCMAKE_C_FLAGS={flags}",
|
||||
)
|
||||
)
|
||||
|
||||
if len(self.lief_extra_compilation_flags) > 0:
|
||||
flags = ";".join(self.lief_extra_compilation_flags)
|
||||
out.extend((f"-DLIEF_EXTRA_FLAGS={flags}",))
|
||||
|
||||
free_threaded = self.free_threaded
|
||||
if free_threaded is None:
|
||||
free_threaded = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
|
||||
|
||||
out.extend(
|
||||
[
|
||||
f"-DLIEF_PYTHON_STABLE_ABI={cmake_serialize(self.stable_abi)}",
|
||||
f"-DLIEF_PYTHON_FREE_THREADED={cmake_serialize(free_threaded)}",
|
||||
]
|
||||
)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
class ThirdParty(BaseModel):
|
||||
spdlog: Optional[EnvString] = None
|
||||
nanobind: Optional[EnvString] = None
|
||||
spdlog: EnvString | None = None
|
||||
nanobind: EnvString | None = None
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
out: List[str] = []
|
||||
def cmake_dump(self) -> list[str]:
|
||||
out: list[str] = []
|
||||
if self.spdlog is not None:
|
||||
out.extend((
|
||||
"-DLIEF_EXTERNAL_SPDLOG=ON",
|
||||
f"-Dspdlog_DIR={self.spdlog}"
|
||||
))
|
||||
out.extend(("-DLIEF_EXTERNAL_SPDLOG=ON", f"-Dspdlog_DIR={self.spdlog}"))
|
||||
|
||||
if self.nanobind is not None:
|
||||
out.extend((
|
||||
"-DLIEF_OPT_NANOBIND_EXTERNAL=ON",
|
||||
f"-Dnanobind_DIR={self.nanobind}"
|
||||
))
|
||||
out.extend(
|
||||
("-DLIEF_OPT_NANOBIND_EXTERNAL=ON", f"-Dnanobind_DIR={self.nanobind}")
|
||||
)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
class CrossCompilation(BaseModel):
|
||||
osx_arch: Optional[EnvString] = Field(None, alias="osx-arch")
|
||||
platform: Optional[EnvString] = None
|
||||
pyversion: Optional[EnvString] = None
|
||||
abi: Optional[EnvString] = None
|
||||
osx_arch: EnvString | None = Field(None, alias="osx-arch")
|
||||
platform: EnvString | None = None
|
||||
pyversion: EnvString | None = None
|
||||
abi: EnvString | None = None
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
out: List[str] = []
|
||||
def cmake_dump(self) -> list[str]:
|
||||
out: list[str] = []
|
||||
if self.osx_arch is not None:
|
||||
out.extend((
|
||||
f'-DCMAKE_OSX_ARCHITECTURES={self.osx_arch}',
|
||||
))
|
||||
out.extend((f"-DCMAKE_OSX_ARCHITECTURES={self.osx_arch}",))
|
||||
return out
|
||||
|
||||
|
||||
class Formats(BaseModel):
|
||||
elf: bool = True
|
||||
pe: bool = True
|
||||
@@ -148,7 +176,7 @@ class Formats(BaseModel):
|
||||
oat: bool = True
|
||||
vdex: bool = True
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
def cmake_dump(self) -> list[str]:
|
||||
return [
|
||||
f"-DLIEF_ELF={cmake_serialize(self.elf)}",
|
||||
f"-DLIEF_PE={cmake_serialize(self.pe)}",
|
||||
@@ -160,44 +188,67 @@ class Formats(BaseModel):
|
||||
f"-DLIEF_VDEX={cmake_serialize(self.vdex)}",
|
||||
]
|
||||
|
||||
|
||||
class Logging(BaseModel):
|
||||
enabled: bool = True
|
||||
debug: bool = False
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
def cmake_dump(self) -> list[str]:
|
||||
return [
|
||||
f"-DLIEF_LOGGING={cmake_serialize(self.enabled)}",
|
||||
f"-DLIEF_LOGGING_DEBUG={cmake_serialize(self.debug)}",
|
||||
]
|
||||
|
||||
|
||||
class Features(BaseModel):
|
||||
# json is an attribute already defined in BaseModel
|
||||
json_support: bool = Field(True, alias="json")
|
||||
frozen: bool = True
|
||||
runtime: bool | EnvString = Field(False)
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
def cmake_dump(self) -> list[str]:
|
||||
return [
|
||||
f"-DLIEF_RUNTIME={cmake_serialize(self.runtime)}",
|
||||
f"-DLIEF_ENABLE_JSON={cmake_serialize(self.json_support)}",
|
||||
f"-DLIEF_DISABLE_FROZEN={cmake_serialize(not self.frozen)}",
|
||||
]
|
||||
|
||||
|
||||
class Runtime(BaseModel):
|
||||
platform: Literal["linux", "windows", "android", "osx", "ios"] | None = None
|
||||
architecture: EnvString | Literal["arm64", "x86_64"] | None = None
|
||||
|
||||
def cmake_dump(self) -> list[str]:
|
||||
out: list[str] = []
|
||||
|
||||
if self.platform is not None:
|
||||
out.append(f"-DLIEF_RUNTIME_PLATFORM={self.platform}")
|
||||
|
||||
if self.architecture is not None:
|
||||
out.append(f"-DLIEF_RUNTIME_ARCH={self.architecture}")
|
||||
|
||||
return out
|
||||
|
||||
|
||||
class ConfigT(BaseModel):
|
||||
build: BuildConfig = BuildConfig()
|
||||
formats: Formats = Formats()
|
||||
third_party: ThirdParty = Field(ThirdParty(), alias="third-party")
|
||||
features: Features = Features()
|
||||
logging: Logging = Logging()
|
||||
cross_compilation: CrossCompilation = Field(CrossCompilation(),
|
||||
alias="cross-compilation")
|
||||
runtime: Runtime = Runtime()
|
||||
cross_compilation: CrossCompilation = Field(
|
||||
CrossCompilation(), alias="cross-compilation"
|
||||
)
|
||||
|
||||
def _cmake_base_args(self) -> List[str]:
|
||||
def _cmake_base_args(self) -> list[str]:
|
||||
return [
|
||||
"-DLIEF_PYTHON_API=on",
|
||||
"-DLIEF_INSTALL=off",
|
||||
"-DLIEF_INSTALL_COMPILED_EXAMPLES=off",
|
||||
]
|
||||
|
||||
def cmake_dump(self) -> List[str]:
|
||||
def cmake_dump(self) -> list[str]:
|
||||
return [
|
||||
*self._cmake_base_args(),
|
||||
*self.build.cmake_dump(),
|
||||
@@ -205,20 +256,22 @@ class ConfigT(BaseModel):
|
||||
*self.third_party.cmake_dump(),
|
||||
*self.features.cmake_dump(),
|
||||
*self.logging.cmake_dump(),
|
||||
*self.runtime.cmake_dump(),
|
||||
*self.cross_compilation.cmake_dump(),
|
||||
]
|
||||
|
||||
|
||||
def pretty_error(err: ErrorDetails, file: Path):
|
||||
loc = '.'.join(err['loc'])
|
||||
if err['type'] == 'value_error.missing':
|
||||
loc = ".".join([str(e) for e in err["loc"]])
|
||||
if err["type"] == "value_error.missing":
|
||||
rich_print(f"[red]'{loc}' is missing in {file}")
|
||||
else:
|
||||
rich_print(f"[red]Error with '{loc}' in {file} ({err['msg']})")
|
||||
|
||||
|
||||
class Config:
|
||||
DEFAULT_EXCLUDE: List[str] = [
|
||||
"*.so", "*.pyd"
|
||||
]
|
||||
DEFAULT_EXCLUDE: list[str] = ["*.so", "*.pyd"]
|
||||
|
||||
def __init__(self, config: ConfigT):
|
||||
self._config: ConfigT = config
|
||||
|
||||
@@ -248,7 +301,7 @@ class Config:
|
||||
|
||||
return ""
|
||||
|
||||
def get_cmake_args(self, editable: bool = False) -> List[str]:
|
||||
def get_cmake_args(self, editable: bool = False) -> list[str]:
|
||||
cmake_args = self._config.cmake_dump()
|
||||
if editable:
|
||||
cmake_args.append(
|
||||
@@ -257,9 +310,11 @@ class Config:
|
||||
return cmake_args
|
||||
|
||||
@property
|
||||
def cmake_generator(self) -> List[str]:
|
||||
def cmake_generator(self) -> list[str]:
|
||||
if self._config.build.ninja:
|
||||
return ["-GNinja",]
|
||||
return [
|
||||
"-GNinja",
|
||||
]
|
||||
return []
|
||||
|
||||
@property
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any
|
||||
|
||||
from scikit_build_core._logging import rich_print
|
||||
from setup import BINDING_DIR
|
||||
from versioning import Versioning
|
||||
from scikit_build_core.settings.skbuild_read_settings import rich_print
|
||||
|
||||
def dynamic_metadata(field, config) -> str:
|
||||
if field == "version":
|
||||
version = Versioning().get_version()
|
||||
rich_print(f"[green]LIEF Version: {version}")
|
||||
return version
|
||||
|
||||
if field == "readme":
|
||||
return (BINDING_DIR / "README.rst").as_posix()
|
||||
def dynamic_metadata(
|
||||
_settings: Mapping[str, Any],
|
||||
_project: Mapping[str, Any],
|
||||
) -> dict[str, Any]:
|
||||
version = Versioning().get_version()
|
||||
rich_print("{green}LIEF Version: {version}", version=version)
|
||||
return {
|
||||
"version": version,
|
||||
"readme": (BINDING_DIR / "README.md").as_posix(),
|
||||
}
|
||||
|
||||
+72
-47
@@ -1,11 +1,11 @@
|
||||
from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import sysconfig
|
||||
import platform
|
||||
from functools import lru_cache
|
||||
from typing import Optional, Union, List
|
||||
from pathlib import Path
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
ROOT_DIR = CWD / ".." / ".." / ".."
|
||||
@@ -16,17 +16,21 @@ DEFAULT_CONF = CWD / ".." / "config-default.toml"
|
||||
|
||||
_WHEEL_TAG_COMPUTE_BEST = None
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def get_config():
|
||||
from config import Config
|
||||
|
||||
if path := os.getenv("PYLIEF_CONF"):
|
||||
config_path = Path(path).resolve().absolute()
|
||||
return Config.from_file(config_path)
|
||||
return Config.from_file(DEFAULT_CONF.as_posix())
|
||||
return Config.from_file(DEFAULT_CONF)
|
||||
|
||||
|
||||
def _compute_best(cls, *arg, **kwargs):
|
||||
from scikit_build_core.builder.wheel_tag import WheelTag
|
||||
|
||||
assert _WHEEL_TAG_COMPUTE_BEST is not None
|
||||
best_tag = _WHEEL_TAG_COMPUTE_BEST(cls, *arg, **kwargs)
|
||||
config = get_config()
|
||||
|
||||
@@ -45,52 +49,54 @@ def _compute_best(cls, *arg, **kwargs):
|
||||
|
||||
return WheelTag(pyvers, abis, archs)
|
||||
|
||||
|
||||
def _get_vc_env(vc_arch: str) -> dict[str, str]:
|
||||
try:
|
||||
from setuptools import distutils # type: ignore[import,attr-defined]
|
||||
from setuptools import distutils # type: ignore
|
||||
|
||||
return distutils._msvccompiler._get_vc_env(vc_arch) # type: ignore[no-any-return]
|
||||
return distutils._msvccompiler._get_vc_env(vc_arch) # type: ignore
|
||||
except AttributeError:
|
||||
from setuptools._distutils import (
|
||||
_msvccompiler, # type: ignore[import,attr-defined]
|
||||
)
|
||||
from setuptools._distutils import _msvccompiler # type: ignore
|
||||
|
||||
return _msvccompiler._get_vc_env(vc_arch) # type: ignore
|
||||
|
||||
return _msvccompiler._get_vc_env(vc_arch) # type: ignore[no-any-return,attr-defined]
|
||||
|
||||
def _fix_env():
|
||||
config = get_config()
|
||||
if sys.platform.startswith("win"):
|
||||
if config.build.ninja:
|
||||
from setuptools import msvc
|
||||
is64 = sys.maxsize > 2**32
|
||||
arch = 'x64' if is64 else 'x86'
|
||||
arch = "x64" if is64 else "x86"
|
||||
ninja_env = _get_vc_env(arch)
|
||||
os.environ.update(ninja_env)
|
||||
|
||||
if sys.platform.startswith("darwin"):
|
||||
deployment_target = (
|
||||
os.getenv("MACOSX_DEPLOYMENT_TARGET", None) or
|
||||
sysconfig.get_config_var("MACOSX_DEPLOYMENT_TARGET")
|
||||
deployment_target = os.getenv(
|
||||
"MACOSX_DEPLOYMENT_TARGET", None
|
||||
) or sysconfig.get_config_var("MACOSX_DEPLOYMENT_TARGET")
|
||||
os.environ["_PYTHON_HOST_PLATFORM"] = (
|
||||
f"macosx-{deployment_target}-{config.osx_arch}"
|
||||
)
|
||||
os.environ["_PYTHON_HOST_PLATFORM"] = f"macosx-{deployment_target}-{config.osx_arch}"
|
||||
# scikit_build_core is aware of ARCHFLAGS for the wheel arch:
|
||||
# builder/builder.py:get_archs()
|
||||
os.environ["ARCHFLAGS"]= f"-arch {config.osx_arch}"
|
||||
os.environ["ARCHFLAGS"] = f"-arch {config.osx_arch}"
|
||||
|
||||
if platform := config.cross_compilation.platform:
|
||||
global _WHEEL_TAG_COMPUTE_BEST
|
||||
from scikit_build_core.builder.wheel_tag import WheelTag
|
||||
|
||||
_WHEEL_TAG_COMPUTE_BEST = WheelTag.compute_best
|
||||
WheelTag.compute_best = _compute_best
|
||||
WheelTag.compute_best = _compute_best # type: ignore
|
||||
|
||||
os.environ["_PYTHON_HOST_PLATFORM"] = platform
|
||||
|
||||
if os.name == 'nt' and platform == 'win32':
|
||||
if os.name == "nt" and platform == "win32":
|
||||
os.environ["VSCMD_ARG_TGT_ARCH"] = "x86"
|
||||
sys.version = sys.version.lower().replace("amd64", "")
|
||||
sys.platform = "win32"
|
||||
|
||||
def _get_hooked_config(is_editable: bool) -> Optional[dict[str, Union[str, List[str]]]]:
|
||||
|
||||
def _get_hooked_config(is_editable: bool) -> dict[str, str | list[str]] | None:
|
||||
from config import Config
|
||||
|
||||
config = get_config()
|
||||
@@ -103,21 +109,17 @@ def _get_hooked_config(is_editable: bool) -> Optional[dict[str, Union[str, List[
|
||||
# Make sure that this check is not silently warned since it could lead
|
||||
# to a wrong .whl filename
|
||||
minor = int(config.build.py_api[3:])
|
||||
if (
|
||||
sys.implementation.name != "cpython" or
|
||||
minor > sys.version_info.minor
|
||||
):
|
||||
if sys.implementation.name != "cpython" or minor > sys.version_info.minor:
|
||||
msg = f"Ignoring py-api, not a CPython interpreter ({sys.implementation.name}) or version (3.{minor}) is too high"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
|
||||
config_settings = {
|
||||
"logging.level": "DEBUG",
|
||||
"build-dir": config.build_dir,
|
||||
"build.targets": config.build.targets,
|
||||
"install.strip": config.strip,
|
||||
"backport.find-python": "0",
|
||||
"wheel.py-api": config.build.py_api,
|
||||
"wheel.py-api": config.build.py_api,
|
||||
"cmake.source-dir": SRC_DIR.as_posix(),
|
||||
"cmake.build-type": config.build.build_type,
|
||||
"cmake.args": [
|
||||
@@ -128,28 +130,46 @@ def _get_hooked_config(is_editable: bool) -> Optional[dict[str, Union[str, List[
|
||||
}
|
||||
return config_settings
|
||||
|
||||
def _get_build_requirements(is_editable: bool) -> List[str]:
|
||||
|
||||
def _get_build_requirements(is_editable: bool) -> list[str]:
|
||||
build_req_file = BINDING_DIR / "build-requirements.txt"
|
||||
if not build_req_file.is_file() and not (BINDING_DIR / "src").is_dir():
|
||||
# By convention this is an mocked sdist
|
||||
print(f"LIEF does not provide precompiled wheels for '{sys.platform} - {platform.machine()}'", file=sys.stderr)
|
||||
# By convention this is a mocked sdist
|
||||
impl = sys.implementation.name
|
||||
version = "{0.major}.{0.minor}.{0.micro}".format(sys.version_info)
|
||||
free_threaded = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
|
||||
ft_status = "free-threaded" if free_threaded else "GIL-enabled"
|
||||
print(
|
||||
f"LIEF does not provide precompiled wheels for "
|
||||
f"'{sys.platform} - {platform.machine()}' "
|
||||
f"(Python: {impl} {version} [{ft_status}])",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
reqs = [line for line in build_req_file.read_text().splitlines() if not line.startswith("#")]
|
||||
reqs = [
|
||||
line
|
||||
for line in build_req_file.read_text().splitlines()
|
||||
if not line.startswith("#")
|
||||
]
|
||||
return reqs
|
||||
|
||||
|
||||
def get_requires_for_build_wheel(
|
||||
config_settings: Optional[dict[str, Union[str, List[str]]]] = None,
|
||||
config_settings: dict[str, str | list[str]] | None = None,
|
||||
) -> list[str]:
|
||||
return _get_build_requirements(is_editable=False)
|
||||
|
||||
|
||||
def prepare_metadata_for_build_wheel(
|
||||
metadata_directory: str,
|
||||
config_settings: Optional[dict[str, Union[str, List[str]]]] = None,
|
||||
config_settings: dict[str, str | list[str]] | None = None,
|
||||
) -> str:
|
||||
from scikit_build_core.build import prepare_metadata_for_build_wheel as _impl
|
||||
|
||||
_fix_env()
|
||||
return _impl(metadata_directory, config_settings)
|
||||
|
||||
|
||||
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
|
||||
from scikit_build_core.build import build_wheel as _impl
|
||||
|
||||
@@ -157,23 +177,27 @@ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
|
||||
_fix_env()
|
||||
return _impl(wheel_directory, config_settings, metadata_directory)
|
||||
|
||||
|
||||
def get_requires_for_build_editable(
|
||||
config_settings: Optional[dict[str, Union[str, List[str]]]] = None,
|
||||
) -> List[str]:
|
||||
config_settings: dict[str, str | list[str]] | None = None,
|
||||
) -> list[str]:
|
||||
return _get_build_requirements(is_editable=True)
|
||||
|
||||
|
||||
def prepare_metadata_for_build_editable(
|
||||
metadata_directory: str,
|
||||
config_settings: Optional[dict[str, Union[str, List[str]]]] = None,
|
||||
config_settings: dict[str, str | list[str]] | None = None,
|
||||
) -> str:
|
||||
from scikit_build_core.build import prepare_metadata_for_build_editable as _impl
|
||||
|
||||
_fix_env()
|
||||
return _impl(metadata_directory, config_settings)
|
||||
|
||||
|
||||
def build_editable(
|
||||
wheel_directory: str,
|
||||
config_settings: Optional[dict[str, Union[str, List[str]]]] = None,
|
||||
metadata_directory: Optional[str] = None,
|
||||
config_settings: dict[str, str | list[str]] | None = None,
|
||||
metadata_directory: str | None = None,
|
||||
) -> str:
|
||||
from scikit_build_core.build import build_editable as _impl
|
||||
|
||||
@@ -181,20 +205,21 @@ def build_editable(
|
||||
_fix_env()
|
||||
return _impl(wheel_directory, config_settings, metadata_directory)
|
||||
|
||||
|
||||
def build_sdist(
|
||||
sdist_directory: str,
|
||||
config_settings: Optional[dict[str, Union[str, List[str]]]] = None,
|
||||
config_settings: dict[str, str | list[str]] | None = None,
|
||||
) -> str:
|
||||
from scikit_build_core.build.sdist import build_sdist as _impl
|
||||
|
||||
config_settings = _get_hooked_config(is_editable=False)
|
||||
config_settings['sdist.exclude'].extend([
|
||||
'*'
|
||||
])
|
||||
config_settings['sdist.include'] = [
|
||||
'pyproject.toml',
|
||||
'backend/setup.py',
|
||||
'backend/versioning.py',
|
||||
'backend/config.py',
|
||||
'backend/dynamic_provider.py',
|
||||
assert config_settings is not None
|
||||
config_settings["sdist.exclude"].extend(["*"]) # type: ignore
|
||||
config_settings["sdist.include"] = [
|
||||
"pyproject.toml",
|
||||
"backend/setup.py",
|
||||
"backend/versioning.py",
|
||||
"backend/config.py",
|
||||
"backend/dynamic_provider.py",
|
||||
]
|
||||
return _impl(sdist_directory, config_settings)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
|
||||
from setup import ROOT_DIR
|
||||
from scikit_build_core.settings.skbuild_read_settings import rich_print as _rich_print
|
||||
from shutil import which
|
||||
from typing import Optional
|
||||
|
||||
from scikit_build_core._logging import rich_print as _rich_print
|
||||
from setup import ROOT_DIR
|
||||
|
||||
|
||||
def rich_print(*args):
|
||||
if sys.platform.startswith("win"):
|
||||
@@ -19,12 +20,13 @@ def rich_print(*args):
|
||||
return print(*args)
|
||||
return _rich_print(*args)
|
||||
|
||||
|
||||
class Versioning:
|
||||
COMMAND = '{git} describe --tags --long --dirty'
|
||||
GIT_BRANCH = '{git} rev-parse --abbrev-ref HEAD'
|
||||
IS_TAGGED_CMD = '{git} tag --list --points-at=HEAD'
|
||||
FMT_DEV = '{tag}.dev0'
|
||||
FMT_TAGGED = '{tag}'
|
||||
COMMAND = "{git} describe --tags --long --dirty"
|
||||
GIT_BRANCH = "{git} rev-parse --abbrev-ref HEAD"
|
||||
IS_TAGGED_CMD = "{git} tag --list --points-at=HEAD"
|
||||
FMT_DEV = "{tag}.dev0"
|
||||
FMT_TAGGED = "{tag}"
|
||||
CMAKE_VERSION_R = r"set\(LIEF_VERSION_(MAJOR|MINOR|PATCH)\s(\d+)\)"
|
||||
|
||||
def __init__(self):
|
||||
@@ -34,14 +36,14 @@ class Versioning:
|
||||
args = dict(kwargs)
|
||||
args["git"] = self._git
|
||||
cmd_list = shlex.split(cmd.format(**args))
|
||||
return subprocess.check_output(cmd_list,
|
||||
text=True,
|
||||
cwd=ROOT_DIR.as_posix()).strip()
|
||||
return subprocess.check_output(
|
||||
cmd_list, text=True, cwd=ROOT_DIR.as_posix()
|
||||
).strip()
|
||||
|
||||
def has_git(self) -> bool:
|
||||
return self._git is not None and (ROOT_DIR / ".git").is_dir()
|
||||
|
||||
def get_branch(self) -> Optional[str]:
|
||||
def get_branch(self) -> str | None:
|
||||
if not self.has_git():
|
||||
return None
|
||||
|
||||
@@ -59,16 +61,16 @@ class Versioning:
|
||||
|
||||
if branch is not None and branch.startswith("release/"):
|
||||
_, version = branch.split("release/")
|
||||
major, minor, patch = version.split('.')
|
||||
if patch == 'x':
|
||||
major, minor, patch = version.split(".")
|
||||
if patch == "x":
|
||||
return f"{major}.{minor}"
|
||||
return version
|
||||
|
||||
parts = version.split('-')
|
||||
parts = version.split("-")
|
||||
assert len(parts) in (3, 4)
|
||||
dirty = len(parts) == 4
|
||||
tag, count, sha = parts[:3]
|
||||
MA, MI, PA = map(int, tag.split(".")) # 0.9.0 -> (0, 9, 0)
|
||||
MA, MI, PA = map(int, tag.split(".")) # 0.9.0 -> (0, 9, 0)
|
||||
|
||||
if is_dev:
|
||||
if MI == 17:
|
||||
@@ -76,13 +78,13 @@ class Versioning:
|
||||
# the 0.X.Y series
|
||||
tag = "1.0.0"
|
||||
else:
|
||||
tag = f"{MA}.{MI + 1}.{0}"
|
||||
tag = f"{MA + 1}.{MI}.{0}"
|
||||
|
||||
if count == '0' and not dirty:
|
||||
if count == "0" and not dirty:
|
||||
return tag
|
||||
return fmt.format(tag=tag, gitsha=sha.lstrip('g'))
|
||||
return fmt.format(tag=tag, gitsha=sha.lstrip("g"))
|
||||
|
||||
def version_from_git(self) -> Optional[str]:
|
||||
def version_from_git(self) -> str | None:
|
||||
if not self.has_git():
|
||||
return None
|
||||
|
||||
@@ -90,21 +92,24 @@ class Versioning:
|
||||
is_tagged = self._exec_git_cmd(Versioning.IS_TAGGED_CMD) != ""
|
||||
git_version = self._exec_git_cmd(Versioning.COMMAND)
|
||||
if is_tagged:
|
||||
return self.format_version(version=git_version, fmt=Versioning.FMT_TAGGED)
|
||||
return self.format_version(version=git_version, fmt=Versioning.FMT_DEV, is_dev=True)
|
||||
return self.format_version(
|
||||
version=git_version, fmt=Versioning.FMT_TAGGED
|
||||
)
|
||||
return self.format_version(
|
||||
version=git_version, fmt=Versioning.FMT_DEV, is_dev=True
|
||||
)
|
||||
except Exception as e:
|
||||
rich_print(f"[red]Error: {e}")
|
||||
return None
|
||||
|
||||
def version_from_cmake(self) -> Optional[str]:
|
||||
def version_from_cmake(self) -> str | None:
|
||||
main_cmake = ROOT_DIR / "CMakeLists.txt"
|
||||
cmakefile = main_cmake.read_text()
|
||||
major: Optional[int] = None
|
||||
minor: Optional[int] = None
|
||||
patch: Optional[int] = None
|
||||
major: int | None = None
|
||||
minor: int | None = None
|
||||
patch: int | None = None
|
||||
|
||||
itre = re.finditer(Versioning.CMAKE_VERSION_R, cmakefile,
|
||||
flags=re.MULTILINE)
|
||||
itre = re.finditer(Versioning.CMAKE_VERSION_R, cmakefile, flags=re.MULTILINE)
|
||||
|
||||
for cmake_version in itre:
|
||||
typ, value = cmake_version.groups()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
tomli==2.4.0
|
||||
scikit-build-core==0.11.6
|
||||
tomli==2.4.1
|
||||
scikit-build-core==1.0.3
|
||||
# For Ninja: msvc.msvc14_get_vc_env
|
||||
setuptools==80.9.0
|
||||
setuptools==83.0.0
|
||||
# For the "env" feature
|
||||
pydantic==2.12.5
|
||||
pydantic==2.13.4
|
||||
# Implicit from scikit-build-core
|
||||
pathspec==1.0.3
|
||||
build==1.4.0
|
||||
wheel==0.46.3
|
||||
pathspec==1.1.1
|
||||
build==1.5.0
|
||||
wheel==0.47.0
|
||||
|
||||
@@ -17,16 +17,8 @@ dex = true
|
||||
[lief.features]
|
||||
json = true
|
||||
frozen = true
|
||||
runtime = false
|
||||
|
||||
[lief.logging]
|
||||
enabled = true
|
||||
debug = false
|
||||
|
||||
#[lief.cross-compilation]
|
||||
#osx-arch = "arm64"
|
||||
|
||||
#[lief.third-party]
|
||||
#spdlog = "/path/to/spdlog-install"
|
||||
|
||||
|
||||
|
||||
|
||||
Regular → Executable
+29
-14
@@ -1,25 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
"""Dump the *abstract* view of a binary (ELF / PE / Mach-O) as JSON.
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Dump abstract informations in a JSON format
|
||||
# see: abstract_reader.py
|
||||
The abstract layer exposes the subset of information shared by every
|
||||
supported executable format (sections, symbols, relocations, ...). This
|
||||
script parses the input file, converts its abstract representation to
|
||||
JSON via ``lief.to_json`` and pretty-prints it.
|
||||
|
||||
Example:
|
||||
|
||||
$ python abstract_json.py /bin/ls
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import lief
|
||||
import json
|
||||
import sys
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('binary', help = 'A binary')
|
||||
import lief
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("binary", help="Path to an ELF, PE or Mach-O binary")
|
||||
args = parser.parse_args()
|
||||
|
||||
binary = lief.parse(args.binary)
|
||||
binary = lief.parse(args.binary)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{args.binary}'", file=sys.stderr)
|
||||
return 1
|
||||
if isinstance(binary, lief.COFF.Binary):
|
||||
print("COFF objects do not expose an abstract view", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
json_data = json.loads(lief.to_json(binary.abstract))
|
||||
print(json.dumps(json_data, sort_keys = True, indent = 4))
|
||||
print(json.dumps(json_data, sort_keys=True, indent=4))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
|
||||
Regular → Executable
+109
-71
@@ -1,21 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Format-agnostic binary reader.
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Universal format reader.
|
||||
# Input can be PE, ELF or Mach-O
|
||||
Uses the abstract layer of LIEF to render the common subset of
|
||||
information (header, sections, relocations, symbols, imports,
|
||||
exports, libraries) for an ELF, PE or Mach-O binary.
|
||||
|
||||
Example:
|
||||
|
||||
$ python abstract_reader.py -a /bin/ls
|
||||
"""
|
||||
|
||||
import lief
|
||||
import sys
|
||||
import argparse
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
class exceptions_handler(object):
|
||||
import lief
|
||||
|
||||
|
||||
class exceptions_handler:
|
||||
func = None
|
||||
|
||||
def __init__(self, exceptions, on_except_callback=None):
|
||||
self.exceptions = exceptions
|
||||
self.exceptions = exceptions
|
||||
self.on_except_callback = on_except_callback
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
@@ -29,13 +35,12 @@ class exceptions_handler(object):
|
||||
self.on_except_callback(e)
|
||||
else:
|
||||
print("-" * 60)
|
||||
print("Exception in {}: {}".format(self.func.__name__, e))
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
print(f"Exception in {self.func.__name__}: {e}")
|
||||
_exc_type, _exc_value, exc_traceback = sys.exc_info()
|
||||
traceback.print_tb(exc_traceback)
|
||||
print("-" * 60)
|
||||
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_header(binary):
|
||||
header = binary.header
|
||||
@@ -43,8 +48,6 @@ def print_header(binary):
|
||||
print("== Header ==\n")
|
||||
format_str = "{:<15} {:<30}"
|
||||
format_hex = "{:<15} 0x{:<13x}"
|
||||
format_dec = "{:<15} {:<30d}"
|
||||
|
||||
|
||||
modes_str = " - ".join([str(m).split(".")[-1] for m in header.modes])
|
||||
bitness = ""
|
||||
@@ -54,14 +57,13 @@ def print_header(binary):
|
||||
if header.is_64:
|
||||
bitness = "64-bits"
|
||||
|
||||
|
||||
print(format_str.format("Architecture:", str(header.architecture).split(".")[-1]))
|
||||
print(format_str.format("Modes:", modes_str))
|
||||
print(format_hex.format("Entrypoint:", header.entrypoint))
|
||||
print(format_str.format("Object type:", str(header.object_type).split(".")[-1]))
|
||||
print(format_str.format("Endianness:", str(header.endianness).split(".")[-1]))
|
||||
print(format_str.format("Bitness:", bitness))
|
||||
print("")
|
||||
print(format_str.format("Modes:", modes_str))
|
||||
print(format_hex.format("Entrypoint:", header.entrypoint))
|
||||
print(format_str.format("Object type:", str(header.object_type).split(".")[-1]))
|
||||
print(format_str.format("Endianness:", str(header.endianness).split(".")[-1]))
|
||||
print(format_str.format("Bitness:", bitness))
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -71,13 +73,16 @@ def print_sections(binary):
|
||||
f_value = "|{:<30} | 0x{:<16x}| 0x{:<16x}| 0x{:<16x}| {:<9.2f}|"
|
||||
print(f_title.format("Name", "File offset", "Size", "Virtual Address", "Entropy"))
|
||||
for section in binary.sections:
|
||||
print(f_value.format(\
|
||||
section.name,\
|
||||
section.offset,\
|
||||
section.size,\
|
||||
section.virtual_address,\
|
||||
section.entropy))
|
||||
print("")
|
||||
print(
|
||||
f_value.format(
|
||||
section.name,
|
||||
section.offset,
|
||||
section.size,
|
||||
section.virtual_address,
|
||||
section.entropy,
|
||||
)
|
||||
)
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -87,10 +92,9 @@ def print_relocations(binary):
|
||||
f_value = "|0x{:<16x} | {:<6d}|"
|
||||
print(f_title.format("Address", "Size"))
|
||||
for relocation in binary.relocations:
|
||||
print(f_value.format(\
|
||||
relocation.address,\
|
||||
relocation.size))
|
||||
print("")
|
||||
print(f_value.format(relocation.address, relocation.size))
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_symbols(binary):
|
||||
@@ -103,7 +107,7 @@ def print_symbols(binary):
|
||||
|
||||
for symbol in binary.symbols:
|
||||
print(f.format(symbol.name))
|
||||
print("")
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -113,8 +117,9 @@ def print_exported_functions(binary):
|
||||
f = "|{:<30} |"
|
||||
print(f.format("Name"))
|
||||
for func in binary.exported_functions:
|
||||
print(f.format(func))
|
||||
print("")
|
||||
print(f.format(func))
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_imported_functions(binary):
|
||||
@@ -124,7 +129,7 @@ def print_imported_functions(binary):
|
||||
print(f.format("Name"))
|
||||
for func in binary.imported_functions:
|
||||
print(f.format(func))
|
||||
print("")
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -135,58 +140,91 @@ def print_imported_libraries(binary):
|
||||
print(f.format("Name"))
|
||||
for library in binary.libraries:
|
||||
print(f.format(library))
|
||||
print("")
|
||||
print()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(usage='%(prog)s [options] <elf-pe-macho>')
|
||||
parser.add_argument('-a', '--all',
|
||||
action='store_true', dest='show_all',
|
||||
help='Show all information')
|
||||
parser = argparse.ArgumentParser(usage="%(prog)s [options] <elf-pe-macho>")
|
||||
parser.add_argument(
|
||||
"-a", "--all", action="store_true", dest="show_all", help="Show all information"
|
||||
)
|
||||
|
||||
parser.add_argument('-H', '--header',
|
||||
action='store_true', dest='show_header',
|
||||
help='Display header')
|
||||
parser.add_argument(
|
||||
"-H", "--header", action="store_true", dest="show_header", help="Display header"
|
||||
)
|
||||
|
||||
parser.add_argument('-i', '--imported',
|
||||
action='store_true', dest='show_imported_functions',
|
||||
help='Display imported functions')
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--imported",
|
||||
action="store_true",
|
||||
dest="show_imported_functions",
|
||||
help="Display imported functions",
|
||||
)
|
||||
|
||||
parser.add_argument('-L', '--libraries',
|
||||
action='store_true', dest='show_libraries',
|
||||
help='Display Imported Libraries')
|
||||
parser.add_argument(
|
||||
"-L",
|
||||
"--libraries",
|
||||
action="store_true",
|
||||
dest="show_libraries",
|
||||
help="Display Imported Libraries",
|
||||
)
|
||||
|
||||
parser.add_argument('-r', '--relocations',
|
||||
action='store_true', dest='show_relocs',
|
||||
help='Display the relocations (if present)')
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--relocations",
|
||||
action="store_true",
|
||||
dest="show_relocs",
|
||||
help="Display the relocations (if present)",
|
||||
)
|
||||
|
||||
parser.add_argument('-s', '--symbols',
|
||||
action='store_true', dest='show_symbols',
|
||||
help='Display Symbols')
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--symbols",
|
||||
action="store_true",
|
||||
dest="show_symbols",
|
||||
help="Display Symbols",
|
||||
)
|
||||
|
||||
parser.add_argument('-S', '--sections',
|
||||
action='store_true', dest='show_sections',
|
||||
help='Display Sections')
|
||||
parser.add_argument(
|
||||
"-S",
|
||||
"--sections",
|
||||
action="store_true",
|
||||
dest="show_sections",
|
||||
help="Display Sections",
|
||||
)
|
||||
|
||||
parser.add_argument('-x', '--exported',
|
||||
action='store_true', dest='show_exported_functions',
|
||||
help='Display exported functions')
|
||||
parser.add_argument(
|
||||
"-x",
|
||||
"--exported",
|
||||
action="store_true",
|
||||
dest="show_exported_functions",
|
||||
help="Display exported functions",
|
||||
)
|
||||
|
||||
parser.add_argument("binary",
|
||||
metavar="<elf-pe-macho>",
|
||||
help='Target File')
|
||||
parser.add_argument("binary", metavar="<elf-pe-macho>", help="Target File")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
binary = lief.parse(args.binary)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{args.binary}'", file=sys.stderr)
|
||||
return 1
|
||||
if isinstance(binary, lief.COFF.Binary):
|
||||
print("COFF objects do not expose an abstract view", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
binary = binary.abstract
|
||||
if args.show_header or args.show_all:
|
||||
print_header(binary)
|
||||
|
||||
if (args.show_imported_functions or args.show_all) and len(binary.imported_functions) > 0:
|
||||
if (args.show_imported_functions or args.show_all) and len(
|
||||
binary.imported_functions
|
||||
) > 0:
|
||||
print_imported_functions(binary)
|
||||
|
||||
if (args.show_exported_functions or args.show_all) and len(binary.exported_functions) > 0:
|
||||
if (args.show_exported_functions or args.show_all) and len(
|
||||
binary.exported_functions
|
||||
) > 0:
|
||||
print_exported_functions(binary)
|
||||
|
||||
if (args.show_libraries or args.show_all) and len(binary.libraries) > 0:
|
||||
@@ -201,8 +239,8 @@ def main():
|
||||
if (args.show_relocs or args.show_all) and len(binary.relocations) > 0:
|
||||
print_relocations(binary)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
sys.exit(main())
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import lief
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Parse PE file
|
||||
pe = lief.parse(sys.argv[1])
|
||||
|
||||
sep = (":") if sys.version_info.minor > 7 else ()
|
||||
|
||||
# Get authenticode
|
||||
print(pe.authentihash_md5.hex(*sep)) # 1c:a0:91:53:dc:9a:3a:5f:34:1d:7f:9b:b9:56:69:4d
|
||||
print(pe.authentihash(lief.PE.ALGORITHMS.SHA_1).hex(*sep)) # 1e:ad:dc:29:1e:db:41:a2:69:c2:ba:ae:4b:fb:9d:31:e7:bb:ab:59
|
||||
|
||||
# Check signature according to PKCS #7 and Microsoft documentation
|
||||
print(pe.verify_signature()) # Return VERIFICATION_FLAGS.OK
|
||||
|
||||
bin_ca = None
|
||||
# Look for the root CA in the PE file
|
||||
for crt in pe.signatures[0].certificates:
|
||||
if crt.issuer == "C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA":
|
||||
bin_ca = crt
|
||||
|
||||
# Verify CA chain
|
||||
bundle_path = os.getenv("LIEF_CA_BUNDLE", None) # Path to CA bundle (one can use those from signify:
|
||||
# signify/certs/authenticode-bundle.pem)
|
||||
if bundle_path is not None:
|
||||
# Parse cert bundle and return a list of lief.PE.x509 objects
|
||||
bundle = lief.PE.x509.parse(bundle_path)
|
||||
print(bin_ca.is_trusted_by(bundle)) # VERIFICATION_FLAGS.OK
|
||||
|
||||
|
||||
# Get the certificate used by the signer
|
||||
cert_signer = pe.signatures[0].signers[0].cert
|
||||
print(cert_signer)
|
||||
bin_ca.verify(cert_signer) # Verify that cert_signer is signed the CA
|
||||
|
||||
# running with:
|
||||
# LIEF_CA_BUNDLE=signify/signify/certs/authenticode-bundle.pem python ./authenticode.py avast_free_antivirus_setup_online.exe
|
||||
#
|
||||
# 1c:a0:91:53:dc:9a:3a:5f:34:1d:7f:9b:b9:56:69:4d
|
||||
# 1e:ad:dc:29:1e:db:41:a2:69:c2:ba:ae:4b:fb:9d:31:e7:bb:ab:59
|
||||
# VERIFICATION_FLAGS.OK
|
||||
# cert. version : 3
|
||||
# serial number : 04:09:18:1B:5F:D5:BB:66:75:53:43:B5:6F:95:50:08
|
||||
# issuer name : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
|
||||
# subject name : C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Assured ID Code Signing CA
|
||||
# issued on : 2013-10-22 12:00:00
|
||||
# expires on : 2028-10-22 12:00:00
|
||||
# signed using : RSA with SHA-256
|
||||
# RSA key size : 2048 bits
|
||||
# basic constraints : CA=true, max_pathlen=0
|
||||
# key usage : Digital Signature, Key Cert Sign, CRL Sign
|
||||
# ext key usage : Code Signing
|
||||
#
|
||||
# VERIFICATION_FLAGS.OK
|
||||
@@ -1,68 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import lief
|
||||
import argparse
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
def change_interpreter(target, interpreter, output=None):
|
||||
if not os.path.isfile(target) or not lief.is_elf(target):
|
||||
print("Wrong target! ({})".format(target))
|
||||
return 1
|
||||
|
||||
|
||||
if not os.path.isfile(interpreter) or not lief.is_elf(interpreter):
|
||||
print("Wrong interpreter! ({})".format(interpreter))
|
||||
return 1
|
||||
|
||||
binary = lief.ELF.parse(target)
|
||||
if not binary.has_interpreter:
|
||||
print("The given target doesn't have interpreter!")
|
||||
return 1
|
||||
|
||||
binary.interpreter = interpreter
|
||||
|
||||
output_path = output
|
||||
if output_path is None:
|
||||
output_path = os.path.basename(target)
|
||||
output_path += "_updated"
|
||||
|
||||
if os.path.isfile(output_path):
|
||||
os.remove(output_path)
|
||||
|
||||
binary.write(output_path)
|
||||
|
||||
# Set as executable
|
||||
st = os.stat(output_path)
|
||||
os.chmod(output_path, st.st_mode | stat.S_IEXEC)
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Change the ELF interpreter of the given binary')
|
||||
|
||||
|
||||
parser.add_argument("-o", "--output",
|
||||
help = 'Path to the binary rewritten',
|
||||
action = 'store',
|
||||
default = None)
|
||||
|
||||
parser.add_argument("target",
|
||||
metavar="<elf>",
|
||||
help='Target ELF file')
|
||||
|
||||
parser.add_argument("interpreter",
|
||||
metavar="<interpreter>",
|
||||
help='Path to the new interpreter')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
status = change_interpreter(args.target, args.interpreter, args.output)
|
||||
sys.exit(status)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
Regular → Executable
+26
-13
@@ -1,27 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Dump a DEX file (Android Dalvik bytecode) as JSON.
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Print information about a DEX file in the JSON format
|
||||
Parses a ``.dex`` file and writes a pretty-printed JSON dump of its
|
||||
structure (header, classes, methods, strings, ...) using
|
||||
``lief.to_json``.
|
||||
|
||||
Example:
|
||||
|
||||
$ python dex_json.py classes.dex
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import lief
|
||||
import json
|
||||
import sys
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('file', help='DEX binary')
|
||||
import lief
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("file", help="Path to a DEX file")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not lief.is_dex(args.file):
|
||||
print("{} is not a DEX file".format(args.file))
|
||||
print(f"'{args.file}' is not a DEX file", file=sys.stderr)
|
||||
return 1
|
||||
dexfile = lief.DEX.parse(args.file)
|
||||
|
||||
dexfile = lief.DEX.parse(args.file)
|
||||
if dexfile is None:
|
||||
print(f"Error: failed to parse '{args.file}'", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
json_data = json.loads(lief.to_json(dexfile))
|
||||
print(json.dumps(json_data, sort_keys = True, indent = 4))
|
||||
print(json.dumps(json_data, sort_keys=True, indent=4))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
|
||||
Regular → Executable
+123
-109
@@ -1,29 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Pretty-print the structure of an Android DEX file.
|
||||
|
||||
Parses a ``.dex`` file with ``lief.DEX.parse`` and renders header,
|
||||
classes, methods, fields, strings, types, prototypes and the map
|
||||
list, selected by command-line flags.
|
||||
|
||||
Example:
|
||||
|
||||
$ python dex_reader.py -a classes.dex
|
||||
"""
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Print information about Android DEX files
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import lief
|
||||
from lief import DEX
|
||||
|
||||
EXIT_STATUS = 0
|
||||
terminal_rows, terminal_columns = 100, 100
|
||||
try:
|
||||
terminal_rows, terminal_columns = os.popen('stty size', 'r').read().split()
|
||||
except ValueError:
|
||||
pass
|
||||
_term_size = shutil.get_terminal_size((100, 100))
|
||||
terminal_columns = _term_size.columns
|
||||
terminal_rows = _term_size.lines
|
||||
|
||||
|
||||
class exceptions_handler(object):
|
||||
class exceptions_handler:
|
||||
func = None
|
||||
|
||||
def __init__(self, exceptions, on_except_callback=None):
|
||||
self.exceptions = exceptions
|
||||
self.exceptions = exceptions
|
||||
self.on_except_callback = on_except_callback
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
@@ -34,93 +39,73 @@ class exceptions_handler(object):
|
||||
return self.func(*args, **kwargs)
|
||||
except self.exceptions as e:
|
||||
global EXIT_STATUS
|
||||
print("{} raised: {}".format(self.func.__name__, e))
|
||||
print(f"{self.func.__name__} raised: {e}")
|
||||
EXIT_STATUS = 1
|
||||
if self.on_except_callback is not None:
|
||||
self.on_except_callback(e)
|
||||
else:
|
||||
print("-" * 60)
|
||||
print("Exception in {}: {}".format(self.func.__name__, e))
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
print(f"Exception in {self.func.__name__}: {e}")
|
||||
_exc_type, _exc_value, exc_traceback = sys.exc_info()
|
||||
traceback.print_tb(exc_traceback)
|
||||
print("-" * 60)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_information(dexfile):
|
||||
print("== Information ==")
|
||||
format_str = "{:<30} {:<30}"
|
||||
format_hex = "{:<30} 0x{:<28x}"
|
||||
format_dec = "{:<30} {:<30d}"
|
||||
version = dexfile.version
|
||||
|
||||
print("DEX File version: {}".format(version))
|
||||
print("")
|
||||
print(f"DEX File version: {dexfile.version}")
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_header(dexfile):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
print("== Header ==")
|
||||
header = dexfile.header
|
||||
print(header)
|
||||
print(dexfile.header)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_classes(dexfile):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
classes = dexfile.classes
|
||||
|
||||
print("== Classes ==")
|
||||
for cls in classes:
|
||||
for cls in dexfile.classes:
|
||||
print(cls)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_fields(dexfile):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
fields = dexfile.fields
|
||||
|
||||
print("== Fields ==")
|
||||
for f in fields:
|
||||
for f in dexfile.fields:
|
||||
print(f)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_methods(dexfile):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
methods = dexfile.methods
|
||||
|
||||
print("== Methods ==")
|
||||
for m in methods:
|
||||
for m in dexfile.methods:
|
||||
print(m)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_strings(dexfile):
|
||||
print("== Strings ==")
|
||||
for s in dexfile.strings:
|
||||
print(s)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_types(dexfile):
|
||||
print("== Types ==")
|
||||
for t in dexfile.types:
|
||||
print(t)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_prototypes(dexfile):
|
||||
print("== Prototypes ==")
|
||||
for t in dexfile.prototypes:
|
||||
print(t)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_map(dexfile):
|
||||
print("== Map ==")
|
||||
@@ -128,87 +113,116 @@ def print_map(dexfile):
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(usage='%(prog)s [options] DEX files')
|
||||
parser.add_argument('-a', '--all',
|
||||
action='store_true', dest='show_all',
|
||||
help='Show all information')
|
||||
parser = argparse.ArgumentParser(usage="%(prog)s [options] DEX files")
|
||||
parser.add_argument(
|
||||
"-a", "--all", action="store_true", dest="show_all", help="Show all information"
|
||||
)
|
||||
|
||||
parser.add_argument('-H', '--header',
|
||||
action='store_true', dest='show_header',
|
||||
help='Display header')
|
||||
parser.add_argument(
|
||||
"-H", "--header", action="store_true", dest="show_header", help="Display header"
|
||||
)
|
||||
|
||||
parser.add_argument('-c', '--classes',
|
||||
action='store_true', dest='show_classes',
|
||||
help='Display classes')
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--classes",
|
||||
action="store_true",
|
||||
dest="show_classes",
|
||||
help="Display classes",
|
||||
)
|
||||
|
||||
parser.add_argument('-f', '--fields',
|
||||
action='store_true', dest='show_fields',
|
||||
help='Display Fields')
|
||||
parser.add_argument(
|
||||
"-f", "--fields", action="store_true", dest="show_fields", help="Display Fields"
|
||||
)
|
||||
|
||||
parser.add_argument('-m', '--methods',
|
||||
action='store_true', dest='show_methods',
|
||||
help='Display Methods')
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--methods",
|
||||
action="store_true",
|
||||
dest="show_methods",
|
||||
help="Display Methods",
|
||||
)
|
||||
|
||||
parser.add_argument('-s', '--strings',
|
||||
action='store_true', dest='show_strings',
|
||||
help='Display Strings')
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--strings",
|
||||
action="store_true",
|
||||
dest="show_strings",
|
||||
help="Display Strings",
|
||||
)
|
||||
|
||||
parser.add_argument('-t', '--types',
|
||||
action='store_true', dest='show_types',
|
||||
help='Display Types')
|
||||
parser.add_argument(
|
||||
"-t", "--types", action="store_true", dest="show_types", help="Display Types"
|
||||
)
|
||||
|
||||
parser.add_argument('-p', '--prototypes',
|
||||
action='store_true', dest='show_prototypes',
|
||||
help='Display Prototypes')
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--prototypes",
|
||||
action="store_true",
|
||||
dest="show_prototypes",
|
||||
help="Display Prototypes",
|
||||
)
|
||||
|
||||
parser.add_argument('-M', '--map',
|
||||
action='store_true', dest='show_map',
|
||||
help='Display Map')
|
||||
parser.add_argument(
|
||||
"-M", "--map", action="store_true", dest="show_map", help="Display Map"
|
||||
)
|
||||
|
||||
parser.add_argument("file",
|
||||
metavar="<dex-file>",
|
||||
help='Target DEX File')
|
||||
parser.add_argument("file", metavar="<dex-file>", help="Target DEX File")
|
||||
|
||||
logger_group = parser.add_argument_group('Logger')
|
||||
logger_group = parser.add_argument_group("Logger")
|
||||
verbosity = logger_group.add_mutually_exclusive_group()
|
||||
|
||||
verbosity.add_argument('--debug',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.DEBUG)
|
||||
verbosity.add_argument(
|
||||
"--debug",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Debug,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--trace',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.TRACE)
|
||||
verbosity.add_argument(
|
||||
"--trace",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Trace,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--info',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.INFO)
|
||||
verbosity.add_argument(
|
||||
"--info",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Info,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--warn',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.WARN)
|
||||
verbosity.add_argument(
|
||||
"--warn",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Warn,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--err',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.ERROR)
|
||||
verbosity.add_argument(
|
||||
"--err",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Err,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--critical',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.CRITICAL)
|
||||
verbosity.add_argument(
|
||||
"--critical",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Critical,
|
||||
)
|
||||
|
||||
parser.set_defaults(main_verbosity=lief.logging.LEVEL.WARN)
|
||||
parser.set_defaults(main_verbosity=lief.logging.Level.Warn)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
lief.logging.set_level(args.main_verbosity)
|
||||
|
||||
dexfile = DEX.parse(args.file)
|
||||
if dexfile is None:
|
||||
print(f"Error: failed to parse '{args.file}' as DEX", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print_information(dexfile)
|
||||
|
||||
@@ -236,8 +250,8 @@ def main():
|
||||
if args.show_map or args.show_all:
|
||||
print_map(dexfile)
|
||||
|
||||
sys.exit(EXIT_STATUS)
|
||||
return EXIT_STATUS
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
||||
@@ -1,35 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
This script disassembles an ELF/PE/Mach-O binary using LIEF's extended API
|
||||
"""Disassemble instructions at an address of an ELF/PE/Mach-O binary.
|
||||
|
||||
Uses LIEF's extended disassembly API to iterate over the instructions
|
||||
located at the given virtual address of the binary.
|
||||
|
||||
Note: only available with the extended version of LIEF.
|
||||
|
||||
Example:
|
||||
|
||||
$ python disassembler.py /bin/ls 0x4000
|
||||
"""
|
||||
|
||||
Note: this script is only working with the extended version of LIEF
|
||||
'''
|
||||
import argparse
|
||||
import lief
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def disassemble(target: lief.Binary, addr: int):
|
||||
import lief
|
||||
|
||||
|
||||
def disassemble(target: lief.Binary, addr: int) -> None:
|
||||
for inst in target.disassemble(addr):
|
||||
print(inst)
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("file", help='Target file', type=Path)
|
||||
parser.add_argument("address", help='Address to disassemble',
|
||||
type=lambda x: int(x,0))
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("file", help="Target binary", type=Path)
|
||||
parser.add_argument(
|
||||
"address", help="Address to disassemble", type=lambda x: int(x, 0)
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
target_file = args.file
|
||||
addr = args.address
|
||||
|
||||
target = lief.parse(target_file)
|
||||
target = lief.parse(args.file)
|
||||
if target is None:
|
||||
print(f"Can't load: {target_file}")
|
||||
print(f"Can't load: {args.file}", file=sys.stderr)
|
||||
return 1
|
||||
if isinstance(target, lief.COFF.Binary):
|
||||
print("COFF binaries are not supported by the disassembler", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
disassemble(target, addr)
|
||||
disassemble(target, args.address)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
Regular → Executable
+58
-17
@@ -1,25 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
"""Create a companion DWARF file from a PE binary.
|
||||
|
||||
Demonstrates the DWARF editor API: loads a PE binary, synthesizes a
|
||||
compilation unit with one function returning a pointer to a
|
||||
structure and a stack variable, then writes the result to
|
||||
``/tmp/out.debug``.
|
||||
|
||||
Note: only available with the extended version of LIEF.
|
||||
|
||||
Example:
|
||||
|
||||
$ python dwarf_editor.py program.exe
|
||||
"""
|
||||
This example shows how to create a DWARF file by using LIEF's Python API
|
||||
"""
|
||||
import lief
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
if not lief.__extended__:
|
||||
print("This example requires the extended version of LIEF")
|
||||
import lief
|
||||
|
||||
pe = lief.PE.parse(sys.argv[1])
|
||||
editor: lief.dwarf.Editor = lief.dwarf.Editor.from_binary(pe)
|
||||
|
||||
unit: lief.dwarf.editor.CompilationUnit = editor.create_compilation_unit()
|
||||
unit.set_producer("LIEF")
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("file", help="Input PE binary")
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
default="/tmp/out.debug",
|
||||
help="Output DWARF file (default: %(default)s)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
func: lief.dwarf.editor.Function = unit.create_function("hello")
|
||||
func.set_address(0x123)
|
||||
func.set_return_type(
|
||||
unit.create_structure("my_struct_t").pointer_to()
|
||||
)
|
||||
if not lief.__extended__:
|
||||
print("This example requires the extended version of LIEF", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
var: lief.dwarf.editor.Variable = func.create_stack_variable("local_var")
|
||||
var.set_stack_offset(8)
|
||||
pe = lief.PE.parse(args.file)
|
||||
if pe is None:
|
||||
print(f"Error: failed to parse '{args.file}' as PE", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
editor.write("/tmp/out.debug")
|
||||
editor = lief.dwarf.Editor.from_binary(pe)
|
||||
if editor is None:
|
||||
print("Failed to create a DWARF editor", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
unit = editor.create_compilation_unit()
|
||||
unit.set_producer("LIEF")
|
||||
|
||||
func = unit.create_function("hello")
|
||||
func.set_address(0x123)
|
||||
|
||||
pointer_type = unit.create_structure("my_struct_t").pointer_to()
|
||||
if pointer_type is None:
|
||||
print("Failed to create the pointer type", file=sys.stderr)
|
||||
return 1
|
||||
func.set_return_type(pointer_type)
|
||||
|
||||
var = func.create_stack_variable("local_var")
|
||||
var.set_stack_offset(8)
|
||||
|
||||
editor.write(args.output)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
@@ -1,40 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
This script lists libraries embedded in a dyld shared cache file
|
||||
"""List the contents of a dyld shared cache.
|
||||
|
||||
Note: this script is only working with the extended version of LIEF
|
||||
'''
|
||||
Loads an Apple ``dyld`` shared cache (single file or multi-file
|
||||
directory layout) and prints the embedded libraries, the mapping
|
||||
information for each page range and the UUID of the sub-caches.
|
||||
|
||||
Note: only available with the extended version of LIEF.
|
||||
|
||||
Example:
|
||||
|
||||
$ python dyld_shared_cache_reader.py /System/Library/dyld/dyld_shared_cache_arm64e
|
||||
"""
|
||||
|
||||
import sys
|
||||
import lief
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import lief
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("target", type=Path,
|
||||
help='Target dyld shared file (file or dir)')
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument(
|
||||
"target", type=Path, help="Target dyld shared cache file or directory"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
target: Path = args.target
|
||||
if not target.exists():
|
||||
print(f"'{target}' does not exist")
|
||||
print(f"'{target}' does not exist", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
dyld_cache = lief.dsc.load(target)
|
||||
if dyld_cache is None:
|
||||
print(f"Can't parse '{target}'")
|
||||
print(f"Can't parse '{target}'", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
for lib in dyld_cache.libraries:
|
||||
print(f"0x{lib.address:016x} {lib.path}")
|
||||
print(f"{lib.address:#016x} {lib.path}")
|
||||
|
||||
for idx, info in enumerate(dyld_cache.mapping_info):
|
||||
print(f"mapping_info[{idx:02d}]: [{info.address:016x}, {info.end_address:016x}] -> 0x{info.file_offset:016x}")
|
||||
print(
|
||||
f"mapping_info[{idx:02d}]: "
|
||||
f"[{info.address:#016x}, {info.end_address:#016x}] -> "
|
||||
f"{info.file_offset:#016x}"
|
||||
)
|
||||
|
||||
for idx, subcache in enumerate(dyld_cache.subcaches):
|
||||
uuid_str = ':'.join(map(lambda e: f"{e:02x}", subcache.uuid))
|
||||
uuid_str = ":".join(f"{e:02x}" for e in subcache.uuid)
|
||||
print(f"cache[{idx:02d}]: {uuid_str} {subcache.suffix}")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
Regular → Executable
+39
-17
@@ -1,31 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
"""Promote a PIE executable to a shared library by exporting a function.
|
||||
|
||||
Takes a PIE ELF executable, declares an exported function at the
|
||||
given address, and rewrites the binary so that it can be ``dlopen``-ed
|
||||
and the function invoked via ``dlsym``.
|
||||
|
||||
Example:
|
||||
|
||||
$ python elf_bin2lib.py -n compute -o libcompute.so ./prog 0x1200
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import lief
|
||||
import sys
|
||||
|
||||
def bin2lib(binary, address, output, name=""):
|
||||
import lief
|
||||
|
||||
|
||||
def bin2lib(binary: lief.ELF.Binary, address: int, output: str, name: str = "") -> int:
|
||||
if not binary.is_pie:
|
||||
print("It only works with PIE binaries")
|
||||
sys.exit(1)
|
||||
print("It only works with PIE binaries", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
function = binary.add_exported_function(address, name)
|
||||
print("Function created:")
|
||||
print(function)
|
||||
print("Function created:", function)
|
||||
binary.write(output)
|
||||
return 0
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="")
|
||||
|
||||
parser.add_argument("--name", "-n", default="", help="Name of the function to create")
|
||||
parser.add_argument("--output", "-o", default="libfoo.so", help="Output name. (Default: %(default)")
|
||||
|
||||
parser.add_argument("binary", help="The target binary")
|
||||
parser.add_argument("address", type=lambda e: int(e, 0), help="Address of the function to export")
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument(
|
||||
"--name", "-n", default="", help="Name of the function to create"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output", "-o", default="libfoo.so", help="Output name (default: %(default)s)"
|
||||
)
|
||||
parser.add_argument("binary", help="The target ELF binary")
|
||||
parser.add_argument(
|
||||
"address", type=lambda e: int(e, 0), help="Address of the function to export"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
binary = lief.parse(args.binary)
|
||||
bin2lib(binary, args.address, args.output, name=args.name)
|
||||
binary = lief.ELF.parse(args.binary)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{args.binary}' as ELF", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
return bin2lib(binary, args.address, args.output, name=args.name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python
|
||||
"""Change the program interpreter of an ELF executable.
|
||||
|
||||
Replaces the ``PT_INTERP`` entry (the ``.interp`` section) of a
|
||||
dynamically-linked ELF executable with the path of another ELF
|
||||
interpreter, then writes the patched binary to disk with the execute
|
||||
bit set.
|
||||
|
||||
Example:
|
||||
|
||||
$ python elf_change_interpreter.py \\
|
||||
--output /tmp/ls_musl /bin/ls /usr/lib/ld-musl-x86_64.so.1
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import stat
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import lief
|
||||
|
||||
|
||||
def change_interpreter(
|
||||
target: Path, interpreter: Path, output: Path | None = None
|
||||
) -> int:
|
||||
if not target.is_file() or not lief.is_elf(target):
|
||||
print(f"Wrong target! ({target})", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if not interpreter.is_file() or not lief.is_elf(interpreter):
|
||||
print(f"Wrong interpreter! ({interpreter})", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
binary = lief.ELF.parse(target)
|
||||
if binary is None:
|
||||
print(f"Failed to parse '{target}' as ELF", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if not binary.has_interpreter:
|
||||
print("The given target doesn't have an interpreter!", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
binary.interpreter = str(interpreter)
|
||||
|
||||
output_path = output or Path(f"{target.name}_updated")
|
||||
|
||||
output_path.unlink(missing_ok=True)
|
||||
|
||||
binary.write(output_path)
|
||||
|
||||
# Restore the execute bit that LIEF doesn't propagate.
|
||||
st = output_path.stat()
|
||||
output_path.chmod(st.st_mode | stat.S_IEXEC)
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument(
|
||||
"-o", "--output", help="Path to the rewritten binary", default=None, type=Path
|
||||
)
|
||||
parser.add_argument("target", metavar="<elf>", help="Target ELF file", type=Path)
|
||||
parser.add_argument(
|
||||
"interpreter",
|
||||
metavar="<interpreter>",
|
||||
help="Path to the new interpreter",
|
||||
type=Path,
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
return change_interpreter(args.target, args.interpreter, args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Executable
+150
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Analyze ELF shared library dependencies and symbol versioning.
|
||||
|
||||
A cross-platform alternative to ldd that works without executing the binary.
|
||||
Lists shared library dependencies, RPATH/RUNPATH search paths, and optionally
|
||||
shows imported symbol versions (useful for checking glibc compatibility).
|
||||
|
||||
Inspired by conda-build's liefldd.py and Bitcoin's symbol-check.py.
|
||||
|
||||
Example:
|
||||
|
||||
$ python elf_deps.py /usr/bin/ls
|
||||
Dependencies: /usr/bin/ls
|
||||
========================================
|
||||
Interpreter: /lib64/ld-linux-x86-64.so.2
|
||||
Type: DYN (Position-Independent Executable)
|
||||
|
||||
Shared Libraries:
|
||||
libselinux.so.1
|
||||
libc.so.6
|
||||
ld-linux-x86-64.so.2
|
||||
|
||||
$ python elf_deps.py --versions /usr/bin/ls
|
||||
...
|
||||
Symbol Versions:
|
||||
GLIBC_2.2.5 (25 symbols)
|
||||
GLIBC_2.3 (1 symbols)
|
||||
GLIBC_2.17 (2 symbols)
|
||||
"""
|
||||
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
|
||||
import lief
|
||||
|
||||
HEADER_TYPES = {
|
||||
lief.ELF.Header.FILE_TYPE.EXEC: "EXEC (Executable)",
|
||||
lief.ELF.Header.FILE_TYPE.DYN: "DYN (Shared Object / PIE)",
|
||||
lief.ELF.Header.FILE_TYPE.REL: "REL (Relocatable)",
|
||||
lief.ELF.Header.FILE_TYPE.CORE: "CORE (Core Dump)",
|
||||
}
|
||||
|
||||
|
||||
def analyze_deps(filename, show_versions=False):
|
||||
"""Analyze ELF dependencies and symbol version requirements."""
|
||||
binary = lief.ELF.parse(filename)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{filename}' as ELF")
|
||||
return False
|
||||
|
||||
file_type = HEADER_TYPES.get(binary.header.file_type, str(binary.header.file_type))
|
||||
interpreter = binary.interpreter or "(none — statically linked)"
|
||||
|
||||
print(f"Dependencies: {filename}")
|
||||
print("=" * 48)
|
||||
print(f" Interpreter: {interpreter}")
|
||||
print(f" Type: {file_type}")
|
||||
print(f" Arch: {binary.header.machine_type.name}")
|
||||
print()
|
||||
|
||||
# Shared libraries (DT_NEEDED entries)
|
||||
libraries = list(binary.libraries)
|
||||
if libraries:
|
||||
print(" Shared Libraries:")
|
||||
for lib in libraries:
|
||||
print(f" {lib}")
|
||||
else:
|
||||
print(" Shared Libraries: (none — statically linked)")
|
||||
print()
|
||||
|
||||
# RPATH and RUNPATH
|
||||
rpath = None
|
||||
runpath = None
|
||||
for entry in binary.dynamic_entries:
|
||||
if isinstance(entry, lief.ELF.DynamicEntryRpath):
|
||||
rpath = entry.rpath
|
||||
elif isinstance(entry, lief.ELF.DynamicEntryRunPath):
|
||||
runpath = entry.runpath
|
||||
|
||||
if rpath or runpath:
|
||||
print(" Search Paths:")
|
||||
if rpath:
|
||||
print(f" RPATH: {rpath}")
|
||||
if runpath:
|
||||
print(f" RUNPATH: {runpath}")
|
||||
print()
|
||||
|
||||
# Symbol versions
|
||||
if show_versions:
|
||||
version_counts = defaultdict(int)
|
||||
version_symbols = defaultdict(list)
|
||||
|
||||
for sym in binary.imported_symbols:
|
||||
if not sym.has_version:
|
||||
continue
|
||||
version = sym.symbol_version
|
||||
if not version.has_auxiliary_version:
|
||||
continue
|
||||
ver_name = version.symbol_version_auxiliary.name
|
||||
version_counts[ver_name] += 1
|
||||
version_symbols[ver_name].append(sym.name)
|
||||
|
||||
if version_counts:
|
||||
print(" Symbol Versions:")
|
||||
for ver_name in sorted(version_counts):
|
||||
count = version_counts[ver_name]
|
||||
print(f" {ver_name:<24} ({count} symbol{'s' if count != 1 else ''})")
|
||||
print()
|
||||
|
||||
# Show highest required version per library prefix
|
||||
lib_versions = defaultdict(list)
|
||||
for ver_name in version_counts:
|
||||
parts = ver_name.rsplit("_", 1)
|
||||
if len(parts) == 2:
|
||||
lib, ver_str = parts
|
||||
try:
|
||||
ver_tuple = tuple(int(x) for x in ver_str.split("."))
|
||||
lib_versions[lib].append((ver_tuple, ver_name))
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if lib_versions:
|
||||
print(" Minimum Required Versions:")
|
||||
for lib in sorted(lib_versions):
|
||||
max_ver = max(lib_versions[lib], key=lambda x: x[0])
|
||||
print(f" {lib}: {max_ver[1]}")
|
||||
print()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Analyze ELF shared library dependencies"
|
||||
)
|
||||
parser.add_argument("binaries", nargs="+", help="ELF binaries to analyze")
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--versions",
|
||||
action="store_true",
|
||||
help="Show imported symbol version requirements",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
for path in args.binaries:
|
||||
analyze_deps(path, show_versions=args.versions)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Regular → Executable
+22
-29
@@ -1,43 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Dump an ELF binary as JSON.
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Print information about a ELF binary in the JSON format
|
||||
#
|
||||
# python elf_json.py /bin/ls
|
||||
#
|
||||
# {
|
||||
# "dynamic_entries": [
|
||||
# {
|
||||
# "library": "libcap.so.2",
|
||||
# "tag": "NEEDED",
|
||||
# "value": 1
|
||||
# },
|
||||
# {
|
||||
# "library": "libc.so.6",
|
||||
# "tag": "NEEDED",
|
||||
# "value": 74
|
||||
# },
|
||||
# ...
|
||||
Parses an ELF file and writes a pretty-printed JSON dump of the full
|
||||
structure (header, sections, segments, dynamic entries, symbols, ...)
|
||||
using ``lief.to_json``.
|
||||
|
||||
Example:
|
||||
|
||||
$ python elf_json.py /bin/ls
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import lief
|
||||
import json
|
||||
import sys
|
||||
|
||||
import lief
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('binary', help='ELF binary')
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("binary", help="Path to an ELF binary")
|
||||
args = parser.parse_args()
|
||||
|
||||
binary = lief.parse(args.binary)
|
||||
binary = lief.ELF.parse(args.binary)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{args.binary}' as ELF", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
json_data = json.loads(lief.to_json(binary))
|
||||
print(json.dumps(json_data, sort_keys = True, indent = 4))
|
||||
print(json.dumps(json_data, sort_keys=True, indent=4))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
|
||||
Regular → Executable
+392
-229
@@ -1,33 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Pretty-print the structure of an ELF binary.
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Print information about an ELF binary
|
||||
Equivalent to ``readelf`` with a selection of the most useful flags
|
||||
(``-h``, ``-S``, ``-l``, ``-d``, ``-s``, ``-r``, ``-V`` ...). The
|
||||
target file is parsed with ``lief.ELF.parse`` and the requested
|
||||
sections are rendered as formatted tables.
|
||||
|
||||
import os
|
||||
Example:
|
||||
|
||||
$ python elf_reader.py -a /bin/ls
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import shutil
|
||||
import sys
|
||||
import textwrap
|
||||
import traceback
|
||||
|
||||
import lief
|
||||
from lief import ELF
|
||||
import argparse
|
||||
|
||||
terminal_rows, terminal_columns = 100, 110
|
||||
try:
|
||||
terminal_rows, terminal_columns = os.popen('stty size', 'r').read().split()
|
||||
except ValueError:
|
||||
pass
|
||||
_term_size = shutil.get_terminal_size((110, 100))
|
||||
terminal_columns = _term_size.columns - 10
|
||||
terminal_rows = _term_size.lines
|
||||
|
||||
terminal_columns = int(terminal_columns) - 10
|
||||
terminal_rows = int(terminal_rows)
|
||||
|
||||
class exceptions_handler(object):
|
||||
class exceptions_handler:
|
||||
func = None
|
||||
|
||||
def __init__(self, exceptions, on_except_callback=None):
|
||||
self.exceptions = exceptions
|
||||
self.exceptions = exceptions
|
||||
self.on_except_callback = on_except_callback
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
@@ -41,8 +43,8 @@ class exceptions_handler(object):
|
||||
self.on_except_callback(e)
|
||||
else:
|
||||
print("-" * 60)
|
||||
print("Exception in {}: {}".format(self.func.__name__, e))
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
print(f"Exception in {self.func.__name__}: {e}")
|
||||
_exc_type, _exc_value, exc_traceback = sys.exc_info()
|
||||
traceback.print_tb(exc_traceback)
|
||||
print("-" * 60)
|
||||
|
||||
@@ -52,7 +54,6 @@ def print_header(binary):
|
||||
header = binary.header
|
||||
identity = header.identity
|
||||
|
||||
|
||||
print("== Header ==\n")
|
||||
format_str = "{:<30} {:<30}"
|
||||
format_hex = "{:<30} 0x{:<13x}"
|
||||
@@ -63,37 +64,53 @@ def print_header(binary):
|
||||
if header.machine_type == lief.ELF.ARCH.ARM:
|
||||
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.arm_flags_list])
|
||||
|
||||
if header.machine_type in [lief.ELF.ARCH.MIPS, lief.ELF.ARCH.MIPS_RS3_LE, lief.ELF.ARCH.MIPS_X]:
|
||||
if header.machine_type in [
|
||||
lief.ELF.ARCH.MIPS,
|
||||
lief.ELF.ARCH.MIPS_RS3_LE,
|
||||
lief.ELF.ARCH.MIPS_X,
|
||||
]:
|
||||
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.mips_flags_list])
|
||||
|
||||
if header.machine_type == lief.ELF.ARCH.PPC64:
|
||||
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.ppc64_flags_list])
|
||||
eflags_str = " - ".join(
|
||||
[str(s).split(".")[-1] for s in header.ppc64_flags_list]
|
||||
)
|
||||
|
||||
if header.machine_type == lief.ELF.ARCH.HEXAGON:
|
||||
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.hexagon_flags_list])
|
||||
eflags_str = " - ".join(
|
||||
[str(s).split(".")[-1] for s in header.hexagon_flags_list]
|
||||
)
|
||||
|
||||
if header.machine_type == lief.ELF.ARCH.LOONGARCH:
|
||||
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.loongarch_flags_list])
|
||||
eflags_str = " - ".join(
|
||||
[str(s).split(".")[-1] for s in header.loongarch_flags_list]
|
||||
)
|
||||
print(identity)
|
||||
print(format_ide.format("Magic:", identity[0], identity[1], identity[2], identity[3]))
|
||||
print(format_str.format("Class:", str(header.identity_class).split(".")[-1]))
|
||||
print(format_str.format("Endianness:", str(header.identity_data).split(".")[-1]))
|
||||
print(format_str.format("Version:", str(header.identity_version).split(".")[-1]))
|
||||
print(format_str.format("OS/ABI:", str(header.identity_os_abi).split(".")[-1]))
|
||||
print(format_dec.format("ABI Version:", header.identity_abi_version))
|
||||
print(format_str.format("File Type:", str(header.file_type).split(".")[-1]))
|
||||
print(format_str.format("Machine Type:", str(header.machine_type).split(".")[-1]))
|
||||
print(format_str.format("Object File Version:", str(header.object_file_version).split(".")[-1]))
|
||||
print(format_hex.format("Entry Point:", header.entrypoint))
|
||||
print(
|
||||
format_ide.format("Magic:", identity[0], identity[1], identity[2], identity[3])
|
||||
)
|
||||
print(format_str.format("Class:", str(header.identity_class).split(".")[-1]))
|
||||
print(format_str.format("Endianness:", str(header.identity_data).split(".")[-1]))
|
||||
print(format_str.format("Version:", str(header.identity_version).split(".")[-1]))
|
||||
print(format_str.format("OS/ABI:", str(header.identity_os_abi).split(".")[-1]))
|
||||
print(format_dec.format("ABI Version:", header.identity_abi_version))
|
||||
print(format_str.format("File Type:", str(header.file_type).split(".")[-1]))
|
||||
print(format_str.format("Machine Type:", str(header.machine_type).split(".")[-1]))
|
||||
print(
|
||||
format_str.format(
|
||||
"Object File Version:", str(header.object_file_version).split(".")[-1]
|
||||
)
|
||||
)
|
||||
print(format_hex.format("Entry Point:", header.entrypoint))
|
||||
print(format_hex.format("Program Header Offset:", header.program_header_offset))
|
||||
print(format_hex.format("Section Header Offset:", header.section_header_offset))
|
||||
print(format_hex.format("Processor flags:", header.processor_flag) + eflags_str)
|
||||
print(format_dec.format("Header Size:", header.header_size))
|
||||
print(format_dec.format("Program Header Size:", header.program_header_size))
|
||||
print(format_dec.format("Section Header Size:", header.section_header_size))
|
||||
print(format_dec.format("Number of segments:", header.numberof_segments))
|
||||
print(format_dec.format("Number of sections:", header.numberof_sections))
|
||||
print("")
|
||||
print(format_hex.format("Processor flags:", header.processor_flag) + eflags_str)
|
||||
print(format_dec.format("Header Size:", header.header_size))
|
||||
print(format_dec.format("Program Header Size:", header.program_header_size))
|
||||
print(format_dec.format("Section Header Size:", header.section_header_size))
|
||||
print(format_dec.format("Number of segments:", header.numberof_segments))
|
||||
print(format_dec.format("Number of sections:", header.numberof_sections))
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -103,22 +120,38 @@ def print_sections(binary):
|
||||
print("== Sections ==\n")
|
||||
f_title = "|{:<30} | {:<12}| {:<17}| {:<12}| {:<10}| {:<8}| {:<8}|"
|
||||
f_value = "|{:<30} | {:<12}| 0x{:<14x} | 0x{:<10x}| 0x{:<8x}| {:<8.2f}| {:<10}"
|
||||
print(f_title.format("Name", "Type", "Virtual address", "File offset", "Size", "Entropy", "Segment(s)"))
|
||||
print(
|
||||
f_title.format(
|
||||
"Name",
|
||||
"Type",
|
||||
"Virtual address",
|
||||
"File offset",
|
||||
"Size",
|
||||
"Entropy",
|
||||
"Segment(s)",
|
||||
)
|
||||
)
|
||||
|
||||
for section in sections:
|
||||
segments_str = " - ".join([str(s.type).split(".")[-1] for s in section.segments])
|
||||
print(f_value.format(
|
||||
section.name,
|
||||
str(section.type).split(".")[-1],
|
||||
section.virtual_address,
|
||||
section.file_offset,
|
||||
section.size,
|
||||
abs(section.entropy),
|
||||
segments_str))
|
||||
print("")
|
||||
segments_str = " - ".join(
|
||||
[str(s.type).split(".")[-1] for s in section.segments]
|
||||
)
|
||||
print(
|
||||
f_value.format(
|
||||
section.name,
|
||||
str(section.type).split(".")[-1],
|
||||
section.virtual_address,
|
||||
section.file_offset,
|
||||
section.size,
|
||||
abs(section.entropy),
|
||||
segments_str,
|
||||
)
|
||||
)
|
||||
print()
|
||||
else:
|
||||
print("No sections")
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_segments(binary):
|
||||
segments = binary.segments
|
||||
@@ -127,8 +160,17 @@ def print_segments(binary):
|
||||
print("== Segments ==\n")
|
||||
f_title = "|{:<30} | {:<10}| {:<18}| {:<17}| {:<17}| {:<17}| {:<19}|"
|
||||
f_value = "|{:<30} | {:<10}| 0x{:<16x}| 0x{:<15x}| 0x{:<15x}| 0x{:<15x}| {}"
|
||||
print(f_title.format("Type",
|
||||
"Flags", "File offset", "Virtual Address", "Virtual Size", "Size", "Sections"))
|
||||
print(
|
||||
f_title.format(
|
||||
"Type",
|
||||
"Flags",
|
||||
"File offset",
|
||||
"Virtual Address",
|
||||
"Virtual Size",
|
||||
"Size",
|
||||
"Sections",
|
||||
)
|
||||
)
|
||||
|
||||
for segment in segments:
|
||||
sections = segment.sections
|
||||
@@ -144,17 +186,22 @@ def print_segments(binary):
|
||||
flags_str[2] = "x"
|
||||
flags_str = "".join(flags_str)
|
||||
|
||||
print(f_value.format(
|
||||
str(segment.type).split(".")[-1],
|
||||
flags_str,
|
||||
segment.file_offset,
|
||||
segment.virtual_address,
|
||||
segment.virtual_size,
|
||||
segment.physical_size, s))
|
||||
print("")
|
||||
print(
|
||||
f_value.format(
|
||||
str(segment.type).split(".")[-1],
|
||||
flags_str,
|
||||
segment.file_offset,
|
||||
segment.virtual_address,
|
||||
segment.virtual_size,
|
||||
segment.physical_size,
|
||||
s,
|
||||
)
|
||||
)
|
||||
print()
|
||||
else:
|
||||
print("No segments")
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_dynamic_entries(binary):
|
||||
dynamic_entries = binary.dynamic_entries
|
||||
@@ -170,20 +217,37 @@ def print_dynamic_entries(binary):
|
||||
if entry.tag == ELF.DynamicEntry.TAG.NULL:
|
||||
continue
|
||||
|
||||
if entry.tag in [ELF.DynamicEntry.TAG.SONAME, ELF.DynamicEntry.TAG.NEEDED, ELF.DynamicEntry.TAG.RUNPATH, ELF.DynamicEntry.TAG.RPATH]:
|
||||
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, entry.name))
|
||||
elif type(entry) is ELF.DynamicEntryArray: # [ELF.DynamicEntry.TAG.INIT_ARRAY,ELF.DynamicEntry.TAG.FINI_ARRAY]:
|
||||
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, ", ".join(map(hex, entry.array))))
|
||||
elif entry.tag == ELF.DynamicEntry.TAG.FLAGS:
|
||||
flags_str = " - ".join([str(ELF.DynamicEntryFlags.FLAG(s)).split(".")[-1] for s in entry.flags])
|
||||
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, flags_str))
|
||||
elif entry.tag == ELF.DynamicEntry.TAG.FLAGS_1:
|
||||
flags_str = " - ".join([str(ELF.DynamicEntryFlags.FLAG(s)).split(".")[-1] for s in entry.flags])
|
||||
if entry.tag in [
|
||||
ELF.DynamicEntry.TAG.SONAME,
|
||||
ELF.DynamicEntry.TAG.NEEDED,
|
||||
ELF.DynamicEntry.TAG.RUNPATH,
|
||||
ELF.DynamicEntry.TAG.RPATH,
|
||||
]:
|
||||
print(
|
||||
f_value.format(str(entry.tag).split(".")[-1], entry.value, entry.name)
|
||||
)
|
||||
elif (
|
||||
type(entry) is ELF.DynamicEntryArray
|
||||
): # [ELF.DynamicEntry.TAG.INIT_ARRAY,ELF.DynamicEntry.TAG.FINI_ARRAY]:
|
||||
print(
|
||||
f_value.format(
|
||||
str(entry.tag).split(".")[-1],
|
||||
entry.value,
|
||||
", ".join(map(hex, entry.array)),
|
||||
)
|
||||
)
|
||||
elif (
|
||||
entry.tag == ELF.DynamicEntry.TAG.FLAGS
|
||||
or entry.tag == ELF.DynamicEntry.TAG.FLAGS_1
|
||||
):
|
||||
flags_str = " - ".join(
|
||||
[str(ELF.DynamicEntryFlags.FLAG(s)).split(".")[-1] for s in entry.flags]
|
||||
)
|
||||
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, flags_str))
|
||||
else:
|
||||
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, ""))
|
||||
|
||||
print("")
|
||||
print()
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -195,12 +259,20 @@ def print_symbols(symbols, no_trunc):
|
||||
maxsize = max([len(symbol.name) for symbol in symbols])
|
||||
|
||||
SIZE = 70
|
||||
maxsize = min(maxsize, terminal_columns - SIZE) if terminal_columns > SIZE else terminal_columns
|
||||
maxsize = (
|
||||
min(maxsize, terminal_columns - SIZE)
|
||||
if terminal_columns > SIZE
|
||||
else terminal_columns
|
||||
)
|
||||
|
||||
f_title = "|{:<" + str(maxsize) + "} | {:<7}| {:<8}| {:<10}| {:<8}| {:<4}| {:<14}|"
|
||||
f_value = "|{:<" + str(maxsize) + "} | {:<7}| {:<8x}| {:<10}| {:<8}| {:<4}| {:<14}|"
|
||||
|
||||
print(f_title.format("Name", "Type", "Value", "Visibility", "Binding", "I/E", "Version"))
|
||||
print(
|
||||
f_title.format(
|
||||
"Name", "Type", "Value", "Visibility", "Binding", "I/E", "Version"
|
||||
)
|
||||
)
|
||||
|
||||
for symbol in symbols:
|
||||
symbol_version = symbol.symbol_version if symbol.has_version else ""
|
||||
@@ -218,20 +290,21 @@ def print_symbols(symbols, no_trunc):
|
||||
|
||||
wrapped = textwrap.wrap(symbol_name, maxsize)
|
||||
|
||||
if len(wrapped) <= 1 or no_trunc:
|
||||
symbol_name = symbol_name
|
||||
else:
|
||||
if len(wrapped) > 1 and not no_trunc:
|
||||
symbol_name = wrapped[0][:-3] + "..."
|
||||
|
||||
print(f_value.format(
|
||||
symbol_name,
|
||||
str(symbol.type).split(".")[-1],
|
||||
symbol.value,
|
||||
str(symbol.visibility).split(".")[-1],
|
||||
str(symbol.binding).split(".")[-1],
|
||||
import_export,
|
||||
str(symbol_version)
|
||||
))
|
||||
print(
|
||||
f_value.format(
|
||||
symbol_name,
|
||||
str(symbol.type).split(".")[-1],
|
||||
symbol.value,
|
||||
str(symbol.visibility).split(".")[-1],
|
||||
str(symbol.binding).split(".")[-1],
|
||||
import_export,
|
||||
str(symbol_version),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_dynamic_symbols(binary, args):
|
||||
@@ -244,22 +317,24 @@ def print_symtab_symbols(binary, args):
|
||||
print("== Symtab symbols ==\n")
|
||||
print_symbols(binary.symtab_symbols, args.no_trunc)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_relocations(binary, relocations):
|
||||
f_title = "|{:<10} | {:<10}| {:<8}| {:<8}| {:<8}| {:<15}| {:<30} |"
|
||||
f_value = "|0x{:<8x} | {:<10}| {:<8d}| {:<8d}| {:<8x}| {:<15}| {:<30} |"
|
||||
|
||||
print(f_title.format("Address", "Type", "Info", "Size", "Addend", "Purpose", "Symbol"))
|
||||
print(
|
||||
f_title.format("Address", "Type", "Info", "Size", "Addend", "Purpose", "Symbol")
|
||||
)
|
||||
|
||||
for relocation in relocations:
|
||||
type = str(relocation.type)
|
||||
if binary.header.machine_type == ELF.ARCH.x86_64:
|
||||
type = str(relocation.type)
|
||||
elif binary.header.machine_type == ELF.ARCH.i386:
|
||||
type = str(relocation.type)
|
||||
elif binary.header.machine_type == ELF.ARCH.ARM:
|
||||
type = str(relocation.type)
|
||||
elif binary.header.machine_type == ELF.ARCH.AARCH64:
|
||||
if (
|
||||
binary.header.machine_type == ELF.ARCH.x86_64
|
||||
or binary.header.machine_type == ELF.ARCH.i386
|
||||
or binary.header.machine_type == ELF.ARCH.ARM
|
||||
or binary.header.machine_type == ELF.ARCH.AARCH64
|
||||
):
|
||||
type = str(relocation.type)
|
||||
|
||||
symbol_name = ""
|
||||
@@ -270,20 +345,22 @@ def print_relocations(binary, relocations):
|
||||
elif symbol.type == lief.ELF.Symbol.TYPE.SECTION:
|
||||
shndx = symbol.shndx
|
||||
sections = binary.sections
|
||||
if 0 < shndx and shndx < len(sections):
|
||||
if 0 < shndx < len(sections):
|
||||
symbol_name = sections[shndx].name + " + " + hex(relocation.addend)
|
||||
else:
|
||||
symbol_name = "<section #{}>".format(shndx)
|
||||
symbol_name = f"<section #{shndx}>"
|
||||
|
||||
|
||||
print(f_value.format(
|
||||
relocation.address,
|
||||
type.split(".")[-1],
|
||||
relocation.info,
|
||||
relocation.size,
|
||||
relocation.addend,
|
||||
str(relocation.purpose).split(".")[-1],
|
||||
symbol_name))
|
||||
print(
|
||||
f_value.format(
|
||||
relocation.address,
|
||||
type.split(".")[-1],
|
||||
relocation.info,
|
||||
relocation.size,
|
||||
relocation.addend,
|
||||
str(relocation.purpose).split(".")[-1],
|
||||
symbol_name,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -296,7 +373,6 @@ def print_all_relocations(binary):
|
||||
print("== Dynamic Relocations ==\n")
|
||||
print_relocations(binary, dynamicrelocations)
|
||||
|
||||
|
||||
if len(pltgot_relocations) > 0:
|
||||
print("== PLT/GOT Relocations ==\n")
|
||||
print_relocations(binary, pltgot_relocations)
|
||||
@@ -305,6 +381,7 @@ def print_all_relocations(binary):
|
||||
print("== Object Relocations ==\n")
|
||||
print_relocations(binary, object_relocations)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_exported_symbols(binary, args):
|
||||
symbols = binary.exported_symbols
|
||||
@@ -315,6 +392,7 @@ def print_exported_symbols(binary, args):
|
||||
return
|
||||
print_symbols(symbols, args.no_trunc)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_imported_symbols(binary, args):
|
||||
symbols = binary.imported_symbols
|
||||
@@ -325,16 +403,17 @@ def print_imported_symbols(binary, args):
|
||||
return
|
||||
print_symbols(symbols, args.no_trunc)
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_information(binary):
|
||||
print("== Information ==\n")
|
||||
format_str = "{:<30} {:<30}"
|
||||
format_hex = "{:<30} 0x{:<28x}"
|
||||
format_dec = "{:<30} {:<30d}"
|
||||
print(format_hex.format("Address base:", binary.imagebase))
|
||||
print(format_hex.format("Virtual size:", binary.virtual_size))
|
||||
print(format_str.format("PIE:", str(binary.is_pie)))
|
||||
print(format_str.format("NX:", str(binary.has_nx)))
|
||||
print(format_str.format("PIE:", str(binary.is_pie)))
|
||||
print(format_str.format("NX:", str(binary.has_nx)))
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_gnu_hash(binary):
|
||||
@@ -349,12 +428,12 @@ def print_gnu_hash(binary):
|
||||
format_hex = "{:<30} 0x{:<28x}"
|
||||
format_dec = "{:<30} {:<30d}"
|
||||
|
||||
print(format_dec.format("Number of buckets:", gnu_hash.nb_buckets))
|
||||
print(format_dec.format("Number of buckets:", gnu_hash.nb_buckets))
|
||||
print(format_dec.format("First symbol index:", gnu_hash.symbol_index))
|
||||
print(format_hex.format("Shift Count:", gnu_hash.shift2))
|
||||
print(format_str.format("Bloom filters:", gnu_hash.bloom_filters))
|
||||
print(format_str.format("Buckets:", gnu_hash.buckets))
|
||||
print(format_str.format("Hash values:", gnu_hash.hash_values))
|
||||
print(format_hex.format("Shift Count:", gnu_hash.shift2))
|
||||
print(format_str.format("Bloom filters:", gnu_hash.bloom_filters))
|
||||
print(format_str.format("Buckets:", gnu_hash.buckets))
|
||||
print(format_str.format("Hash values:", gnu_hash.hash_values))
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -367,13 +446,12 @@ def print_sysv_hash(binary):
|
||||
sysv_hash = binary.sysv_hash
|
||||
|
||||
format_str = "{:<30} {}"
|
||||
format_hex = "{:<30} 0x{:<28x}"
|
||||
format_dec = "{:<30} {:<30d}"
|
||||
|
||||
print(format_dec.format("Number of buckets:", sysv_hash.nbucket))
|
||||
print(format_dec.format("Number of chains:", sysv_hash.nchain))
|
||||
print(format_str.format("Buckets:", sysv_hash.buckets))
|
||||
print(format_str.format("Chains:", sysv_hash.chains))
|
||||
print(format_dec.format("Number of chains:", sysv_hash.nchain))
|
||||
print(format_str.format("Buckets:", sysv_hash.buckets))
|
||||
print(format_str.format("Chains:", sysv_hash.chains))
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -381,37 +459,36 @@ def print_notes(binary):
|
||||
print("== Notes ==\n")
|
||||
|
||||
format_str = "{:<19} {}"
|
||||
format_hex = "{:<19} 0x{:<28x}"
|
||||
format_dec = "{:<19} {:<30d}"
|
||||
|
||||
notes = binary.notes
|
||||
for idx, note in enumerate(notes):
|
||||
description = note.description
|
||||
description_str = " ".join(map(lambda e : "{:02x}".format(e), description[:16]))
|
||||
description_str = " ".join(f"{e:02x}" for e in description[:16])
|
||||
if len(description) > 16:
|
||||
description_str += " ..."
|
||||
|
||||
print("Note #{:d}".format(idx))
|
||||
print(f"Note #{idx:d}")
|
||||
|
||||
type_str = note.type_core if note.is_core else note.type
|
||||
type_str = str(type_str).split(".")[-1]
|
||||
|
||||
print(format_str.format("Name:", note.name))
|
||||
print(format_str.format("Type:", type_str))
|
||||
print(format_str.format("Name:", note.name))
|
||||
print(format_str.format("Type:", type_str))
|
||||
print(format_str.format("Description:", description_str))
|
||||
|
||||
note_details = note.details
|
||||
|
||||
if isinstance(note_details, lief.ELF.AndroidIdent):
|
||||
print(format_dec.format("SDK Version:", note_details.sdk_version))
|
||||
print(format_str.format("NDK Version:", note_details.ndk_version))
|
||||
print(format_dec.format("SDK Version:", note_details.sdk_version))
|
||||
print(format_str.format("NDK Version:", note_details.ndk_version))
|
||||
print(format_str.format("NDK build number:", note_details.ndk_build_number))
|
||||
|
||||
if isinstance(note_details, lief.ELF.NoteAbi):
|
||||
version = note_details.version
|
||||
version_str = "{:d}.{:d}.{:d}".format(version[0], version[1], version[2])
|
||||
version = note_details.version
|
||||
version_str = f"{version[0]:d}.{version[1]:d}.{version[2]:d}"
|
||||
|
||||
print(format_str.format("ABI:", note_details.abi))
|
||||
print(format_str.format("ABI:", note_details.abi))
|
||||
print(format_str.format("Version:", version_str))
|
||||
|
||||
if note.type == ELF.Note.TYPE.GNU_GOLD_VERSION:
|
||||
@@ -420,7 +497,6 @@ def print_notes(binary):
|
||||
if note.is_core:
|
||||
print(note_details)
|
||||
|
||||
|
||||
print("\n")
|
||||
|
||||
|
||||
@@ -428,19 +504,19 @@ def print_notes(binary):
|
||||
def print_ctor(binary):
|
||||
print("== Constructors ==\n")
|
||||
|
||||
print("Functions: ({:d})".format(len(binary.ctor_functions)))
|
||||
print(f"Functions: ({len(binary.ctor_functions):d})")
|
||||
for idx, f in enumerate(binary.ctor_functions):
|
||||
print(" [{:d}] {}: 0x{:x}".format(idx, f.name, f.address))
|
||||
print(f" [{idx:d}] {f.name}: 0x{f.address:x}")
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
def print_strings(binary):
|
||||
print("== Strings ==\n")
|
||||
|
||||
|
||||
strings = binary.strings
|
||||
print("Strings: ({:d})".format(len(binary.strings)))
|
||||
print(f"Strings: ({len(binary.strings):d})")
|
||||
for s in strings:
|
||||
print(" {}".format(s))
|
||||
print(f" {s}")
|
||||
|
||||
|
||||
@exceptions_handler(Exception)
|
||||
@@ -448,140 +524,223 @@ def print_functions(binary):
|
||||
print("== Functions ==\n")
|
||||
|
||||
functions = binary.functions
|
||||
print("Functions: ({:d})".format(len(functions)))
|
||||
print(f"Functions: ({len(functions):d})")
|
||||
for idx, f in enumerate(functions):
|
||||
print(" [{:d}] {}: 0x{:x}".format(idx, f.name, f.address))
|
||||
print(f" [{idx:d}] {f.name}: 0x{f.address:x}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(add_help=False, prog=sys.argv[0])
|
||||
parser.add_argument("elf_file")
|
||||
|
||||
parser.add_argument('-a', '--all',
|
||||
action='store_true', dest='show_all',
|
||||
help='Equivalent to: -h -l -S -s -r -d -V')
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
"--all",
|
||||
action="store_true",
|
||||
dest="show_all",
|
||||
help="Equivalent to: -h -l -S -s -r -d -V",
|
||||
)
|
||||
|
||||
parser.add_argument('-d', '--dynamic',
|
||||
action='store_true', dest='show_dynamic_tags',
|
||||
help='Display the dynamic section')
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dynamic",
|
||||
action="store_true",
|
||||
dest="show_dynamic_tags",
|
||||
help="Display the dynamic section",
|
||||
)
|
||||
|
||||
parser.add_argument('-H', '--help',
|
||||
action='help', dest='help',
|
||||
help='Display this information')
|
||||
parser.add_argument(
|
||||
"-H", "--help", action="help", dest="help", help="Display this information"
|
||||
)
|
||||
|
||||
parser.add_argument('-h', '--file-header',
|
||||
action='store_true', dest='show_file_header',
|
||||
help='Display the ELF file header')
|
||||
parser.add_argument(
|
||||
"-h",
|
||||
"--file-header",
|
||||
action="store_true",
|
||||
dest="show_file_header",
|
||||
help="Display the ELF file header",
|
||||
)
|
||||
|
||||
parser.add_argument('-i', '--imported',
|
||||
action='store_true', dest='show_imported_symbols',
|
||||
help='Display imported symbols')
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--imported",
|
||||
action="store_true",
|
||||
dest="show_imported_symbols",
|
||||
help="Display imported symbols",
|
||||
)
|
||||
|
||||
parser.add_argument('-l', '--program-headers', '--segments',
|
||||
action='store_true', dest='show_program_header',
|
||||
help='Display the program headers')
|
||||
parser.add_argument(
|
||||
"-l",
|
||||
"--program-headers",
|
||||
"--segments",
|
||||
action="store_true",
|
||||
dest="show_program_header",
|
||||
help="Display the program headers",
|
||||
)
|
||||
|
||||
parser.add_argument('-S', '--section-headers', '--sections',
|
||||
action='store_true', dest='show_section_header',
|
||||
help="Display the sections' headers")
|
||||
parser.add_argument(
|
||||
"-S",
|
||||
"--section-headers",
|
||||
"--sections",
|
||||
action="store_true",
|
||||
dest="show_section_header",
|
||||
help="Display the sections' headers",
|
||||
)
|
||||
|
||||
parser.add_argument('-e', '--headers',
|
||||
action='store_true', dest='show_all_headers',
|
||||
help='Equivalent to: -h -l -S')
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
"--headers",
|
||||
action="store_true",
|
||||
dest="show_all_headers",
|
||||
help="Equivalent to: -h -l -S",
|
||||
)
|
||||
|
||||
parser.add_argument('-s', '--symbols', '--syms',
|
||||
action='store_true', dest='show_symbols',
|
||||
help='Display the symbol table')
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--symbols",
|
||||
"--syms",
|
||||
action="store_true",
|
||||
dest="show_symbols",
|
||||
help="Display the symbol table",
|
||||
)
|
||||
|
||||
parser.add_argument('--dynamic-symbols', '--dsyms',
|
||||
action='store_true', dest='show_dynamic_symbols',
|
||||
help='Display the dynamic symbols')
|
||||
parser.add_argument(
|
||||
"--dynamic-symbols",
|
||||
"--dsyms",
|
||||
action="store_true",
|
||||
dest="show_dynamic_symbols",
|
||||
help="Display the dynamic symbols",
|
||||
)
|
||||
|
||||
parser.add_argument('--symtab-symbols', '--ssyms',
|
||||
action='store_true', dest='show_symtab_symbols',
|
||||
help='Display the symtab symbols')
|
||||
parser.add_argument(
|
||||
"--symtab-symbols",
|
||||
"--ssyms",
|
||||
action="store_true",
|
||||
dest="show_symtab_symbols",
|
||||
help="Display the symtab symbols",
|
||||
)
|
||||
|
||||
parser.add_argument('-r', '--relocs',
|
||||
action='store_true', dest='show_relocs',
|
||||
help='Display the relocations (if present)')
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--relocs",
|
||||
action="store_true",
|
||||
dest="show_relocs",
|
||||
help="Display the relocations (if present)",
|
||||
)
|
||||
|
||||
parser.add_argument('-V', '--version-info',
|
||||
action='store_true', dest='show_version_info',
|
||||
help='Display the version sections (if present)')
|
||||
parser.add_argument(
|
||||
"-V",
|
||||
"--version-info",
|
||||
action="store_true",
|
||||
dest="show_version_info",
|
||||
help="Display the version sections (if present)",
|
||||
)
|
||||
|
||||
parser.add_argument('-x', '--exported',
|
||||
action='store_true', dest='show_exported_symbols',
|
||||
help='Display exported symbols')
|
||||
parser.add_argument(
|
||||
"-x",
|
||||
"--exported",
|
||||
action="store_true",
|
||||
dest="show_exported_symbols",
|
||||
help="Display exported symbols",
|
||||
)
|
||||
|
||||
parser.add_argument('--gnu-hash',
|
||||
action='store_true', dest='show_gnu_hash',
|
||||
help='Display GNU Hash')
|
||||
parser.add_argument(
|
||||
"--gnu-hash", action="store_true", dest="show_gnu_hash", help="Display GNU Hash"
|
||||
)
|
||||
|
||||
parser.add_argument('--sysv-hash',
|
||||
action='store_true', dest='show_sysv_hash',
|
||||
help='Display SYSV Hash')
|
||||
parser.add_argument(
|
||||
"--sysv-hash",
|
||||
action="store_true",
|
||||
dest="show_sysv_hash",
|
||||
help="Display SYSV Hash",
|
||||
)
|
||||
|
||||
parser.add_argument('-n', '--notes',
|
||||
action='store_true', dest='show_notes',
|
||||
help='Display Notes')
|
||||
parser.add_argument(
|
||||
"-n", "--notes", action="store_true", dest="show_notes", help="Display Notes"
|
||||
)
|
||||
|
||||
parser.add_argument('--no-trunc',
|
||||
action='store_true', dest='no_trunc',
|
||||
default=False,
|
||||
help='Do not trunc symbol names ...')
|
||||
parser.add_argument(
|
||||
"--no-trunc",
|
||||
action="store_true",
|
||||
dest="no_trunc",
|
||||
default=False,
|
||||
help="Do not trunc symbol names ...",
|
||||
)
|
||||
|
||||
parser.add_argument('--ctor',
|
||||
action='store_true', dest='show_ctor',
|
||||
help='Constructor functions')
|
||||
parser.add_argument(
|
||||
"--ctor", action="store_true", dest="show_ctor", help="Constructor functions"
|
||||
)
|
||||
|
||||
parser.add_argument('--strings',
|
||||
action='store_true', dest='show_strings',
|
||||
help='Strings present in the current ELF')
|
||||
parser.add_argument(
|
||||
"--strings",
|
||||
action="store_true",
|
||||
dest="show_strings",
|
||||
help="Strings present in the current ELF",
|
||||
)
|
||||
|
||||
parser.add_argument('--functions',
|
||||
action='store_true', dest='show_functions',
|
||||
help='List all function addresses found')
|
||||
parser.add_argument(
|
||||
"--functions",
|
||||
action="store_true",
|
||||
dest="show_functions",
|
||||
help="List all function addresses found",
|
||||
)
|
||||
|
||||
# Logging setup
|
||||
logger_group = parser.add_argument_group('Logger')
|
||||
logger_group = parser.add_argument_group("Logger")
|
||||
verbosity = logger_group.add_mutually_exclusive_group()
|
||||
|
||||
verbosity.add_argument('--debug',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.DEBUG)
|
||||
verbosity.add_argument(
|
||||
"--debug",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Debug,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--trace',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.TRACE)
|
||||
verbosity.add_argument(
|
||||
"--trace",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Trace,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--info',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.INFO)
|
||||
verbosity.add_argument(
|
||||
"--info",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Info,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--warn',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.WARN)
|
||||
verbosity.add_argument(
|
||||
"--warn",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Warn,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--err',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.ERROR)
|
||||
verbosity.add_argument(
|
||||
"--err",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Err,
|
||||
)
|
||||
|
||||
verbosity.add_argument('--critical',
|
||||
dest='main_verbosity',
|
||||
action='store_const',
|
||||
const=lief.logging.LEVEL.CRITICAL)
|
||||
verbosity.add_argument(
|
||||
"--critical",
|
||||
dest="main_verbosity",
|
||||
action="store_const",
|
||||
const=lief.logging.Level.Critical,
|
||||
)
|
||||
|
||||
parser.set_defaults(main_verbosity=lief.logging.LEVEL.WARN)
|
||||
parser.set_defaults(main_verbosity=lief.logging.Level.Warn)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
lief.logging.set_level(args.main_verbosity)
|
||||
binary = ELF.parse(args.elf_file)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{args.elf_file}' as ELF", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print_information(binary)
|
||||
if args.show_all:
|
||||
do_file_header = do_section_header = do_program_header = True
|
||||
@@ -589,7 +748,7 @@ def main():
|
||||
if args.show_all_headers:
|
||||
do_file_header = do_section_header = do_program_header = True
|
||||
else:
|
||||
do_file_header = args.show_file_header
|
||||
do_file_header = args.show_file_header
|
||||
do_section_header = args.show_section_header
|
||||
do_program_header = args.show_program_header
|
||||
|
||||
@@ -605,10 +764,14 @@ def main():
|
||||
if args.show_dynamic_tags or args.show_all:
|
||||
print_dynamic_entries(binary)
|
||||
|
||||
if (args.show_symbols or args.show_all or args.show_dynamic_symbols) and len(binary.dynamic_symbols) > 0:
|
||||
if (args.show_symbols or args.show_all or args.show_dynamic_symbols) and len(
|
||||
binary.dynamic_symbols
|
||||
) > 0:
|
||||
print_dynamic_symbols(binary, args)
|
||||
|
||||
if (args.show_symbols or args.show_all or args.show_symtab_symbols) and len(binary.symtab_symbols) > 0:
|
||||
if (args.show_symbols or args.show_all or args.show_symtab_symbols) and len(
|
||||
binary.symtab_symbols
|
||||
) > 0:
|
||||
print_symtab_symbols(binary, args)
|
||||
|
||||
if args.show_relocs or args.show_all:
|
||||
@@ -638,8 +801,8 @@ def main():
|
||||
if args.show_functions:
|
||||
print_functions(binary)
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
||||
Regular → Executable
+33
-31
@@ -1,43 +1,45 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Strip the section table from an ELF binary.
|
||||
|
||||
# Description
|
||||
# -----------
|
||||
# Remove the section table from an ELF binary
|
||||
# so that some tools are blow minded (e.g. gdb)
|
||||
#
|
||||
# Example:
|
||||
# $ python elf_remove_section_table.py /bin/ls ls_without_sections
|
||||
# $ ls
|
||||
# elf_remove_section_table.py ls_without_sections
|
||||
# $ ls_without_sections
|
||||
# $ elf_remove_section_table.py ls_without_sections
|
||||
# $ readelf -S ls_without_sections
|
||||
#
|
||||
# Il n'y a pas de section dans ce fichier.
|
||||
# $ gdb ls_without_sections
|
||||
# "ls_without_sections": not in executable format: File format not recognized
|
||||
Zeros out the ``e_shoff`` and ``e_shnum`` fields of the ELF header so
|
||||
that tools relying on the section table (notably ``gdb``, ``readelf
|
||||
-S``) lose visibility into the binary while the program headers
|
||||
remain intact and the file still runs.
|
||||
|
||||
Example:
|
||||
|
||||
$ python elf_remove_section_table.py /bin/ls ls_nosec
|
||||
$ readelf -S ls_nosec
|
||||
There are no sections in this file.
|
||||
$ ./ls_nosec # still runs
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import lief
|
||||
from lief import ELF
|
||||
|
||||
def remove_section_table(filename, output):
|
||||
binary = lief.ELF.parse(filename) # Build an ELF binary
|
||||
import lief
|
||||
|
||||
|
||||
def remove_section_table(filename: str, output: str) -> int:
|
||||
binary = lief.ELF.parse(filename)
|
||||
if binary is None:
|
||||
print(f"Error: failed to parse '{filename}' as ELF", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
header = binary.header
|
||||
header.section_header_offset = 0;
|
||||
header.numberof_sections = 0;
|
||||
header.section_header_offset = 0
|
||||
header.numberof_sections = 0
|
||||
binary.write(output)
|
||||
return 0
|
||||
|
||||
binary.write(output);
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: {} <elf binary> <output>".format(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
remove_section_table(sys.argv[1], sys.argv[2])
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("input", metavar="<elf>", help="Input ELF binary")
|
||||
parser.add_argument("output", metavar="<out>", help="Path to the rewritten binary")
|
||||
args = parser.parse_args()
|
||||
return remove_section_table(args.input, args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user