Compare commits

...
124 Commits
Author SHA1 Message Date
Romain Thomas 8cd66ae9b3 WIP 2023-07-24 22:01:12 +02:00
Romain Thomas 555bcdabaa Test 2023-07-24 22:00:07 +02:00
Romain Thomas 3dfc393f95 Clean code 2023-07-23 20:34:23 +02:00
Romain Thomas 79302f3ed4 Fix docstring 2023-07-23 07:41:10 +02:00
Romain Thomas 3bc38c315b Fix doc 2023-07-23 07:32:09 +02:00
Romain Thomas 7289bbb01f Refactor and clean PE debug entries 2023-07-22 13:39:11 +02:00
Romain Thomas 9c9bd0e52f Fix log message 2023-07-22 09:03:17 +02:00
Romain Thomas 98e85cd6f6 Expose copy method 2023-07-22 08:35:59 +02:00
Romain Thomas 76aa4eb895 Fix typo 2023-07-22 05:56:50 +02:00
Romain Thomas fa5a0dd27b Use a unique_ptr 2023-07-22 05:49:45 +02:00
Romain Thomas 114fb11bc4 Cleanup 2023-07-22 05:45:12 +02:00
Romain Thomas 550f8cbcb4 Update tests 2023-07-22 05:34:03 +02:00
Romain Thomas b265280a63 Update README 2023-07-15 13:12:20 +02:00
Romain Thomas 60ab1f281d Resolve #943 2023-07-15 13:08:13 +02:00
Romain Thomas ac4aa0487b Fix for Windows 2023-07-15 06:34:59 +02:00
Romain Thomas 9fecc8301a Use cache for the iOS ci and improve testing 2023-07-15 06:34:59 +02:00
Romain Thomas 4b29b87c14 Fix Python module API 2023-07-15 05:39:57 +02:00
Romain Thomas 12f359f748 Code cleaning 2023-07-15 05:33:12 +02:00
Romain Thomas afc84c9c0c Move to pointers 2023-07-14 05:44:23 +02:00
Romain Thomas ae9a7b2085 Fix Python 2023-07-09 10:15:32 +02:00
Romain Thomas 2b5f38bbeb Fix OSX x64 package name 2023-07-09 22:13:54 +02:00
Romain Thomas caf50de5e5 Remove deps 2023-07-09 21:58:03 +02:00
Romain Thomas 944fa67c30 Fix 2023-07-09 21:54:36 +02:00
Romain Thomas e37ffa9ec8 Switch the bindings to nanobind (and update the CI) 2023-07-09 21:33:43 +02:00
Romain Thomas 7e387675ac Merge pull request #939 from liyansong2018/master
Fix integer underflow in PHDR relocator
2023-07-09 03:34:30 +00:00
Romain Thomas a60987f237 Resolve #938, resolve #940, resolve #941 2023-07-06 21:39:23 +02:00
liyansong2018 f404470e0d Fix integer underflow 2023-07-06 19:25:20 +08:00
Romain Thomas 7057b9d359 Resolve #936 2023-07-01 08:38:56 +02:00
Romain Thomas eee71c930e Resolve #937 2023-07-01 07:01:12 +02:00
Romain Thomas 1a3b65117f Update setup.py 2023-07-01 06:39:33 +02:00
Romain Thomas c22a8fa9c6 Fix forward definition 2023-07-01 06:25:33 +02:00
Romain Thomas 6495242f54 Fix missing fwd declaration 2023-07-01 06:23:45 +02:00
Romain Thomas 57a59c5696 Do not reset the position
(issue: #935)
2023-06-26 07:46:16 +02:00
Romain Thomas 1335cb41be Fix header 2023-06-24 19:22:32 +02:00
Romain Thomas 15f40f2b8d Resolve #935 2023-06-24 07:37:00 +02:00
Romain Thomas 3e8dc1b1ad Fix missing include 2023-06-24 07:36:59 +02:00
Romain Thomas eda67d7910 Fix missing include 2023-06-24 07:36:58 +02:00
Romain Thomas a30b8adb2b remove useless checks
`seek` and `tell` are always present when inheriting from `io.IOBase`
2023-06-24 07:36:57 +02:00
Romain Thomas c50abdc645 Remove functions 2023-06-24 07:36:56 +02:00
Romain Thomas f9e6a021db Support flags from config 2023-06-24 07:36:55 +02:00
Romain Thomas 3a7d084081 Wraps by a main function 2023-06-24 07:36:55 +02:00
Romain Thomas 85518ff44c Merge pull request #924 from LouisBrunner/feature/dysym-command
feat(macho): allow to create DynamicSymbolCommand in Python
2023-06-21 14:17:22 +00:00
Romain Thomas 5436509a23 Update OSX version 2023-06-21 06:31:59 +02:00
Romain Thomas 622293c64e Fix compiler 2023-06-19 04:36:24 +02:00
Romain Thomas 9a13a77691 Fix missing quotes 2023-06-18 09:03:05 +02:00
Romain Thomas 3ccd280bd0 Fix warnings 2023-06-18 09:01:25 +02:00
Romain Thomas f6f8c749f2 Update to new version 2023-06-18 09:01:18 +02:00
Romain Thomas 5eb5e197b4 Handle CMAKE_OSX_ARCHITECTURES 2023-06-18 08:50:15 +02:00
Romain Thomas f39b9296d0 Update versions 2023-06-17 22:01:21 +02:00
Romain Thomas a9989d3ecd Update to new versions 2023-06-17 18:49:26 +02:00
Romain Thomas 21731e6824 Update README 2023-06-17 18:46:56 +02:00
Romain Thomas 27b8bf22bf Update changelog with 0.13.2 2023-06-17 18:46:29 +02:00
Romain Thomas ac9a5f2f1a More classof 2023-06-12 22:56:03 +02:00
Romain Thomas 1fd21cd7a5 Remove unsupported version 2023-06-12 22:45:33 +02:00
Romain Thomas ba6f88661f Merge pull request #930 from marcelotduarte/python312
Add Python 3.12-dev to build workflow
2023-06-12 06:28:19 +00:00
Marcelo Duarte 359ed0728a Add Python 3.12-dev to build workflow 2023-06-12 00:08:57 -03:00
Romain Thomas 19a1bae289 Add classof method 2023-06-11 19:35:27 +02:00
Romain Thomas 7a4e4f9189 Remove unnecessary inline 2023-06-11 19:28:31 +02:00
Romain Thomas b477c60d6c Include ctest 2023-06-11 07:02:36 +02:00
Romain Thomas bb0a6cc918 Fix warnings 2023-06-11 06:21:45 +02:00
Romain Thomas c5d0daa9da Merge pull request #929 from fzakaria/elf_undef
Add additional missing undef for ELF
2023-06-11 03:25:55 +00:00
Farid Zakaria fc323081ad Add additional missing undef for ELF
Add missing undef for ELF that cause failures if
lib/elf.h is included before LIEF.
2023-06-10 21:35:52 +00:00
Romain Thomas 7a10d2b866 Expose static helpers 2023-06-10 22:11:00 +02:00
Romain Thomas ee64e7e368 Fix build path 2023-06-10 13:22:59 +02:00
Romain Thomas 0f788c3990 Cleanup 2023-06-10 13:21:36 +02:00
Romain Thomas 6f04ecd472 Update stubs 2023-06-10 13:13:19 +02:00
Romain Thomas 177338f28a Fix tests 2023-06-10 13:13:09 +02:00
Romain Thomas 194d5f5478 Update README 2023-06-10 12:42:31 +02:00
Romain Thomas 4184aa05f7 Update README 2023-06-10 10:55:47 +02:00
Romain Thomas 97292eca03 Add interface (LIEF::ELF::ParserConfig) for configuring the ELF parser 2023-06-10 10:37:07 +02:00
Romain Thomas 1a69a1b16b Expose the DynamicSymbolCommand default constructor 2023-06-10 09:54:54 +02:00
Romain Thomas f0c3870db0 Merge pull request #923 from LouisBrunner/feature/allow-no-dysym
feat(macho): handle building a binary without LC_DYSYMTAB
2023-06-07 18:23:49 +00:00
Romain Thomas c17a3cbb86 Merge pull request #925 from LouisBrunner/feature/thread-command
feat(macho): allow to create ThreadCommand in Python
2023-06-07 18:23:05 +00:00
Romain Thomas 8d756b995e Merge pull request #926 from LouisBrunner/feature/main-command
feat(macho): allow to create MainCommand in Python
2023-06-07 18:20:03 +00:00
Louis Brunner 719249a2a5 feat(macho): handle building a binary without LC_DYSYMTAB 2023-06-07 15:54:57 +01:00
Louis Brunner 4560ce79f6 feat(macho): allow to create DynamicSymbolCommand in Python 2023-06-07 15:50:30 +01:00
Louis Brunner 3dec87b9b5 feat(macho): allow to create ThreadCommand in Python 2023-06-07 15:44:20 +01:00
Louis Brunner a7b114d8bb feat(macho): allow to create MainCommand in Python 2023-06-07 15:42:14 +01:00
Romain Thomas e3071a1e40 Update doc 2023-06-04 18:15:05 +02:00
Romain Thomas 76653f5380 Update changelog 2023-06-04 10:40:28 +02:00
Romain Thomas 2f2e5bf7fe Bump LIEF to C++17
LIEF internal code now uses C++17 while the API is still C++11 compliant
2023-06-04 10:39:19 +02:00
Romain Thomas 63f37f5fe2 Update stubs 2023-06-04 10:22:03 +02:00
Romain Thomas aa45e2ed71 Add tests for LoongArch (PR: 921) 2023-06-04 09:07:15 +02:00
Romain Thomas 2f8f81b119 Update changelog 2023-06-04 08:11:35 +02:00
Romain Thomas 0daf527ddf Merge pull request #921 from loongson-zn/dev-la
Add LoongArch support for ELF
2023-06-04 06:10:07 +00:00
Romain Thomas 84523d94f2 Update changelog 2023-06-03 10:25:13 +02:00
Romain Thomas f3d651ab31 Merge branch 'fix/issue-922' 2023-06-03 10:23:30 +02:00
Romain Thomas aa4d601b8e Remove irrelevant flag 2023-06-03 09:11:46 +02:00
Romain Thomas 2f333ffbd6 Do not force a specific tag 2023-06-03 09:11:25 +02:00
Romain Thomas 528435f14f Improve the logic of the AUTO symbol counting (idea from: @adamjseitz) 2023-06-03 09:06:45 +02:00
Zhang Na 375592aef4 Add LoongArch support for ELF 2023-05-31 17:33:13 +08:00
Romain Thomas 0d7c39d9f5 Fix typo 2023-05-28 22:38:17 +02:00
Romain Thomas 5db4acd816 Disable static link with libstdc++ 2023-05-28 12:27:43 +02:00
Romain Thomas e148d9ebd6 Add OSX arm64 workflow 2023-05-28 09:25:43 +02:00
Romain Thomas b828a2be6c Include 0.13.1 changelog 2023-05-27 21:40:06 +02:00
Romain Thomas 5d04ecc4ff Add sponsor 2023-05-27 21:19:16 +02:00
Romain Thomas 3df2e3f2b6 Fix C99 comment style (#916) 2023-05-27 20:49:30 +02:00
Romain Thomas 32d4848993 Fix #916 2023-05-16 04:11:15 +02:00
Romain Thomas 5e5a5bf632 Update 2023-05-14 18:20:12 +02:00
Romain Thomas c14385be08 Replace boost's leaf by tl/expected 2023-05-14 11:40:02 +02:00
Romain Thomas 23223aaefa Fix missing include 2023-05-08 14:59:09 +02:00
Romain Thomas 7f47307dab Update changelog 2023-05-06 12:29:18 +02:00
Romain Thomas eeae3e9859 Fix #912 2023-05-06 12:27:52 +02:00
Romain Thomas cf1ca21d1b Merge pull request #911 from LouisBrunner/feature/macho-dylinker
feat(macho): allow to create DylinkerCommand in Python (+ simpler constructor)
2023-05-06 04:28:57 +00:00
Louis Brunner 104df74246 feat(macho): allow to create DylinkerCommand in Python (+ simpler constructor) 2023-05-04 10:42:01 +01:00
Romain Thomas ac47c2a9a0 Enhance checks 2023-05-04 06:38:09 +02:00
Romain Thomas 2e06bdb4af Resolve #909 2023-05-03 06:06:17 +02:00
Romain Thomas 5e814ea606 Fix removed attribute 2023-04-29 07:16:32 +02:00
Romain Thomas 9f66386cef Fix removed attribute 2023-04-28 06:30:32 +02:00
Romain Thomas c33391222a Update stubs 2023-04-28 06:21:11 +02:00
Romain Thomas 8908fe4a45 Add interface to tweak the PE parser (resolve #839)
This commit also removes the Binary's name attribute.
2023-04-28 06:17:26 +02:00
Romain Thomas 227665312b Move to dedicated folder 2023-04-27 06:50:52 +02:00
Romain Thomas 284001d4c1 Update stubs 2023-04-25 19:02:01 +02:00
Romain Thomas 0714d2e783 Resolve #904 2023-04-23 12:55:25 +02:00
spobit 4ef1759bd4 fixed Binary::has_relocations_ field. 2023-04-21 13:51:12 +02:00
Romain Thomas f796720f63 Fix code 2023-04-19 12:10:56 +02:00
Romain Thomas fe2f20a49a Merge pull request #898 from adamjseitz/reloc-symbol-table
Utilize SH_LINK section metadata to resolve relocation's target symbol table
2023-04-19 09:38:03 +00:00
Adam Seitz bf7f36b707 Add symbol_table() API to ELF Relocations 2023-04-19 09:45:24 +02:00
Romain Thomas 6749446c59 Remove legacy files 2023-04-16 11:45:39 +02:00
Romain Thomas 901b798b69 Merge pull request #894 from kilograham/shstrtab_name
use correct .shstrtab section name when relocating it
2023-04-15 12:13:19 +00:00
Romain Thomas 27163edbd9 Merge pull request #896 from pkking/master
fix miscalculating offset in debug log
2023-04-15 11:18:03 +00:00
Romain Thomas cfe89fdc3c Bump version 2023-04-15 13:16:25 +02:00
Li Chaoran fd2cbb82c9 fix miscalculating offset in debug log
Signed-off-by: Li Chaoran <pkwarcraft@gmail.com>
2023-04-14 17:28:28 +08:00
graham sanderson 79ddf1ad98 use correct .shstrtab section name when relocating it 2023-04-13 21:52:29 -05:00
840 changed files with 19537 additions and 22549 deletions
-35
View File
@@ -1,35 +0,0 @@
Checks: >
-*,
bugprone-*,
google-*,
misc-*,
modernize-*,
performance-*,
portability-*,
readability-*,
cppcoreguidelines-*,
-bugprone-easily-swappable-parameters,
-bugprone-narrowing-conversions,
-google-readability-namespace-comments,
-google-readability-todo,
-google-runtime-int,
-google-default-arguments
-google-runtime-references,
-misc-non-private-member-variables-in-classes,
-modernize-use-trailing-return-type,
-performance-noexcept-move-constructor,
-readability-function-cognitive-complexity,
-readability-inconsistent-declaration-parameter-name,
-readability-magic-numbers,
-readability-named-parameter,
-readability-redundant-string-cstr
-readability-uppercase-literal-suffix,
# Turn all the warnings from the checks above into errors.
#WarningsAsErrors: "*"
UseColor: false
CheckOptions:
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
- { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ }
- { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }
-1
View File
@@ -1 +0,0 @@
build
+1
View File
@@ -0,0 +1 @@
github: [romainthomas]
+10
View File
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<title>Links for lief</title>
<body>
<h1>Links for lief</h1>
% for path, filename in files:
<a href="/${path}">${filename}</a><br />
% endfor
</body>
</html>
+9
View File
@@ -0,0 +1,9 @@
[lief.s3]
region = "fr-par"
bucket = "lief"
endpoint = "https://s3.fr-par.scw.cloud"
[lief.deploy]
branches = ["master", "deploy", "devel"]
main-branches = ["master", "main"]
default-dir = "latest"
+258 -242
View File
@@ -1,282 +1,298 @@
#!/usr/bin/env python3
import sys
import os
import re
import logging
import pathlib
import subprocess
import shutil
import json
import itertools
from collections import defaultdict
from datetime import datetime
from mako.template import Template
from enum import Enum, auto
import tempfile
import boto3
from botocore.exceptions import ClientError
from mako.template import Template
from pathlib import Path
from typing import Any, Optional
class CI(Enum):
UNKNOWN = auto()
TRAVIS = auto()
APPVEYOR = auto()
GITLAB_CI = auto()
CIRCLE_CI = auto()
GITHUB_ACTIONS = auto()
AZURE = auto()
LOCAL = auto()
def pretty_ci_name(ci):
return str(ci).split(".")[-1].replace("_", "-").lower()
def is_pr(ci):
if ci == CI.TRAVIS:
cond1 = os.getenv("TRAVIS_EVENT_TYPE", "pull_request") == "pull_request"
cond2 = not (os.getenv("TRAVIS_REPO_SLUG", "").startswith("lief-project/") or os.getenv("TRAVIS_REPO_SLUG", "").startswith("romainthomas/LIEF"))
return cond1 or cond2
elif ci == CI.APPVEYOR:
logger.info("%s - %s", os.getenv("APPVEYOR_PULL_REQUEST_NUMBER", -1), os.getenv("APPVEYOR_REPO_NAME", ""))
pr_number = os.getenv("APPVEYOR_PULL_REQUEST_NUMBER", "")
cond1 = len(pr_number) != 0 and int(pr_number) >= 0
cond2 = not (os.getenv("APPVEYOR_REPO_NAME", "").startswith("lief-project/") or os.getenv("APPVEYOR_REPO_NAME", "").startswith("romainthomas/"))
return cond1 or cond2
elif ci == CI.CIRCLE_CI:
cond1 = int(os.getenv("CIRCLE_PR_NUMBER", -1)) >= 0
cond2 = os.getenv("CIRCLE_PROJECT_USERNAME", "") != "lief-project" and os.getenv("CIRCLE_PROJECT_USERNAME", "") != "romainthomas"
return cond1 or cond2
elif ci == CI.GITHUB_ACTIONS:
cond1 = os.getenv("GITHUB_HEAD_REF", "") != ""
cond2 = not (os.getenv("GITHUB_REPOSITORY", "").startswith("lief-project/") or os.getenv("GITHUB_REPOSITORY", "").startswith("romainthomas/LIEF"))
return cond1 or cond2
elif ci == CI.LOCAL:
return False
return True
def get_branch(ci):
if ci == CI.TRAVIS:
return os.getenv("TRAVIS_BRANCH")
elif ci == CI.APPVEYOR:
return os.getenv("APPVEYOR_REPO_BRANCH")
elif ci == CI.CIRCLE_CI:
return os.getenv("CIRCLE_BRANCH")
elif ci == CI.GITHUB_ACTIONS:
return os.getenv("GITHUB_REF").replace("refs/heads/", "")
elif ci == CI.LOCAL:
return os.getenv("CI_BRANCH")
return None
def get_ci_workdir(ci):
if ci == CI.CIRCLE_CI:
return os.getenv("CIRCLE_WORKING_DIRECTORY")
elif ci == CI.TRAVIS:
return os.getenv("TRAVIS_BUILD_DIR")
elif ci == CI.APPVEYOR:
return os.getenv("APPVEYOR_BUILD_FOLDER")
elif ci == CI.GITHUB_ACTIONS:
return os.getenv("GITHUB_WORKSPACE")
elif ci == CI.LOCAL:
return os.getenv("CI_WORKING_DIR")
else:
logger.critical("Unsupported CI to resolve working directory")
sys.exit(1)
def get_tag(ci):
if ci == CI.CIRCLE_CI:
return os.getenv("CIRCLE_TAG", "")
elif ci == CI.TRAVIS:
return os.getenv("TRAVIS_TAG", "")
elif ci == CI.APPVEYOR:
if "APPVEYOR_REPO_TAG_NAME" in os.environ:
return os.getenv("APPVEYOR_REPO_TAG_NAME", "")
return ""
elif ci == CI.GITHUB_ACTIONS:
ref = os.getenv("GITHUB_REF", "")
logger.info("Github Action tag: {}".format(ref))
if ref.startswith("refs/tags/"):
return ref.replace("refs/tags/", "")
return ""
elif ci == CI.LOCAL:
return os.getenv("CI_TAG")
else:
logger.critical("Unsupported CI to resolve working directory")
sys.exit(1)
import argparse
import boto3
import functools
import logging
import os
import sys
import tempfile
import tomli
LOG_LEVEL = logging.INFO
CURRENTDIR = Path(__file__).resolve().parent
REPODIR = CURRENTDIR.parent
ASSET_DIR = CURRENTDIR / "assets"
CONFIG_DIR = CURRENTDIR / "config"
LIEF_S3_KEY = os.getenv("LIEF_S3_KEY", None)
LIEF_S3_SECRET = os.getenv("LIEF_S3_SECRET", None)
OWNED_ORGS = ["lief-project/", "romainthomas/"]
RELEASE_KEYWRD = "release-"
DEFAULT_CONFIG = CONFIG_DIR / "gh-ci.toml"
DEFAULT_TEMPLATE = (ASSET_DIR / "index.j2").read_text()
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
logging.getLogger().setLevel(LOG_LEVEL)
logger = logging.getLogger(__name__)
CURRENT_CI = CI.UNKNOWN
# Detect CI
# ===========================================
if os.getenv("TRAVIS", None) is not None:
CURRENT_CI = CI.TRAVIS
elif os.getenv("APPVEYOR", None) is not None:
CURRENT_CI = CI.APPVEYOR
elif os.getenv("GITHUB_ACTIONS", None) is not None:
CURRENT_CI = CI.GITHUB_ACTIONS
elif os.getenv("GITLAB_CI", None) is not None:
CURRENT_CI = CI.GITLAB_CI
elif os.getenv("CI_LOCAL", "") == "true":
CURRENT_CI = CI.LOCAL
else:
logger.error("Can't detect CI!")
sys.exit(1)
CI_PRETTY_NAME = pretty_ci_name(CURRENT_CI)
logger.info("CI: %s", CI_PRETTY_NAME)
ALLOWED_BRANCHES = {"master", "deploy", "devel"}
BRANCH_NAME = get_branch(CURRENT_CI)
TAG_NAME = get_tag(CURRENT_CI)
IS_TAGGED = TAG_NAME is not None and len(TAG_NAME) > 0
logger.info("Branch: %s", BRANCH_NAME)
logger.info("Tag: %s", TAG_NAME)
if BRANCH_NAME.startswith("release-"):
logger.info("Branch release")
elif BRANCH_NAME not in ALLOWED_BRANCHES and not IS_TAGGED:
logger.info("Skip deployment for branch '%s'", BRANCH_NAME)
sys.exit(0)
if is_pr(CURRENT_CI):
logger.info("Skip pull request")
sys.exit(0)
CURRENTDIR = pathlib.Path(__file__).resolve().parent
REPODIR = CURRENTDIR.parent
# According to Scaleway S3 documentation, the endpoint
# should starts with '<bucket>'.s3.<region>.scw.cloud
# Nevertheless boto3 uses /{Bucket} endpoints suffix
# which create issues (see: https://stackoverflow.com/a/70383653)
LIEF_S3_REGION = "fr-par"
LIEF_S3_ENDPOINT = "https://s3.{region}.scw.cloud".format(region=LIEF_S3_REGION)
LIEF_S3_BUCKET = "lief"
LIEF_S3_KEY = os.getenv("LIEF_S3_KEY", None)
LIEF_S3_SECRET = os.getenv("LIEF_S3_SECRET", None)
if LIEF_S3_KEY is None or len(LIEF_S3_KEY) == 0:
logger.error("LIEF_S3_KEY is not set!")
sys.exit(1)
if LIEF_S3_SECRET is None or len(LIEF_S3_SECRET) == 0:
logger.error("LIEF_S3_SECRET is not set!")
sys.exit(1)
CI_CWD = pathlib.Path(get_ci_workdir(CURRENT_CI))
class S3Manager:
def __init__(self, dirname: str, bucket: str,
region: str, endpoint: str,
dry_run: bool = False):
self._s3_dirname: str = dirname
self._s3_bucket: str = bucket
self._s3_region: str = region
self._s3_endpoint: str = endpoint
self._dry_run: bool = dry_run
if CI_CWD is None:
logger.error("Can't resolve CI working dir")
sys.exit(1)
logger.info("[S3] Bucket : %s", self._s3_bucket)
logger.info("[S3] Region : %s", self._s3_region)
logger.info("[S3] Endpoint: %s", self._s3_endpoint)
logger.info("[S3] Dir : %s", self._s3_dirname)
DIST_DIR = REPODIR / "dist"
BUILD_DIR = REPODIR / "build"
def change_dir(self, dirname: str):
self._s3_dirname = dirname
logger.info("Working directory: %s", CI_CWD)
@property
def s3_lief_sdk(self) -> str:
return f"{self._s3_dirname}/sdk"
INDEX_TEMPLATE = r"""
<!DOCTYPE html>
<html>
<title>Links for lief</title>
<body>
<h1>Links for lief</h1>
% for path, filename in files:
<a href="/${path}">${filename}</a><br />
% endfor
</body>
</html>
"""
@property
def s3_lief_wheel(self) -> str:
return f"{self._s3_dirname}/lief"
SKIP_LIST = ["index.html"]
@property
def url(self):
return f"https://{self._s3_bucket}.s3-website.{self._s3_region}.scw.cloud/{self._s3_dirname}"
s3 = boto3.resource(
's3',
region_name=LIEF_S3_REGION,
use_ssl=True,
endpoint_url=LIEF_S3_ENDPOINT,
aws_access_key_id=LIEF_S3_KEY,
aws_secret_access_key=LIEF_S3_SECRET
)
@functools.lru_cache(maxsize=1)
def s3(self) -> boto3.Session:
s3_res = boto3.resource(
's3',
region_name=self._s3_region,
use_ssl=True,
endpoint_url=self._s3_endpoint,
aws_access_key_id=LIEF_S3_KEY,
aws_secret_access_key=LIEF_S3_SECRET
)
return s3_res
@classmethod
def from_config(cls, config):
pass
def _s3_push(self, file: Path, dst: str):
logger.info("Uploading %s to %s", file, dst)
try:
obj = self.s3().Object(self._s3_bucket, dst)
if not self._dry_run:
obj.put(Body=file.read_bytes())
else:
logger.info("[--] put: %s/%s - %s", self._s3_bucket, dst, file.as_posix())
return 0
except ClientError as e:
logger.error("S3 push failed: %s", e)
return 1
def push_wheel(self, file: str):
wheel_file = Path(file)
if not wheel_file.is_file():
logger.error("'%s' is not a valid file!", wheel_file)
return
dst = f"{self.s3_lief_wheel}/{wheel_file.name}"
self._s3_push(wheel_file, dst)
def push_sdk(self, file: str):
sdk_path = Path(file)
if not sdk_path.is_file():
logger.error("'%s' is not a valid file!", sdk_path)
return
dst = f"{self.s3_lief_sdk}/{sdk_path.name}"
self._s3_push(sdk_path, dst)
def push_content(self, content: str, dst: str):
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
index = tmp_path / "index.html"
index.write_text(content)
self._s3_push(index, dst)
def process_sdk_wheels(self, directory: Path, maxdepth: int = 0,
depth: int = 0, recurse: bool = True):
logger.info("Processing directory: %s", directory)
for item in directory.iterdir():
if item.is_dir() and recurse:
if 0 < maxdepth < depth:
logger.debug("Maximum iteration depth reached")
else:
self.process_sdk_wheels(item, maxdepth, depth + 1, recurse)
elif item.is_file():
extension = item.suffix
if extension in (".zip", ".gz"):
logger.info("[SDK ] Uploading '%s'", item.as_posix())
self.push_sdk(item.as_posix())
elif extension in (".whl", ):
logger.info("[WHEEL] Uploading '%s'", item.as_posix())
self.push_wheel(item.as_posix())
def push_wheel(file: str, dir_name: str):
wheel_file = pathlib.Path(file)
dst = f"{dir_name}/lief/{wheel_file.name}"
logger.info("Uploading %s to %s", file, dst)
try:
obj = s3.Object(LIEF_S3_BUCKET, dst)
obj.put(Body=wheel_file.read_bytes())
return 0
except ClientError as e:
logger.error("S3 push failed: %s", e)
return 1
def upload_wheels_sdk(self, src_dir: Path, maxdepth: int):
logger.info("Looking for wheels and sdk from: %s", src_dir)
self.process_sdk_wheels(src_dir, maxdepth=maxdepth, recurse=True)
wheels_index = self.generate_index(self.s3_lief_wheel,
DEFAULT_TEMPLATE,
skiplist=("index.html", ))
sdk_index = self.generate_index(self.s3_lief_sdk, DEFAULT_TEMPLATE,
skiplist=("index.html", ))
self.push_content(wheels_index, f"{self.s3_lief_wheel}/index.html")
self.push_content(sdk_index, f"{self.s3_lief_sdk}/index.html")
logger.info("Done!")
logger.info("URL: %s/%s", self.url, "sdk")
logger.info("URL: %s/%s", self.url, "lief")
def s3_list(self, dirname: str) -> list[Any]:
if self._dry_run:
return []
return self.s3().Bucket(self._s3_bucket).objects.filter(Prefix=dirname)
def generate_index(self, dirname: str, template: str, skiplist=None):
files = self.s3_list(dirname)
selected_files = []
for s3_object in files:
filename = Path(s3_object.key).name
if skiplist is not None and filename in skiplist:
continue
selected_files.append((s3_object.key, filename))
return Template(template).render(files=selected_files)
class GithubDeploy:
def __init__(self, branches: list[str],
main_branches: list[str],
default_dir: str,
s3_manager: S3Manager):
self.s3_manager: S3Manager = s3_manager
self._branches: list[str] = branches
self._main_branches: list[str] = main_branches
self._default_dir: str = default_dir
def push_sdk(file: str, dir_name: str):
sdk_file = pathlib.Path(file)
dst = f"{dir_name}/sdk/{sdk_file.name}"
logger.info("Uploading %s to %s", file, dst)
try:
obj = s3.Object(LIEF_S3_BUCKET, dst)
obj.put(Body=sdk_file.read_bytes())
return 0
except ClientError as e:
logger.error("S3 push failed: %s", e)
return 1
@classmethod
def from_config(cls, config_file: Path):
with open(config_file, "rb") as f:
toml_config = tomli.load(f)
def filename(object):
return pathlib.Path(object.key).name
if "lief" not in toml_config:
logger.warning("Missing lief entries in '%s'", config_file)
return None
lief_conf = toml_config["lief"]
def generate_sdk_index(dir_name: str):
files = s3.Bucket(LIEF_S3_BUCKET).objects.filter(Prefix=f'{dir_name}/sdk')
tmpl_info = [(object.key, filename(object)) for object in files if filename(object) not in SKIP_LIST]
html = Template(INDEX_TEMPLATE).render(files=tmpl_info)
return html
if "s3" not in lief_conf:
logger.warning("Missing lief.s3 entries in '%s'", config_file)
return None
def generate_pypi_index(dir_name: str):
files = s3.Bucket(LIEF_S3_BUCKET).objects.filter(Prefix=f'{dir_name}/lief')
tmpl_info = [(object.key, filename(object)) for object in files if filename(object) not in SKIP_LIST]
html = Template(INDEX_TEMPLATE).render(files=tmpl_info)
return html
if "deploy" not in lief_conf:
logger.warning("Missing lief.deploy entries in '%s'", config_file)
return None
dir_name = "latest"
branches = lief_conf["deploy"]["branches"]
main_branches = lief_conf["deploy"]["main-branches"]
default_dir = lief_conf["deploy"]["default-dir"]
s3_config = lief_conf["s3"]
s3_region = s3_config["region"]
s3_bucket = s3_config["bucket"]
s3_endpoint = s3_config["endpoint"]
if BRANCH_NAME != "master":
dir_name = "{}".format(BRANCH_NAME.replace("/", "-").replace("_", "-"))
s3_manager = S3Manager(default_dir, s3_bucket, s3_region, s3_endpoint)
return cls(branches, main_branches, default_dir, s3_manager)
if BRANCH_NAME.startswith("release-"):
_, dir_name = BRANCH_NAME.split("release-")
@staticmethod
def branch() -> Optional[str]:
ref = os.getenv("GITHUB_REF")
if ref is None:
return None
return ref.replace("refs/heads/", "")
if IS_TAGGED:
dir_name = str(TAG_NAME)
@staticmethod
def is_pr() -> bool:
head_ref = os.getenv("GITHUB_HEAD_REF", "")
repo_path = os.getenv("GITHUB_REPOSITORY", "")
is_owned_repo = any(repo_path.startswith(org) for org in OWNED_ORGS)
return head_ref != "" or not is_owned_repo
logger.info("Destination directory: %s", dir_name)
@staticmethod
def is_tagged() -> bool:
tag = GithubDeploy.tag_name()
return tag is not None and len(tag) > 0
for file in DIST_DIR.glob("*.whl"):
logger.info("[WHEEL] Uploading '%s'", file.as_posix())
push_wheel(file.as_posix(), dir_name)
@staticmethod
def tag_name() -> Optional[str]:
ref = os.getenv("GITHUB_REF", "")
logger.info("Github Action tag: %s", ref)
if ref.startswith("refs/tags/"):
return ref.replace("refs/tags/", "")
return ""
for file in itertools.chain(BUILD_DIR.glob("*.zip"), BUILD_DIR.glob("*.tar.gz")):
logger.info("[SDK ] Uploading '%s'", file.as_posix())
push_sdk(file.as_posix(), dir_name)
@staticmethod
def workspace() -> str:
return os.getenv("GITHUB_WORKSPACE", "")
sdk_index = generate_sdk_index(dir_name)
with tempfile.TemporaryDirectory() as tmp:
tmp = pathlib.Path(tmp)
index = (tmp / "index.html")
index.write_text(sdk_index)
push_sdk(index.as_posix(), dir_name)
def is_main_branch(self, name: str) -> bool:
return name in self._main_branches
pypi_index = generate_pypi_index(dir_name)
with tempfile.TemporaryDirectory() as tmp:
tmp = pathlib.Path(tmp)
index = (tmp / "index.html")
index.write_text(pypi_index)
push_wheel(index.as_posix(), dir_name)
def deploy(self, directories: list[str]):
s3dir = None
if GithubDeploy.is_tagged():
s3dir = GithubDeploy.tag_name()
else:
branch = GithubDeploy.branch()
if branch is None:
logger.warning("Can't resolve the branch name")
sys.exit(1)
logger.info("Done!")
if branch.startswith(RELEASE_KEYWRD):
_, s3dir = branch.split(RELEASE_KEYWRD)
elif self.is_main_branch(branch):
s3dir = self._default_dir
else:
s3dir = branch.replace("/", "-").replace("_", "-")
if s3dir is None:
logger.error("Target directory is not set")
sys.exit(1)
logger.info("s3dir: %s", s3dir)
self.s3_manager.change_dir(s3dir)
for dirname in directories:
dirpath = Path(dirname).resolve().absolute().expanduser()
self.s3_manager.upload_wheels_sdk(dirpath, maxdepth=1)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--config", "-c")
parser.add_argument("--dry-run", "-n", action="store_true", default=False)
parser.add_argument("directories", nargs="+")
args = parser.parse_args()
config_path = None
if args.config is not None:
config_path = Path(args.config)
else:
config_path = DEFAULT_CONFIG
if not config_path.is_file():
logger.error("'%s' is not a valid config path")
sys.exit(1)
gh_deploy = GithubDeploy.from_config(config_path)
gh_deploy.deploy(args.directories)
if __name__ == "__main__":
main()
sys.exit(0)
+45 -35
View File
@@ -1,69 +1,79 @@
name: 'Android'
on: push
on: workflow_dispatch
jobs:
build-and-deploy:
build-sdk:
runs-on: ubuntu-latest
strategy:
matrix:
arch: ['arm', 'arm64']
fail-fast: false
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
key: android-${{ runner.os }}-${{ steps.get-date.outputs.date }}
key: android-${{ runner.os }}-${{ matrix.arch }}-${{ steps.get-date.outputs.date }}
restore-keys: |
android-${{ runner.os }}-
- name: Build ARM SDK
android-${{ runner.os }}-${{ matrix.arch }}
- name: Build SDK [${{ matrix.arch }}]
shell: bash
env:
ARCH: ${{ matrix.arch }}
run: |
docker run \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
docker run \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-v $GITHUB_WORKSPACE:/work \
-v $HOME/.ccache:/ccache \
--rm liefproject/android-arm bash /work/scripts/docker/android-arm.sh
- name: Build AArch64 SDK
shell: bash
run: |
docker run \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-v $GITHUB_WORKSPACE:/work \
-v $HOME/.ccache:/ccache \
--rm liefproject/android-arm64 bash /work/scripts/docker/android-aarch64.sh
-v $HOME/.ccache:/ccache \
--rm liefproject/android-${ARCH} bash /work/scripts/docker/android-${ARCH}.sh
- name: 'Upload Artifact'
uses: actions/upload-artifact@v3
with:
name: android-sdk
name: android-sdk-${{ matrix.arch }}
path: build/*.tar.gz
retention-days: 3
deploy:
if: ${{ always() }}
runs-on: ubuntu-latest
needs: build-sdk
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}/artifacts
- name: Display artifacts
run: ls -R
working-directory: ${{ runner.temp }}/artifacts
- name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
shell: bash
run: |
docker run \
-v $GITHUB_WORKSPACE:/src \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP:/runner_tmp \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
-e GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
--rm \
liefproject/deploy python3 /src/.github/deploy.py
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
liefproject/deploy python3 /src/.github/deploy.py /runner_tmp/artifacts
+31
View File
@@ -0,0 +1,31 @@
name: code-check
on:
workflow_dispatch:
inputs:
branch:
description: 'LIEF branch'
default: 'master'
required: false
type: string
push:
branches:
- test/code-check
jobs:
coverage:
runs-on: ubuntu-latest
container:
image: liefproject/code-check
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
GH_BRANCH: ${{ inputs.branch }}
steps:
- uses: actions/checkout@v3
with:
repository: lief-project/code-check
token: ${{ secrets.LIEF_CLONE_TOKEN }}
- name: Print info
run: |
echo ${GH_BRANCH}
- name: Running LIEF coverage
run: ./lief-coverage --debug
+38 -12
View File
@@ -1,17 +1,20 @@
name: 'iOS'
on: push
on: workflow_dispatch
env:
python-version: '3.10'
jobs:
osx-sdk:
ios-sdk:
runs-on: macos-11.0
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python 3.9
uses: actions/setup-python@v2
- name: Set up Python ${{ env.python-version }}
uses: actions/setup-python@v3
with:
python-version: 3.9
python-version: ${{ env.python-version }}
- name: Install system dependencies
run: |
brew install cmake ninja ccache
@@ -19,7 +22,7 @@ jobs:
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Setup cache dir
shell: bash
@@ -28,14 +31,14 @@ jobs:
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
path: ${{ runner.temp }}/.ccache
key: ios-${{ runner.os }}-${{ steps.get-date.outputs.date }}
restore-keys: |
ios-${{ runner.os }}-
ios-${{ runner.os }}
- name: Build iOS SDK
shell: bash
env:
CCACHE_DIR: ~/.ccache
CCACHE_DIR: ${{ runner.temp }}/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
@@ -47,14 +50,37 @@ jobs:
name: ios-sdk
path: build/*.tar.gz
retention-days: 3
deploy:
runs-on: ubuntu-latest
if: ${{ always() }}
needs: ios-sdk
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}/artifacts
- name: Display artifacts
run: ls -R
working-directory: ${{ runner.temp }}/artifacts
- name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
shell: bash
run: |
python -m pip install --upgrade requests mako boto3
python .github/deploy.py
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP:/runner_tmp \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
-e GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
liefproject/deploy python3 /src/.github/deploy.py /runner_tmp/artifacts
+84 -39
View File
@@ -1,84 +1,129 @@
name: 'Linux AArch64'
on: push
on: workflow_dispatch
jobs:
linux-sdk:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
key: linux-aarch64-${{ runner.os }}-${{ steps.get-date.outputs.date }}
key: linux-aarch64-${{ runner.os }}-sdk-${{ steps.get-date.outputs.date }}
restore-keys: |
linux-aarch64-${{ runner.os }}-
linux-aarch64-${{ runner.os }}-sdk
- name: Build SDK
if: matrix.python-version == '3.9'
shell: bash
run: |
docker run \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-v $GITHUB_WORKSPACE:/work \
-v $HOME/.ccache:/ccache \
--rm liefproject/manylinux2014-aarch64 bash /work/scripts/docker/linux-aarch64.sh
- name: Build Python ${{ matrix.python-version }} wheel
shell: bash
env:
PYTHON_VERSION: ${{ matrix.python-version }}
run: |
PYTHON_VERSION2=$(echo "${PYTHON_VERSION}" | sed 's/\.//') # Transform 3.8 -> 38
docker run \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_BINARY=/opt/python/cp${PYTHON_VERSION2}-cp${PYTHON_VERSION2}/bin/python${PYTHON_VERSION} \
-v $GITHUB_WORKSPACE:/work \
-v $HOME/.ccache:/ccache \
--rm liefproject/manylinux2014-aarch64 bash /work/scripts/docker/manylinux2014-aarch64.sh
mkdir -p $RUNNER_TEMP/lief-install
docker run --name lief_sdk --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_DIR=/ccache \
-v $GITHUB_WORKSPACE:/work \
-v $RUNNER_TEMP/lief-install:/install \
-v $HOME/.ccache:/ccache \
liefproject/manylinux2014-aarch64 bash /work/scripts/docker/linux-aarch64.sh
- name: 'Upload SDK Artifact'
if: matrix.python-version == '3.9'
uses: actions/upload-artifact@v3
with:
name: linux-aarch64-sdk
path: build/*.tar.gz
retention-days: 3
- name: 'Upload Python Wheel Artifact - ${{ matrix.python-version }}'
- name: 'Upload Install Artifact'
uses: actions/upload-artifact@v3
with:
name: linux-aarch64-wheel-${{ matrix.python-version }}
name: linux-aarch64-install
path: ${{ runner.temp }}/lief-install
retention-days: 1
wheels:
runs-on: ubuntu-latest
needs: linux-sdk
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11']
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
key: linux-aarch64-${{ runner.os }}-${{ matrix.python-version }}-${{ steps.get-date.outputs.date }}
restore-keys: |
linux-aarch64-${{ runner.os }}-${{ matrix.python-version }}
- name: Download LIEF install dir
uses: actions/download-artifact@v3
with:
name: linux-aarch64-install
path: ${{ runner.temp }}/lief-install
- name: Python ${{ matrix.python-version }} -- Wheel
shell: bash
env:
PYTHON_VERSION: ${{ matrix.python-version }}
run: |
PYTHON_VERSION_ALT=$(echo "${PYTHON_VERSION}" | sed 's/\.//') # Transform 3.8 -> 38
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION_ALT \
-e PYTHON_BINARY=/opt/python/cp${PYTHON_VERSION_ALT}-cp${PYTHON_VERSION_ALT}/bin/python${PYTHON_VERSION} \
-v $GITHUB_WORKSPACE:/work \
-v $HOME/.ccache:/ccache \
-v $RUNNER_TEMP/lief-install:/install \
liefproject/manylinux2014-aarch64 bash /work/scripts/docker/manylinux2014-aarch64.sh
- name: 'Artifact'
uses: actions/upload-artifact@v3
with:
name: linux-aarch64-python${{ matrix.python-version }}-wheel
path: dist/*.whl
retention-days: 3
deploy:
runs-on: ubuntu-latest
if: ${{ always() }}
needs: [linux-sdk, wheels]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}/artifacts
- name: Display artifacts
run: ls -R
working-directory: ${{ runner.temp }}/artifacts
- name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
shell: bash
run: |
docker run \
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP:/runner_tmp \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
-e GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
--rm \
liefproject/deploy python3 /src/.github/deploy.py
liefproject/deploy python3 /src/.github/deploy.py /runner_tmp/artifacts
+130 -97
View File
@@ -1,103 +1,36 @@
name: 'Linux x86-64'
on: push
on: workflow_dispatch
jobs:
linux-sdk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
key: linux-x86-64-${{ runner.os }}-${{ steps.get-date.outputs.date }}
key: linux-x86-64-${{ runner.os }}-sdk-${{ steps.get-date.outputs.date }}
restore-keys: |
linux-x86-64-${{ runner.os }}-
- name: Build Python 3.8 wheel & test
shell: bash
env:
PYTHON_VERSION: 38
run: |
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION \
-e PYTHON_BINARY=/opt/python/cp38-cp38/bin/python3.8 \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux_test.sh
- name: Build Python 3.9 wheel
shell: bash
env:
PYTHON_VERSION: 39
run: |
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION \
-e PYTHON_BINARY=/opt/python/cp39-cp39/bin/python3.9 \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux.sh
- name: Build Python 3.10 wheel
shell: bash
env:
PYTHON_VERSION: 310
run: |
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION \
-e PYTHON_BINARY=/opt/python/cp310-cp310/bin/python3.10 \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux.sh
- name: Test LIEF on Archlinux
shell: bash
env:
PYTHON_VERSION: 310
run: |
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
liefproject/archlinux bash /src/scripts/docker/run_archlinux.sh
- name: Build Python 3.11 wheel
shell: bash
env:
PYTHON_VERSION: 311
run: |
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION \
-e PYTHON_BINARY=/opt/python/cp311-cp311/bin/python3.11 \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux.sh
linux-x86-64-${{ runner.os }}-sdk
- name: Build SDK
shell: bash
run: |
docker run --name lief_sdk --rm \
-e PYTHON_BINARY=/opt/python/cp39-cp39/bin/python3.9 \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_DIR=/ccache \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
mkdir -p $RUNNER_TEMP/lief-install
docker run --name lief_sdk --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_DIR=/ccache \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP/lief-install:/install \
-v $HOME/.ccache:/ccache \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux_sdk.sh
- name: 'Upload SDK Artifact'
uses: actions/upload-artifact@v3
@@ -105,40 +38,140 @@ jobs:
name: linux-x86-64-sdk
path: build/*.tar.gz
retention-days: 3
- name: 'Upload SDK Artifact'
- name: 'Upload Install Artifact'
uses: actions/upload-artifact@v3
with:
name: linux-x86-64-python-wheel
name: linux-x86-64-install
path: ${{ runner.temp }}/lief-install
retention-days: 1
testing:
if: "!contains(github.event.commits[0].message, '[skip-test]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
key: linux-x86-64-${{ runner.os }}-test-${{ steps.get-date.outputs.date }}
restore-keys: |
linux-x86-64-${{ runner.os }}-test
- name: Python 3.8 -- Wheel & Test
shell: bash
env:
PYTHON_VERSION: 38
run: |
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION \
-e PYTHON_BINARY=/opt/python/cp38-cp38/bin/python3.8 \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux_test.sh
pywheels:
runs-on: ubuntu-latest
needs: linux-sdk
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.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@v3
with:
name: linux-x86-64-install
path: ${{ runner.temp }}/lief-install
- name: Python ${{ matrix.python-version }} -- Wheel
shell: bash
env:
PYTHON_VERSION: ${{ matrix.python-version }}
run: |
PYTHON_VERSION_ALT=$(echo "${PYTHON_VERSION}" | sed 's/\.//') # Transform 3.8 -> 38
docker run --rm \
-e CCACHE_COMPRESS=1 \
-e CCACHE_MAXSIZE=10.0G \
-e CCACHE_CPP2=1 \
-e CCACHE_DIR=/ccache \
-e PYTHON_VERSION=$PYTHON_VERSION_ALT \
-e PYTHON_BINARY=/opt/python/cp${PYTHON_VERSION_ALT}-cp${PYTHON_VERSION_ALT}/bin/python${PYTHON_VERSION} \
-v $GITHUB_WORKSPACE:/src \
-v $HOME/.ccache:/ccache \
-v $RUNNER_TEMP/lief-install:/install \
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux.sh
- name: 'Artifact'
uses: actions/upload-artifact@v3
with:
name: linux-x86-64-python${{ matrix.python-version }}-wheel
path: dist/*.whl
retention-days: 3
deploy:
runs-on: ubuntu-latest
if: ${{ always() }}
needs: [linux-sdk, pywheels]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}/artifacts
- name: Display artifacts
run: ls -R
working-directory: ${{ runner.temp }}/artifacts
- name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
shell: bash
run: |
docker run \
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP:/runner_tmp \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
-e GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
--rm \
liefproject/deploy python3 /src/.github/deploy.py
liefproject/deploy python3 /src/.github/deploy.py /runner_tmp/artifacts
documentation:
needs: [deploy]
runs-on: ubuntu-latest
container:
image: liefproject/manylinux_2_28_x86_64
env:
CIRCLE_CI_URL: "https://circleci.com/api/v2/project/gh/lief-project/doc/pipeline"
CIRCLE_CI_TOKEN: ${{ secrets.CIRCLE_CI_TOKEN }}
steps:
- name: Trigger documentation
if: github.ref == 'refs/heads/master'
env:
CIRCLE_CI_TOKEN: ${{ secrets.CIRCLE_CI_TOKEN }}
shell: bash
run: |
docker run --rm \
-e CIRCLE_CI_TOKEN=$CIRCLE_CI_TOKEN \
liefproject/manylinux_2_28_x86_64 \
bash -c "curl --request POST --url https://circleci.com/api/v2/project/gh/lief-project/doc/pipeline --header 'Circle-Token: ${CIRCLE_CI_TOKEN}' --header 'content-type: application/json'";
curl --request POST --url ${CIRCLE_CI_URL} \
--header "Circle-Token: ${CIRCLE_CI_TOKEN}" \
--header 'content-type: application/json' \
--data '{"parameters":{"lief-branch":"master"}}'
+163 -74
View File
@@ -1,14 +1,132 @@
name: 'macOS'
on: push
on: workflow_dispatch
env:
python-test-version: '3.10'
jobs:
osx-sdk:
runs-on: macos-11.0
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install system dependencies
run: |
brew install cmake ninja ccache
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Setup cache dir
shell: bash
run: |
mkdir -p $RUNNER_TEMP/.ccache
- name: ccache cache files
uses: actions/cache@v3
with:
path: ${{ runner.temp }}/.ccache
key: osx-${{ runner.os }}-sdk-${{ steps.get-date.outputs.date }}
restore-keys: |
osx-${{ runner.os }}-sdk
- name: Build SDK
shell: bash
env:
MACOSX_DEPLOYMENT_TARGET: "11.0"
CCACHE_DIR: ${{ runner.temp }}/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
run: |
bash scripts/osx/package_sdk.sh
- name: 'Upload SDK Artifact'
uses: actions/upload-artifact@v3
with:
name: osx-sdk
path: build/*.tar.gz
retention-days: 3
- name: 'Upload install artifact [arm64]'
uses: actions/upload-artifact@v3
with:
name: osx-arm64-install
path: install/arm64
retention-days: 1
- name: 'Upload install artifact [x64]'
uses: actions/upload-artifact@v3
with:
name: osx-x64-install
path: install/x64
retention-days: 1
osx-testing:
runs-on: macos-11.0
if: "!contains(github.event.commits[0].message, '[skip-test]')"
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ env.python-test-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.python-test-version }}
- name: Install system dependencies
run: |
brew install cmake ninja ccache
python -m pip install --upgrade pip setuptools wheel
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Setup cache dir
shell: bash
run: |
mkdir -p $RUNNER_TEMP/.ccache
- name: ccache cache files
uses: actions/cache@v3
with:
path: ${{ runner.temp }}/.ccache
key: osx-${{ runner.os }}-test-${{ steps.get-date.outputs.date }}
restore-keys: |
osx-${{ runner.os }}-test
- name: Upgrade pip
shell: bash
run: |
python -m pip install --upgrade pip setuptools
- name: Build Python 3.10 with tests
shell: bash
env:
LIEF_SAMPLES_DIR: "/tmp/samples"
BUILD_DIR: "/tmp/lief-build"
MACOSX_TARGET: "11.7"
MACOSX_DEPLOYMENT_TARGET: "11.0"
CCACHE_DIR: ${{ runner.temp }}/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
run: |
python -m pip install -r tests/requirements.txt
python tests/dl_samples.py ${LIEF_SAMPLES_DIR}
cd api/python
PYLIEF_CONF=${GITHUB_WORKSPACE}/scripts/osx/osx-testing-x64.toml \
python ./setup.py build \
--build-base=${BUILD_DIR}/base \
--build-temp=${BUILD_DIR}/temp \
install --user
cd ${GITHUB_WORKSPACE}
python tests/run_pytest.py
python tests/run_tools_check.py ${BUILD_DIR}/temp
ctest --output-on-failure --test-dir ${BUILD_DIR}/temp
wheels:
runs-on: macos-11.0
needs: osx-sdk
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11.0']
python-version: [3.8, 3.9, '3.10', '3.11']
arch: ['x64', 'arm64']
fail-fast: false
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
@@ -22,104 +140,75 @@ jobs:
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Setup cache dir
shell: bash
run: |
mkdir -p ~/.ccache
mkdir -p $RUNNER_TEMP/.ccache
- name: ccache cache files
uses: actions/cache@v3
with:
path: ~/.ccache
key: osx-${{ runner.os }}-${{ steps.get-date.outputs.date }}
path: ${{ runner.temp }}/.ccache
key: osx-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.python-version }}-${{ steps.get-date.outputs.date }}
restore-keys: |
osx-${{ runner.os }}-
osx-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.python-version }}
- name: Upgrade pip
shell: bash
run: |
python -m pip install --upgrade pip setuptools
#
# Run LIEF tests on Python 3.8 (only)
# ========================================
- name: Build Python ${{ matrix.python-version }} wheel & test
- name: Download LIEF install dir
uses: actions/download-artifact@v3
with:
name: osx-${{ matrix.arch }}-install
path: ~/lief-${{ matrix.arch }}-install
- name: Build Python ${{ matrix.python-version }} [${{ matrix.arch }}]
shell: bash
if: matrix.python-version == '3.8'
env:
LIEF_SAMPLES_DIR: "/tmp/samples"
MACOSX_DEPLOYMENT_TARGET: "10.14"
CCACHE_DIR: ~/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
run: |
python -m pip install pytest requests
python tests/dl_samples.py ${LIEF_SAMPLES_DIR}
python -m pip -vv wheel --wheel-dir=dist/ api/python
python -m pip -vv install api/python
python ./tests/run_pytest.py
cmake -S . -B ./api/python/build/temp.macosx-10.15-x86_64-cpython-38 -DLIEF_TESTS=on
ninja -C ./api/python/build/temp.macosx-10.15-x86_64-cpython-38
python ./tests/run_tools_check.py ./api/python/build/temp.macosx-10.15-x86_64-cpython-38
ctest --output-on-failure --test-dir ./api/python/build/temp.macosx-10.15-x86_64-cpython-38
- name: Build Python ${{ matrix.python-version }} wheel (x86-64)
shell: bash
if: matrix.python-version != '3.8'
env:
MACOSX_DEPLOYMENT_TARGET: "10.14"
CCACHE_DIR: ~/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
run: |
python -m pip wheel --wheel-dir=dist/ api/python
#
# cross-compile for Apple M1 for Python >= 3.9
# ============================================
- name: Build Python ${{ matrix.python-version }} wheel (arm64)
shell: bash
if: matrix.python-version != '3.8'
env:
MACOSX_DEPLOYMENT_TARGET: "11.0"
CCACHE_DIR: ~/.ccache
CCACHE_DIR: ${{ runner.temp }}/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
PYLIEF_CONF: "${{ github.workspace }}/scripts/osx/py-${{ matrix.arch }}.toml"
run: |
PYLIEF_CONF="$(pwd)/scripts/osx/config-xcompile-arm64.toml" \
python -m pip -vv wheel --wheel-dir=dist/ api/python
#
# Build the SDK while running with Python 3.9 (only once)
# =======================================================
- name: Build SDK
shell: bash
if: matrix.python-version == '3.9' # Build the SDD only with Python 3.9
env:
MACOSX_DEPLOYMENT_TARGET: "10.14"
CCACHE_DIR: ~/.ccache
CCACHE_MAXSIZE: 10.0G
CCACHE_CPP2: 1
CCACHE_COMPRESS: 1
run: |
bash scripts/osx/package_sdk.sh
- name: 'Upload SDK Artifact'
if: matrix.python-version == '3.9' # Build the SDk only with Python 3.9
- name: 'Upload Python wheel artifact - ${{ matrix.python-version }}'
uses: actions/upload-artifact@v3
with:
name: osx-sdk
path: build/*.tar.gz
retention-days: 3
- name: 'Upload Python Wheel Artifact - ${{ matrix.python-version }}'
uses: actions/upload-artifact@v3
with:
name: osx-wheel-${{ matrix.python-version }}
name: osx-wheel-${{ matrix.arch }}-${{ matrix.python-version }}
path: dist/*.whl
retention-days: 3
deploy:
runs-on: ubuntu-latest
if: ${{ always() }}
needs: [osx-sdk, wheels]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}/artifacts
- name: Display artifacts
run: ls -R
working-directory: ${{ runner.temp }}/artifacts
- name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
shell: bash
run: |
python -m pip install --upgrade requests mako boto3
python .github/deploy.py
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP:/runner_tmp \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
-e GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
liefproject/deploy python3 /src/.github/deploy.py /runner_tmp/artifacts
+35 -19
View File
@@ -1,13 +1,13 @@
name: LIEF PR
on: [pull_request, workflow_dispatch]
env:
python-osx-version: '3.10'
python-win-version: '3.10'
jobs:
osx:
runs-on: macos-11.0
strategy:
matrix:
python-version: ["3.10"]
steps:
- uses: actions/checkout@v2
with:
@@ -15,20 +15,29 @@ jobs:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
python-version: ${{ env.python-osx-version }}
- name: Install system dependencies
run: |
brew install cmake ninja ccache
python -m pip install --upgrade pip setuptools wheel
- name: Build with Python ${{ matrix.python-version }} & Test
- name: Build with Python ${{ env.python-osx-version }} & Test
shell: bash
env:
LIEF_SAMPLES_DIR: "/tmp/samples"
BUILD_DIR: "/tmp/lief-build"
run: |
python -m pip install pytest requests
python -m pip install -r tests/requirements.txt
python tests/dl_samples.py ${LIEF_SAMPLES_DIR}
python -m pip -vv install api/python
python ./tests/run_pytest.py
cd api/python
PYLIEF_CONF=${GITHUB_WORKSPACE}/scripts/osx/osx-testing-x64.toml \
python ./setup.py build \
--build-base=${BUILD_DIR}/base \
--build-temp=${BUILD_DIR}/temp \
install --user
cd ${GITHUB_WORKSPACE}
python tests/run_pytest.py
python tests/run_tools_check.py ${BUILD_DIR}/temp
ctest --output-on-failure --test-dir ${BUILD_DIR}/temp
linux:
runs-on: ubuntu-latest
steps:
@@ -47,21 +56,17 @@ jobs:
liefproject/manylinux_2_28_x86_64 bash /src/scripts/docker/run_linux_test.sh
windows:
runs-on: windows-latest
strategy:
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
- name: Set up Python ${{ env.python-win-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
python-version: ${{ env.python-win-version }}
architecture: x64
- name: Install system dependencies
run: |
choco install ninja
python -m pip install --upgrade pip setuptools
python -m pip install wheel mako
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
@@ -69,12 +74,23 @@ jobs:
run: |
chcp 65001 #set code page to utf-8
echo ("LIEF_SAMPLES_DIR=" + $env:RUNNER_TEMP + "/samples") >> $env:GITHUB_ENV
- name: Build and Test
echo ("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 }}
run: |
python -m pip install pytest requests
python -m pip install -r tests/requirements.txt
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
python -m pip -vv install api/python
python ./tests/run_pytest.py
cd api/python
python ./setup.py build ^
--build-base=%BUILD_DIR%/base ^
--build-temp=%BUILD_DIR%/temp ^
install --user
shell: cmd
- name: Run tests
run: |
cd %GITHUB_WORKSPACE%
python tests/run_pytest.py
ctest --output-on-failure --test-dir %BUILD_DIR%/temp/Release
shell: cmd
+2 -8
View File
@@ -1,17 +1,11 @@
name: 'sanitize'
on:
push:
tags:
- '**'
schedule:
- cron: '0 0 * * 1'
workflow_dispatch:
on: workflow_dispatch
jobs:
gcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: compile
+249
View File
@@ -0,0 +1,249 @@
name: LIEF Windows
on: workflow_dispatch
env:
python-test-version: '3.10'
python-version: '3.9'
jobs:
build-sdk:
runs-on: windows-2019
strategy:
matrix:
arch: ['x64', 'x86']
fail-fast: false
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ env.python-version }}
architecture: ${{ matrix.arch }}
- name: Install system dependencies
run: |
choco install ninja
choco install sccache
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Setup sccache
uses: actions/cache@v3
continue-on-error: false
with:
path: ${{ vars.SCCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.arch }}-sccache-sdk-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-sccache-sdk
- name: Start sccache server
run: sccache --start-server
- name: Build SDK
run: |
python ./scripts/windows/package_sdk.py
- name: 'Upload SDK artifact'
uses: actions/upload-artifact@v3
with:
name: windows-${{ matrix.arch }}-sdk
path: build/*.zip
retention-days: 3
- name: 'Upload install artifact'
uses: actions/upload-artifact@v3
with:
name: windows-${{ matrix.arch }}-install
path: ${{ runner.temp }}/lief-install
retention-days: 1
- name: sccache stats
run: sccache --show-stats
- name: stop sccache server
run: sccache --stop-server || true
tests:
runs-on: windows-2019
if: "!contains(github.event.commits[0].message, '[skip-test]')"
strategy:
matrix:
arch: ['x64']
fail-fast: false
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ env.python-test-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.python-test-version }}
architecture: ${{ matrix.arch }}
- name: Install system dependencies
run: |
choco install ninja
choco install sccache
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Setup sccache
uses: actions/cache@v3
continue-on-error: false
with:
path: ${{ vars.SCCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.arch }}-sccache-test-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-sccache-test
- name: Start sccache server
run: sccache --start-server
- name: Set arch specific env
if: matrix.arch == 'x64'
run: |
echo "ARCH=x64" >> $env:GITHUB_ENV
- name: Set arch specific env
if: matrix.arch == 'x86'
run: |
echo "ARCH=x86" >> $env:GITHUB_ENV
- name: Set Python config (${{ matrix.arch }})
run: |
echo ("PYLIEF_CONF=" + $env:GITHUB_WORKSPACE + "/scripts/windows/py-" + $env:ARCH + "-test.toml") >> $env:GITHUB_ENV
- name: Set env variables
run: |
chcp 65001 #set code page to utf-8
echo ("LIEF_SAMPLES_DIR=" + $env:RUNNER_TEMP + "/samples") >> $env:GITHUB_ENV
echo ("BUILD_DIR=" + $env:RUNNER_TEMP + "/lief-build") >> $env:GITHUB_ENV
- name: Build Python ${{ env.python-test-version }}
run: |
python -m pip install -r tests/requirements.txt
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
cd api/python
python ./setup.py build ^
--build-base=%BUILD_DIR%/base ^
--build-temp=%BUILD_DIR%/temp ^
install --user
shell: cmd
- name: Run tests
run: |
cd %GITHUB_WORKSPACE%
python tests/run_pytest.py
ctest --output-on-failure --test-dir %BUILD_DIR%/temp/Release
shell: cmd
- name: sccache stats
run: sccache --show-stats
- name: stop sccache server
run: sccache --stop-server || true
wheels:
runs-on: windows-2019
needs: build-sdk
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11', '3.12-dev']
arch: ['x86', 'x64']
fail-fast: false
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.arch }}
- name: Install system dependencies
run: |
choco install ninja
choco install sccache
python -m pip install --upgrade pip setuptools wheel
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- 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@v3
continue-on-error: false
with:
path: ${{ vars.SCCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.arch }}-sccache-${{ matrix.python-version }}-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-sccache-${{ matrix.python-version }}
- name: Download LIEF install dir
uses: actions/download-artifact@v3
with:
name: windows-${{ matrix.arch }}-install
path: ~/lief-${{ matrix.arch }}-install
- name: Start sccache server
run: sccache --start-server
- name: Upgrade pip
run: |
python -m pip install --upgrade pip
shell: cmd
- name: Set arch specific env
if: matrix.arch == 'x64'
run: |
echo "ARCH=x64" >> $env:GITHUB_ENV
- name: Set arch specific env
if: matrix.arch == 'x86'
run: |
echo "ARCH=x86" >> $env:GITHUB_ENV
- name: Set Python config (${{ matrix.arch }})
run: |
echo ("PYLIEF_CONF=" + $env:GITHUB_WORKSPACE + "/scripts/windows/py-" + $env:ARCH + ".toml") >> $env:GITHUB_ENV
- name: Set env variables
run: |
chcp 65001 #set code page to utf-8
- name: Build Python ${{ matrix.python-version }}
run: |
python -m pip -vv wheel --wheel-dir=dist/ api/python
shell: cmd
- name: 'Upload Python artifacts [${{ matrix.python-version }}]'
uses: actions/upload-artifact@v3
with:
name: windows-${{ matrix.arch }}-wheel-${{ matrix.python-version }}
path: dist/*.whl
retention-days: 3
deploy:
if: ${{ always() }}
runs-on: ubuntu-latest
needs: [build-sdk, wheels]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}/artifacts
- name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
shell: bash
run: |
docker run --rm \
-v $GITHUB_WORKSPACE:/src \
-v $RUNNER_TEMP:/runner_tmp \
-e GITHUB_ACTIONS="true" \
-e GITHUB_WORKSPACE=$GITHUB_WORKSPACE \
-e GITHUB_REF=$GITHUB_REF \
-e GITHUB_REPOSITORY=$GITHUB_REPOSITORY \
-e LIEF_S3_KEY=$LIEF_S3_KEY \
-e LIEF_S3_SECRET=$LIEF_S3_SECRET \
liefproject/deploy python3 /src/.github/deploy.py /runner_tmp/artifacts
@@ -1,55 +1,49 @@
name: LIEF Windows Quick
on: workflow_dispatch
name: LIEF Windows x86 Quick
on:
push:
branches:
- '**'
- '!master'
- '!release-**'
tags-ignore:
- "**"
env:
python-version: '3.9'
jobs:
build:
quick-test:
runs-on: windows-2019
strategy:
matrix:
python-version: [3.9]
arch: [x64, x86]
fail-fast: false
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
SCCACHE_DIR: ${{ vars.SCCACHE_DIR }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
- name: Set up Python ${{ env.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
architecture: x86
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 setuptools
python -m pip install wheel mako
python -m pip install --upgrade pip setuptools wheel
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
echo "date=$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
shell: bash
- name: Save sccache
uses: actions/cache@v3
continue-on-error: false
with:
path: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
key: ${{ runner.os }}-x86-sccache-${{ steps.get-date.outputs.date }}
path: ${{ vars.SCCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.arch }}-quick-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-x86-sccache-
${{ runner.os }}-${{ matrix.arch }}-quick
- name: Start sccache server
run: sccache --start-server
- name: Set env variables
@@ -60,14 +54,17 @@ jobs:
run: |
python -m pip install --upgrade pip
shell: cmd
- name: ⛓ Build Python ${{ matrix.python-version }} & Test
- name: Build Python ${{ env.python-version }}
run: |
python -m pip install pytest requests
python -m pip install -r tests/requirements.txt
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
python -m pip -vv install api/python
shell: cmd
- name: Run tests
run: |
python ./tests/run_pytest.py
shell: cmd
- name: 📊 Print sccache stats
- name: sccache stats
run: sccache --show-stats
- name: 🛑 Stop sccache server
- name: sccache server
run: sccache --stop-server || true
-130
View File
@@ -1,130 +0,0 @@
name: LIEF Windows x64
on:
push:
branches:
- 'master'
- 'release-**'
tags:
- '**'
jobs:
build:
runs-on: windows-2019
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11.0']
fail-fast: false
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: x64
- name: Install system dependencies
run: |
choco install ninja
choco install sccache
python -m pip install --upgrade pip setuptools
python -m pip install wheel mako
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
shell: bash
- name: Save sccache
uses: actions/cache@v3
continue-on-error: false
with:
path: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
key: ${{ runner.os }}-x64-sccache-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-x64-sccache-
- 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: Upgrade pip
run: |
python -m pip install --upgrade pip
shell: cmd
- name: ⛓ Build Python ${{ matrix.python-version }} & Test
if: matrix.python-version == 3.8
run: |
python -m pip install pytest requests
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
python -m pip -vv wheel --wheel-dir=dist/ api/python
python -m pip -vv install api/python
python ./tests/run_pytest.py
python ./scripts/windows/run_ctest.py ./api/python/build/temp.win-amd64-cpython-38/Release
python ./tests/run_tools_check.py ./api/python/build/temp.win-amd64-cpython-38/Release
shell: cmd
- name: ❱ Build Python ${{ matrix.python-version }}
if: matrix.python-version != 3.8
run: |
python -m pip -vv wheel --wheel-dir=dist/ api/python
shell: cmd
- name: ❱ Build SDK
if: matrix.python-version == 3.9
run: |
python ./scripts/windows/package_sdk.py
- name: 'Upload SDK Artifact'
if: matrix.python-version == 3.9
uses: actions/upload-artifact@v3
with:
name: windows-x64-sdk
path: build/*.zip
retention-days: 3
- name: 'Upload Python Wheel Artifact - ${{ matrix.python-version }}'
uses: actions/upload-artifact@v3
with:
name: windows-x64-wheel-${{ matrix.python-version }}
path: dist/*.whl
retention-days: 3
- name: 📊 Print sccache stats
run: sccache --show-stats
- name: 🛑 Stop sccache server
run: sccache --stop-server || true
- name: Setup WSL
uses: Vampire/setup-wsl@v1
with:
distribution: Debian
use-cache: 'true'
wsl-shell-user: root
set-as-default: 'true'
wsl-conf: |
[automount]
options = "metadata"
additional-packages:
ca-certificates
curl
locales
python3 python3-pip
git
openssl
ssh
- shell: wsl-bash {0}
name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
GITHUB_ACTIONS: "true"
GITHUB_WORKSPACE: ${{ env.GITHUB_WORKSPACE }}
GITHUB_REF: ${{ env.GITHUB_REF }}
GITHUB_REPOSITORY: ${{ env.GITHUB_REPOSITORY }}
WSLENV: LIEF_S3_KEY:LIEF_S3_SECRET:GITHUB_ACTIONS:GITHUB_WORKSPACE:GITHUB_REF:GITHUB_REPOSITORY
run: |
python3 -m pip install --no-cache-dir --upgrade pip setuptools requests mako wheel boto3
python3 .github/deploy.py
-73
View File
@@ -1,73 +0,0 @@
name: LIEF Windows x64 Quick
on:
push:
branches:
- '**'
- '!master'
- '!release-**'
tags-ignore:
- "**"
jobs:
build:
runs-on: windows-2019
strategy:
matrix:
python-version: [3.9]
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: x64
- name: Install system dependencies
run: |
choco install ninja
choco install sccache
python -m pip install --upgrade pip setuptools
python -m pip install wheel mako
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
shell: bash
- name: Save sccache
uses: actions/cache@v3
continue-on-error: false
with:
path: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
key: ${{ runner.os }}-x64-sccache-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-x64-sccache-
- 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: Upgrade pip
run: |
python -m pip install --upgrade pip
shell: cmd
- name: ⛓ Build Python ${{ matrix.python-version }} & Test
run: |
python -m pip install pytest requests
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
python -m pip -vv install api/python
python ./tests/run_pytest.py
shell: cmd
- name: 📊 Print sccache stats
run: sccache --show-stats
- name: 🛑 Stop sccache server
run: sccache --stop-server || true
-131
View File
@@ -1,131 +0,0 @@
name: LIEF Windows x86
on:
push:
branches:
- 'master'
- 'release-**'
- 'devel'
tags:
- '**'
jobs:
build:
runs-on: windows-2019
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11.0']
fail-fast: false
env:
SCCACHE_CACHE_SIZE: 2G
SCCACHE_DIR: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
architecture: x86
- name: Install system dependencies
run: |
choco install ninja
choco install sccache
python -m pip install --upgrade pip setuptools
python -m pip install wheel mako
- uses: ilammy/msvc-dev-cmd@v1
with:
toolset: "14.16"
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m-%d-%H;%M;%S")"
shell: bash
- name: Save sccache
uses: actions/cache@v3
continue-on-error: false
with:
path: "C:\\Users\\runner\\AppData\\Local\\Mozilla\\sccache"
key: ${{ runner.os }}-x86-sccache-${{ steps.get-date.outputs.date }}
restore-keys: |
${{ runner.os }}-x86-sccache-
- 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: Set env variables
run: |
chcp 65001 #set code page to utf-8
echo ("PYLIEF_CONF=" + $env:GITHUB_WORKSPACE + "/scripts/windows/config-win32.toml") >> $env:GITHUB_ENV
- name: Upgrade pip
run: |
python -m pip install --upgrade pip
shell: cmd
- name: ⛓ Build Python ${{ matrix.python-version }} & Test
if: matrix.python-version == 3.8
run: |
python -m pip install pytest requests
python tests/dl_samples.py %LIEF_SAMPLES_DIR%
python -m pip -vv wheel --wheel-dir=dist/ api/python
python -m pip -vv install api/python
python ./tests/run_pytest.py
shell: cmd
- name: ❱ Build Python ${{ matrix.python-version }}
if: matrix.python-version != 3.8
run: |
python -m pip -vv wheel --wheel-dir=dist/ api/python
shell: cmd
- name: ❱ Build SDK
if: matrix.python-version == 3.9
run: |
python ./scripts/windows/package_sdk.py
- name: 'Upload SDK Artifact'
if: matrix.python-version == 3.9
uses: actions/upload-artifact@v3
with:
name: windows-x86-sdk
path: build/*.zip
retention-days: 3
- name: 'Upload Python Wheel Artifact - ${{ matrix.python-version }}'
uses: actions/upload-artifact@v3
with:
name: windows-x86-wheel-${{ matrix.python-version }}
path: dist/*.whl
retention-days: 3
- name: 📊 Print sccache stats
run: sccache --show-stats
- name: 🛑 Stop sccache server
run: sccache --stop-server || true
- name: Setup WSL
uses: Vampire/setup-wsl@v1
with:
distribution: Debian
use-cache: 'true'
wsl-shell-user: root
set-as-default: 'true'
wsl-conf: |
[automount]
options = "metadata"
additional-packages:
ca-certificates
curl
locales
python3 python3-pip
git
openssl
ssh
- shell: wsl-bash {0}
name: Deploy
env:
LIEF_S3_KEY: ${{ secrets.LIEF_S3_KEY }}
LIEF_S3_SECRET: ${{ secrets.LIEF_S3_SECRET }}
GITHUB_ACTIONS: "true"
GITHUB_WORKSPACE: ${{ env.GITHUB_WORKSPACE }}
GITHUB_REF: ${{ env.GITHUB_REF }}
GITHUB_REPOSITORY: ${{ env.GITHUB_REPOSITORY }}
WSLENV: LIEF_S3_KEY:LIEF_S3_SECRET:GITHUB_ACTIONS:GITHUB_WORKSPACE:GITHUB_REF:GITHUB_REPOSITORY
run: |
python3 -m pip install --no-cache-dir --upgrade pip setuptools requests mako wheel boto3
python3 .github/deploy.py
+19 -36
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.15)
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
cmake_policy(SET CMP0135 NEW)
endif()
@@ -27,7 +27,7 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git"
include(LIEFGit)
else()
set(LIEF_VERSION_MAJOR "0")
set(LIEF_VERSION_MINOR "13")
set(LIEF_VERSION_MINOR "14")
set(LIEF_VERSION_PATCH "0")
endif()
@@ -203,7 +203,10 @@ source_group("Source Files" FILES ${LIBLIEF_SOURCE_FILES})
source_group("Header Files\\visitors" FILES ${LIEF_VISITOR_INCLUDE_FILES})
add_library(LIB_LIEF ${LIBLIEF_SOURCE_FILES} ${LIEF_INCLUDE_FILES})
add_library(LIEF::LIEF ALIAS LIB_LIEF)
if(NOT LIEF_PY_LIEF_EXT)
add_library(LIEF::LIEF ALIAS LIB_LIEF)
endif()
if(NOT LIEF_OPT_MBEDTLS_EXTERNAL)
set_source_files_properties(${mbedtls_src_crypto} PROPERTIES GENERATED TRUE)
@@ -254,9 +257,6 @@ if(BUILD_SHARED_LIBS OR LIEF_FORCE_API_EXPORTS)
else()
target_compile_definitions(LIB_LIEF PRIVATE -DLIEF_STATIC)
endif()
if(LIEF_SUPPORT_CXX14)
target_compile_features(LIB_LIEF PRIVATE cxx_std_14)
endif()
# Abstract part
include("${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/CMakeLists.txt")
@@ -299,10 +299,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
target_compile_definitions(LIB_LIEF PRIVATE SPDLOG_NO_THREAD_ID)
endif()
# Frozen Configuration
# ====================
if(LIEF_FROZEN_ENABLED)
endif()
# OAT part
# ========
@@ -399,29 +395,28 @@ if(LIEF_FROZEN_ENABLED)
endif()
endif()
# =======================================
# Leaf
# Expected
# =======================================
if(LIEF_EXTERNAL_LEAF)
message(STATUS "Using external LEAF version")
if(LIEF_EXTERNAL_LEAF_DIR)
message(STATUS "External LEAF include dir: ${LIEF_EXTERNAL_LEAF_DIR}")
target_include_directories(LIB_LIEF SYSTEM PUBLIC
"$<BUILD_INTERFACE:${LIEF_EXTERNAL_LEAF_DIR}>")
endif()
if(LIEF_EXTERNAL_EXPECTED)
message(STATUS "Using external Expected version")
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/leaf.hpp
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 ${LEAF_SRC_DIR}/
${CMAKE_COMMAND} -E copy_directory ${EXPECTED_SRC_DIR}/include/tl/
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/
DEPENDS lief_leaf)
DEPENDS lief_expected)
target_sources(LIB_LIEF PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/leaf.hpp)
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/expected.hpp)
endif()
# =======================================
# utfcpp
# =======================================
@@ -465,8 +460,6 @@ else()
${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/internal/span.hpp)
endif()
target_link_libraries(LIB_LIEF PRIVATE lief_spdlog)
if(ANDROID AND BUILD_SHARED_LIBS AND LIEF_LOGGING)
@@ -480,7 +473,7 @@ endif()
set_target_properties(
LIB_LIEF
PROPERTIES POSITION_INDEPENDENT_CODE ON
CXX_STANDARD 11
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_VISIBILITY_PRESET hidden
C_VISIBILITY_PRESET hidden)
@@ -565,20 +558,10 @@ endif()
include(LIEFCompilerFlags)
# Profiling flags
# ---------------
if(LIEF_PROFILING)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/profiling")
endif()
# Coverage flags
# --------------
if(LIEF_COVERAGE)
target_compile_options(LIB_LIEF PRIVATE -g -O0 --coverage -fprofile-arcs
-ftest-coverage)
target_link_libraries(LIB_LIEF gcov)
endif()
set_target_properties(LIB_LIEF PROPERTIES
OUTPUT_NAME LIEF
EXPORT_NAME LIEF
@@ -651,7 +634,7 @@ endif()
# Generate install target and package
# =======================================
if (LIEF_INSTALL)
if(LIEF_INSTALL)
# Find Package Config
# ======================
+15 -15
View File
@@ -3,32 +3,32 @@
</p>
<p align="center">
<a href="https://gitter.im/lief-project">
<img src="https://img.shields.io/gitter/room/gitterHQ/gitter.svg?style=flat-square">
<a href="https://discord.gg/7hRFGWYedu">
<img src="https://img.shields.io/discord/1117013848914931762">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/actions?query=workflow%3A%22Linux+x86-64%22">
<a href="https://github.com/lief-project/LIEF/actions/workflows/linux-x86-64.yml">
<img alt="Linux x86-64 CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/linux-x86-64.yml?branch=master&label=Linux%20x86-64&logo=github">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/actions?query=workflow%3A%22Linux+AArch64%22">
<a href="https://github.com/lief-project/LIEF/actions/workflows/linux-aarch64.yml">
<img alt="Linux AArch64 CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/linux-aarch64.yml?branch=master&label=Linux%20AArch64&logo=github">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/actions?query=workflow%3AAndroid">
<a href="https://github.com/lief-project/LIEF/actions/workflows/android.yml">
<img alt="Android CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/android.yml?branch=master&label=Android&logo=github">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/actions?query=workflow%3AmacOS">
<a href="https://github.com/lief-project/LIEF/actions/workflows/osx.yml">
<img alt="macOS CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/osx.yml?branch=master&label=macOS&logo=github">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/actions?query=workflow%3AiOS">
<a href="https://github.com/lief-project/LIEF/actions/workflows/ios.yml">
<img alt="iOS CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/ios.yml?branch=master&label=iOS&logo=github">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/actions/workflows/windows-x64-all.yml">
<img alt="Windows CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/windows-x64-all.yml?branch=master&label=Windows&logo=github">
<a href="https://github.com/lief-project/LIEF/actions/workflows/windows-all.yml">
<img alt="Windows CI status" src="https://img.shields.io/github/actions/workflow/status/lief-project/LIEF/windows-all.yml?branch=master&label=Windows&logo=github">
</a>
&nbsp;
<a href="https://github.com/lief-project/LIEF/releases">
@@ -36,7 +36,7 @@
</a>
&nbsp;
<a href="https://twitter.com/LIEF_project">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/lief_project?color=1da1f2&label=Follow&logo=twitter&logoColor=white&style=flat-square">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/lief_project">
</a>
</p>
@@ -44,7 +44,7 @@
<p align="center">
<a href="https://lief-project.github.io/blog/"><b>Blog</b></a> •
<a href="https://lief-project.github.io/doc/latest/index.html"><b>Documentation</b></a> •
<a href="#about-A"><b>About</b></a>
<a href="#user-content-about-1"><b>About</b></a>
</p>
<br />
@@ -105,7 +105,7 @@ pip install lief
To install nightly build:
```console
pip install [--user] --index-url https://lief.s3-website.fr-par.scw.cloud/latest lief==0.13.0.dev0
pip install [--user] --index-url https://lief.s3-website.fr-par.scw.cloud/latest lief==0.14.0.dev0
```
### Packages
@@ -113,7 +113,7 @@ pip install [--user] --index-url https://lief.s3-website.fr-par.scw.cloud/latest
- **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.12.3**: https://github.com/lief-project/LIEF/releases/tag/0.12.3
- **v0.13.2**: https://github.com/lief-project/LIEF/releases/tag/0.13.2
Here are guides to install or integrate LIEF:
@@ -197,7 +197,7 @@ int main(int argc, char** argv) {
## Contact
* **Mail**: contact at lief re
* **Gitter**: [lief-project](https://gitter.im/lief-project)
* **Discord**: [LIEF](https://discord.gg/7hRFGWYedu)
## About
@@ -207,7 +207,7 @@ Romain Thomas ([@rh0main](https://twitter.com/rh0main)) - [Quarkslab](https://ww
### License
LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.12.3/LICENSE).
LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.13.0/LICENSE).
### Bibtex
-1
View File
@@ -36,7 +36,6 @@ namespace LIEF {
namespace ELF {
void init_c_binary(Elf_Binary_t* c_binary, Binary* binary) {
c_binary->handler = reinterpret_cast<void*>(binary);
c_binary->name = binary->name().c_str();
c_binary->type = static_cast<enum LIEF_ELF_ELF_CLASS>(binary->type());
c_binary->interpreter = nullptr;
if (binary->has_interpreter()) {
-1
View File
@@ -32,7 +32,6 @@ namespace MachO {
void init_c_binary(Macho_Binary_t* c_binary, Binary* binary) {
c_binary->handler = reinterpret_cast<void*>(binary);
c_binary->name = binary->name().c_str();
c_binary->imagebase = binary->imagebase();
init_c_header(c_binary, binary);
init_c_commands(c_binary, binary);
-1
View File
@@ -34,7 +34,6 @@ namespace LIEF {
namespace PE {
void init_c_binary(Pe_Binary_t* c_binary, Binary* binary) {
c_binary->name = binary->name().c_str();
c_binary->handler = reinterpret_cast<void*>(binary);
init_c_dos_header(c_binary, binary);
+1 -1
View File
@@ -16,7 +16,7 @@
#ifndef C_LIEF_ELF_H_
#define C_LIEF_ELF_H_
//! @defgroup elf_c_api ELF C API
/** @defgroup elf_c_api ELF C API */
#include "LIEF/ELF/Binary.h"
#include "LIEF/ELF/Symbol.h"
+3 -3
View File
@@ -6,9 +6,9 @@
extern "C" {
#endif
#define _LIEF_EN(N) LIEF_ELF_##N // enum LIEF_N {
#define _LIEF_EN_2(N, TYPE) LIEF_ELF_##N // enum LIEF_N {
#define _LIEF_EI(X) LIEF_ELF_##X // LIEF_X
#define _LIEF_EN(N) LIEF_ELF_##N
#define _LIEF_EN_2(N, TYPE) LIEF_ELF_##N
#define _LIEF_EI(X) LIEF_ELF_##X
#include "LIEF/ELF/enums.inc"
+1 -1
View File
@@ -16,7 +16,7 @@
#ifndef C_LIEF_MACHO_H_
#define C_LIEF_MACHO_H_
//! @defgroup macho_c_api MachO C API
/** @defgroup macho_c_api MachO C API */
#include "LIEF/MachO/Binary.h"
#include "LIEF/MachO/Symbol.h"
+3 -3
View File
@@ -18,9 +18,9 @@ extern "C" {
#undef _LIEF_EI
#endif
#define _LIEF_EN(N) LIEF_MACHO_##N // enum LIEF_N {
#define _LIEF_EN_2(N, TYPE) LIEF_MACHO_##N // enum LIEF_N {
#define _LIEF_EI(X) LIEF_MACHO_##X // LIEF_X
#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"
+1 -1
View File
@@ -16,7 +16,7 @@
#ifndef C_LIEF_PE_H_
#define C_LIEF_PE_H_
//! @defgroup pe_c_api PE C API
/** @defgroup pe_c_api PE C API */
#include "LIEF/PE/Binary.h"
#include "LIEF/PE/EnumToString.h"
+3 -3
View File
@@ -6,9 +6,9 @@
extern "C" {
#endif
#define _LIEF_EN(N) LIEF_PE_##N // enum LIEF_N {
#define _LIEF_EN_2(N, TYPE) LIEF_PE_##N // enum LIEF_N {
#define _LIEF_EI(X) LIEF_PE_##X // LIEF_X
#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"
+70 -107
View File
@@ -1,16 +1,25 @@
cmake_minimum_required(VERSION 3.1)
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
if (LIEF_PY_LIEF_EXT)
find_package(LIEF REQUIRED COMPONENTS STATIC)
message(STATUS "Using pre-installed version of LIEF")
set(LIEF_TARGET LIEF::LIEF)
else()
set(LIEF_TARGET LIB_LIEF)
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()
include(ExternalProject)
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
macro(ADD_FLAG_IF_SUPPORTED flag name)
CHECK_C_COMPILER_FLAG("${flag}" "C_SUPPORTS_${name}")
CHECK_CXX_COMPILER_FLAG("${flag}" "CXX_SUPPORTS_${name}")
@@ -24,143 +33,102 @@ macro(ADD_FLAG_IF_SUPPORTED flag name)
endif()
endmacro()
add_library(lief_pybind11 INTERFACE)
if (LIEF_EXTERNAL_PYBIND11)
find_package(pybind11 REQUIRED)
find_package(PythonLibsNew MODULE REQUIRED)
target_link_libraries(lief_pybind11 INTERFACE pybind11::module)
get_target_property(PYBIND_INC_DIR pybind11::module INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(lief_pybind11 SYSTEM INTERFACE ${PYBIND_INC_DIR} ${Python_INCLUDE_DIRS})
if (LIEF_EXTERNAL_NANOBINDS)
find_package(nanobind REQUIRED)
else()
find_package(PythonLibsNew MODULE REQUIRED)
set(PYBIND11_VERSION 2.10.1)
set(PYBIND11_SHA256 SHA256=fcf94065efcfd0a7a828bacf118fa11c43f6390d0c805e3e6342ac119f2e9976)
set(PYBIND11_URL "${THIRD_PARTY_DIRECTORY}/pybind11-${PYBIND11_VERSION}.zip" CACHE STRING "URL to the Pybind11 repo")
ExternalProject_Add(lief_pybind11_project
URL ${PYBIND11_URL}
URL_HASH ${PYBIND11_SHA256}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
add_dependencies(lief_pybind11 lief_pybind11_project)
ExternalProject_get_property(lief_pybind11_project SOURCE_DIR)
target_include_directories(lief_pybind11 SYSTEM INTERFACE "${SOURCE_DIR}/include")
set(NANOBIND_VERSION 1c462d6)
set(NANOBIND_SHA256 SHA256=84e8334c97aa870fa5531108f945b77c24ad30addf09f9cb40c04ffc1f6f757b)
set(NANOBIND_URL "${THIRD_PARTY_DIRECTORY}/nanobind-${NANOBIND_VERSION}.zip" CACHE STRING "URL to the Nanobind")
FetchContent_Declare(nanobind
URL ${NANOBIND_URL}
URL_HASH ${NANOBIND_SHA256}
)
FetchContent_Populate(nanobind)
find_package(nanobind REQUIRED PATHS ${nanobind_SOURCE_DIR}/cmake NO_DEFAULT_PATH)
endif()
message(STATUS "Python version: ${PYTHON_VERSION}")
message(STATUS "Python lib: ${PYTHON_LIBRARY}")
message(STATUS "Python include: ${PYTHON_INCLUDE_DIR}")
message(STATUS "Python interpreter: ${PYTHON_EXECUTABLE}")
# Define source files
set(LIEF_PYTHON_BASIC_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyLIEF.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyUtils.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyLogger.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyHash.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyObject.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyErr.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/encoding.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/PyIOStream.cpp"
)
list(APPEND LIEF_PYTHON_BASIC_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyJson.cpp")
message(STATUS "Python version: ${Python_VERSION}")
message(STATUS "Python lib: ${Python_LIBRARIES}")
message(STATUS "Python include: ${Python_INCLUDE_DIRS}")
message(STATUS "Python interpreter: ${Python_EXECUTABLE}")
set(LIEF_PYTHON_SRC
${LIEF_PYTHON_BASIC_SRC}
)
set(LIEF_PYTHON_BASIC_HDR
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyErr.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyIterators.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyLIEF.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/enums_wrapper.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/encoding.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/PyIOStream.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyLIEF.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pySafeString.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyErr.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyIOStream.cpp"
)
set(LIEF_PYTHON_HDR
${LIEF_PYTHON_BASIC_HDR}
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyLIEF.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pyErr.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/pySafeString.hpp"
)
source_group("Header Files" FILES ${LIEF_PYTHON_BASIC_HDR})
nanobind_add_module(
pyLIEF
NB_STATIC
add_library(pyLIEF SHARED ${LIEF_PYTHON_SRC} ${LIEF_PYTHON_HDR})
${LIEF_PYTHON_SRC}
${LIEF_PYTHON_HDR}
# Do not default to -Os
NOMINSIZE
)
target_include_directories(pyLIEF PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/src"
)
target_include_directories(pyLIEF SYSTEM PRIVATE
"${PYTHON_INCLUDE_DIR}"
"${PYBIND11_SOURCE_DIR}/include")
include("${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/CMakeLists.txt")
add_subdirectory(src/Abstract)
add_subdirectory(src/platforms)
if(LIEF_ELF)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/ELF/CMakeLists.txt")
add_subdirectory(src/ELF)
endif()
if(LIEF_PE)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/PE/CMakeLists.txt")
add_subdirectory(src/PE)
endif()
if(LIEF_MACHO)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/MachO/CMakeLists.txt")
add_subdirectory(src/MachO)
endif()
if(LIEF_OAT)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/OAT/CMakeLists.txt")
add_subdirectory(src/OAT)
endif()
if(LIEF_DEX)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/DEX/CMakeLists.txt")
add_subdirectory(src/DEX)
endif()
if(LIEF_VDEX)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/VDEX/CMakeLists.txt")
add_subdirectory(src/VDEX)
endif()
if(LIEF_ART)
include("${CMAKE_CURRENT_SOURCE_DIR}/src/ART/CMakeLists.txt")
add_subdirectory(src/ART)
endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/CMakeLists.txt")
target_compile_features(pyLIEF PRIVATE cxx_attribute_deprecated)
set_target_properties(pyLIEF PROPERTIES
POSITION_INDEPENDENT_CODE ON
CXX_STANDARD 14
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_VISIBILITY_PRESET hidden
C_VISIBILITY_PRESET hidden
PREFIX ""
OUTPUT_NAME "lief"
)
set_target_properties(pyLIEF PROPERTIES PYTHON_VERSION ${PYTHON_VERSION})
set(PYLIEF_DEPS_LIBRARIES LIB_LIEF)
if(LIEF_COVERAGE)
target_compile_options(pyLIEF PRIVATE -g -O0 --coverage -fprofile-arcs -ftest-coverage)
set(PYLIEF_DEPS_LIBRARIES ${PYLIEF_DEPS_LIBRARIES} gcov)
endif()
ADD_FLAG_IF_SUPPORTED("-Wno-macro-redefined" NO_MACRO_REDEFINED)
ADD_FLAG_IF_SUPPORTED("-Wno-deprecated-declarations" NO_DEPRECATED_DECLARATIONS)
set_target_properties(pyLIEF PROPERTIES PREFIX "" OUTPUT_NAME "lief")
target_link_libraries(pyLIEF PRIVATE lief_pybind11 lief_spdlog)
set_target_properties(pyLIEF PROPERTIES PYTHON_VERSION ${Python_VERSION})
target_link_libraries(pyLIEF PUBLIC ${LIEF_TARGET})
if(APPLE)
set_target_properties(pyLIEF PROPERTIES
MACOSX_RPATH ON
LINK_FLAGS "-undefined dynamic_lookup "
)
set_target_properties(pyLIEF PROPERTIES
MACOSX_RPATH ON
LINK_FLAGS "-undefined dynamic_lookup "
)
endif()
set_target_properties(pyLIEF PROPERTIES PREFIX "")
@@ -175,24 +143,19 @@ get_target_property(suffix pyLIEF SUFFIX)
set(LIEF_LIBRARY_NAME "lief${suffix}")
if (WIN32)
set(PYLIEF_DEPS_LIBRARIES ${PYLIEF_DEPS_LIBRARIES} ${PYTHON_LIBRARIES})
target_link_libraries(pyLIEF PUBLIC ${PYTHON_LIBRARIES})
endif()
target_link_libraries(pyLIEF PUBLIC ${PYLIEF_DEPS_LIBRARIES})
if (CMAKE_BUILD_TYPE MATCHES Release AND UNIX AND NOT APPLE)
add_custom_command(
TARGET pyLIEF
COMMENT "Strip LIEF Python bindings"
POST_BUILD
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:pyLIEF>
)
add_custom_command(TARGET pyLIEF
COMMENT "Strip LIEF Python bindings"
POST_BUILD
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:pyLIEF>
)
endif()
if (CMAKE_BUILD_TYPE MATCHES Release AND APPLE)
add_custom_command(
TARGET pyLIEF
add_custom_command(TARGET pyLIEF
COMMENT "Strip LIEF Python bindings"
POST_BUILD
COMMAND ${CMAKE_STRIP} -x -S $<TARGET_FILE:pyLIEF>
@@ -200,12 +163,12 @@ if (CMAKE_BUILD_TYPE MATCHES Release AND APPLE)
endif()
add_custom_command(TARGET pyLIEF POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pyLIEF> ${PROJECT_BINARY_DIR}/api/python/lief
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pyLIEF> ${PROJECT_BINARY_DIR}/api/python/lief
)
if (MSVC)
add_custom_command(TARGET pyLIEF POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pyLIEF> ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pyLIEF> ${CMAKE_CURRENT_BINARY_DIR}
)
endif()
@@ -257,7 +257,7 @@ def main():
args = parser.parse_args()
lief.logging.set_level(args.main_verbosity)
if lief.PE.is_pe(args.file):
if lief.is_pe(args.file):
binary = None
try:
binary: lief.PE.Binary = lief.PE.parse(args.file)
+4 -2
View File
@@ -13,8 +13,7 @@ def bin2lib(binary, address, output, name=""):
print(function)
binary.write(output)
if __name__ == "__main__":
def main():
parser = argparse.ArgumentParser(description="")
parser.add_argument("--name", "-n", default="", help="Name of the function to create")
@@ -27,3 +26,6 @@ if __name__ == "__main__":
args = parser.parse_args()
binary = lief.parse(args.binary)
bin2lib(binary, args.address, args.output, name=args.name)
if __name__ == "__main__":
main()
+2 -2
View File
@@ -6,7 +6,7 @@
# Print information about a ELF binary in the JSON format
#
# python elf_json.py /bin/ls
#  
#
# {
# "dynamic_entries": [
# {
@@ -19,7 +19,7 @@
# "tag": "NEEDED",
# "value": 74
# },
# ...
# ...
import argparse
+7 -5
View File
@@ -71,6 +71,9 @@ def print_header(binary):
if header.machine_type == lief.ELF.ARCH.HEXAGON:
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])
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]))
@@ -251,13 +254,13 @@ def print_relocations(binary, relocations):
for relocation in relocations:
type = str(relocation.type)
if binary.header.machine_type == ELF.ARCH.x86_64:
type = str(ELF.RELOCATION_X86_64(relocation.type))
type = str(relocation.type)
elif binary.header.machine_type == ELF.ARCH.i386:
type = str(ELF.RELOCATION_i386(relocation.type))
type = str(relocation.type)
elif binary.header.machine_type == ELF.ARCH.ARM:
type = str(ELF.RELOCATION_ARM(relocation.type))
type = str(relocation.type)
elif binary.header.machine_type == ELF.ARCH.AARCH64:
type = str(ELF.RELOCATION_AARCH64(relocation.type))
type = str(relocation.type)
symbol_name = ""
if relocation.has_symbol:
@@ -328,7 +331,6 @@ def print_information(binary):
format_str = "{:<30} {:<30}"
format_hex = "{:<30} 0x{:<28x}"
format_dec = "{:<30} {:<30d}"
print(format_str.format("Name:", binary.name))
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)))
@@ -2,21 +2,21 @@
# -*- coding: utf-8 -*-
# Description
# -----------
# -----------
# Remove the section table from an ELF binary
# so that some tools are blow minded (e.g. gdb)
# so that some tools are blow minded (e.g. gdb)
#
# Example:
# 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
# $ 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
# "ls_without_sections": not in executable format: File format not recognized
import sys
import lief
@@ -31,11 +31,13 @@ def remove_section_table(filename, output):
binary.write(output);
if __name__ == "__main__":
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])
if __name__ == "__main__":
main()
@@ -48,7 +48,7 @@ def randomize(binary, output):
binary.write(output)
if __name__ == '__main__':
def main():
if len(sys.argv) != 3:
print("Usage:", sys.argv[0], "<elf binary> <output binary>")
sys.exit(-1)
@@ -56,4 +56,7 @@ if __name__ == '__main__':
binary = lief.parse(sys.argv[1])
randomize(binary, sys.argv[2])
if __name__ == '__main__':
main()
+41 -37
View File
@@ -4,54 +4,58 @@
# Description
# -----------
# In this example, we assume that we found
# the ``main`` function at address 0x402A00
# the ``main`` function at address 0x402A00
# and we add a static symbol to the binary
# so that we can do:
# so that we can do:
#
# (gdb) break main
# Breakpoint 1 at 0x402a00
# (gdb) break main
# Breakpoint 1 at 0x402a00
from lief import ELF
import sys
binary = ELF.parse(sys.argv[1])
symtab_section = ELF.Section()
symtab_section.name = ""
symtab_section.type = ELF.SECTION_TYPES.SYMTAB
symtab_section.entry_size = 0x18
symtab_section.alignment = 8
symtab_section.link = len(binary.sections) + 1
symtab_section.content = [0] * 100
def main():
binary = ELF.parse(sys.argv[1])
symstr_section = ELF.Section()
symstr_section.name = ""
symstr_section.type = ELF.SECTION_TYPES.STRTAB
symstr_section.entry_size = 1
symstr_section.alignment = 1
symstr_section.content = [0] * 100
symtab_section = ELF.Section()
symtab_section.name = ""
symtab_section.type = ELF.SECTION_TYPES.SYMTAB
symtab_section.entry_size = 0x18
symtab_section.alignment = 8
symtab_section.link = len(binary.sections) + 1
symtab_section.content = [0] * 100
symtab_section = binary.add(symtab_section, loaded=False)
symstr_section = binary.add(symstr_section, loaded=False)
symstr_section = ELF.Section()
symstr_section.name = ""
symstr_section.type = ELF.SECTION_TYPES.STRTAB
symstr_section.entry_size = 1
symstr_section.alignment = 1
symstr_section.content = [0] * 100
symbol = ELF.Symbol()
symbol.name = ""
symbol.type = ELF.SYMBOL_TYPES.NOTYPE
symbol.value = 0
symbol.binding = ELF.SYMBOL_BINDINGS.LOCAL
symbol.size = 0
symbol.shndx = 0
symbol = binary.add_static_symbol(symbol)
symtab_section = binary.add(symtab_section, loaded=False)
symstr_section = binary.add(symstr_section, loaded=False)
symbol = ELF.Symbol()
symbol.name = "main"
symbol.type = ELF.SYMBOL_TYPES.FUNC
symbol.value = 0x402A00
symbol.binding = ELF.SYMBOL_BINDINGS.LOCAL
symbol.shndx = 14
symbol = binary.add_static_symbol(symbol)
symbol = ELF.Symbol()
symbol.name = ""
symbol.type = ELF.SYMBOL_TYPES.NOTYPE
symbol.value = 0
symbol.binding = ELF.SYMBOL_BINDINGS.LOCAL
symbol.size = 0
symbol.shndx = 0
symbol = binary.add_static_symbol(symbol)
print(symbol)
symbol = ELF.Symbol()
symbol.name = "main"
symbol.type = ELF.SYMBOL_TYPES.FUNC
symbol.value = 0x402A00
symbol.binding = ELF.SYMBOL_BINDINGS.LOCAL
symbol.shndx = 14
symbol = binary.add_static_symbol(symbol)
binary.write(sys.argv[2])
print(symbol)
binary.write(sys.argv[2])
if __name__ == "__main__":
main()
+6 -25
View File
@@ -60,7 +60,6 @@ def print_information(binary):
cpu = str(header.cpu_type).split('.')[-1]
print(format_str.format("Name:", binary.name))
print(format_hex.format("Address base:", binary.imagebase))
print(format_str.format("PIE:", str(binary.is_pie)))
print(format_str.format("NX:", str(binary.has_nx)))
@@ -599,26 +598,11 @@ def print_relocations(binary):
for reloc in binary.relocations:
type_str = ""
if reloc.origin == lief.MachO.RELOCATION_ORIGINS.DYLDINFO:
type_str = str(lief.MachO.REBASE_TYPES(reloc.type)).split(".")[-1]
if reloc.origin == lief.MachO.RELOCATION_ORIGINS.RELOC_TABLE:
if reloc.architecture == MachO.CPU_TYPES.x86:
type_str = str(MachO.X86_RELOCATION(reloc.type))
if reloc.architecture == MachO.CPU_TYPES.x86_64:
type_str = str(MachO.X86_64_RELOCATION(reloc.type))
if reloc.architecture == MachO.CPU_TYPES.ARM:
type_str = str(MachO.ARM_RELOCATION(reloc.type))
if reloc.architecture == MachO.CPU_TYPES.ARM64:
type_str = str(MachO.ARM64_RELOCATION(reloc.type))
if reloc.architecture == MachO.CPU_TYPES.POWERPC:
type_str = str(MachO.PPC_RELOCATION(reloc.type))
type_str = type_str.split(".")[-1]
rtype = reloc.type
if isinstance(rtype, int):
type_str = str(rtype)
else:
type_str = str(rtype).split(".")[-1]
symbol_name = ""
if reloc.has_symbol:
@@ -1020,9 +1004,6 @@ def main():
if args.show_chained_fixups or args.show_all:
print_chained_fixups(binary)
sys.exit(EXIT_STATUS)
if __name__ == "__main__":
main()
sys.exit(EXIT_STATUS)
+13 -14
View File
@@ -41,7 +41,6 @@ def print_information(binary):
print("== Information ==\n")
format_str = "{:<30} {:<30}"
format_hex = "{:<30} 0x{:<28x}"
print(format_str.format("Name:", binary.name))
print(format_hex.format("Virtual size:", binary.virtual_size))
print(format_str.format("Imphash:", PE.get_imphash(binary)))
print(format_str.format("PIE:", str(binary.is_pie)))
@@ -272,19 +271,20 @@ def print_debug(binary):
print(format_hex.format("Address of raw data:", debug.addressof_rawdata))
print(format_hex.format("Pointer to raw data:", debug.pointerto_rawdata))
if debug.has_code_view:
code_view = debug.code_view
if isinstance(debug, lief.PE.CodeViewPDB):
code_view: lief.PE.CodeViewPDB = debug
cv_signature = code_view.cv_signature
if cv_signature in (lief.PE.CODE_VIEW_SIGNATURES.PDB_70, lief.PE.CODE_VIEW_SIGNATURES.PDB_70):
sig_str = " ".join(map(lambda e : "{:02x}".format(e), code_view.signature))
print(format_str.format("Code View Signature:", str(cv_signature).split(".")[-1]))
print(format_str.format("Signature:", sig_str))
print(format_dec.format("Age:", code_view.age))
print(format_str.format("Filename:", code_view.filename))
if debug.has_pogo:
pogo = debug.pogo
sig_str = " ".join(map(lambda e : "{:02x}".format(e), code_view.signature))
print(format_str.format("Code View Signature:", str(cv_signature).split(".")[-1]))
print(format_str.format("Signature:", sig_str))
print(format_dec.format("Age:", code_view.age))
print(format_str.format("Filename:", code_view.filename))
elif isinstance(debug, lief.PE.CodeView):
code_view: lief.PE.CodeView = debug
cv_signature = code_view.cv_signature
print(format_str.format("Code View Signature:", str(cv_signature).split(".")[-1]))
elif isinstance(debug, lief.PE.Pogo):
pogo: lief.PE.Pogo = debug
sig_str = str(pogo.signature).split(".")[-1]
print(format_str.format("Signature:", sig_str))
print("Entries:")
@@ -293,7 +293,6 @@ def print_debug(binary):
print("\n")
@exceptions_handler(Exception)
def print_signature(binary):
format_str = "{:<33} {:<30}"
+7 -16
View File
@@ -1,4 +1,4 @@
from typing import ClassVar, List
from typing import Any, ClassVar
from typing import overload
import lief # type: ignore
@@ -31,7 +31,7 @@ class Header(lief.Object):
@property
def image_size(self) -> int: ...
@property
def magic(self) -> List[int]: ...
def magic(self) -> list[int]: ...
@property
def nb_methods(self) -> int: ...
@property
@@ -54,29 +54,20 @@ class Header(lief.Object):
def version(self) -> int: ...
class STORAGE_MODES:
__members__: ClassVar[dict] = ... # read-only
LZ4: ClassVar[STORAGE_MODES] = ...
LZ4HC: ClassVar[STORAGE_MODES] = ...
UNCOMPRESSED: ClassVar[STORAGE_MODES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
def android_version(art_version: int) -> lief.Android.ANDROID_VERSIONS: ...
@overload
def is_art(path: str) -> bool: ...
@overload
def is_art(raw: List[int]) -> bool: ...
@overload
def parse(filename: str) -> lief.ART.File: ...
@overload
def parse(raw: List[int], name: str = ...) -> lief.ART.File: ...
def parse(raw: list[int], name: str = ...) -> lief.ART.File: ...
@overload
def parse(io: object, name: str = ...) -> lief.ART.File: ...
def parse(io: object, name: str = ...) -> object: ...
@overload
def version(file: str) -> int: ...
@overload
def version(raw: List[int]) -> int: ...
def version(raw: list[int]) -> int: ...
+5 -6
View File
@@ -1,9 +1,8 @@
from typing import ClassVar
from typing import Any, ClassVar
import lief.Android # type: ignore
class ANDROID_VERSIONS:
__members__: ClassVar[dict] = ... # read-only
UNKNOWN: ClassVar[ANDROID_VERSIONS] = ...
VERSION_601: ClassVar[ANDROID_VERSIONS] = ...
VERSION_700: ClassVar[ANDROID_VERSIONS] = ...
@@ -12,10 +11,10 @@ class ANDROID_VERSIONS:
VERSION_800: ClassVar[ANDROID_VERSIONS] = ...
VERSION_810: ClassVar[ANDROID_VERSIONS] = ...
VERSION_900: ClassVar[ANDROID_VERSIONS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.Android.ANDROID_VERSIONS: ...
@property
def value(self) -> int: ...
+57 -76
View File
@@ -1,11 +1,10 @@
from typing import Any, ClassVar, Iterator, List, Tuple
from typing import Any, ClassVar
from typing import overload
import lief # type: ignore
import lief.DEX # type: ignore
class ACCESS_FLAGS:
__members__: ClassVar[dict] = ... # read-only
ABSTRACT: ClassVar[ACCESS_FLAGS] = ...
ANNOTATION: ClassVar[ACCESS_FLAGS] = ...
BRIDGE: ClassVar[ACCESS_FLAGS] = ...
@@ -26,39 +25,35 @@ class ACCESS_FLAGS:
UNKNOWN: ClassVar[ACCESS_FLAGS] = ...
VARARGS: ClassVar[ACCESS_FLAGS] = ...
VOLATILE: ClassVar[ACCESS_FLAGS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class Class(lief.Object):
class it_fields:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Field: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Field: ...
def __iter__(self) -> lief.DEX.Class.it_fields: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Field: ...
class it_methods:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Method: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Method: ...
def __iter__(self) -> lief.DEX.Class.it_methods: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Method: ...
class it_named_fields:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Field: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Field: ...
def __iter__(self) -> lief.DEX.Class.it_named_fields: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Field: ...
class it_named_methods:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Method: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Method: ...
def __iter__(self) -> lief.DEX.Class.it_named_methods: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Method: ...
def __init__(self, *args, **kwargs) -> None: ...
@@ -66,9 +61,9 @@ class Class(lief.Object):
def get_method(self, name: str) -> lief.DEX.Class.it_named_methods: ...
def has(self, flag: lief.DEX.ACCESS_FLAGS) -> bool: ...
@property
def access_flags(self) -> List[lief.DEX.ACCESS_FLAGS]: ...
def access_flags(self) -> list[lief.DEX.ACCESS_FLAGS]: ...
@property
def dex2dex_info(self) -> Any: ...
def dex2dex_info(self) -> dict[lief.DEX.Method,dict[int,int]]: ...
@property
def fields(self) -> lief.DEX.Class.it_fields: ...
@property
@@ -97,7 +92,7 @@ class Field(lief.Object):
def __init__(self, *args, **kwargs) -> None: ...
def has(self, flag: lief.DEX.ACCESS_FLAGS) -> bool: ...
@property
def access_flags(self) -> List[lief.DEX.ACCESS_FLAGS]: ...
def access_flags(self) -> list[lief.DEX.ACCESS_FLAGS]: ...
@property
def cls(self) -> lief.DEX.Class: ...
@property
@@ -114,43 +109,43 @@ class Field(lief.Object):
class File(lief.Object):
class it_classes:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Class: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Class: ...
def __iter__(self) -> lief.DEX.File.it_classes: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Class: ...
class it_fields:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Field: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Field: ...
def __iter__(self) -> lief.DEX.File.it_fields: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Field: ...
class it_methods:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Method: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Method: ...
def __iter__(self) -> lief.DEX.File.it_methods: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Method: ...
class it_prototypes:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Prototype: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Prototype: ...
def __iter__(self) -> lief.DEX.File.it_prototypes: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Prototype: ...
class it_strings:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> str: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> str: ...
def __iter__(self) -> lief.DEX.File.it_strings: ...
def __len__(self) -> int: ...
def __next__(self) -> str: ...
class it_types:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Type: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Type: ...
def __iter__(self) -> lief.DEX.File.it_types: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Type: ...
location: str
@@ -161,7 +156,7 @@ class File(lief.Object):
@overload
def get_class(self, classname: int) -> lief.DEX.Class: ...
def has_class(self, classname: str) -> bool: ...
def raw(self, deoptimize: bool = ...) -> List[int]: ...
def raw(self, deoptimize: bool = ...) -> list[int]: ...
def save(self, output: str = ..., deoptimize: bool = ...) -> str: ...
@property
def classes(self) -> lief.DEX.File.it_classes: ...
@@ -189,41 +184,40 @@ class Header(lief.Object):
@property
def checksum(self) -> int: ...
@property
def classes(self) -> Tuple[int,int]: ...
def classes(self) -> tuple[int,int]: ...
@property
def data(self) -> Tuple[int,int]: ...
def data(self) -> tuple[int,int]: ...
@property
def endian_tag(self) -> int: ...
@property
def fields(self) -> Tuple[int,int]: ...
def fields(self) -> tuple[int,int]: ...
@property
def file_size(self) -> int: ...
@property
def header_size(self) -> int: ...
@property
def link(self) -> Tuple[int,int]: ...
def link(self) -> tuple[int,int]: ...
@property
def magic(self) -> List[int]: ...
def magic(self) -> list[int]: ...
@property
def map_offset(self) -> int: ...
@property
def methods(self) -> Tuple[int,int]: ...
def methods(self) -> tuple[int,int]: ...
@property
def nb_classes(self) -> int: ...
@property
def nb_methods(self) -> int: ...
@property
def prototypes(self) -> Tuple[int,int]: ...
def prototypes(self) -> tuple[int,int]: ...
@property
def signature(self) -> List[int]: ...
def signature(self) -> list[int]: ...
@property
def strings(self) -> Tuple[int,int]: ...
def strings(self) -> tuple[int,int]: ...
@property
def types(self) -> Tuple[int,int]: ...
def types(self) -> tuple[int,int]: ...
class MapItem(lief.Object):
class TYPES:
__members__: ClassVar[dict] = ... # read-only
ANNOTATION: ClassVar[MapItem.TYPES] = ...
ANNOTATIONS_DIRECTORY: ClassVar[MapItem.TYPES] = ...
ANNOTATION_SET: ClassVar[MapItem.TYPES] = ...
@@ -244,10 +238,10 @@ class MapItem(lief.Object):
STRING_ID: ClassVar[MapItem.TYPES] = ...
TYPE_ID: ClassVar[MapItem.TYPES] = ...
TYPE_LIST: ClassVar[MapItem.TYPES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.DEX.MapItem.TYPES: ...
@property
def value(self) -> int: ...
def __init__(self, *args, **kwargs) -> None: ...
@@ -261,14 +255,14 @@ class MapItem(lief.Object):
class MapList(lief.Object):
class it_items_t:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.MapItem: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.MapItem: ...
def __iter__(self) -> lief.DEX.MapList.it_items_t: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.MapItem: ...
def __init__(self, *args, **kwargs) -> None: ...
def get(self, type: lief.DEX.MapItem.TYPES) -> lief.DEX.MapItem: ...
def has(self, type: lief.DEX.MapItem.TYPES) -> bool: ...
def __getitem__(self, arg0: lief.DEX.MapItem.TYPES) -> lief.DEX.MapItem: ...
def __getitem__(self, arg: lief.DEX.MapItem.TYPES, /) -> lief.DEX.MapItem: ...
@property
def items(self) -> lief.DEX.MapList.it_items_t: ...
@@ -277,9 +271,9 @@ class Method(lief.Object):
def has(self, flag: lief.DEX.ACCESS_FLAGS) -> bool: ...
def insert_dex2dex_info(self, pc: int, index: int) -> None: ...
@property
def access_flags(self) -> List[lief.DEX.ACCESS_FLAGS]: ...
def access_flags(self) -> list[lief.DEX.ACCESS_FLAGS]: ...
@property
def bytecode(self) -> List[int]: ...
def bytecode(self) -> list[int]: ...
@property
def cls(self) -> lief.DEX.Class: ...
@property
@@ -298,8 +292,8 @@ class Method(lief.Object):
class Prototype(lief.Object):
class it_params:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.Type: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.Type: ...
def __iter__(self) -> lief.DEX.Prototype.it_params: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.Type: ...
def __init__(self, *args, **kwargs) -> None: ...
@@ -310,7 +304,6 @@ class Prototype(lief.Object):
class Type(lief.Object):
class PRIMITIVES:
__members__: ClassVar[dict] = ... # read-only
BOOLEAN: ClassVar[Type.PRIMITIVES] = ...
BYTE: ClassVar[Type.PRIMITIVES] = ...
CHAR: ClassVar[Type.PRIMITIVES] = ...
@@ -320,27 +313,19 @@ class Type(lief.Object):
LONG: ClassVar[Type.PRIMITIVES] = ...
SHORT: ClassVar[Type.PRIMITIVES] = ...
VOID_T: ClassVar[Type.PRIMITIVES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class TYPES:
__members__: ClassVar[dict] = ... # read-only
ARRAY: ClassVar[Type.TYPES] = ...
CLASS: ClassVar[Type.TYPES] = ...
PRIMITIVE: ClassVar[Type.TYPES] = ...
UNKNOWN: ClassVar[Type.TYPES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
def __init__(self, *args, **kwargs) -> None: ...
def pretty_name(self, *args, **kwargs) -> Any: ...
@staticmethod
def pretty_name(primitive: lief.DEX.Type.PRIMITIVES) -> str: ...
@property
def dim(self) -> int: ...
@property
@@ -350,17 +335,13 @@ class Type(lief.Object):
@property
def value(self) -> object: ...
@overload
def is_dex(path: str) -> bool: ...
@overload
def is_dex(raw: List[int]) -> bool: ...
@overload
def parse(filename: str) -> lief.DEX.File: ...
@overload
def parse(raw: List[int], name: str = ...) -> lief.DEX.File: ...
def parse(raw: list[int], name: str = ...) -> lief.DEX.File: ...
@overload
def parse(io: object, name: str = ...) -> lief.DEX.File: ...
def parse(io: object, name: str = ...) -> object: ...
@overload
def version(file: str) -> int: ...
@overload
def version(raw: List[int]) -> int: ...
def version(raw: list[int]) -> int: ...
+537 -330
View File
File diff suppressed because it is too large Load Diff
+250 -244
View File
File diff suppressed because it is too large Load Diff
+40 -66
View File
@@ -1,4 +1,4 @@
from typing import Any, ClassVar, Iterator, List
from typing import Any, ClassVar
from typing import overload
import lief # type: ignore
@@ -10,29 +10,29 @@ import lief.OAT # type: ignore
class Binary(lief.ELF.Binary):
class it_classes:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.OAT.Class: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.OAT.Class: ...
def __iter__(self) -> lief.OAT.Binary.it_classes: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.OAT.Class: ...
class it_dex_files:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.DEX.File: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.DEX.File: ...
def __iter__(self) -> lief.OAT.Binary.it_dex_files: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.File: ...
class it_methods:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.OAT.Method: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.OAT.Method: ...
def __iter__(self) -> lief.OAT.Binary.it_methods: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.OAT.Method: ...
class it_oat_dex_files:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.OAT.DexFile: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.OAT.DexFile: ...
def __iter__(self) -> lief.OAT.Binary.it_oat_dex_files: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.OAT.DexFile: ...
def __init__(self, *args, **kwargs) -> None: ...
@@ -58,8 +58,8 @@ class Binary(lief.ELF.Binary):
class Class(lief.Object):
class it_methods:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.OAT.Method: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.OAT.Method: ...
def __iter__(self) -> lief.OAT.Class.it_methods: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.OAT.Method: ...
def __init__(self) -> None: ...
@@ -69,11 +69,11 @@ class Class(lief.Object):
@overload
def is_quickened(self, method_index: int) -> bool: ...
@overload
def method_offsets_index(self, arg0: lief.DEX.Method) -> int: ...
def method_offsets_index(self, arg: lief.DEX.Method, /) -> int: ...
@overload
def method_offsets_index(self, arg0: int) -> int: ...
def method_offsets_index(self, arg: int, /) -> int: ...
@property
def bitmap(self) -> List[int]: ...
def bitmap(self) -> list[int]: ...
@property
def fullname(self) -> str: ...
@property
@@ -96,7 +96,6 @@ class DexFile(lief.Object):
def has_dex_file(self) -> bool: ...
class HEADER_KEYS:
__members__: ClassVar[dict] = ... # read-only
BOOT_CLASS_PATH: ClassVar[HEADER_KEYS] = ...
CLASS_PATH: ClassVar[HEADER_KEYS] = ...
COMPILER_FILTER: ClassVar[HEADER_KEYS] = ...
@@ -108,30 +107,26 @@ class HEADER_KEYS:
IMAGE_LOCATION: ClassVar[HEADER_KEYS] = ...
NATIVE_DEBUGGABLE: ClassVar[HEADER_KEYS] = ...
PIC: ClassVar[HEADER_KEYS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class Header(lief.Object):
class it_key_values_t:
class value_type:
value: str
def __init__(self, *args, **kwargs) -> None: ...
@property
def key(self) -> lief.OAT.HEADER_KEYS: ...
class element_t:
key: lief.OAT.HEADER_KEYS
value: str
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.OAT.Header.it_key_values_t.value_type: ...
class it_key_values_t:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg: int, /) -> lief.OAT.Header.element_t: ...
def __iter__(self) -> lief.OAT.Header.it_key_values_t: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.OAT.Header.it_key_values_t.value_type: ...
def __next__(self) -> lief.OAT.Header.element_t: ...
def __init__(self) -> None: ...
def get(self, key: lief.OAT.HEADER_KEYS) -> str: ...
def set(self, key: lief.OAT.HEADER_KEYS, value: str) -> Any: ...
def __getitem__(self, arg0: lief.OAT.HEADER_KEYS) -> str: ...
def __setitem__(self, arg0: lief.OAT.HEADER_KEYS, arg1: str) -> Any: ...
def __getitem__(self, arg: lief.OAT.HEADER_KEYS, /) -> str: ...
def __setitem__(self, arg0: lief.OAT.HEADER_KEYS, arg1: str, /) -> Any: ...
@property
def checksum(self) -> int: ...
@property
@@ -155,9 +150,9 @@ class Header(lief.Object):
@property
def key_values(self) -> lief.OAT.Header.it_key_values_t: ...
@property
def keys(self) -> List[lief.OAT.HEADER_KEYS]: ...
def keys(self) -> list[lief.OAT.HEADER_KEYS]: ...
@property
def magic(self) -> List[int]: ...
def magic(self) -> list[int]: ...
@property
def nb_dex_files(self) -> int: ...
@property
@@ -171,12 +166,11 @@ class Header(lief.Object):
@property
def quick_to_interpreter_bridge_offset(self) -> int: ...
@property
def values(self) -> List[str]: ...
def values(self) -> list[str]: ...
@property
def version(self) -> int: ...
class INSTRUCTION_SETS:
__members__: ClassVar[dict] = ... # read-only
ARM: ClassVar[INSTRUCTION_SETS] = ...
ARM_64: ClassVar[INSTRUCTION_SETS] = ...
MIPS: ClassVar[INSTRUCTION_SETS] = ...
@@ -185,15 +179,11 @@ class INSTRUCTION_SETS:
THUMB2: ClassVar[INSTRUCTION_SETS] = ...
X86: ClassVar[INSTRUCTION_SETS] = ...
X86_64: ClassVar[INSTRUCTION_SETS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class Method(lief.Object):
quick_code: List[int]
quick_code: list[int]
def __init__(self) -> None: ...
@property
def dex_method(self) -> lief.DEX.Method: ...
@@ -209,7 +199,6 @@ class Method(lief.Object):
def oat_class(self) -> lief.OAT.Class: ...
class OAT_CLASS_STATUS:
__members__: ClassVar[dict] = ... # read-only
ERROR: ClassVar[OAT_CLASS_STATUS] = ...
IDX: ClassVar[OAT_CLASS_STATUS] = ...
INITIALIZED: ClassVar[OAT_CLASS_STATUS] = ...
@@ -223,43 +212,28 @@ class OAT_CLASS_STATUS:
VERIFIED: ClassVar[OAT_CLASS_STATUS] = ...
VERIFYING: ClassVar[OAT_CLASS_STATUS] = ...
VERIFYING_AT_RUNTIME: ClassVar[OAT_CLASS_STATUS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class OAT_CLASS_TYPES:
__members__: ClassVar[dict] = ... # read-only
ALL_COMPILED: ClassVar[OAT_CLASS_TYPES] = ...
NONE_COMPILED: ClassVar[OAT_CLASS_TYPES] = ...
SOME_COMPILED: ClassVar[OAT_CLASS_TYPES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
def android_version(arg0: int) -> lief.Android.ANDROID_VERSIONS: ...
@overload
def is_oat(binary: lief.ELF.Binary) -> bool: ...
@overload
def is_oat(path: str) -> bool: ...
@overload
def is_oat(raw: List[int]) -> bool: ...
def android_version(arg: int, /) -> lief.Android.ANDROID_VERSIONS: ...
@overload
def parse(oat_file: str) -> lief.OAT.Binary: ...
@overload
def parse(oat_file: str, vdex_file: str) -> lief.OAT.Binary: ...
@overload
def parse(raw: List[int], name: str = ...) -> lief.OAT.Binary: ...
def parse(raw: list[int]) -> lief.OAT.Binary: ...
@overload
def parse(io: object, name: str = ...) -> lief.OAT.Binary: ...
def parse(io: object) -> object: ...
@overload
def version(binary: lief.ELF.Binary) -> int: ...
@overload
def version(file: str) -> int: ...
@overload
def version(raw: List[int]) -> int: ...
def version(raw: list[int]) -> int: ...
+475 -405
View File
File diff suppressed because it is too large Load Diff
+10 -11
View File
@@ -1,12 +1,17 @@
from typing import List
from typing import overload
import lief # type: ignore
import lief.Android # type: ignore
import lief.DEX # type: ignore
import lief.OAT # type: ignore
import lief.VDEX # type: ignore
class File(lief.Object):
class it_dex_files:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg: int, /) -> lief.DEX.File: ...
def __iter__(self) -> lief.OAT.Binary.it_dex_files: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.DEX.File: ...
def __init__(self, *args, **kwargs) -> None: ...
@property
def dex2dex_json_info(self) -> str: ...
@@ -20,7 +25,7 @@ class Header(lief.Object):
@property
def dex_size(self) -> int: ...
@property
def magic(self) -> List[int]: ...
def magic(self) -> list[int]: ...
@property
def nb_dex_files(self) -> int: ...
@property
@@ -32,16 +37,10 @@ class Header(lief.Object):
def android_version(vdex_version: int) -> lief.Android.ANDROID_VERSIONS: ...
@overload
def is_vdex(path: str) -> bool: ...
@overload
def is_vdex(raw: List[int]) -> bool: ...
@overload
def parse(filename: str) -> lief.VDEX.File: ...
@overload
def parse(raw: List[int], name: str = ...) -> lief.VDEX.File: ...
@overload
def parse(io: object, name: str = ...) -> lief.VDEX.File: ...
def parse(io: object, name: str = ...) -> object: ...
@overload
def version(file: str) -> int: ...
@overload
def version(raw: List[int]) -> int: ...
def version(raw: list[int]) -> int: ...
+11 -10
View File
@@ -1,12 +1,13 @@
import os
import sys
from . import _lief
from ._lief import *
from ._lief import __version__, __tag__, __commit__, __is_tagged__
# cf. https://github.com/pytorch/pytorch/blob/60a3b7425dde97fe8b46183c154a9c3b24f0c733/torch/__init__.py#L467-L470
for attr in dir(_lief):
candidate = getattr(_lief, attr)
if type(candidate) is type(_lief):
sys.modules.setdefault(f"lief.{attr}", candidate)
import traceback
if len(__path__) > 0 and __path__[0] not in sys.path:
from . import _lief
from ._lief import *
from ._lief import __version__, __tag__, __commit__, __is_tagged__
# cf. https://github.com/pytorch/pytorch/blob/60a3b7425dde97fe8b46183c154a9c3b24f0c733/torch/__init__.py#L467-L470
for attr in dir(_lief):
candidate = getattr(_lief, attr)
if type(candidate) is type(_lief):
sys.modules.setdefault(f"lief.{attr}", candidate)
+75 -124
View File
@@ -1,14 +1,14 @@
from typing import Any, ClassVar, Iterator, List, Set
from typing import Any, ClassVar, List
from . import ART, Android, DEX, ELF, MachO, OAT, PE, VDEX, logging # type: ignore
from typing import overload
import lief # type: ignore
class ARCHITECTURES:
__members__: ClassVar[dict] = ... # read-only
ARM: ClassVar[ARCHITECTURES] = ...
ARM64: ClassVar[ARCHITECTURES] = ...
INTEL: ClassVar[ARCHITECTURES] = ...
LOONGARCH: ClassVar[ARCHITECTURES] = ...
MIPS: ClassVar[ARCHITECTURES] = ...
NONE: ClassVar[ARCHITECTURES] = ...
PPC: ClassVar[ARCHITECTURES] = ...
@@ -17,47 +17,41 @@ class ARCHITECTURES:
SYSZ: ClassVar[ARCHITECTURES] = ...
X86: ClassVar[ARCHITECTURES] = ...
XCORE: ClassVar[ARCHITECTURES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.ARCHITECTURES: ...
@property
def value(self) -> int: ...
class Binary(Object):
class VA_TYPES:
__members__: ClassVar[dict] = ... # read-only
AUTO: ClassVar[Binary.VA_TYPES] = ...
RVA: ClassVar[Binary.VA_TYPES] = ...
VA: ClassVar[Binary.VA_TYPES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class it_relocations:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.Relocation: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.Relocation: ...
def __iter__(self) -> Any: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.Relocation: ...
class it_sections:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.Section: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.Section: ...
def __iter__(self) -> lief.Binary.it_sections: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.Section: ...
class it_symbols:
def __init__(self, *args, **kwargs) -> None: ...
def __getitem__(self, arg0: int) -> lief.Symbol: ...
def __iter__(self) -> Iterator: ...
def __getitem__(self, arg: int, /) -> lief.Symbol: ...
def __iter__(self) -> Any: ...
def __len__(self) -> int: ...
def __next__(self) -> lief.Symbol: ...
name: str
def __init__(self, *args, **kwargs) -> None: ...
def get_content_from_virtual_address(self, virtual_address: int, size: int, va_type: lief.Binary.VA_TYPES = ...) -> memoryview: ...
def get_function_address(self, function_name: str) -> object: ...
@@ -65,21 +59,21 @@ class Binary(Object):
def has_symbol(self, symbol_name: str) -> bool: ...
def offset_to_virtual_address(self, offset: int, slide: int = ...) -> object: ...
@overload
def patch_address(self, address: int, patch_value: List[int], va_type: lief.Binary.VA_TYPES = ...) -> None: ...
def patch_address(self, address: int, patch_value: list[int], va_type: lief.Binary.VA_TYPES = ...) -> None: ...
@overload
def patch_address(self, address: int, patch_value: int, size: int = ..., va_type: lief.Binary.VA_TYPES = ...) -> None: ...
def remove_section(self, name: str, clear: bool = ...) -> None: ...
def xref(self, virtual_address: int) -> List[int]: ...
def xref(self, virtual_address: int) -> list[int]: ...
@property
def abstract(self) -> object: ...
def abstract(self) -> lief.Binary: ...
@property
def concrete(self) -> object: ...
def concrete(self) -> lief.ELF.Binary | lief.PE.Binary | lief.MachO.Binary: ...
@property
def ctor_functions(self) -> Any: ...
def ctor_functions(self) -> List[lief.Function]: ...
@property
def entrypoint(self) -> int: ...
@property
def exported_functions(self) -> Any: ...
def exported_functions(self) -> list[lief.Function]: ...
@property
def format(self) -> lief.EXE_FORMATS: ...
@property
@@ -89,7 +83,7 @@ class Binary(Object):
@property
def imagebase(self) -> int: ...
@property
def imported_functions(self) -> Any: ...
def imported_functions(self) -> list[lief.Function]: ...
@property
def is_pie(self) -> bool: ...
@property
@@ -102,62 +96,55 @@ class Binary(Object):
def symbols(self) -> Any: ...
class ENDIANNESS:
__members__: ClassVar[dict] = ... # read-only
BIG: ClassVar[ENDIANNESS] = ...
LITTLE: ClassVar[ENDIANNESS] = ...
NONE: ClassVar[ENDIANNESS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.ENDIANNESS: ...
@property
def value(self) -> int: ...
class EXE_FORMATS:
__members__: ClassVar[dict] = ... # read-only
ELF: ClassVar[EXE_FORMATS] = ...
MACHO: ClassVar[EXE_FORMATS] = ...
PE: ClassVar[EXE_FORMATS] = ...
UNKNOWN: ClassVar[EXE_FORMATS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.EXE_FORMATS: ...
@property
def value(self) -> int: ...
class Function(Symbol):
class FLAGS:
__members__: ClassVar[dict] = ... # read-only
CONSTRUCTOR: ClassVar[Function.FLAGS] = ...
DEBUG: ClassVar[Function.FLAGS] = ...
DESTRUCTOR: ClassVar[Function.FLAGS] = ...
EXPORTED: ClassVar[Function.FLAGS] = ...
IMPORTED: ClassVar[Function.FLAGS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
address: int
@overload
def __init__(self) -> None: ...
@overload
def __init__(self, arg0: str) -> None: ...
def __init__(self, arg: str, /) -> None: ...
@overload
def __init__(self, arg0: int) -> None: ...
def __init__(self, arg: int, /) -> None: ...
@overload
def __init__(self, arg0: str, arg1: int) -> None: ...
def __init__(self, arg0: str, arg1: int, /) -> None: ...
def add(self, flag: lief.Function.FLAGS) -> lief.Function: ...
@property
def flags(self) -> List[lief.Function.FLAGS]: ...
def flags(self) -> list[lief.Function.FLAGS]: ...
class Header(Object):
architecture: Any
endianness: lief.ENDIANNESS
entrypoint: int
modes: Set[lief.MODES]
modes: set[lief.MODES]
object_type: lief.OBJECT_TYPES
def __init__(self) -> None: ...
@property
@@ -166,7 +153,6 @@ class Header(Object):
def is_64(self) -> bool: ...
class MODES:
__members__: ClassVar[dict] = ... # read-only
ARM: ClassVar[MODES] = ...
M16: ClassVar[MODES] = ...
M32: ClassVar[MODES] = ...
@@ -183,23 +169,22 @@ class MODES:
V7: ClassVar[MODES] = ...
V8: ClassVar[MODES] = ...
V9: ClassVar[MODES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.MODES: ...
@property
def value(self) -> int: ...
class OBJECT_TYPES:
__members__: ClassVar[dict] = ... # read-only
EXECUTABLE: ClassVar[OBJECT_TYPES] = ...
LIBRARY: ClassVar[OBJECT_TYPES] = ...
NONE: ClassVar[OBJECT_TYPES] = ...
OBJECT: ClassVar[OBJECT_TYPES] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.OBJECT_TYPES: ...
@property
def value(self) -> int: ...
@@ -207,27 +192,23 @@ class Object:
def __init__(self, *args, **kwargs) -> None: ...
class PLATFORMS:
__members__: ClassVar[dict] = ... # read-only
ANDROID: ClassVar[PLATFORMS] = ...
IOS: ClassVar[PLATFORMS] = ...
LINUX: ClassVar[PLATFORMS] = ...
OSX: ClassVar[PLATFORMS] = ...
UNKNOWN: ClassVar[PLATFORMS] = ...
WINDOWS: ClassVar[PLATFORMS] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
@staticmethod
def from_value(arg: int, /) -> lief.PLATFORMS: ...
@property
def value(self) -> int: ...
class Relocation(Object):
address: int
size: int
@overload
def __init__(self) -> None: ...
@overload
def __init__(self, address: int, size: int) -> None: ...
def __init__(self, *args, **kwargs) -> None: ...
class Section(Object):
content: memoryview
@@ -235,10 +216,7 @@ class Section(Object):
offset: int
size: int
virtual_address: int
@overload
def __init__(self) -> None: ...
@overload
def __init__(self, name: str) -> None: ...
def __init__(self, *args, **kwargs) -> None: ...
@overload
def search(self, number: int, pos: int = ..., size: int = ...) -> int | None: ...
@overload
@@ -246,9 +224,9 @@ class Section(Object):
@overload
def search(self, bytes: bytes, pos: int = ...) -> int | None: ...
@overload
def search_all(self, number: int, size: int = ...) -> List[int]: ...
def search_all(self, number: int, size: int = ...) -> list[int]: ...
@overload
def search_all(self, str: str) -> List[int]: ...
def search_all(self, str: str) -> list[int]: ...
@property
def entropy(self) -> float: ...
@property
@@ -258,11 +236,9 @@ class Symbol(Object):
name: object
size: int
value: int
def __init__(self) -> None: ...
def __init__(self, *args, **kwargs) -> None: ...
class lief_errors:
__members__: ClassVar[dict] = ... # read-only
__entries: ClassVar[dict] = ...
asn1_bad_tag: ClassVar[lief_errors] = ...
build_error: ClassVar[lief_errors] = ...
conversion_error: ClassVar[lief_errors] = ...
@@ -276,81 +252,56 @@ class lief_errors:
parsing_error: ClassVar[lief_errors] = ...
read_error: ClassVar[lief_errors] = ...
read_out_of_bound: ClassVar[lief_errors] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
class ok_t:
def __init__(self, *args, **kwargs) -> None: ...
def __bool__(self) -> bool: ...
@overload
def art_version(filename: str) -> int: ...
@overload
def art_version(raw: List[int]) -> int: ...
def breakp() -> object: ...
def current_platform() -> lief.PLATFORMS: ...
def demangle(arg0: str) -> object: ...
@overload
def dex_version(filename: str) -> int: ...
def hash(arg: lief.Object, /) -> int: ...
@overload
def dex_version(raw: List[int]) -> int: ...
def hash(arg: list[int], /) -> int: ...
@overload
def hash(arg0: lief.Object) -> int: ...
def hash(arg: bytes, /) -> int: ...
@overload
def hash(arg0: List[int]) -> int: ...
def hash(arg: str, /) -> int: ...
@overload
def hash(arg0: bytes) -> int: ...
def is_art(path: str) -> bool: ...
@overload
def hash(arg0: str) -> int: ...
def is_art(raw: list[int]) -> bool: ...
@overload
def is_art(filename: str) -> bool: ...
def is_dex(path: str) -> bool: ...
@overload
def is_art(raw: List[int]) -> bool: ...
@overload
def is_dex(filename: str) -> bool: ...
@overload
def is_dex(raw: List[int]) -> bool: ...
def is_dex(raw: list[int]) -> bool: ...
@overload
def is_elf(filename: str) -> bool: ...
@overload
def is_elf(raw: List[int]) -> bool: ...
def is_elf(raw: list[int]) -> bool: ...
@overload
def is_macho(filename: str) -> bool: ...
@overload
def is_macho(raw: List[int]) -> bool: ...
def is_macho(raw: list[int]) -> bool: ...
@overload
def is_oat(filename: str) -> bool: ...
def is_oat(binary: lief.ELF.Binary) -> bool: ...
@overload
def is_oat(raw: List[int]) -> bool: ...
def is_oat(path: str) -> bool: ...
@overload
def is_oat(elf: lief.ELF.Binary) -> bool: ...
def is_oat(raw: list[int]) -> bool: ...
@overload
def is_pe(filename: str) -> bool: ...
def is_pe(file: str) -> bool: ...
@overload
def is_pe(raw: List[int]) -> bool: ...
def is_pe(raw: list[int]) -> bool: ...
@overload
def is_vdex(filename: str) -> bool: ...
def is_vdex(path: str) -> bool: ...
@overload
def is_vdex(raw: List[int]) -> bool: ...
def is_vdex(raw: list[int]) -> bool: ...
@overload
def oat_version(filename: str) -> int: ...
@overload
def oat_version(raw: List[int]) -> int: ...
@overload
def oat_version(elf: lief.ELF.Binary) -> int: ...
@overload
def parse(raw: bytes, name: str = ...) -> lief.Binary: ...
def parse(raw: bytes) -> lief.Binary: ...
@overload
def parse(filepath: str) -> lief.Binary: ...
@overload
def parse(io: object, name: str = ...) -> object: ...
def shell() -> object: ...
def to_json(arg0: lief.Object) -> str: ...
def to_json_from_abstract(arg0: lief.Object) -> str: ...
@overload
def vdex_version(filename: str) -> int: ...
@overload
def vdex_version(raw: List[int]) -> int: ...
def parse(io: object) -> object: ...
def to_json(arg: lief.Object, /) -> str: ...
+3 -8
View File
@@ -1,21 +1,16 @@
from typing import ClassVar
from typing import Any, ClassVar
import lief.logging # type: ignore
class LOGGING_LEVEL:
__members__: ClassVar[dict] = ... # read-only
CRITICAL: ClassVar[LOGGING_LEVEL] = ...
DEBUG: ClassVar[LOGGING_LEVEL] = ...
ERROR: ClassVar[LOGGING_LEVEL] = ...
INFO: ClassVar[LOGGING_LEVEL] = ...
TRACE: ClassVar[LOGGING_LEVEL] = ...
WARNING: ClassVar[LOGGING_LEVEL] = ...
__entries: ClassVar[dict] = ...
def __init__(self, value: int) -> None: ...
@property
def name(self) -> str: ...
@property
def value(self) -> int: ...
__name__: Any
def __init__(self, *args, **kwargs) -> None: ...
def disable() -> None: ...
def enable() -> None: ...
+159 -75
View File
@@ -15,6 +15,7 @@ CURRENT_DIR = Path(__file__).parent
LIEF_DIR = (CURRENT_DIR / ".." / "..").absolute().resolve()
PACKAGE_NAME = "lief"
PYLIEF_CONF_ENV = "PYLIEF_CONF"
DEFAULT_TARGET = "pyLIEF"
ENV = os.environ
@@ -30,8 +31,8 @@ class Config:
if "cross-compilation" in self._config["lief"]:
cross_conf = self._config["lief"]["cross-compilation"]
if "platform" in cross_conf:
platform = cross_conf["platform"]
if os.name == "nt" and platform == "win32":
platform_build = cross_conf["platform"]
if os.name == "nt" and platform_build == "win32":
ENV["VSCMD_ARG_TGT_ARCH"] = "x86"
os.environ["VSCMD_ARG_TGT_ARCH"] = "x86"
@@ -49,40 +50,71 @@ class Config:
def build_type(self) -> str:
return self._config['lief']['build']['type']
def gen_cmake_option(self, output: str) -> List[str]:
cfg = self.build_type()
opt = [
f"-DCMAKE_BUILD_TYPE={cfg}",
def get_lief_format_opt(self):
opt = self._config["lief"]["formats"]
return (
"-DLIEF_ELF={}".format("ON" if opt["elf"] else "OFF"),
"-DLIEF_PE={}".format("ON" if opt["pe"] else "OFF"),
"-DLIEF_MACHO={}".format("ON" if opt["macho"] else "OFF"),
"-DLIEF_DEX={}".format("ON" if opt["dex"] else "OFF"),
"-DLIEF_ART={}".format("ON" if opt["art"] else "OFF"),
"-DLIEF_OAT={}".format("ON" if opt["oat"] else "OFF"),
"-DLIEF_VDEX={}".format("ON" if opt["vdex"] else "OFF"),
)
def get_lief_logging_opt(self):
opt = self._config["lief"]["logging"]
return (
"-DLIEF_LOGGING={}".format("ON" if opt["enabled"] else "OFF"),
"-DLIEF_LOGGING_DEBUG={}".format("ON" if opt["debug"] else "OFF"),
)
def get_python_opt(self):
config = ["-DLIEF_PYTHON_API=on"]
interpreter = Path(sys.executable)
base = sysconfig.get_config_var("base")
if base is not None:
config += [f"-DPython_ROOT_DIR={base}"]
config += [
f"-DPython_EXECUTABLE={interpreter.as_posix()}",
]
return config
def get_generic_opt(self, output: str):
return (
f"-DCMAKE_BUILD_TYPE={self.build_type()}",
f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={output}',
"-DLIEF_USE_CCACHE={}".format("ON" if self._config["lief"]["build"]["cache"] else "OFF"),
] + [
"-DLIEF_FORCE_API_EXPORTS=ON",
"-DLIEF_PYTHON_API=on",
f"-DPYTHON_EXECUTABLE={sys.executable}",
] + [
"-DLIEF_ELF={}".format("ON" if self._config["lief"]["formats"]["elf"] else "OFF"),
"-DLIEF_PE={}".format("ON" if self._config["lief"]["formats"]["pe"] else "OFF"),
"-DLIEF_MACHO={}".format("ON" if self._config["lief"]["formats"]["macho"] else "OFF"),
"-DLIEF_DEX={}".format("ON" if self._config["lief"]["formats"]["dex"] else "OFF"),
"-DLIEF_ART={}".format("ON" if self._config["lief"]["formats"]["art"] else "OFF"),
"-DLIEF_OAT={}".format("ON" if self._config["lief"]["formats"]["oat"] else "OFF"),
"-DLIEF_VDEX={}".format("ON" if self._config["lief"]["formats"]["vdex"] else "OFF"),
] + [
"-DLIEF_LOGGING={}".format("ON" if self._config["lief"]["logging"]["enabled"] else "OFF"),
"-DLIEF_LOGGING_DEBUG={}".format("ON" if self._config["lief"]["logging"]["debug"] else "OFF"),
] + [
"-DLIEF_ENABLE_JSON={}".format("ON" if self._config["lief"]["features"]["json"] else "OFF"),
"-DLIEF_DISABLE_FROZEN={}".format("OFF" if self._config["lief"]["features"]["frozen"] else "ON"),
] + [
"-DLIEF_ENABLE_JSON={}".format("ON" if self._config["lief"]["features"]["json"] else "OFF"),
"-DLIEF_DISABLE_FROZEN={}".format("OFF" if self._config["lief"]["features"]["frozen"] else "ON"),
]
)
def get_feat_opt(self):
opt = self._config["lief"]["features"]
return (
"-DLIEF_ENABLE_JSON={}".format("ON" if opt["json"] else "OFF"),
"-DLIEF_DISABLE_FROZEN={}".format("OFF" if opt["frozen"] else "ON"),
)
def get_iwyu_opt(self):
if "include-what-you-use" in self._config["lief"]["build"]:
value = self._config["lief"]["build"]["include-what-you-use"]
opt.append(f"-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE={value}")
return (f"-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE={value}", )
else:
opt.append("-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=''")
return ("-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=''", )
def get_flags_opt(self):
opt = []
if "cxx-flags" in self._config["lief"]["build"]:
value = self._config["lief"]["build"]["cxx-flags"]
opt.append(f"-DCMAKE_CXX_FLAGS={value}")
else:
opt.append("-DCMAKE_CXX_FLAGS=''")
if "c-flags" in self._config["lief"]["build"]:
value = self._config["lief"]["build"]["c-flags"]
opt.append(f"-DCMAKE_C_FLAGS={value}")
else:
opt.append("-DCMAKE_C_FLAGS=''")
cxx_flags = os.getenv("CXXFLAGS", None)
c_flags = os.getenv("CFLAGS", None)
@@ -93,13 +125,86 @@ class Config:
if c_flags is not None:
opt.append(f'-DCMAKE_C_FLAGS={c_flags}')
return opt
def get_cmake_extra_opt(self):
opt = []
if "extra-cmake-opt" in self._config["lief"]["build"]:
value = self._config["lief"]["build"]["extra-cmake-opt"]
if isinstance(value, str):
opt.append(value)
elif hasattr(value, "__iter__"):
opt.extend(value)
else:
print(f"Unsupported opt: {value} ({type(value)})")
sys.exit(1)
return opt
def get_third_party_opt(self) -> List[str]:
if "third-party" not in self._config["lief"]:
return []
cmake_opt = []
tp_conf = self._config["lief"]["third-party"]
if "spdlog" in tp_conf:
cmake_opt += [
"-DLIEF_EXTERNAL_SPDLOG=ON",
"-Dspdlog_DIR={}".format(tp_conf["spdlog"])
]
return cmake_opt
def get_cross_compile_opt(self) -> List[str]:
if "cross-compilation" not in self._config["lief"]:
return []
cmake_opt = []
cross_conf = self._config["lief"]["cross-compilation"]
if "osx-arch" in cross_conf:
cmake_opt += [
f'-DCMAKE_OSX_ARCHITECTURES={cross_conf["osx-arch"]}'
]
return cmake_opt
def get_pre_compile_opt(self):
install_path = self._config["lief"]["build"].get("lief-install-dir", None)
if install_path is None:
return []
install_path = Path(install_path).expanduser().resolve().absolute()
if not install_path.is_dir():
report(f"{install_path} is not a valid directory")
return []
cmake_dir = install_path / "share" / "LIEF" / "cmake"
if not (cmake_dir / "LIEFConfig.cmake").is_file():
report(f"Missing LIEFConfig.cmake in {cmake_dir}")
return []
return (
"-DLIEF_PY_LIEF_EXT=on",
"-DLIEF_INSTALL=off",
f"-DLIEF_DIR={cmake_dir}",
)
def gen_cmake_option(self, output: str) -> List[str]:
cfg = self.build_type()
opt = [
*self.get_generic_opt(output),
*self.get_python_opt(),
*self.get_lief_format_opt(),
*self.get_feat_opt(),
*self.get_iwyu_opt(),
*self.get_flags_opt(),
*self.get_third_party_opt(),
*self.get_pre_compile_opt(),
*self.get_cross_compile_opt(),
*self.get_cmake_extra_opt()
]
if self._use_ninja():
opt = ["-G", "Ninja"] + opt
opt += self._get_third_party_opt()
opt += self._get_cross_compile_opt()
if Config.is_windows():
is64 = sys.maxsize > 2**32
opt += [
@@ -118,30 +223,6 @@ class Config:
return opt
def _get_third_party_opt(self) -> List[str]:
if "third-party" not in self._config["lief"]:
return []
cmake_opt = []
tp_conf = self._config["lief"]["third-party"]
if "spdlog" in tp_conf:
cmake_opt += [
"-DLIEF_EXTERNAL_SPDLOG=ON",
"-Dspdlog_DIR={}".format(tp_conf["spdlog"])
]
return cmake_opt
def _get_cross_compile_opt(self) -> List[str]:
if "cross-compilation" not in self._config["lief"]:
return []
cmake_opt = []
cross_conf = self._config["lief"]["cross-compilation"]
if "osx-arch" in cross_conf:
cmake_opt += [
f'-DCMAKE_OSX_ARCHITECTURES={cross_conf["osx-arch"]}'
]
return cmake_opt
def _get_jobs(self) -> List[str]:
if "parallel-jobs" in self._config["lief"]["build"]:
@@ -151,6 +232,19 @@ class Config:
return []
return []
def _get_targets(self) -> List[str]:
targets = [DEFAULT_TARGET]
if "extra-targets" in self._config["lief"]["build"]:
extra = self._config["lief"]["build"]["extra-targets"]
if isinstance(extra, str):
targets.append(extra)
elif hasattr(extra, "__iter__"):
targets.extend(extra)
else:
print(f"Unsupported opt: {targets} ({type(targets)})")
sys.exit(1)
return targets
def get_target_osx_arch(self) -> str:
if "cross-compilation" in self._config["lief"]:
cross_conf = self._config["lief"]["cross-compilation"]
@@ -162,24 +256,14 @@ class Config:
def _use_ninja(self) -> bool:
return self._config['lief']['build']['ninja']
def _win_compile_cmd(self):
def get_compile_cmd(self):
config = self._config['lief']['build']['type']
return [
'cmake',
'--build', '.',
'--target', 'pyLIEF',
'--config', self._config['lief']['build']['type'],
]
def _unix_compile_cmd(self):
gen = which("ninja") if self._use_ninja() else which("make")
return [gen] + self._get_jobs() + ["pyLIEF"]
def get_compile_cmd(self):
if Config.is_windows():
return self._win_compile_cmd()
return self._unix_compile_cmd()
'--target'] + self._get_targets() + [
'--config', config,
] + self._get_jobs()
class Versioning:
COMMAND = '{git} describe --tags --long --dirty'
@@ -187,7 +271,7 @@ class Versioning:
IS_TAGGED_CMD = '{git} tag --list --points-at=HEAD'
FMT_DEV = '{tag}.dev0'
FMT_TAGGED = '{tag}'
DEFAULT_VERSION = "0.13.0"
DEFAULT_VERSION = "0.14.0"
def __init__(self):
self._git = which("git")
@@ -318,7 +402,7 @@ class BuildLibrary(build_ext):
subprocess.check_call(configure_cmd, **cmake_subprocess_args)
compile_cmd = cmake_conf.get_compile_cmd()
report(" ".join(configure_cmd))
report("Compile with:"," ".join(compile_cmd))
subprocess.check_call(compile_cmd, **cmake_subprocess_args)
pylief_dst = build_lib / self.get_ext_filename(self.get_ext_fullname(ext.name))
+5 -14
View File
@@ -1,19 +1,10 @@
set(LIEF_PYTHON_ART_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyART.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyUtils.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyFile.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyUtils.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init.cpp"
)
set(LIEF_PYTHON_ART_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyART.hpp")
source_group("Source Files\\ART" FILES ${LIEF_PYTHON_ART_SRC})
source_group("Header Files\\ART" FILES ${LIEF_PYTHON_ART_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_ART_SRC}" "${LIEF_PYTHON_ART_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/../")
"${CMAKE_CURRENT_SOURCE_DIR}/pyART.hpp")
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_ART_SRC} ${LIEF_PYTHON_ART_HDR})
add_subdirectory(objects)
@@ -13,21 +13,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyART.hpp"
#include "ART/pyART.hpp"
#include "ART/init.hpp"
#include "LIEF/ART/Parser.hpp"
#include "LIEF/ART/File.hpp"
#include "LIEF/ART/Header.hpp"
#include "LIEF/ART/enums.hpp"
#include "LIEF/ART/EnumToString.hpp"
#define CREATE(X,Y) create<X>(Y)
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace ART {
void init_enums(py::module& m) {
namespace LIEF::ART::py {
py::enum_<STORAGE_MODES>(m, "STORAGE_MODES")
inline void init_objects(nb::module_& m) {
CREATE(Parser, m);
CREATE(File, m);
CREATE(Header, m);
}
inline void init_enums(nb::module_& m) {
nb::enum_<STORAGE_MODES>(m, "STORAGE_MODES")
.value(PY_ENUM(STORAGE_MODES::STORAGE_UNCOMPRESSED))
.value(PY_ENUM(STORAGE_MODES::STORAGE_LZ4))
.value(PY_ENUM(STORAGE_MODES::STORAGE_LZ4HC));
}
}
void init(nb::module_& m) {
nb::module_ mod = m.def_submodule("ART", "Python API for ART format");
init_enums(mod);
init_objects(mod);
init_utils(mod);
}
}
@@ -13,15 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PY_LIEF_ENCODING_H_
#define PY_LIEF_ENCODING_H_
#include <pybind11/pybind11.h>
#include <pybind11/eval.h>
namespace py = pybind11;
py::object safe_string_converter(const std::string& str);
#ifndef PY_LIEF_ART_INIT_H
#define PY_LIEF_ART_INIT_H
#include "pyLIEF.hpp"
namespace LIEF::ART::py {
void init(nb::module_& m);
void init_utils(nb::module_& m);
}
#endif
@@ -0,0 +1,9 @@
set(LIEF_PYTHON_ART_OBJ_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/pyHeader.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyParser.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyFile.cpp"
)
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_ART_OBJ_SRC})
+11 -40
View File
@@ -14,52 +14,23 @@
* limitations under the License.
*/
#include "LIEF/ART/File.hpp"
#include "LIEF/ART/hash.hpp"
#include "pyART.hpp"
#include "ART/pyART.hpp"
namespace LIEF {
namespace ART {
#include <sstream>
#include <nanobind/stl/string.h>
template<class T>
using no_const_getter = T (File::*)(void);
template<class T, class P>
using no_const_func = T (File::*)(P);
template<class T>
using getter_t = T (File::*)(void) const;
template<class T>
using setter_t = void (File::*)(T);
namespace LIEF::ART::py {
template<>
void create<File>(py::module& m) {
void create<File>(nb::module_& m) {
nb::class_<File, LIEF::Object>(m, "File", "ART File representation"_doc)
// File object
py::class_<File, LIEF::Object>(m, "File", "ART File representation")
.def_property_readonly("header",
static_cast<no_const_getter<Header&>>(&File::header),
"Return the ART " RST_CLASS_REF(lief.ART.Header) "",
py::return_value_policy::reference)
.def("__eq__", &File::operator==)
.def("__ne__", &File::operator!=)
.def("__hash__",
[] (const File& file) {
return Hash::hash(file);
})
.def("__str__",
[] (const File& file)
{
std::ostringstream stream;
stream << file;
std::string str = stream.str();
return str;
});
.def_prop_ro("header",
nb::overload_cast<>(&File::header),
"Return the ART " RST_CLASS_REF(lief.ART.Header) ""_doc,
nb::rv_policy::reference_internal)
LIEF_DEFAULT_STR(Header);
}
}
}
+48 -67
View File
@@ -14,100 +14,81 @@
* limitations under the License.
*/
#include "LIEF/ART/Header.hpp"
#include "LIEF/ART/hash.hpp"
#include "pyART.hpp"
#include "ART/pyART.hpp"
namespace LIEF {
namespace ART {
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/array.h>
template<class T>
using getter_t = T (Header::*)(void) const;
template<class T>
using setter_t = void (Header::*)(T);
namespace LIEF::ART::py {
template<>
void create<Header>(py::module& m) {
void create<Header>(nb::module_& m) {
py::class_<Header, LIEF::Object>(m, "Header", "ART Header representation")
.def_property_readonly("magic",
static_cast<getter_t<Header::magic_t>>(&Header::magic)
nb::class_<Header, Object>(m, "Header", "ART Header representation"_doc)
.def_prop_ro("magic",
nb::overload_cast<>(&Header::magic, nb::const_)
)
.def_property_readonly("version",
static_cast<getter_t<art_version_t>>(&Header::version)
.def_prop_ro("version",
nb::overload_cast<>(&Header::version, nb::const_)
)
.def_property_readonly("image_begin",
static_cast<getter_t<uint32_t>>(&Header::image_begin)
.def_prop_ro("image_begin",
nb::overload_cast<>(&Header::image_begin, nb::const_)
)
.def_property_readonly("image_size",
static_cast<getter_t<uint32_t>>(&Header::image_size)
.def_prop_ro("image_size",
nb::overload_cast<>(&Header::image_size, nb::const_)
)
.def_property_readonly("oat_checksum",
static_cast<getter_t<uint32_t>>(&Header::oat_checksum)
.def_prop_ro("oat_checksum",
nb::overload_cast<>(&Header::oat_checksum, nb::const_)
)
.def_property_readonly("oat_file_begin",
static_cast<getter_t<uint32_t>>(&Header::oat_file_begin)
.def_prop_ro("oat_file_begin",
nb::overload_cast<>(&Header::oat_file_begin, nb::const_)
)
.def_property_readonly("oat_file_end",
static_cast<getter_t<uint32_t>>(&Header::oat_file_end)
.def_prop_ro("oat_file_end",
nb::overload_cast<>(&Header::oat_file_end, nb::const_)
)
.def_property_readonly("oat_data_end",
static_cast<getter_t<uint32_t>>(&Header::oat_data_end)
.def_prop_ro("oat_data_end",
nb::overload_cast<>(&Header::oat_data_end, nb::const_)
)
.def_property_readonly("patch_delta",
static_cast<getter_t<int32_t>>(&Header::patch_delta)
.def_prop_ro("patch_delta",
nb::overload_cast<>(&Header::patch_delta, nb::const_)
)
.def_property_readonly("image_roots",
static_cast<getter_t<uint32_t>>(&Header::image_roots)
.def_prop_ro("image_roots",
nb::overload_cast<>(&Header::image_roots, nb::const_)
)
.def_property_readonly("pointer_size",
static_cast<getter_t<uint32_t>>(&Header::pointer_size)
.def_prop_ro("pointer_size",
nb::overload_cast<>(&Header::pointer_size, nb::const_)
)
.def_property_readonly("compile_pic",
static_cast<getter_t<bool>>(&Header::compile_pic)
.def_prop_ro("compile_pic",
nb::overload_cast<>(&Header::compile_pic, nb::const_)
)
.def_property_readonly("nb_sections",
static_cast<getter_t<uint32_t>>(&Header::nb_sections)
.def_prop_ro("nb_sections",
nb::overload_cast<>(&Header::nb_sections, nb::const_)
)
.def_property_readonly("nb_methods",
static_cast<getter_t<uint32_t>>(&Header::nb_methods)
.def_prop_ro("nb_methods",
nb::overload_cast<>(&Header::nb_methods, nb::const_)
)
.def_property_readonly("boot_image_begin",
static_cast<getter_t<uint32_t>>(&Header::boot_image_begin)
.def_prop_ro("boot_image_begin",
nb::overload_cast<>(&Header::boot_image_begin, nb::const_)
)
.def_property_readonly("boot_image_size",
static_cast<getter_t<uint32_t>>(&Header::boot_image_size)
.def_prop_ro("boot_image_size",
nb::overload_cast<>(&Header::boot_image_size, nb::const_)
)
.def_property_readonly("boot_oat_begin",
static_cast<getter_t<uint32_t>>(&Header::boot_oat_begin)
.def_prop_ro("boot_oat_begin",
nb::overload_cast<>(&Header::boot_oat_begin, nb::const_)
)
.def_property_readonly("boot_oat_size",
static_cast<getter_t<uint32_t>>(&Header::boot_oat_size)
.def_prop_ro("boot_oat_size",
nb::overload_cast<>(&Header::boot_oat_size, nb::const_)
)
.def_property_readonly("storage_mode",
static_cast<getter_t<STORAGE_MODES>>(&Header::storage_mode)
.def_prop_ro("storage_mode",
nb::overload_cast<>(&Header::storage_mode, nb::const_)
)
.def_property_readonly("data_size",
static_cast<getter_t<uint32_t>>(&Header::data_size)
.def_prop_ro("data_size",
nb::overload_cast<>(&Header::data_size, nb::const_)
)
.def("__eq__", &Header::operator==)
.def("__ne__", &Header::operator!=)
.def("__hash__",
[] (const Header& header) {
return Hash::hash(header);
})
.def("__str__",
[] (const Header& header)
{
std::ostringstream stream;
stream << header;
std::string str = stream.str();
return str;
});
}
LIEF_DEFAULT_STR(Header);
}
}
+28 -48
View File
@@ -13,68 +13,48 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyART.hpp"
#include "LIEF/ART/Parser.hpp"
#include "LIEF/ART/File.hpp"
#include "LIEF/logging.hpp"
#include "ART/pyART.hpp"
#include "pyIOStream.hpp"
#include <string>
#include <memory>
namespace LIEF {
namespace ART {
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/unique_ptr.h>
namespace LIEF::ART::py {
template<>
void create<Parser>(py::module& m) {
void create<Parser>(nb::module_& m) {
using namespace LIEF::py;
// Parser (Parser)
m.def("parse",
static_cast<std::unique_ptr<File> (*) (const std::string&)>(&Parser::parse),
"Parse the given filename and return an " RST_CLASS_REF(lief.ART.File) " object",
nb::overload_cast<const std::string&>(&Parser::parse),
"Parse the given filename and return an " RST_CLASS_REF(lief.ART.File) " object"_doc,
"filename"_a,
py::return_value_policy::take_ownership);
nb::rv_policy::take_ownership);
m.def("parse",
static_cast<std::unique_ptr<File> (*) (std::vector<uint8_t>, const std::string&)>(&Parser::parse),
"Parse the given raw data and return an " RST_CLASS_REF(lief.ART.File) " object",
nb::overload_cast<std::vector<uint8_t>, const std::string&>(&Parser::parse),
"Parse the given raw data and return an " RST_CLASS_REF(lief.ART.File) " object"_doc,
"raw"_a, "name"_a = "",
py::return_value_policy::take_ownership);
nb::rv_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) {
const auto& io = py::module::import("io");
const auto& RawIOBase = io.attr("RawIOBase");
const auto& BufferedIOBase = io.attr("BufferedIOBase");
const auto& TextIOBase = io.attr("TextIOBase");
py::object rawio;
if (py::isinstance(byteio, RawIOBase)) {
rawio = byteio;
}
else if (py::isinstance(byteio, BufferedIOBase)) {
rawio = byteio.attr("raw");
}
else if (py::isinstance(byteio, TextIOBase)) {
rawio = byteio.attr("buffer").attr("raw");
}
else {
throw py::type_error(py::repr(byteio).cast<std::string>().c_str());
}
std::string raw_str = static_cast<py::bytes>(rawio.attr("readall")());
std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))};
return LIEF::ART::Parser::parse(std::move(raw), name);
},
"io"_a, "name"_a = "",
py::return_value_policy::take_ownership);
}
[] (nb::object byteio, const std::string& name) -> nb::object {
if (auto stream = PyIOStream::from_python(std::move(byteio))) {
auto ptr = std::make_unique<PyIOStream>(std::move(*stream));
return nb::cast(Parser::parse(stream->content(), name));
}
logging::log(logging::LOG_ERR, "Can't create a LIEF stream interface over the provided io");
return nb::none();
}, "io"_a, "name"_a = "", nb::rv_policy::take_ownership);
}
}
+5 -32
View File
@@ -13,41 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PY_LIEF_ART_H_
#define PY_LIEF_ART_H_
#include "LIEF/ART.hpp"
#ifndef PY_LIEF_ART_H
#define PY_LIEF_ART_H
#include "pyLIEF.hpp"
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
namespace ART {
namespace LIEF::ART::py {
template<class T>
void create(py::module&);
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_enums(py::module&);
void init_utils(py::module&);
SPECIALIZE_CREATE(Parser);
SPECIALIZE_CREATE(File);
SPECIALIZE_CREATE(Header);
void create(nb::module_&);
void init_utils(nb::module_&);
}
}
#endif
+16 -16
View File
@@ -13,42 +13,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyART.hpp"
#include "ART/pyART.hpp"
#include "LIEF/ART/utils.hpp"
namespace LIEF {
namespace ART {
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
void init_utils(py::module& m) {
namespace LIEF::ART::py {
m.def("is_art",
static_cast<bool (*)(const std::string&)>(&is_art),
"Check if the **file** given in parameter is an ART",
void init_utils(nb::module_& m) {
lief_mod->def("is_art",
nb::overload_cast<const std::string&>(&is_art),
"Check if the **file** given in parameter is an ART"_doc,
"path"_a);
m.def("is_art",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&is_art),
"Check if the **raw data** given in parameter is a ART",
lief_mod->def("is_art",
nb::overload_cast<const std::vector<uint8_t>&>(&is_art),
"Check if the **raw data** given in parameter is a ART"_doc,
"raw"_a);
m.def("version",
static_cast<art_version_t (*)(const std::string&)>(&version),
"Return the ART version of the **file** given in parameter",
nb::overload_cast<const std::string&>(&version),
"Return the ART version of the **file** given in parameter"_doc,
"file"_a);
m.def("version",
static_cast<art_version_t (*)(const std::vector<uint8_t>&)>(&version),
"Return the ART version of the **raw data** given in parameter",
nb::overload_cast<const std::vector<uint8_t>&>(&version),
"Return the ART version of the **raw data** given in parameter"_doc,
"raw"_a);
m.def("android_version",
&android_version,
"Return the " RST_CLASS_REF(lief.Android.ANDROID_VERSIONS) " associated with the given ART version ",
"Return the " RST_CLASS_REF(lief.Android.ANDROID_VERSIONS) " associated with the given ART version "_doc,
"art_version"_a);
}
}
}
+13 -19
View File
@@ -1,25 +1,19 @@
set(LIEF_PYTHON_ABSTRACT_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyAbstract.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBinary.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySection.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbol.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRelocation.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyFunction.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/enums.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyParser.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyHeader.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pySymbol.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyRelocation.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pySection.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyFunction.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyBinary.cpp"
)
set(LIEF_PYTHON_ABSTRACT_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyAbstract.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/enums.hpp"
)
source_group("Source Files\\Abstract" FILES ${LIEF_PYTHON_ABSTRACT_SRC})
source_group("Header Files\\Abstract" FILES ${LIEF_PYTHON_ABSTRACT_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_ABSTRACT_SRC}" "${LIEF_PYTHON_ABSTRACT_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
target_sources(pyLIEF
PRIVATE ${LIEF_PYTHON_ABSTRACT_SRC} ${LIEF_PYTHON_ELF_HDR})
@@ -13,27 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyAbstract.hpp"
#include "LIEF/Abstract/enums.hpp"
#include "enums.hpp"
#include "LIEF/enums.hpp"
#include "LIEF/Abstract/EnumToString.hpp"
#include "enums_wrapper.hpp"
#define PY_ENUM(x) LIEF::to_string(x), x
namespace LIEF {
#define PY_ENUM(x) to_string(x), x
void init_enums(py::module& m) {
py::enum_<EXE_FORMATS>(m, "EXE_FORMATS")
namespace LIEF::py {
void init_enums(nb::module_& m) {
enum_<EXE_FORMATS>(m, "EXE_FORMATS")
.value(PY_ENUM(EXE_FORMATS::FORMAT_UNKNOWN))
.value(PY_ENUM(EXE_FORMATS::FORMAT_ELF))
.value(PY_ENUM(EXE_FORMATS::FORMAT_PE))
.value(PY_ENUM(EXE_FORMATS::FORMAT_MACHO));
py::enum_<OBJECT_TYPES>(m, "OBJECT_TYPES")
enum_<OBJECT_TYPES>(m, "OBJECT_TYPES")
.value(PY_ENUM(OBJECT_TYPES::TYPE_NONE))
.value(PY_ENUM(OBJECT_TYPES::TYPE_EXECUTABLE))
.value(PY_ENUM(OBJECT_TYPES::TYPE_LIBRARY))
.value(PY_ENUM(OBJECT_TYPES::TYPE_OBJECT));
py::enum_<ARCHITECTURES>(m, "ARCHITECTURES")
enum_<ARCHITECTURES>(m, "ARCHITECTURES")
.value(PY_ENUM(ARCHITECTURES::ARCH_NONE))
.value(PY_ENUM(ARCHITECTURES::ARCH_ARM))
.value(PY_ENUM(ARCHITECTURES::ARCH_ARM64))
@@ -44,9 +45,10 @@ void init_enums(py::module& m) {
.value(PY_ENUM(ARCHITECTURES::ARCH_SYSZ))
.value(PY_ENUM(ARCHITECTURES::ARCH_XCORE))
.value(PY_ENUM(ARCHITECTURES::ARCH_INTEL))
.value(PY_ENUM(ARCHITECTURES::ARCH_RISCV));
.value(PY_ENUM(ARCHITECTURES::ARCH_RISCV))
.value(PY_ENUM(ARCHITECTURES::ARCH_LOONGARCH));
py::enum_<MODES>(m, "MODES")
enum_<MODES>(m, "MODES")
.value(PY_ENUM(MODES::MODE_NONE))
.value(PY_ENUM(MODES::MODE_16))
.value(PY_ENUM(MODES::MODE_32))
@@ -64,9 +66,10 @@ void init_enums(py::module& m) {
.value(PY_ENUM(MODES::MODE_MIPS32))
.value(PY_ENUM(MODES::MODE_MIPS64));
py::enum_<ENDIANNESS>(m, "ENDIANNESS")
enum_<ENDIANNESS>(m, "ENDIANNESS")
.value(PY_ENUM(ENDIANNESS::ENDIAN_NONE))
.value(PY_ENUM(ENDIANNESS::ENDIAN_BIG))
.value(PY_ENUM(ENDIANNESS::ENDIAN_LITTLE));
}
}
@@ -13,14 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/config.h"
#include "LIEF/json.hpp"
#include "LIEF/Abstract/json.hpp"
#include "LIEF/Object.hpp"
#ifndef PY_LIEF_ENUMS_H
#define PY_LIEF_ENUMS_H
#include "pyLIEF.hpp"
void init_json_functions(py::module& m) {
m.def("to_json", &LIEF::to_json);
m.def("to_json_from_abstract", &LIEF::to_json_from_abstract);
namespace LIEF::py {
void init_enums(nb::module_& m);
}
#endif
@@ -13,32 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PY_LIEF_ABSTRACT_H_
#define PY_LIEF_ABSTRACT_H_
#include "pyLIEF.hpp"
#include "LIEF/Abstract.hpp"
#include "Abstract/init.hpp"
#include "Abstract/enums.hpp"
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#include "LIEF/Abstract/Header.hpp"
#include "LIEF/Abstract/Binary.hpp"
#include "LIEF/Abstract/Section.hpp"
#include "LIEF/Abstract/Symbol.hpp"
#include "LIEF/Abstract/Parser.hpp"
#include "LIEF/Abstract/Relocation.hpp"
#include "LIEF/Abstract/Function.hpp"
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
template<class T>
void create(py::module&);
namespace LIEF::py {
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_enums(py::module&);
SPECIALIZE_CREATE(Header);
SPECIALIZE_CREATE(Binary);
SPECIALIZE_CREATE(Section);
SPECIALIZE_CREATE(Symbol);
SPECIALIZE_CREATE(Parser);
SPECIALIZE_CREATE(Relocation);
SPECIALIZE_CREATE(Function);
void init_objects(nb::module_& m) {
CREATE(Header, m);
CREATE(Binary, m);
CREATE(Section, m);
CREATE(Symbol, m);
CREATE(Parser, m);
CREATE(Relocation, m);
CREATE(Function, m);
}
void init_abstract(nb::module_& m) {
init_enums(m);
init_objects(m);
}
}
#endif
@@ -13,24 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyVDEX.hpp"
#ifndef PY_LIEF_ABSTRACT_H
#define PY_LIEF_ABSTRACT_H
namespace LIEF {
namespace VDEX {
void init_python_module(py::module& m) {
py::module LIEF_VDEX_module = m.def_submodule("VDEX", "Python API for VDEX format");
init_objects(LIEF_VDEX_module);
init_utils(LIEF_VDEX_module);
namespace nanobind {
class module_;
}
namespace LIEF::py {
template<class T>
void create(nanobind::module_&);
void init_objects(py::module& m) {
CREATE(Parser, m);
CREATE(File, m);
CREATE(Header, m);
}
}
void init_abstract(nanobind::module_& m);
}
#endif
@@ -1,78 +0,0 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include "pyAbstract.hpp"
#include "LIEF/Abstract/Header.hpp"
namespace LIEF {
template<class T>
using getter_t = T (Header::*)(void) const;
template<class T>
using setter_t = void (Header::*)(T);
template<>
void create<Header>(py::module& m) {
py::class_<Header, Object>(m, "Header")
.def(py::init())
.def_property("architecture",
static_cast<getter_t<ARCHITECTURES>>(&Header::architecture),
static_cast<setter_t<ARCHITECTURES>>(&Header::architecture),
"Target architecture (" RST_CLASS_REF(lief.ARCHITECTURES) ")")
.def_property("modes",
static_cast<getter_t<const std::set<MODES>&>>(&Header::modes),
static_cast<setter_t<const std::set<MODES>&>>(&Header::modes),
"Target " RST_CLASS_REF(lief.MODES) " (32-bits, 64-bits...)")
.def_property("entrypoint",
static_cast<getter_t<uint64_t>>(&Header::entrypoint),
static_cast<setter_t<uint64_t>>(&Header::entrypoint),
"Binary entrypoint")
.def_property("object_type",
static_cast<getter_t<OBJECT_TYPES>>(&Header::object_type),
static_cast<setter_t<OBJECT_TYPES>>(&Header::object_type),
"Type of the binary (executable, library...)\n"
"See: " RST_CLASS_REF(lief.OBJECT_TYPES) "")
.def_property("endianness",
static_cast<getter_t<ENDIANNESS>>(&Header::endianness),
static_cast<setter_t<ENDIANNESS>>(&Header::endianness),
"Binary endianness\n"
"See: " RST_CLASS_REF(lief.ENDIANNESS) "")
.def_property_readonly("is_32",
&Header::is_32,
"``True`` if the binary targets a ``32-bits`` architecture")
.def_property_readonly("is_64",
&Header::is_64,
"``True`` if the binary targets a ``64-bits`` architecture")
.def("__str__",
[] (const Header& header)
{
std::ostringstream stream;
stream << header;
std::string str = stream.str();
return str;
});
}
}
@@ -1,119 +0,0 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 "pyAbstract.hpp"
#include "PyIOStream.hpp"
#include "LIEF/logging.hpp"
#include "LIEF/Abstract/Parser.hpp"
#include <string>
#include <stdexcept>
namespace LIEF {
template<>
void create<Parser>(py::module& m) {
m.def("parse",
[] (py::bytes bytes, const std::string& name) {
std::string raw_str = bytes;
std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))
};
std::unique_ptr<Binary> binary;
std::exception_ptr ep;
Py_BEGIN_ALLOW_THREADS
try {
binary = Parser::parse(std::move(raw), name);
} catch (...) {
ep = std::current_exception();
}
Py_END_ALLOW_THREADS
if (ep) std::rethrow_exception(ep);
return binary;
},
R"delim(
Parse a binary supported by LIEF from the given bytes and return either:
- :class:`lief.ELF.Binary`
- :class:`lief.PE.Binary`
- :class:`lief.MachO.Binary`
depending on the given binary format.
)delim",
"raw"_a, "name"_a = "",
py::return_value_policy::take_ownership);
m.def("parse",
[] (const std::string& filepath) {
std::unique_ptr<Binary> binary;
std::exception_ptr ep;
Py_BEGIN_ALLOW_THREADS
try {
binary = Parser::parse(filepath);
} catch (...) {
ep = std::current_exception();
}
Py_END_ALLOW_THREADS
if (ep) std::rethrow_exception(ep);
return binary;
},
R"delim(
Parse a binary from the given file path and return either:
- :class:`lief.ELF.Binary`
- :class:`lief.PE.Binary`
- :class:`lief.MachO.Binary`
depending on the given binary format.
)delim",
"filepath"_a,
py::return_value_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) -> py::object {
if (auto stream = PyIOStream::from_python(byteio)) {
auto ptr = std::make_unique<PyIOStream>(std::move(*stream));
py::object binary;
std::exception_ptr ep;
Py_BEGIN_ALLOW_THREADS
try {
binary = py::cast(Parser::parse(std::move(ptr)));
} catch (...) {
ep = std::current_exception();
}
Py_END_ALLOW_THREADS
if (ep) std::rethrow_exception(ep);
return binary;
}
logging::log(logging::LOG_ERR, "Can't create a LIEF stream interface over the provided io");
return py::none();
},
R"delim(
Parse a binary supported by LIEF from the given Python IO interface and return either:
- :class:`lief.ELF.Binary`
- :class:`lief.PE.Binary`
- :class:`lief.MachO.Binary`
depending on the given binary format.
)delim",
"io"_a, "name"_a = "",
py::return_value_policy::take_ownership);
}
}
@@ -1,69 +0,0 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include "pyAbstract.hpp"
#include "LIEF/Abstract/hash.hpp"
#include "LIEF/Abstract/Relocation.hpp"
namespace LIEF {
template<class T>
using getter_t = T (Relocation::*)(void) const;
template<class T>
using setter_t = void (Relocation::*)(T);
template<>
void create<Relocation>(py::module& m) {
py::class_<Relocation, Object>(m, "Relocation",
R"delim(
Class which represents an abstracted Relocation
)delim")
.def(py::init(),
"Default constructor")
.def(py::init<uint64_t, uint8_t>(),
"Constructor from an :attr:`~lief.Relocation.address` and a :attr:`~lief.Relocation.size`",
"address"_a, "size"_a)
.def_property("address",
static_cast<getter_t<uint64_t>>(&Relocation::address),
static_cast<setter_t<uint64_t>>(&Relocation::address),
"Relocation's address")
.def_property("size",
static_cast<getter_t<size_t>>(&Relocation::size),
static_cast<setter_t<size_t>>(&Relocation::size),
"Relocation's size (in **bits**)")
.def("__eq__", &Relocation::operator==)
.def("__ne__", &Relocation::operator!=)
.def("__hash__",
[] (const Relocation& relocation) {
return AbstractHash::hash(relocation);
})
.def("__str__",
[] (const Relocation& entry)
{
std::ostringstream stream;
stream << entry;
std::string str = stream.str();
return str;
});
}
}
@@ -1,135 +0,0 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include "pyAbstract.hpp"
#include "LIEF/Abstract/Section.hpp"
namespace LIEF {
template<class T>
using getter_t = T (Section::*)(void) const;
template<class T>
using setter_t = void (Section::*)(T);
template<>
void create<Section>(py::module& m) {
py::class_<Section, Object>(m, "Section",
R"delim(
Class which represents an abstracted section
)delim")
.def(py::init(),
"Default constructor")
.def(py::init<const std::string&>(),
"Constructor from section name",
"name"_a)
.def_property("name",
[] (const Section& obj) {
return safe_string_converter(obj.name());
},
static_cast<setter_t<const std::string&>>(&Section::name),
"Section's name")
.def_property_readonly("fullname",
&Section::fullname,
"Return the **fullname** of the section including the trailing bytes")
.def_property("size",
static_cast<getter_t<uint64_t>>(&Section::size),
static_cast<setter_t<uint64_t>>(&Section::size),
"Section's size")
.def_property("offset",
static_cast<getter_t<uint64_t>>(&Section::offset),
static_cast<setter_t<uint64_t>>(&Section::offset),
"Section's file offset")
.def_property("virtual_address",
static_cast<getter_t<uint64_t>>(&Section::virtual_address),
static_cast<setter_t<uint64_t>>(&Section::virtual_address),
"Section's virtual address")
.def_property("content",
[] (const Section& self) {
span<const uint8_t> content = self.content();
return py::memoryview::from_memory(content.data(), content.size());
},
static_cast<setter_t<const std::vector<uint8_t>&>>(&Section::content),
"Section's content")
.def_property_readonly("entropy",
&Section::entropy,
"Section's entropy")
.def("search",
[] (const Section& self, uint64_t number, size_t pos, size_t size) -> py::object {
size_t res = self.search(number, pos, size);
if (res == Section::npos) {
return py::none();
}
return py::cast(res);
},
"Look for **integer** within the current section",
"number"_a, "pos"_a = 0, "size"_a = 0)
.def("search",
[] (const Section& self, const std::string& str, size_t pos) -> py::object {
size_t res = self.search(str, pos);
if (res == Section::npos) {
return py::none();
}
return py::cast(res);
},
"Look for **string** within the current section",
"str"_a, "pos"_a = 0)
.def("search",
[] (const Section& self, py::bytes bytes, size_t pos) -> py::object {
std::string raw_str = bytes;
std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))
};
size_t res = self.search(raw, pos);
if (res == Section::npos) {
return py::none();
}
return py::cast(res);
},
"Look for the given bytes within the current section",
"bytes"_a, "pos"_a = 0)
.def("search_all",
static_cast<std::vector<size_t> (Section::*)(uint64_t, size_t) const>(&Section::search_all),
"Look for **all** integers within the current section",
"number"_a, "size"_a = 0)
.def("search_all",
static_cast<std::vector<size_t> (Section::*)(const std::string&) const>(&Section::search_all),
"Look for all **strings** within the current section",
"str"_a)
.def("__str__",
[] (const Section& section)
{
std::ostringstream stream;
stream << section;
std::string str = stream.str();
return str;
});
}
}
@@ -1,66 +0,0 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 "pyAbstract.hpp"
#include "LIEF/Abstract/Symbol.hpp"
#include <string>
#include <sstream>
namespace LIEF {
template<class T>
using getter_t = T (Symbol::*)(void) const;
template<class T>
using setter_t = void (Symbol::*)(T);
template<>
void create<Symbol>(py::module& m) {
py::class_<Symbol, Object>(m, "Symbol",
R"delim(
This class represents a symbol in an executable format.
)delim")
.def(py::init())
.def_property("name",
[] (const Symbol& obj) {
return safe_string_converter(obj.name());
},
static_cast<setter_t<const std::string&>>(&Symbol::name),
"Symbol's name")
.def_property("value",
static_cast<getter_t<uint64_t>>(&Symbol::value),
static_cast<setter_t<uint64_t>>(&Symbol::value),
"Symbol's value")
.def_property("size",
static_cast<getter_t<uint64_t>>(&Symbol::size),
static_cast<setter_t<uint64_t>>(&Symbol::size),
"Symbol's size")
.def("__str__",
[] (const Symbol& symbol)
{
std::ostringstream stream;
stream << symbol;
std::string str = stream.str();
return str;
});
}
}
@@ -13,43 +13,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <algorithm>
#include <sstream>
#include <iostream>
#include "pyAbstract.hpp"
#include "pyIterators.hpp"
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "pyErr.hpp"
#include "LIEF/Abstract/Binary.hpp"
#include "pySafeString.hpp"
#include "nanobind/extra/memoryview.hpp"
#include "pyIterator.hpp"
#include "LIEF/logging.hpp"
#include "LIEF/Abstract/Binary.hpp"
#include "LIEF/Abstract/Relocation.hpp"
#include "LIEF/Abstract/Symbol.hpp"
#include "LIEF/Abstract/Section.hpp"
#include "LIEF/Abstract/Header.hpp"
#include "LIEF/Abstract/EnumToString.hpp"
#define PY_ENUM(x) LIEF::to_string(x), x
namespace LIEF {
template<class T>
using getter_t = T (Binary::*)(void) const;
template<class T>
using setter_t = void (Binary::*)(T);
template<class T>
using it_t = T (Binary::*)(void);
template<class T, class P>
using no_const_func = T (Binary::*)(P);
namespace LIEF::py {
template<>
void create<Binary>(py::module& m) {
py::class_<Binary, Object> pybinary(m, "Binary",
void create<Binary>(nb::module_& m) {
nb::class_<Binary, Object> pybinary(m, "Binary",
R"delim(
File format abstract representation.
This object represents the abstraction of an executable file format.
It enables to access common features (like the :attr:`~lief.Binary.entrypoint`) regardless
of the concrete format (e.g. :attr:`lief.ELF.Binary.entrypoint`)
)delim");
)delim"_doc);
py::enum_<Binary::VA_TYPES>(pybinary, "VA_TYPES")
nb::enum_<Binary::VA_TYPES>(pybinary, "VA_TYPES")
.value(PY_ENUM(Binary::VA_TYPES::AUTO))
.value(PY_ENUM(Binary::VA_TYPES::VA))
.value(PY_ENUM(Binary::VA_TYPES::RVA));
@@ -59,122 +60,117 @@ void create<Binary>(py::module& m) {
init_ref_iterator<Binary::it_relocations>(pybinary, "it_relocations");
pybinary
.def_property_readonly("format",
.def_prop_ro("format",
&Binary::format,
"File format " RST_CLASS_REF(lief.EXE_FORMATS) " of the underlying binary.")
"File format " RST_CLASS_REF(lief.EXE_FORMATS) " of the underlying binary."_doc)
.def_property_readonly("is_pie",
.def_prop_ro("is_pie",
&Binary::is_pie,
"Check if the binary is position independent")
"Check if the binary is position independent"_doc)
.def_property_readonly("has_nx",
.def_prop_ro("has_nx",
&Binary::has_nx,
"Check if the binary has ``NX`` protection (non executable stack)")
"Check if the binary has ``NX`` protection (non executable stack)"_doc)
.def_property("name",
static_cast<getter_t<const std::string&>>(&Binary::name),
static_cast<setter_t<const std::string&>>(&Binary::name),
"Binary's name")
.def_property_readonly("header",
.def_prop_ro("header",
&Binary::header,
"Binary's abstract header (" RST_CLASS_REF(lief.Header) ")")
"Binary's abstract header (" RST_CLASS_REF(lief.Header) ")"_doc)
.def_property_readonly("entrypoint",
.def_prop_ro("entrypoint",
&Binary::entrypoint,
"Binary's entrypoint")
"Binary's entrypoint"_doc)
.def("remove_section",
static_cast<void (Binary::*)(const std::string&, bool)>(&Binary::remove_section),
"Remove the section with the given name",
nb::overload_cast<const std::string&, bool>(&Binary::remove_section),
"Remove the section with the given name"_doc,
"name"_a, "clear"_a = false)
.def_property_readonly("sections",
static_cast<it_t<Binary::it_sections>>(&Binary::sections),
"Return an iterator over the binary's abstract sections (" RST_CLASS_REF(lief.Section) ")",
py::return_value_policy::reference_internal)
.def_prop_ro("sections",
nb::overload_cast<>(&Binary::sections),
"Return an iterator over the binary's abstract sections (" RST_CLASS_REF(lief.Section) ")"_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("relocations",
static_cast<it_t<Binary::it_relocations>>(&Binary::relocations),
"Return an iterator over abstract " RST_CLASS_REF(lief.Relocation) "",
py::return_value_policy::reference_internal)
.def_prop_ro("relocations",
nb::overload_cast<>(&Binary::relocations),
"Return an iterator over abstract " RST_CLASS_REF(lief.Relocation) ""_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("exported_functions",
.def_prop_ro("exported_functions",
&Binary::exported_functions,
"Return the binary's exported " RST_CLASS_REF(lief.Function) "")
"Return the binary's exported " RST_CLASS_REF(lief.Function) ""_doc)
.def_property_readonly("imported_functions",
.def_prop_ro("imported_functions",
&Binary::imported_functions,
"Return the binary's imported " RST_CLASS_REF(lief.Function) " (name)")
"Return the binary's imported " RST_CLASS_REF(lief.Function) " (name)"_doc)
.def_property_readonly("libraries",
.def_prop_ro("libraries",
[] (const Binary& binary) {
const std::vector<std::string>& imported_libraries = binary.imported_libraries();
std::vector<py::object> imported_libraries_encoded;
std::vector<nb::object> imported_libraries_encoded;
imported_libraries_encoded.reserve(imported_libraries.size());
std::transform(
std::begin(imported_libraries), std::end(imported_libraries),
std::back_inserter(imported_libraries_encoded),
&safe_string_converter);
&safe_string);
return imported_libraries_encoded;
},
"Return binary's imported libraries (name)")
"Return binary's imported libraries (name)"_doc)
.def_property_readonly("symbols",
static_cast<it_t<Binary::it_symbols>>(&Binary::symbols),
"Return an iterator over the binary's abstract " RST_CLASS_REF(lief.Symbol) "",
py::return_value_policy::reference_internal)
.def_prop_ro("symbols",
nb::overload_cast<>(&Binary::symbols),
"Return an iterator over the binary's abstract " RST_CLASS_REF(lief.Symbol) ""_doc,
nb::keep_alive<0, 1>())
.def("has_symbol",
&Binary::has_symbol,
"Check if a " RST_CLASS_REF(lief.Symbol) " with the given name exists",
"Check if a " RST_CLASS_REF(lief.Symbol) " with the given name exists"_doc,
"symbol_name"_a)
.def("get_symbol",
static_cast<no_const_func<Symbol*, const std::string&>>(&Binary::get_symbol),
nb::overload_cast<const std::string&>(&Binary::get_symbol),
R"delim(
Return the :class:`~lief.Symbol` from the given ``name``.
If the symbol can't be found, it returns None.
)delim",
)delim"_doc,
"symbol_name"_a,
py::return_value_policy::reference_internal)
nb::rv_policy::reference_internal)
.def("get_function_address",
[] (const Binary& self, const std::string& name) {
return error_or(&Binary::get_function_address, self, name);
},
"Return the address of the given function name",
"Return the address of the given function name"_doc,
"function_name"_a)
.def("patch_address",
static_cast<void (Binary::*) (uint64_t, const std::vector<uint8_t>&, Binary::VA_TYPES)>(&Binary::patch_address),
nb::overload_cast<uint64_t, const std::vector<uint8_t>&, Binary::VA_TYPES>(&Binary::patch_address),
R"delim(
Patch the address with the given list of bytes.
The virtual address is specified in the first argument and the content in the second (as a list of bytes).
If the underlying binary is a PE, one can specify if the virtual address is a :attr:`~lief.Binary.VA_TYPES.RVA` or
a :attr:`~lief.Binary.VA_TYPES.VA`. By default, it is set to :attr:`~lief.Binary.VA_TYPES.AUTO`.
)delim",
)delim"_doc,
"address"_a, "patch_value"_a, "va_type"_a = Binary::VA_TYPES::AUTO)
.def("patch_address",
static_cast<void (Binary::*) (uint64_t, uint64_t, size_t, Binary::VA_TYPES)>(&Binary::patch_address),
nb::overload_cast<uint64_t, uint64_t, size_t, Binary::VA_TYPES>(&Binary::patch_address),
R"delim(
Patch the address with the given integer value.
The virtual address is specified in the first argument, the integer in the second and the integer's size of in third one.
If the underlying binary is a PE, one can specify if the virtual address is a :attr:`~lief.Binary.VA_TYPES.RVA` or
a :attr:`~lief.Binary.VA_TYPES.VA`. By default, it is set to :attr:`~lief.Binary.VA_TYPES.AUTO`.
)delim",
)delim"_doc,
"address"_a, "patch_value"_a, "size"_a = 8, "va_type"_a = Binary::VA_TYPES::AUTO)
.def("get_content_from_virtual_address",
[] (const Binary& self, uint64_t va, size_t size, Binary::VA_TYPES type) {
span<const uint8_t> content = self.get_content_from_virtual_address(va, size, type);
return py::memoryview::from_memory(content.data(), content.size());
.def("get_content_from_virtual_address",
[] (const Binary& self, uint64_t va, size_t size, Binary::VA_TYPES type) {
const span<const uint8_t> content = self.get_content_from_virtual_address(va, size, type);
return nb::memoryview::from_memory(content.data(), content.size());
},
R"delim(
Return the content located at the provided virtual address.
@@ -182,70 +178,55 @@ void create<Binary>(py::module& m) {
If the underlying binary is a PE, one can specify if the virtual address is a :attr:`~lief.Binary.VA_TYPES.RVA` or
a :attr:`~lief.Binary.VA_TYPES.VA`. By default, it is set to :attr:`~lief.Binary.VA_TYPES.AUTO`.
)delim",
)delim"_doc,
"virtual_address"_a, "size"_a, "va_type"_a = Binary::VA_TYPES::AUTO)
.def_property_readonly("abstract",
[m] (py::object& self) {
self.attr("__class__") = m.attr("Binary");
return self;
.def_prop_ro("abstract",
[] (nb::object& self) -> nb::object {
auto* ab = nb::cast<LIEF::Binary*>(self);
const nb::handle base_type = nb::type<LIEF::Binary>();
nb::object py_inst = nb::inst_reference(base_type, ab, self);
nb::inst_set_state(py_inst, /*ready=*/true, /*destruct=*/false);
return py_inst;
},
R"delim(
Return the abstract representation of the current binary (:class:`lief.Binary`)
)delim"_doc,
nb::rv_policy::reference_internal)
.. warning::
Getting this property modifies the ``__class__`` attribute such as
the current binary looks like a :class:`lief.Binary`.
To get back to the original binary, one needs to access :attr:`lief.Binary.concrete`
)delim",
py::return_value_policy::reference)
.def_property_readonly("concrete",
[m] (py::object& self) {
self.attr("__class__") = py::cast(self.cast<Binary*>()).attr("__class__");
return self;
.def_prop_ro("concrete",
[] (nb::object& self) {
return nb::cast(nb::cast<LIEF::Binary*>(self));
},
R"delim(
The *concrete* representation of the binary. Basically, this property cast a :class:`lief.Binary`
into a :class:`lief.PE.Binary`, :class:`lief.ELF.Binary` or :class:`lief.MachO.Binary`.
See also: :attr:`lief.Binary.abstract`
)delim",
py::return_value_policy::reference)
)delim"_doc,
nb::rv_policy::reference)
.def_property_readonly("ctor_functions",
.def_prop_ro("ctor_functions",
&Binary::ctor_functions,
"Constructor functions that are called prior to any other functions")
"Constructor functions that are called prior to any other functions"_doc)
.def("xref",
&Binary::xref,
"Return all **virtual addresses** that *use* the ``address`` given in parameter",
"Return all **virtual addresses** that *use* the ``address`` given in parameter"_doc,
"virtual_address"_a)
.def("offset_to_virtual_address",
[] (const Binary& self, uint64_t offset, uint64_t slide) {
return error_or(&Binary::offset_to_virtual_address, self, offset, slide);
},
"Convert an offset into a virtual address.",
"Convert an offset into a virtual address."_doc,
"offset"_a, "slide"_a = 0)
.def_property_readonly("imagebase",
.def_prop_ro("imagebase",
&Binary::imagebase,
"Default image base (i.e. if the ASLR is not enabled)")
"Default image base (i.e. if the ASLR is not enabled)"_doc)
.def("__str__",
[] (const Binary& binary)
{
std::ostringstream stream;
stream << binary;
std::string str = stream.str();
return str;
});
LIEF_DEFAULT_STR(Binary);
}
}
@@ -13,31 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyAbstract.hpp"
#include "LIEF/Abstract/Symbol.hpp"
#include <string>
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/set.h>
#include <nanobind/stl/vector.h>
#include "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "LIEF/Abstract/Function.hpp"
#include "LIEF/Abstract/EnumToString.hpp"
#define PY_ENUM(x) LIEF::to_string(x), x
namespace LIEF {
template<class T>
using getter_t = T (Function::*)(void) const;
template<class T>
using setter_t = void (Function::*)(T);
namespace LIEF::py {
template<>
void create<Function>(py::module& m) {
py::class_<Function, Symbol> pyfunction(m, "Function",
void create<Function>(nb::module_& m) {
nb::class_<Function, Symbol> pyfunction(m, "Function",
R"delim(
Class which represents a Function in an executable file format.
)delim");
)delim"_doc);
py::enum_<Function::FLAGS>(pyfunction, "FLAGS")
nb::enum_<Function::FLAGS>(pyfunction, "FLAGS")
.value(PY_ENUM(Function::FLAGS::IMPORTED))
.value(PY_ENUM(Function::FLAGS::EXPORTED))
.value(PY_ENUM(Function::FLAGS::CONSTRUCTOR))
@@ -45,32 +44,26 @@ void create<Function>(py::module& m) {
.value(PY_ENUM(Function::FLAGS::DEBUG));
pyfunction
.def(py::init())
.def(py::init<const std::string&>())
.def(py::init<uint64_t>())
.def(py::init<const std::string&, uint64_t>())
.def(nb::init())
.def(nb::init<const std::string&>())
.def(nb::init<uint64_t>())
.def(nb::init<const std::string&, uint64_t>())
.def("add",
&Function::add,
"Add the given " RST_CLASS_REF(lief.Function.FLAGS) "",
"Add the given " RST_CLASS_REF(lief.Function.FLAGS) ""_doc,
"flag"_a)
.def_property_readonly("flags",
.def_prop_ro("flags",
&Function::flags,
"Function flags as a list of " RST_CLASS_REF(lief.Function.FLAGS) "")
"Function flags as a list of " RST_CLASS_REF(lief.Function.FLAGS) ""_doc)
.def_property("address",
static_cast<getter_t<uint64_t>>(&Function::address),
static_cast<setter_t<uint64_t>>(&Function::address),
"Function's address")
.def_prop_rw("address",
nb::overload_cast<>(&Function::address, nb::const_),
nb::overload_cast<uint64_t>(&Function::address),
"Function's address"_doc)
.def("__str__",
[] (const Function& f) {
std::ostringstream stream;
stream << f;
std::string str = stream.str();
return str;
});
}
LIEF_DEFAULT_STR(Function);
}
}
+72
View File
@@ -0,0 +1,72 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/set.h>
#include "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "LIEF/Abstract/Header.hpp"
namespace LIEF::py {
template<>
void create<Header>(nb::module_& m) {
nb::class_<Header, Object>(m, "Header",
R"delim(
Class which represents an abstracted Header
)delim"_doc)
.def(nb::init())
.def_prop_rw("architecture",
nb::overload_cast<>(&Header::architecture, nb::const_),
nb::overload_cast<ARCHITECTURES>(&Header::architecture),
"Target architecture (" RST_CLASS_REF(lief.ARCHITECTURES) ")"_doc)
.def_prop_rw("modes",
nb::overload_cast<>(&Header::modes, nb::const_),
nb::overload_cast<const std::set<MODES>&>(&Header::modes),
"Target " RST_CLASS_REF(lief.MODES) " (32-bits, 64-bits...)"_doc)
.def_prop_rw("entrypoint",
nb::overload_cast<>(&Header::entrypoint, nb::const_),
nb::overload_cast<uint64_t>(&Header::entrypoint),
"Binary entrypoint"_doc)
.def_prop_rw("object_type",
nb::overload_cast<>(&Header::object_type, nb::const_),
nb::overload_cast<OBJECT_TYPES>(&Header::object_type),
"Type of the binary (executable, library...)\n"
"See: " RST_CLASS_REF(lief.OBJECT_TYPES) ""_doc)
.def_prop_rw("endianness",
nb::overload_cast<>(&Header::endianness, nb::const_),
nb::overload_cast<ENDIANNESS>(&Header::endianness),
"Binary endianness\n"
"See: " RST_CLASS_REF(lief.ENDIANNESS) ""_doc)
.def_prop_ro("is_32",
&Header::is_32,
"``True`` if the binary targets a ``32-bits`` architecture"_doc)
.def_prop_ro("is_64",
&Header::is_64,
"``True`` if the binary targets a ``64-bits`` architecture"_doc)
LIEF_DEFAULT_STR(Header);
}
}
+89
View File
@@ -0,0 +1,89 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "pyIOStream.hpp"
#include <nanobind/stl/unique_ptr.h>
#include <nanobind/stl/string.h>
#include "LIEF/Abstract/Parser.hpp"
#include "LIEF/Abstract/Binary.hpp"
#include "LIEF/logging.hpp"
namespace LIEF::py {
template<>
void create<Parser>(nb::module_& m) {
m.def("parse",
[] (nb::bytes bytes) {
std::string raw_str(bytes.c_str(), bytes.size());
const std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))
};
std::unique_ptr<Binary> binary = Parser::parse(raw);
return binary;
},
R"delim(
Parse a binary supported by LIEF from the given bytes and return either:
- :class:`lief.ELF.Binary`
- :class:`lief.PE.Binary`
- :class:`lief.MachO.Binary`
depending on the given binary format.
)delim"_doc,
"raw"_a,
nb::rv_policy::take_ownership);
m.def("parse", nb::overload_cast<const std::string&>(&Parser::parse),
R"delim(
Parse a binary from the given file path and return either:
- :class:`lief.ELF.Binary`
- :class:`lief.PE.Binary`
- :class:`lief.MachO.Binary`
depending on the given binary format.
)delim"_doc,
"filepath"_a, nb::rv_policy::take_ownership);
m.def("parse",
[] (nb::object byteio) -> nb::object {
if (auto stream = PyIOStream::from_python(std::move(byteio))) {
auto ptr = std::make_unique<PyIOStream>(std::move(*stream));
return nb::cast(Parser::parse(std::move(ptr)));
}
logging::log(logging::LOG_ERR,
"Can't create a LIEF stream interface over the provided io");
return nb::none();
},
R"delim(
Parse a binary supported by LIEF from the given Python IO interface and return either:
- :class:`lief.ELF.Binary`
- :class:`lief.PE.Binary`
- :class:`lief.MachO.Binary`
depending on the given binary format.
)delim"_doc,
"io"_a,
nb::rv_policy::take_ownership);
}
}
+46
View File
@@ -0,0 +1,46 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include <nanobind/stl/string.h>
#include "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "LIEF/Abstract/hash.hpp"
#include "LIEF/Abstract/Relocation.hpp"
namespace LIEF::py {
template<>
void create<Relocation>(nb::module_& m) {
nb::class_<Relocation, Object>(m, "Relocation",
R"delim(
Class which represents an abstracted Relocation
)delim")
.def_prop_rw("address",
nb::overload_cast<>(&Relocation::address, nb::const_),
nb::overload_cast<uint64_t>(&Relocation::address),
"Relocation's address"_doc)
.def_prop_rw("size",
nb::overload_cast<>(&Relocation::size, nb::const_),
nb::overload_cast<size_t>(&Relocation::size),
"Relocation's size (in **bits**)"_doc)
LIEF_DEFAULT_STR(Relocation);
}
}
+132
View File
@@ -0,0 +1,132 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "pySafeString.hpp"
#include "nanobind/extra/memoryview.hpp"
#include "LIEF/Abstract/Section.hpp"
namespace LIEF::py {
template<>
void create<Section>(nb::module_& m) {
nb::class_<Section, Object>(m, "Section",
R"delim(
Class which represents an abstracted section
)delim"_doc)
.def_prop_rw("name",
[] (const Section& obj) {
return safe_string(obj.name());
},
nb::overload_cast<const std::string&>(&Section::name),
"Section's name"_doc)
.def_prop_ro("fullname",
&Section::fullname,
"Return the **fullname** of the section including the trailing bytes"_doc)
.def_prop_rw("size",
nb::overload_cast<>(&Section::size, nb::const_),
nb::overload_cast<uint64_t>(&Section::size),
"Section's size"_doc)
.def_prop_rw("offset",
nb::overload_cast<>(&Section::offset, nb::const_),
nb::overload_cast<uint64_t>(&Section::offset),
"Section's file offset"_doc)
.def_prop_rw("virtual_address",
nb::overload_cast<>(&Section::virtual_address, nb::const_),
nb::overload_cast<uint64_t>(&Section::virtual_address),
"Section's virtual address"_doc)
.def_prop_rw("content",
[] (const Section& self) {
const span<const uint8_t> content = self.content();
return nb::memoryview::from_memory(content.data(), content.size());
},
nb::overload_cast<const std::vector<uint8_t>&>(&Section::content),
"Section's content"_doc)
.def_prop_ro("entropy",
&Section::entropy,
"Section's entropy"_doc)
.def("search",
[] (const Section& self,
uint64_t number, size_t pos, size_t size) -> nb::object
{
size_t res = self.search(number, pos, size);
if (res == Section::npos) {
return nb::none();
}
return nb::cast(res);
},
"Look for **integer** within the current section"_doc,
"number"_a, "pos"_a = 0, "size"_a = 0)
.def("search",
[] (const Section& self,
const std::string& str, size_t pos) ->nb::object
{
size_t res = self.search(str, pos);
if (res == Section::npos) {
return nb::none();
}
return nb::cast(res);
},
"Look for **string** within the current section"_doc,
"str"_a, "pos"_a = 0)
.def("search",
[] (const Section& self,
nb::bytes bytes, size_t pos) -> nb::object
{
std::string raw_str(bytes.c_str(), bytes.size());
const std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))
};
size_t res = self.search(raw, pos);
if (res == Section::npos) {
return nb::none();
}
return nb::cast(res);
},
"Look for the given bytes within the current section"_doc,
"bytes"_a, "pos"_a = 0)
.def("search_all",
nb::overload_cast<uint64_t, size_t>(&Section::search_all, nb::const_),
"Look for **all** integers within the current section"_doc,
"number"_a, "size"_a = 0)
.def("search_all",
nb::overload_cast<const std::string&>(&Section::search_all, nb::const_),
"Look for all **strings** within the current section"_doc,
"str"_a)
LIEF_DEFAULT_STR(Section);
}
}
+53
View File
@@ -0,0 +1,53 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 <sstream>
#include <nanobind/stl/string.h>
#include "Abstract/init.hpp"
#include "pyLIEF.hpp"
#include "pySafeString.hpp"
#include "LIEF/Abstract/Symbol.hpp"
namespace LIEF::py {
template<>
void create<Symbol>(nb::module_& m) {
nb::class_<Symbol, Object>(m, "Symbol",
R"delim(
This class represents a symbol in an executable format.
)delim"_doc)
.def_prop_rw("name",
[] (const Symbol& obj) {
return safe_string(obj.name());
},
nb::overload_cast<const std::string&>(&Symbol::name),
"Symbol's name"_doc)
.def_prop_rw("value",
nb::overload_cast<>(&Symbol::value, nb::const_),
nb::overload_cast<uint64_t>(&Symbol::value),
"Symbol's value"_doc)
.def_prop_rw("size",
nb::overload_cast<>(&Symbol::size, nb::const_),
nb::overload_cast<uint64_t>(&Symbol::size),
"Symbol's size"_doc)
LIEF_DEFAULT_STR(Symbol);
}
}
+6 -20
View File
@@ -1,27 +1,13 @@
set(LIEF_PYTHON_DEX_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyDEX.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyUtils.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyFile.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyClass.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyField.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyMethod.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyMapList.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyMapItem.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyType.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyPrototype.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyUtils.cpp"
)
set(LIEF_PYTHON_DEX_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyDEX.hpp")
"${CMAKE_CURRENT_SOURCE_DIR}/pyDEX.hpp")
source_group("Source Files\\DEX" FILES ${LIEF_PYTHON_DEX_SRC})
source_group("Header Files\\DEX" FILES ${LIEF_PYTHON_DEX_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_DEX_SRC}" "${LIEF_PYTHON_DEX_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/../")
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_DEX_SRC} ${LIEF_PYTHON_DEX_HDR})
add_subdirectory(objects)
@@ -13,21 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
#include "DEX/init.hpp"
#include "LIEF/DEX/Parser.hpp"
#include "LIEF/DEX/File.hpp"
#include "LIEF/DEX/Header.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/Method.hpp"
#include "LIEF/DEX/Field.hpp"
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/Type.hpp"
#include "LIEF/DEX/MapList.hpp"
#include "LIEF/DEX/MapItem.hpp"
#include "LIEF/DEX/CodeInfo.hpp"
namespace LIEF {
namespace DEX {
void init_python_module(py::module& m) {
py::module LIEF_DEX_module = m.def_submodule("DEX", "Python API for DEX format");
#define CREATE(X,Y) create<X>(Y)
init_enums(LIEF_DEX_module);
init_objects(LIEF_DEX_module);
init_utils(LIEF_DEX_module);
}
void init_objects(py::module& m) {
namespace LIEF::DEX::py {
void init_objects(nb::module_& m) {
CREATE(Parser, m);
CREATE(File, m);
CREATE(Header, m);
@@ -41,5 +45,12 @@ void init_objects(py::module& m) {
CREATE(CodeInfo, m);
}
void init(nb::module_& m) {
nb::module_ mod = m.def_submodule("DEX", "Python API for DEX format");
init_enums(mod);
init_objects(mod);
init_utils(mod);
}
}
+25
View File
@@ -0,0 +1,25 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 PY_LIEF_DEX_INIT_H
#define PY_LIEF_DEX_INIT_H
#include "pyLIEF.hpp"
namespace LIEF::DEX::py {
void init(nb::module_& m);
void init_enums(nb::module_& m);
void init_utils(nb::module_& m);
}
#endif
+17
View File
@@ -0,0 +1,17 @@
set(LIEF_PYTHON_DEX_OBJ_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/pyHeader.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyParser.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyFile.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyClass.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyField.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyMethod.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyCodeInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyMapList.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyMapItem.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyType.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyPrototype.cpp"
)
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_DEX_OBJ_SRC})
+46 -77
View File
@@ -13,29 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "DEX/pyDEX.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/Field.hpp"
#include "LIEF/DEX/Method.hpp"
#include "pyIterators.hpp"
#include "pyDEX.hpp"
#include "pyIterator.hpp"
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (Class::*)(void) const;
template<class T>
using no_const_getter_t = T (Class::*)(void);
template<class T>
using setter_t = void (Class::*)(T);
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/unordered_map.h>
namespace LIEF::DEX::py {
template<>
void create<Class>(py::module& m) {
void create<Class>(nb::module_& m) {
using namespace LIEF::py;
py::class_<Class, LIEF::Object> cls(m, "Class", "DEX Class representation");
nb::class_<Class, LIEF::Object> cls(m, "Class", "DEX Class representation"_doc);
init_ref_iterator<Class::it_methods>(cls, "it_methods");
init_ref_iterator<Class::it_fields>(cls, "it_fields");
@@ -44,84 +42,55 @@ void create<Class>(py::module& m) {
init_ref_iterator<Class::it_named_fields>(cls, "it_named_fields");
cls
.def_property_readonly("fullname",
&Class::fullname,
"Mangled class name (e.g. ``Lcom/example/android/MyActivity;``)")
.def_prop_ro("fullname", &Class::fullname,
"Mangled class name (e.g. ``Lcom/example/android/MyActivity;``)"_doc)
.def_property_readonly("pretty_name",
&Class::pretty_name,
"Demangled class name (e.g. ``com.example.android.MyActivity``)")
.def_prop_ro("pretty_name", &Class::pretty_name,
"Demangled class name (e.g. ``com.example.android.MyActivity``)"_doc)
.def_property_readonly("name",
&Class::name,
"Class name (e.g. ``MyActivity``)")
.def_prop_ro("name", &Class::name,
"Class name (e.g. ``MyActivity``)"_doc)
.def_property_readonly("source_filename",
&Class::source_filename,
"Original filename")
.def_prop_ro("source_filename", &Class::source_filename,
"Original filename"_doc)
.def_property_readonly("package_name",
&Class::package_name,
"Package Name (e.g. ``com.example.android``)")
.def_prop_ro("package_name", &Class::package_name,
"Package Name (e.g. ``com.example.android``)"_doc)
.def_property_readonly("has_parent",
&Class::has_parent,
"True if the current class extends another one")
.def_prop_ro("has_parent", &Class::has_parent,
"True if the current class extends another one"_doc)
.def_property_readonly("parent",
static_cast<no_const_getter_t<Class*>>(&Class::parent),
"" RST_CLASS_REF(lief.DEX.Class) " parent class")
.def_prop_ro("parent", nb::overload_cast<>(&Class::parent),
"" RST_CLASS_REF(lief.DEX.Class) " parent class"_doc)
.def_property_readonly("methods",
static_cast<no_const_getter_t<Class::it_methods>>(&Class::methods),
"Iterator over " RST_CLASS_REF(lief.DEX.Method) " implemented in this class")
.def_prop_ro("methods", nb::overload_cast<>(&Class::methods),
"Iterator over " RST_CLASS_REF(lief.DEX.Method) " implemented in this class"_doc)
.def("get_method",
static_cast<Class::it_named_methods(Class::*)(const std::string&)>(&Class::methods),
"Iterator over " RST_CLASS_REF(lief.DEX.Method) " (s) having the given name",
.def("get_method", nb::overload_cast<const std::string&>(&Class::methods),
"Iterator over " RST_CLASS_REF(lief.DEX.Method) " (s) having the given name"_doc,
"name"_a)
.def_property_readonly("fields",
static_cast<no_const_getter_t<Class::it_fields>>(&Class::fields),
"Iterator over " RST_CLASS_REF(lief.DEX.Field) " in this class")
.def_prop_ro("fields", nb::overload_cast<>(&Class::fields),
"Iterator over " RST_CLASS_REF(lief.DEX.Field) " in this class"_doc)
.def("get_field",
static_cast<Class::it_named_fields(Class::*)(const std::string&)>(&Class::fields),
"Iterator over " RST_CLASS_REF(lief.DEX.Field) " (s) having the given name",
.def("get_field", nb::overload_cast<const std::string&>(&Class::fields),
"Iterator over " RST_CLASS_REF(lief.DEX.Field) " (s) having the given name"_doc,
"name"_a)
.def_property_readonly("access_flags",
static_cast<getter_t<Class::access_flags_list_t>>(&Class::access_flags),
"List of " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) "")
.def_prop_ro("access_flags",
nb::overload_cast<>(&Class::access_flags, nb::const_),
"List of " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) ""_doc)
.def_property_readonly("dex2dex_info",
&Class::dex2dex_info,
"De-optimize information")
.def_prop_ro("dex2dex_info", &Class::dex2dex_info,
"De-optimize information"_doc)
.def_property_readonly("index",
&Class::index,
"Original index in the DEX class pool")
.def_prop_ro("index", &Class::index,
"Original index in the DEX class pool"_doc)
.def("has",
static_cast<bool(Class::*)(ACCESS_FLAGS) const>(&Class::has),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present",
.def("has", nb::overload_cast<ACCESS_FLAGS>(&Class::has, nb::const_),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present"_doc,
"flag"_a)
.def("__eq__", &Class::operator==)
.def("__ne__", &Class::operator!=)
.def("__hash__",
[] (const Class& cls) {
return Hash::hash(cls);
})
.def("__str__",
[] (const Class& cls) {
std::ostringstream stream;
stream << cls;
return stream.str();
});
}
LIEF_DEFAULT_STR(Class);
}
}
+7 -30
View File
@@ -14,42 +14,19 @@
* limitations under the License.
*/
#include "LIEF/DEX/CodeInfo.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (CodeInfo::*)(void) const;
template<class T>
using no_const_getter_t = T (CodeInfo::*)(void);
template<class T>
using setter_t = void (CodeInfo::*)(T);
#include <string>
#include <sstream>
namespace LIEF::DEX::py {
template<>
void create<CodeInfo>(py::module& m) {
void create<CodeInfo>(nb::module_& m) {
py::class_<CodeInfo, LIEF::Object>(m, "CodeInfo", "DEX CodeInfo representation")
.def("__eq__", &CodeInfo::operator==)
.def("__ne__", &CodeInfo::operator!=)
.def("__hash__",
[] (const CodeInfo& cinfo) {
return Hash::hash(cinfo);
})
.def("__str__",
[] (const CodeInfo& cinfo) {
std::ostringstream stream;
stream << cinfo;
return stream.str();
});
}
nb::class_<CodeInfo, LIEF::Object>(m, "CodeInfo", "DEX CodeInfo representation"_doc)
LIEF_DEFAULT_STR(CodeInfo);
}
}
+28 -52
View File
@@ -1,72 +1,48 @@
#include "LIEF/DEX/Field.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/Type.hpp"
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (Field::*)(void) const;
template<class T>
using no_const_getter_t = T (Field::*)(void);
template<class T>
using setter_t = void (Field::*)(T);
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
namespace LIEF::DEX::py {
template<>
void create<Field>(py::module& m) {
void create<Field>(nb::module_& m) {
py::class_<Field, LIEF::Object>(m, "Field", "DEX Field representation")
.def_property_readonly("name",
nb::class_<Field, LIEF::Object>(m, "Field", "DEX Field representation"_doc)
.def_prop_ro("name",
&Field::name,
"Field's name")
"Field's name"_doc)
.def_property_readonly("index",
&Field::index,
"Original DEX file index of the field")
.def_prop_ro("index", &Field::index,
"Original DEX file index of the field"_doc)
.def_property_readonly("has_class",
&Field::has_class,
"True if a class is associated with this field")
.def_prop_ro("has_class", &Field::has_class,
"True if a class is associated with this field"_doc)
.def_property_readonly("cls",
static_cast<no_const_getter_t<Class*>>(&Field::cls),
"" RST_CLASS_REF(lief.DEX.Class) " associated with this field")
.def_prop_ro("cls", nb::overload_cast<>(&Field::cls),
"" RST_CLASS_REF(lief.DEX.Class) " associated with this field"_doc)
.def_property_readonly("is_static",
&Field::is_static,
"True if the field is static")
.def_prop_ro("is_static", &Field::is_static,
"True if the field is static"_doc)
.def_property_readonly("type",
static_cast<no_const_getter_t<Type*>>(&Field::type),
"" RST_CLASS_REF(lief.DEX.Type) " of this field", py::return_value_policy::reference)
.def_prop_ro("type", nb::overload_cast<>(&Field::type),
"" RST_CLASS_REF(lief.DEX.Type) " of this field"_doc,
nb::rv_policy::reference_internal)
.def_property_readonly("access_flags",
static_cast<getter_t<Field::access_flags_list_t>>(&Field::access_flags),
"List of " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) "")
.def_prop_ro("access_flags",
nb::overload_cast<>(&Field::access_flags, nb::const_),
"List of " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) ""_doc)
.def("has",
static_cast<bool(Field::*)(ACCESS_FLAGS) const>(&Field::has),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present",
nb::overload_cast<ACCESS_FLAGS>(&Field::has, nb::const_),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present"_doc,
"flag"_a)
.def("__eq__", &Field::operator==)
.def("__ne__", &Field::operator!=)
.def("__hash__",
[] (const Field& fld) {
return Hash::hash(fld);
})
.def("__str__",
[] (const Field& fld) {
std::ostringstream stream;
stream << fld;
return stream.str();
});
}
LIEF_DEFAULT_STR(Field);
}
}
+62 -82
View File
@@ -14,28 +14,28 @@
* limitations under the License.
*/
#include "LIEF/DEX/File.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/Method.hpp"
#include "LIEF/DEX/Type.hpp"
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/Field.hpp"
#include "pyIterators.hpp"
#include "pyDEX.hpp"
#include "pyIterator.hpp"
#include "DEX/pyDEX.hpp"
namespace LIEF {
namespace DEX {
#include <sstream>
template<class T>
using getter_t = T (File::*)(void) const;
template<class T>
using no_const_getter_t = T (File::*)(void);
template<class T>
using setter_t = void (File::*)(T);
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/unique_ptr.h>
namespace LIEF::DEX::py {
template<>
void create<File>(py::module& m) {
void create<File>(nb::module_& m) {
using namespace LIEF::py;
py::class_<File, LIEF::Object> file(m, "File", "DEX File representation");
nb::class_<File, Object> file(m, "File", "DEX File representation"_doc);
init_ref_iterator<File::it_classes>(file, "it_classes");
init_ref_iterator<File::it_methods>(file, "it_methods");
@@ -45,98 +45,78 @@ void create<File>(py::module& m) {
init_ref_iterator<File::it_fields>(file, "it_fields");
file
.def_property_readonly("version",
&File::version,
"Dex version")
.def_prop_ro("version", &File::version,
"Dex version"_doc)
.def_property_readonly("header",
static_cast<no_const_getter_t<Header&>>(&File::header),
"Dex File " RST_CLASS_REF(lief.DEX.Header) "",
py::return_value_policy::reference)
.def_prop_ro("header", nb::overload_cast<>(&File::header, nb::const_),
"Dex File " RST_CLASS_REF(lief.DEX.Header) ""_doc,
nb::rv_policy::reference_internal)
.def_property_readonly("classes",
static_cast<no_const_getter_t<File::it_classes>>(&File::classes),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Class) "")
.def_prop_ro("classes", nb::overload_cast<>(&File::classes),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Class) ""_doc,
nb::keep_alive<0, 1>())
.def("has_class",
&File::has_class,
"Check if a class with a name given in parameter exists",
.def("has_class", &File::has_class,
"Check if a class with a name given in parameter exists"_doc,
"classname"_a)
.def("get_class",
static_cast<Class*(File::*)(const std::string&)>(&File::get_class),
"classname"_a,
py::return_value_policy::reference)
nb::overload_cast<const std::string&>(&File::get_class),
"classname"_a, nb::rv_policy::reference_internal)
.def("get_class",
static_cast<Class*(File::*)(size_t)>(&File::get_class),
"classname"_a,
py::return_value_policy::reference)
nb::overload_cast<size_t>(&File::get_class),
"classname"_a, nb::rv_policy::reference_internal)
.def_property_readonly("methods",
static_cast<no_const_getter_t<File::it_methods>>(&File::methods),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Method) "")
.def_prop_ro("methods", nb::overload_cast<>(&File::methods),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Method) ""_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("fields",
static_cast<no_const_getter_t<File::it_fields>>(&File::fields),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Field) "")
.def_prop_ro("fields", nb::overload_cast<>(&File::fields),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Field) ""_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("strings",
static_cast<no_const_getter_t<File::it_strings>>(&File::strings),
"Iterator over Dex strings")
.def_prop_ro("strings", nb::overload_cast<>(&File::strings),
"Iterator over Dex strings"_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("types",
static_cast<no_const_getter_t<File::it_types>>(&File::types),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Type) "")
.def_prop_ro("types", nb::overload_cast<>(&File::types),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Type) ""_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("prototypes",
static_cast<no_const_getter_t<File::it_prototypes>>(&File::prototypes),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Prototype) "")
.def_prop_ro("prototypes",
nb::overload_cast<>(&File::prototypes),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Prototype) ""_doc,
nb::keep_alive<0, 1>())
.def_property_readonly("map",
static_cast<no_const_getter_t<MapList&>>(&File::map),
"Dex " RST_CLASS_REF(lief.DEX.MapList) "")
.def_prop_ro("map", nb::overload_cast<>(&File::map, nb::const_),
"Dex " RST_CLASS_REF(lief.DEX.MapList) ""_doc)
.def("raw",
&File::raw,
"Original raw file",
.def("raw", &File::raw,
"Original raw file"_doc,
"deoptimize"_a = true)
.def_property("name",
static_cast<getter_t<const std::string&>>(&File::name),
static_cast<setter_t<const std::string&>>(&File::name),
"Name of the dex file")
.def_prop_rw("name",
nb::overload_cast<>(&File::name, nb::const_),
nb::overload_cast<const std::string&>(&File::name),
"Name of the dex file"_doc)
.def_property("location",
static_cast<getter_t<const std::string&>>(&File::location),
static_cast<setter_t<const std::string&>>(&File::location),
"Original location of the dex file")
.def_prop_rw("location",
nb::overload_cast<>(&File::location, nb::const_),
nb::overload_cast<const std::string&>(&File::location),
"Original location of the dex file"_doc)
//.def_property_readonly("dex2dex_info",
//.def_prop_ro("dex2dex_info",
// &File::dex2dex_info)
.def_property_readonly("dex2dex_json_info",
.def_prop_ro("dex2dex_json_info",
&File::dex2dex_json_info)
.def("save",
&File::save,
"Save the **original** file into the file given in first parameter",
.def("save", &File::save,
"Save the **original** file into the file given in first parameter"_doc,
"output"_a = "", "deoptimize"_a = true)
.def("__eq__", &File::operator==)
.def("__ne__", &File::operator!=)
.def("__hash__",
[] (const File& file) {
return Hash::hash(file);
})
.def("__str__",
[] (const File& file) {
std::ostringstream stream;
stream << file;
return stream.str();
});
LIEF_DEFAULT_STR(File);
}
}
}
+59 -77
View File
@@ -14,108 +14,90 @@
* limitations under the License.
*/
#include "LIEF/DEX/Header.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
namespace LIEF {
namespace DEX {
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/array.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/pair.h>
template<class T>
using getter_t = T (Header::*)(void) const;
template<class T>
using setter_t = void (Header::*)(T);
namespace LIEF::DEX::py {
template<>
void create<Header>(py::module& m) {
void create<Header>(nb::module_& m) {
py::class_<Header, LIEF::Object>(m, "Header", "DEX Header")
nb::class_<Header, Object>(m, "Header", "DEX Header"_doc)
.def_property_readonly("magic",
static_cast<getter_t<Header::magic_t>>(&Header::magic),
.def_prop_ro("magic",
nb::overload_cast<>(&Header::magic, nb::const_),
"Magic value")
.def_property_readonly("checksum",
static_cast<getter_t<uint32_t>>(&Header::checksum),
"Checksum value of the rest of the file (without " RST_ATTR_REF(lief.DEX.Header.magic) ")")
.def_prop_ro("checksum",
nb::overload_cast<>(&Header::checksum, nb::const_),
"Checksum value of the rest of the file (without " RST_ATTR_REF(lief.DEX.Header.magic) ")"_doc)
.def_property_readonly("signature",
static_cast<getter_t<Header::signature_t>>(&Header::signature),
"SHA-1 signature of the rest of the file (without " RST_ATTR_REF(lief.DEX.Header.magic) " and " RST_ATTR_REF(lief.DEX.Header.checksum) ")")
.def_prop_ro("signature",
nb::overload_cast<>(&Header::signature, nb::const_),
R"delim(
SHA-1 signature of the rest of the file
(without :attr:`~lief.DEX.Header.magic` and :attr:`~lief.DEX.Header.checksum`).
)delim"_doc)
.def_property_readonly("file_size",
static_cast<getter_t<uint32_t>>(&Header::file_size),
"Size of the current DEX file")
.def_prop_ro("file_size",
nb::overload_cast<>(&Header::file_size, nb::const_),
"Size of the current DEX file"_doc)
.def_property_readonly("header_size",
static_cast<getter_t<uint32_t>>(&Header::header_size),
"Size of this header. Should be ``0x70``")
.def_prop_ro("header_size",
nb::overload_cast<>(&Header::header_size, nb::const_),
"Size of this header. Should be ``0x70``"_doc)
.def_property_readonly("endian_tag",
static_cast<getter_t<uint32_t>>(&Header::endian_tag),
"Endianness tag. Should be ``ENDIAN_CONSTANT``")
.def_prop_ro("endian_tag",
nb::overload_cast<>(&Header::endian_tag, nb::const_),
"Endianness tag. Should be ``ENDIAN_CONSTANT``"_doc)
.def_property_readonly("map_offset",
static_cast<getter_t<uint32_t>>(&Header::map),
"Offset from the start of the file to the map item")
.def_prop_ro("map_offset",
nb::overload_cast<>(&Header::map, nb::const_),
"Offset from the start of the file to the map item"_doc)
.def_property_readonly("strings",
static_cast<getter_t<Header::location_t>>(&Header::strings),
"String identifiers")
.def_prop_ro("strings",
nb::overload_cast<>(&Header::strings, nb::const_),
"String identifiers"_doc)
.def_property_readonly("link",
static_cast<getter_t<Header::location_t>>(&Header::link),
"Link (raw data)")
.def_prop_ro("link",
nb::overload_cast<>(&Header::link, nb::const_),
"Link (raw data)"_doc)
.def_property_readonly("types",
static_cast<getter_t<Header::location_t>>(&Header::types),
"Type identifiers")
.def_prop_ro("types",
nb::overload_cast<>(&Header::types, nb::const_),
"Type identifiers"_doc)
.def_property_readonly("prototypes",
static_cast<getter_t<Header::location_t>>(&Header::prototypes),
"Prototypes identifiers")
.def_prop_ro("prototypes",
nb::overload_cast<>(&Header::prototypes, nb::const_),
"Prototypes identifiers"_doc)
.def_property_readonly("fields",
static_cast<getter_t<Header::location_t>>(&Header::fields),
"Fields identifiers")
.def_prop_ro("fields", nb::overload_cast<>(&Header::fields, nb::const_),
"Fields identifiers"_doc)
.def_property_readonly("methods",
static_cast<getter_t<Header::location_t>>(&Header::methods),
"Methods identifiers")
.def_prop_ro("methods", nb::overload_cast<>(&Header::methods, nb::const_),
"Methods identifiers"_doc)
.def_property_readonly("classes",
static_cast<getter_t<Header::location_t>>(&Header::classes),
"Classess identifiers")
.def_prop_ro("classes", nb::overload_cast<>(&Header::classes, nb::const_),
"Classess identifiers"_doc)
.def_property_readonly("data",
static_cast<getter_t<Header::location_t>>(&Header::data),
"Raw data. Should be align on 32-bits")
.def_prop_ro("data", nb::overload_cast<>(&Header::data, nb::const_),
"Raw data. Should be align on 32-bits"_doc)
.def_property_readonly("nb_classes",
static_cast<getter_t<uint32_t>>(&Header::nb_classes),
"Number of classes in the current DEX")
.def_prop_ro("nb_classes",
nb::overload_cast<>(&Header::nb_classes, nb::const_),
"Number of classes in the current DEX"_doc)
.def_property_readonly("nb_methods",
static_cast<getter_t<uint32_t>>(&Header::nb_methods),
"Number of methods in the current DEX")
.def("__eq__", &Header::operator==)
.def("__ne__", &Header::operator!=)
.def("__hash__",
[] (const Header& header) {
return Hash::hash(header);
})
.def("__str__",
[] (const Header& header) {
std::ostringstream stream;
stream << header;
return stream.str();
});
}
.def_prop_ro("nb_methods",
nb::overload_cast<>(&Header::nb_methods, nb::const_),
"Number of methods in the current DEX"_doc)
LIEF_DEFAULT_STR(Header);
}
}
+18 -39
View File
@@ -14,32 +14,24 @@
* limitations under the License.
*/
#include "LIEF/DEX/MapItem.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
#include "enums_wrapper.hpp"
namespace LIEF {
namespace DEX {
#include <sstream>
#define PY_ENUM(x) to_string(x), x
template<class T>
using getter_t = T (MapItem::*)(void) const;
template<class T>
using no_const_getter_t = T (MapItem::*)(void);
template<class T>
using setter_t = void (MapItem::*)(T);
namespace LIEF::DEX::py {
template<>
void create<MapItem>(py::module& m) {
void create<MapItem>(nb::module_& m) {
py::class_<MapItem, LIEF::Object> mapitem(m, "MapItem", "DEX MapItem representation");
nb::class_<MapItem, LIEF::Object> mapitem(m, "MapItem",
"DEX MapItem representation"_doc);
py::enum_<MapItem::TYPES>(mapitem, "TYPES")
enum_<MapItem::TYPES>(mapitem, "TYPES")
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::HEADER))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::STRING_ID))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::TYPE_ID))
@@ -62,32 +54,19 @@ void create<MapItem>(py::module& m) {
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::ANNOTATIONS_DIRECTORY));
mapitem
.def_property_readonly("type",
static_cast<getter_t<MapItem::TYPES>>(&MapItem::type),
"" RST_CLASS_REF(lief.DEX.MapItem.TYPES) " of the item")
.def_prop_ro("type",
nb::overload_cast<>(&MapItem::type, nb::const_),
"" RST_CLASS_REF(lief.DEX.MapItem.TYPES) " of the item"_doc)
.def_property_readonly("offset",
static_cast<getter_t<uint32_t>>(&MapItem::offset),
"Offset from the start of the file to the items in question")
.def_prop_ro("offset",
nb::overload_cast<>(&MapItem::offset, nb::const_),
"Offset from the start of the file to the items in question"_doc)
.def_property_readonly("size",
static_cast<getter_t<uint32_t>>(&MapItem::size),
"count of the number of items to be found at the indicated offset")
.def_prop_ro("size",
nb::overload_cast<>(&MapItem::size, nb::const_),
"count of the number of items to be found at the indicated offset"_doc)
.def("__eq__", &MapItem::operator==)
.def("__ne__", &MapItem::operator!=)
.def("__hash__",
[] (const MapItem& mlist) {
return Hash::hash(mlist);
})
.def("__str__",
[] (const MapItem& mlist) {
std::ostringstream stream;
stream << mlist;
return stream.str();
});
LIEF_DEFAULT_STR(MapItem);
}
}
}
+21 -43
View File
@@ -14,65 +14,43 @@
* limitations under the License.
*/
#include "LIEF/DEX/MapList.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
#include "pyIterators.hpp"
#include "DEX/pyDEX.hpp"
#include "pyIterator.hpp"
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (MapList::*)(void) const;
template<class T>
using no_const_getter_t = T (MapList::*)(void);
template<class T>
using setter_t = void (MapList::*)(T);
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
namespace LIEF::DEX::py {
template<>
void create<MapList>(py::module& m) {
void create<MapList>(nb::module_& m) {
using namespace LIEF::py;
py::class_<MapList, LIEF::Object> map_list(m, "MapList", "DEX MapList representation");
nb::class_<MapList, LIEF::Object> map_list(m, "MapList",
"DEX MapList representation"_doc);
init_ref_iterator<MapList::it_items_t>(map_list, "it_items_t");
map_list
.def_property_readonly("items",
static_cast<no_const_getter_t<MapList::it_items_t>>(&MapList::items),
"Iterator over " RST_CLASS_REF(lief.DEX.MapItem) "")
.def_prop_ro("items", nb::overload_cast<>(&MapList::items),
"Iterator over " RST_CLASS_REF(lief.DEX.MapItem) ""_doc)
.def("has",
&MapList::has,
"Check if the given " RST_CLASS_REF(lief.DEX.MapItem.TYPES) " is present",
.def("has", &MapList::has,
"Check if the given " RST_CLASS_REF(lief.DEX.MapItem.TYPES) " is present"_doc,
"type"_a)
.def("get",
static_cast<MapItem&(MapList::*)(MapItem::TYPES)>(&MapList::get),
"Return the " RST_CLASS_REF(lief.DEX.MapItem.TYPES) " from "
"the given " RST_CLASS_REF(lief.DEX.MapItem.TYPES) "",
"type"_a,
py::return_value_policy::reference)
.def("get", nb::overload_cast<MapItem::TYPES>(&MapList::get),
R"delim(
Return the :class:`~lief.DEX.MapItem` from the given
:class:`~lief.DEX.MapItem.TYPES`
)delim"_doc, "type"_a, nb::rv_policy::reference_internal)
.def("__getitem__",
static_cast<MapItem&(MapList::*)(MapItem::TYPES)>(&MapList::get))
nb::overload_cast<MapItem::TYPES>(&MapList::get))
.def("__eq__", &MapList::operator==)
.def("__ne__", &MapList::operator!=)
.def("__hash__",
[] (const MapList& mlist) {
return Hash::hash(mlist);
})
.def("__str__",
[] (const MapList& mlist) {
std::ostringstream stream;
stream << mlist;
return stream.str();
});
}
LIEF_DEFAULT_STR(MapList);
}
}
+34 -62
View File
@@ -14,87 +14,59 @@
* limitations under the License.
*/
#include "LIEF/DEX/Method.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/Class.hpp"
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (Method::*)(void) const;
template<class T>
using no_const_getter_t = T (Method::*)(void);
template<class T>
using setter_t = void (Method::*)(T);
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
namespace LIEF::DEX::py {
template<>
void create<Method>(py::module& m) {
void create<Method>(nb::module_& m) {
py::class_<Method, LIEF::Object>(m, "Method", "DEX Method representation")
.def_property_readonly("name",
&Method::name,
"Method's name")
nb::class_<Method, LIEF::Object>(m, "Method", "DEX Method representation"_doc)
.def_prop_ro("name", &Method::name,
"Method's name"_doc)
.def_property_readonly("index",
&Method::index,
"Original DEX file index of the method")
.def_prop_ro("index", &Method::index,
"Original DEX file index of the method"_doc)
.def_property_readonly("has_class",
&Method::has_class,
"True if a class is associated with this method")
.def_prop_ro("has_class", &Method::has_class,
"True if a class is associated with this method"_doc)
.def_property_readonly("cls",
static_cast<no_const_getter_t<Class*>>(&Method::cls),
"" RST_CLASS_REF(lief.DEX.Class) " associated with this method")
.def_prop_ro("cls", nb::overload_cast<>(&Method::cls, nb::const_),
"" RST_CLASS_REF(lief.DEX.Class) " associated with this method"_doc)
.def_property_readonly("code_offset",
static_cast<getter_t<uint64_t>>(&Method::code_offset),
"Offset to the Dalvik Bytecode")
.def_prop_ro("code_offset", nb::overload_cast<>(&Method::code_offset, nb::const_),
"Offset to the Dalvik Bytecode"_doc)
.def_property_readonly("bytecode",
static_cast<getter_t<const Method::bytecode_t&>>(&Method::bytecode),
"Dalvik Bytecode as a list of bytes")
.def_prop_ro("bytecode", nb::overload_cast<>(&Method::bytecode, nb::const_),
"Dalvik Bytecode as a list of bytes"_doc)
.def_property_readonly("is_virtual",
&Method::is_virtual,
"True if the method is a virtual (not **private**, **static**, **final**, **constructor**)")
.def_prop_ro("is_virtual", &Method::is_virtual,
"True if the method is a virtual (not **private**, **static**, **final**, **constructor**)"_doc)
.def_property_readonly("prototype",
static_cast<no_const_getter_t<Prototype*>>(&Method::prototype),
"" RST_CLASS_REF(lief.DEX.Prototype) " of this method")
.def_prop_ro("prototype",
nb::overload_cast<>(&Method::prototype, nb::const_),
"" RST_CLASS_REF(lief.DEX.Prototype) " of this method"_doc)
.def_property_readonly("access_flags",
static_cast<getter_t<Method::access_flags_list_t>>(&Method::access_flags),
"List of " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) "")
.def_prop_ro("access_flags",
nb::overload_cast<>(&Method::access_flags, nb::const_),
"List of " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) ""_doc)
.def("has",
static_cast<bool(Method::*)(ACCESS_FLAGS) const>(&Method::has),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present",
.def("has", nb::overload_cast<ACCESS_FLAGS>(&Method::has, nb::const_),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present"_doc,
"flag"_a)
.def("insert_dex2dex_info",
&Method::insert_dex2dex_info,
"Insert de-optimization information",
.def("insert_dex2dex_info", &Method::insert_dex2dex_info,
"Insert de-optimization information"_doc,
"pc"_a, "index"_a)
.def("__eq__", &Method::operator==)
.def("__ne__", &Method::operator!=)
.def("__hash__",
[] (const Method& cls) {
return Hash::hash(cls);
})
.def("__str__",
[] (const Method& cls) {
std::ostringstream stream;
stream << cls;
return stream.str();
});
LIEF_DEFAULT_STR(Method);
}
}
}
+25 -45
View File
@@ -13,67 +13,47 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
#include "LIEF/DEX/Parser.hpp"
#include "LIEF/DEX/File.hpp"
#include "LIEF/logging.hpp"
#include "pyIOStream.hpp"
#include <string>
#include <memory>
namespace LIEF {
namespace DEX {
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/unique_ptr.h>
namespace LIEF::DEX::py {
template<>
void create<Parser>(py::module& m) {
void create<Parser>(nb::module_& m) {
using namespace LIEF::py;
m.def("parse",
static_cast<std::unique_ptr<File> (*) (const std::string&)>(&Parser::parse),
"Parse the given filename and return a " RST_CLASS_REF(lief.DEX.File) " object",
"Parse the given filename and return a " RST_CLASS_REF(lief.DEX.File) " object"_doc,
"filename"_a,
py::return_value_policy::take_ownership);
nb::rv_policy::take_ownership);
m.def("parse",
static_cast<std::unique_ptr<File>(*)(std::vector<uint8_t>, const std::string&)>(&Parser::parse),
"Parse the given raw data and return a " RST_CLASS_REF(lief.DEX.File) " object",
"Parse the given raw data and return a " RST_CLASS_REF(lief.DEX.File) " object"_doc,
"raw"_a, "name"_a = "",
py::return_value_policy::take_ownership);
nb::rv_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) {
const auto& io = py::module::import("io");
const auto& RawIOBase = io.attr("RawIOBase");
const auto& BufferedIOBase = io.attr("BufferedIOBase");
const auto& TextIOBase = io.attr("TextIOBase");
py::object rawio;
if (py::isinstance(byteio, RawIOBase)) {
rawio = byteio;
}
else if (py::isinstance(byteio, BufferedIOBase)) {
rawio = byteio.attr("raw");
}
else if (py::isinstance(byteio, TextIOBase)) {
rawio = byteio.attr("buffer").attr("raw");
}
else {
throw py::type_error(py::repr(byteio).cast<std::string>().c_str());
}
std::string raw_str = static_cast<py::bytes>(rawio.attr("readall")());
std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))};
return LIEF::DEX::Parser::parse(std::move(raw), name);
},
"io"_a, "name"_a = "",
py::return_value_policy::take_ownership);
}
[] (nb::object byteio, const std::string& name) -> nb::object {
if (auto stream = PyIOStream::from_python(std::move(byteio))) {
auto ptr = std::make_unique<PyIOStream>(std::move(*stream));
return nb::cast(LIEF::DEX::Parser::parse(stream->content(), name));
}
logging::log(logging::LOG_ERR, "Can't create a LIEF stream interface over the provided io");
return nb::none();
}, "io"_a, "name"_a = "", nb::rv_policy::take_ownership);
}
}
+20 -39
View File
@@ -14,56 +14,37 @@
* limitations under the License.
*/
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/Type.hpp"
#include "pyDEX.hpp"
#include "pyIterators.hpp"
#include "DEX/pyDEX.hpp"
#include "pyIterator.hpp"
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (Prototype::*)(void) const;
template<class T>
using no_const_getter_t = T (Prototype::*)(void);
template<class T>
using setter_t = void (Prototype::*)(T);
#include <string>
#include <sstream>
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
namespace LIEF::DEX::py {
template<>
void create<Prototype>(py::module& m) {
void create<Prototype>(nb::module_& m) {
using namespace LIEF::py;
py::class_<Prototype, LIEF::Object> proto(m, "Prototype", "DEX Prototype representation");
nb::class_<Prototype, LIEF::Object> proto(m, "Prototype",
"DEX Prototype representation"_doc);
init_ref_iterator<Prototype::it_params>(proto, "it_params");
proto
.def_property_readonly("return_type",
static_cast<no_const_getter_t<Type*>>(&Prototype::return_type),
"" RST_CLASS_REF(lief.DEX.Type) " returned",
py::return_value_policy::reference)
.def_prop_ro("return_type",
nb::overload_cast<>(&Prototype::return_type, nb::const_),
"" RST_CLASS_REF(lief.DEX.Type) " returned"_doc,
nb::rv_policy::reference_internal)
.def_property_readonly("parameters_type",
static_cast<no_const_getter_t<Prototype::it_params>>(&Prototype::parameters_type),
"Iterator over parameters " RST_CLASS_REF(lief.DEX.Type) "")
.def("__eq__", &Prototype::operator==)
.def("__ne__", &Prototype::operator!=)
.def("__hash__",
[] (const Prototype& ptype) {
return Hash::hash(ptype);
})
.def("__str__",
[] (const Prototype& ptype) {
std::ostringstream stream;
stream << ptype;
return stream.str();
});
}
.def_prop_ro("parameters_type",
nb::overload_cast<>(&Prototype::parameters_type),
"Iterator over parameters " RST_CLASS_REF(lief.DEX.Type) ""_doc)
LIEF_DEFAULT_STR(Prototype);
}
}
+30 -53
View File
@@ -14,39 +14,33 @@
* limitations under the License.
*/
#include "LIEF/DEX/Type.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
#include <sstream>
#include <string>
#include <nanobind/stl/string.h>
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace DEX {
template<class T>
using getter_t = T (Type::*)(void) const;
template<class T>
using no_const_getter_t = T (Type::*)(void);
template<class T>
using setter_t = void (Type::*)(T);
namespace LIEF::DEX::py {
template<>
void create<Type>(py::module& m) {
void create<Type>(nb::module_& m) {
py::class_<Type, LIEF::Object> pytype(m, "Type", "DEX Type representation");
nb::class_<Type, LIEF::Object> pytype(m, "Type",
"DEX Type representation"_doc);
py::enum_<Type::TYPES>(pytype, "TYPES")
nb::enum_<Type::TYPES>(pytype, "TYPES")
.value(PY_ENUM(Type::TYPES::UNKNOWN))
.value(PY_ENUM(Type::TYPES::ARRAY))
.value(PY_ENUM(Type::TYPES::PRIMITIVE))
.value(PY_ENUM(Type::TYPES::CLASS));
py::enum_<Type::PRIMITIVES>(pytype, "PRIMITIVES")
nb::enum_<Type::PRIMITIVES>(pytype, "PRIMITIVES")
.value(PY_ENUM(Type::PRIMITIVES::VOID_T))
.value(PY_ENUM(Type::PRIMITIVES::BOOLEAN))
.value(PY_ENUM(Type::PRIMITIVES::BYTE))
@@ -57,69 +51,52 @@ void create<Type>(py::module& m) {
.value(PY_ENUM(Type::PRIMITIVES::FLOAT))
.value(PY_ENUM(Type::PRIMITIVES::DOUBLE));
pytype
.def_property_readonly("type",
&Type::type,
"" RST_CLASS_REF(lief.DEX.Type.TYPES) " of this object")
.def_prop_ro("type", &Type::type,
"" RST_CLASS_REF(lief.DEX.Type.TYPES) " of this object"_doc)
.def_property_readonly("value",
[] (Type& type) -> py::object {
.def_prop_ro("value",
[] (Type& type) -> nb::object {
switch (type.type()) {
case Type::TYPES::ARRAY:
{
return py::cast(type.array());
return nb::cast(type.array());
}
case Type::TYPES::CLASS:
{
return py::cast(type.cls(), py::return_value_policy::reference);
return nb::cast(type.cls(), nb::rv_policy::reference_internal);
}
case Type::TYPES::PRIMITIVE:
{
return py::cast(type.primitive());
return nb::cast(type.primitive());
}
case Type::TYPES::UNKNOWN:
default:
{
return py::none{};
return nb::none();
}
}
},
"Depending on the " RST_CLASS_REF(lief.DEX.Type.TYPES) ", return "
" " RST_CLASS_REF(lief.DEX.Class) " or " RST_CLASS_REF(lief.DEX.Type.PRIMITIVES) " or array",
py::return_value_policy::reference)
" " RST_CLASS_REF(lief.DEX.Class) " or " RST_CLASS_REF(lief.DEX.Type.PRIMITIVES) " or array"_doc,
nb::rv_policy::reference_internal)
.def_property_readonly("dim",
.def_prop_ro("dim",
&Type::dim,
"If the current type is an array, return its dimension otherwise 0")
.def_property_readonly("underlying_array_type",
static_cast<no_const_getter_t<Type&>>(&Type::underlying_array_type),
"Underlying type of the array",
py::return_value_policy::reference)
.def_prop_ro("underlying_array_type",
nb::overload_cast<>(&Type::underlying_array_type, nb::const_),
"Underlying type of the array"_doc,
nb::rv_policy::reference_internal)
.def_static("pretty_name",
&Type::pretty_name,
"Pretty name of primitives",
.def_static("pretty_name", &Type::pretty_name,
"Pretty name of primitives"_doc,
"primitive"_a)
.def("__eq__", &Type::operator==)
.def("__ne__", &Type::operator!=)
.def("__hash__",
[] (const Type& type) {
return Hash::hash(type);
})
.def("__str__",
[] (const Type& type) {
std::ostringstream stream;
stream << type;
return stream.str();
});
}
LIEF_DEFAULT_STR(Type);
}
}
+4 -38
View File
@@ -13,48 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PY_LIEF_DEX_H_
#define PY_LIEF_DEX_H_
#include "LIEF/DEX.hpp"
#ifndef PY_LIEF_DEX_H
#define PY_LIEF_DEX_H
#include "pyLIEF.hpp"
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
namespace DEX {
namespace LIEF::DEX::py {
template<class T>
void create(py::module&);
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_enums(py::module&);
void init_utils(py::module&);
SPECIALIZE_CREATE(Parser);
SPECIALIZE_CREATE(File);
SPECIALIZE_CREATE(Header);
SPECIALIZE_CREATE(Class);
SPECIALIZE_CREATE(Method);
SPECIALIZE_CREATE(Field);
SPECIALIZE_CREATE(Prototype);
SPECIALIZE_CREATE(Type);
SPECIALIZE_CREATE(MapList);
SPECIALIZE_CREATE(MapItem);
SPECIALIZE_CREATE(CodeInfo);
}
void create(nb::module_&);
}
+4 -7
View File
@@ -13,17 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
#include "LIEF/DEX/enums.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace DEX {
void init_enums(py::module& m) {
namespace LIEF::DEX::py {
void init_enums(nb::module_& m) {
py::enum_<ACCESS_FLAGS>(m, "ACCESS_FLAGS")
nb::enum_<ACCESS_FLAGS>(m, "ACCESS_FLAGS")
.value(PY_ENUM(ACCESS_FLAGS::ACC_UNKNOWN))
.value(PY_ENUM(ACCESS_FLAGS::ACC_PUBLIC))
.value(PY_ENUM(ACCESS_FLAGS::ACC_PRIVATE))
@@ -44,7 +43,5 @@ void init_enums(py::module& m) {
.value(PY_ENUM(ACCESS_FLAGS::ACC_ENUM))
.value(PY_ENUM(ACCESS_FLAGS::ACC_CONSTRUCTOR))
.value(PY_ENUM(ACCESS_FLAGS::ACC_DECLARED_SYNCHRONIZED));
}
}
}
+15 -17
View File
@@ -13,37 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyDEX.hpp"
#include "DEX/pyDEX.hpp"
#include "LIEF/DEX/utils.hpp"
namespace LIEF {
namespace DEX {
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
void init_utils(py::module& m) {
namespace LIEF::DEX::py {
m.def("is_dex",
static_cast<bool (*)(const std::string&)>(&is_dex),
"Check if the **file** given in parameter is a DEX",
void init_utils(nb::module_& m) {
lief_mod->def("is_dex",
nb::overload_cast<const std::string&>(&is_dex),
"Check if the **file** given in parameter is a DEX"_doc,
"path"_a);
m.def("is_dex",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&is_dex),
"Check if the **raw data** given in parameter is a DEX",
lief_mod->def("is_dex",
nb::overload_cast<const std::vector<uint8_t>&>(&is_dex),
"Check if the **raw data** given in parameter is a DEX"_doc,
"raw"_a);
m.def("version",
static_cast<dex_version_t (*)(const std::string&)>(&version),
"Return the DEX version of the **file** given in parameter",
nb::overload_cast<const std::string&>(&version),
"Return the DEX version of the **file** given in parameter"_doc,
"file"_a);
m.def("version",
static_cast<dex_version_t (*)(const std::vector<uint8_t>&)>(&version),
"Return the DEX version of the **raw data** given in parameter",
nb::overload_cast<const std::vector<uint8_t>&>(&version),
"Return the DEX version of the **raw data** given in parameter"_doc,
"raw"_a);
}
}
}
+8 -37
View File
@@ -1,46 +1,17 @@
set(LIEF_PYTHON_ELF_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyELF.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntry.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbolVersionAuxRequirement.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbolVersion.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryRunPath.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbolVersionRequirement.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBinary.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbolVersionDefinition.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbolVersionAux.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryArray.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryFlags.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySegment.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySection.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryRpath.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRelocation.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicSharedObject.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryLibrary.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbol.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyGnuHash.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySysvHash.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBuilder.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/enums.cpp"
)
set(LIEF_PYTHON_ELF_NOTE
"${CMAKE_CURRENT_LIST_DIR}/objects/pyNote.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyNoteDetails.cpp"
)
list(APPEND LIEF_PYTHON_ELF_SRC ${LIEF_PYTHON_ELF_NOTE})
include("${CMAKE_CURRENT_LIST_DIR}/objects/NoteDetails/CMakeLists.txt")
set(LIEF_PYTHON_ELF_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyELF.hpp")
"${CMAKE_CURRENT_SOURCE_DIR}/pyELF.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/init.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/enums.hpp"
)
source_group("Source Files\\ELF" FILES ${LIEF_PYTHON_ELF_SRC})
source_group("Header Files\\ELF" FILES ${LIEF_PYTHON_ELF_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_ELF_SRC}" "${LIEF_PYTHON_ELF_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
target_sources(pyLIEF PRIVATE ${LIEF_PYTHON_ELF_SRC} ${LIEF_PYTHON_ELF_HDR})
add_subdirectory(objects)
@@ -13,31 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pyELF.hpp"
#include "enums_wrapper.hpp"
#include "ELF/enums.hpp"
#include "LIEF/ELF/enums.hpp"
#include "LIEF/ELF/EnumToString.hpp"
#include "enums_wrapper.hpp"
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace ELF {
void init_enums(py::module& m) {
LIEF::enum_<ELF_CLASS>(m, "ELF_CLASS")
namespace LIEF::ELF::py {
void init_enums(nb::module_& m) {
enum_<ELF_CLASS>(m, "ELF_CLASS")
.value(PY_ENUM(ELF_CLASS::ELFCLASSNONE))
.value(PY_ENUM(ELF_CLASS::ELFCLASS32))
.value(PY_ENUM(ELF_CLASS::ELFCLASS64));
LIEF::enum_<ELF_DATA>(m, "ELF_DATA")
enum_<ELF_DATA>(m, "ELF_DATA")
.value(PY_ENUM(ELF_DATA::ELFDATANONE))
.value(PY_ENUM(ELF_DATA::ELFDATA2LSB))
.value(PY_ENUM(ELF_DATA::ELFDATA2MSB));
LIEF::enum_<OS_ABI>(m, "OS_ABI")
enum_<OS_ABI>(m, "OS_ABI")
.value(PY_ENUM(OS_ABI::ELFOSABI_SYSTEMV))
.value(PY_ENUM(OS_ABI::ELFOSABI_HPUX))
.value(PY_ENUM(OS_ABI::ELFOSABI_NETBSD))
@@ -63,7 +58,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(OS_ABI::ELFOSABI_STANDALONE));
// Enum for the *e_type* of ElfXX_Ehdr
LIEF::enum_<E_TYPE>(m, "E_TYPE")
enum_<E_TYPE>(m, "E_TYPE")
.value(PY_ENUM(E_TYPE::ET_NONE))
.value(PY_ENUM(E_TYPE::ET_REL))
.value(PY_ENUM(E_TYPE::ET_EXEC))
@@ -73,12 +68,12 @@ void init_enums(py::module& m) {
.value(PY_ENUM(E_TYPE::ET_HIPROC));
//! Enum for the *e_version* of ElfXX_Ehdr;
LIEF::enum_<VERSION>(m, "VERSION")
enum_<VERSION>(m, "VERSION")
.value(PY_ENUM(VERSION::EV_NONE))
.value(PY_ENUM(VERSION::EV_CURRENT));
// Enum for the *e_machine* of ElfXX_Ehdr
LIEF::enum_<ARCH>(m, "ARCH")
enum_<ARCH>(m, "ARCH")
.value(PY_ENUM(ARCH::EM_NONE))
.value(PY_ENUM(ARCH::EM_M32))
.value(PY_ENUM(ARCH::EM_SPARC))
@@ -255,11 +250,12 @@ void init_enums(py::module& m) {
.value(PY_ENUM(ARCH::EM_CSR_KALIMBA))
.value(PY_ENUM(ARCH::EM_AMDGPU))
.value(PY_ENUM(ARCH::EM_RISCV))
.value(PY_ENUM(ARCH::EM_BPF));
.value(PY_ENUM(ARCH::EM_BPF))
.value(PY_ENUM(ARCH::EM_LOONGARCH));
//! Enum for the *sh_type* of ElfXX_Shdr;
LIEF::enum_<ELF_SECTION_TYPES>(m, "SECTION_TYPES")
enum_<ELF_SECTION_TYPES>(m, "SECTION_TYPES")
.value(PY_ENUM(ELF_SECTION_TYPES::SHT_NULL))
.value(PY_ENUM(ELF_SECTION_TYPES::SHT_PROGBITS))
.value(PY_ENUM(ELF_SECTION_TYPES::SHT_SYMTAB))
@@ -304,7 +300,7 @@ void init_enums(py::module& m) {
//! Enum for the *sh_flags* field of ElfXX_Shdr;
LIEF::enum_<ELF_SECTION_FLAGS>(m, "SECTION_FLAGS", py::arithmetic())
enum_<ELF_SECTION_FLAGS>(m, "SECTION_FLAGS", nb::is_arithmetic())
.value(PY_ENUM(ELF_SECTION_FLAGS::SHF_NONE))
.value(PY_ENUM(ELF_SECTION_FLAGS::SHF_WRITE))
.value(PY_ENUM(ELF_SECTION_FLAGS::SHF_ALLOC))
@@ -324,7 +320,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(ELF_SECTION_FLAGS::SHF_HEX_GPREL));
//! Enum for the *p_type* field of ElfXX_Phdr
LIEF::enum_<SEGMENT_TYPES>(m, "SEGMENT_TYPES")
enum_<SEGMENT_TYPES>(m, "SEGMENT_TYPES")
.value(PY_ENUM(SEGMENT_TYPES::PT_NULL))
.value(PY_ENUM(SEGMENT_TYPES::PT_LOAD))
.value(PY_ENUM(SEGMENT_TYPES::PT_DYNAMIC))
@@ -342,13 +338,13 @@ void init_enums(py::module& m) {
.value("UNWIND", SEGMENT_TYPES::PT_ARM_UNWIND);
//! Enum for the *p_flags* field of ElfXX_Phdr
LIEF::enum_<ELF_SEGMENT_FLAGS>(m, "SEGMENT_FLAGS", py::arithmetic())
enum_<ELF_SEGMENT_FLAGS>(m, "SEGMENT_FLAGS", nb::is_arithmetic())
.value(PY_ENUM(ELF_SEGMENT_FLAGS::PF_NONE))
.value(PY_ENUM(ELF_SEGMENT_FLAGS::PF_X))
.value(PY_ENUM(ELF_SEGMENT_FLAGS::PF_W))
.value(PY_ENUM(ELF_SEGMENT_FLAGS::PF_R));
LIEF::enum_<DYNAMIC_TAGS>(m, "DYNAMIC_TAGS")
enum_<DYNAMIC_TAGS>(m, "DYNAMIC_TAGS")
.value(PY_ENUM(DYNAMIC_TAGS::DT_NULL))
.value(PY_ENUM(DYNAMIC_TAGS::DT_NEEDED))
.value(PY_ENUM(DYNAMIC_TAGS::DT_PLTRELSZ))
@@ -448,7 +444,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(DYNAMIC_TAGS::DT_RELRCOUNT));
LIEF::enum_<ELF_SYMBOL_TYPES>(m, "SYMBOL_TYPES")
enum_<ELF_SYMBOL_TYPES>(m, "SYMBOL_TYPES")
.value(PY_ENUM(ELF_SYMBOL_TYPES::STT_NOTYPE))
.value(PY_ENUM(ELF_SYMBOL_TYPES::STT_OBJECT))
.value(PY_ENUM(ELF_SYMBOL_TYPES::STT_FUNC))
@@ -459,14 +455,14 @@ void init_enums(py::module& m) {
.value(PY_ENUM(ELF_SYMBOL_TYPES::STT_GNU_IFUNC));
LIEF::enum_<SYMBOL_BINDINGS>(m, "SYMBOL_BINDINGS")
enum_<SYMBOL_BINDINGS>(m, "SYMBOL_BINDINGS")
.value(PY_ENUM(SYMBOL_BINDINGS::STB_LOCAL))
.value(PY_ENUM(SYMBOL_BINDINGS::STB_GLOBAL))
.value(PY_ENUM(SYMBOL_BINDINGS::STB_WEAK))
.value(PY_ENUM(SYMBOL_BINDINGS::STB_GNU_UNIQUE));
LIEF::enum_<RELOC_x86_64>(m, "RELOCATION_X86_64")
enum_<RELOC_x86_64>(m, "RELOCATION_X86_64")
.value(PY_ENUM(RELOC_x86_64::R_X86_64_NONE))
.value(PY_ENUM(RELOC_x86_64::R_X86_64_64))
.value(PY_ENUM(RELOC_x86_64::R_X86_64_PC32))
@@ -513,7 +509,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_x86_64::R_X86_64_REX_GOTPCRELX));
LIEF::enum_<RELOC_ARM>(m, "RELOCATION_ARM")
enum_<RELOC_ARM>(m, "RELOCATION_ARM")
.value(PY_ENUM(RELOC_ARM::R_ARM_NONE))
.value(PY_ENUM(RELOC_ARM::R_ARM_PC24))
.value(PY_ENUM(RELOC_ARM::R_ARM_ABS32))
@@ -654,7 +650,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_ARM::R_ARM_RBASE));
LIEF::enum_<RELOC_i386>(m, "RELOCATION_i386")
enum_<RELOC_i386>(m, "RELOCATION_i386")
.value(PY_ENUM(RELOC_i386::R_386_NONE))
.value(PY_ENUM(RELOC_i386::R_386_32))
.value(PY_ENUM(RELOC_i386::R_386_PC32))
@@ -698,7 +694,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_i386::R_386_NUM));
LIEF::enum_<RELOC_AARCH64>(m, "RELOCATION_AARCH64")
enum_<RELOC_AARCH64>(m, "RELOCATION_AARCH64")
.value(PY_ENUM(RELOC_AARCH64::R_AARCH64_NONE))
.value(PY_ENUM(RELOC_AARCH64::R_AARCH64_ABS64))
.value(PY_ENUM(RELOC_AARCH64::R_AARCH64_ABS32))
@@ -823,7 +819,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_AARCH64::R_AARCH64_TLSDESC))
.value(PY_ENUM(RELOC_AARCH64::R_AARCH64_IRELATIVE));
LIEF::enum_<RELOC_POWERPC32>(m, "RELOCATION_PPC")
enum_<RELOC_POWERPC32>(m, "RELOCATION_PPC")
.value(PY_ENUM(RELOC_POWERPC32::R_PPC_NONE))
.value(PY_ENUM(RELOC_POWERPC32::R_PPC_ADDR32))
.value(PY_ENUM(RELOC_POWERPC32::R_PPC_ADDR24))
@@ -882,7 +878,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_POWERPC32::R_PPC_REL16_HI))
.value(PY_ENUM(RELOC_POWERPC32::R_PPC_REL16_HA));
LIEF::enum_<RELOC_POWERPC64>(m, "RELOCATION_PPC64")
enum_<RELOC_POWERPC64>(m, "RELOCATION_PPC64")
.value(PY_ENUM(RELOC_POWERPC64::R_PPC64_NONE))
.value(PY_ENUM(RELOC_POWERPC64::R_PPC64_ADDR32))
.value(PY_ENUM(RELOC_POWERPC64::R_PPC64_ADDR24))
@@ -968,7 +964,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_POWERPC64::R_PPC64_REL16_HI))
.value(PY_ENUM(RELOC_POWERPC64::R_PPC64_REL16_HA));
LIEF::enum_<RELOC_MIPS>(m, "RELOCATION_MIPS")
enum_<RELOC_MIPS>(m, "RELOCATION_MIPS")
.value(PY_ENUM(RELOC_MIPS::R_MIPS_NONE))
.value(PY_ENUM(RELOC_MIPS::R_MIPS_16))
.value(PY_ENUM(RELOC_MIPS::R_MIPS_32))
@@ -1079,15 +1075,105 @@ void init_enums(py::module& m) {
.value(PY_ENUM(RELOC_MIPS::R_MICROMIPS_PC18_S3))
.value(PY_ENUM(RELOC_MIPS::R_MICROMIPS_PC19_S2));
enum_<RELOC_LOONGARCH>(m, "RELOCATION_LOONGARCH")
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_NONE))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_32))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_64))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_RELATIVE))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_COPY))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_JUMP_SLOT))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD32))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD64))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPREL32))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPREL64))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_TPREL32))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_TPREL64))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_IRELATIVE))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_MARK_LA))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_MARK_PCREL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PCREL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_ABSOLUTE))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_DUP))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_GPREL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_TPREL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GOT))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GD))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PLT_PCREL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_ASSERT))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_NOT))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_SUB))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_SL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_SR))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_ADD))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_AND))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_IF_ELSE))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_5))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U_10_12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16_S2))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_5_20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_5_10_16_S2))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_10_10_16_S2))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD8))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD16))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD24))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD32))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD64))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB8))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB16))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB24))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB32))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB64))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GNU_VTINHERIT))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GNU_VTENTRY))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_B16))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_B21))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_B26))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS64_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS64_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA64_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA64_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_PC_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_PC_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_PC_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_PC_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE64_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE64_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_LO12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_LO20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_HI12))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LD_PC_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LD_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_GD_PC_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_GD_HI20))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_32_PCREL))
.value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_RELAX));
LIEF::enum_<DYNSYM_COUNT_METHODS>(m, "DYNSYM_COUNT_METHODS")
enum_<DYNSYM_COUNT_METHODS>(m, "DYNSYM_COUNT_METHODS")
.value(PY_ENUM(DYNSYM_COUNT_METHODS::COUNT_AUTO))
.value(PY_ENUM(DYNSYM_COUNT_METHODS::COUNT_SECTION))
.value(PY_ENUM(DYNSYM_COUNT_METHODS::COUNT_HASH))
.value(PY_ENUM(DYNSYM_COUNT_METHODS::COUNT_RELOCATIONS));
LIEF::enum_<NOTE_TYPES>(m, "NOTE_TYPES")
enum_<NOTE_TYPES>(m, "NOTE_TYPES")
.value(PY_ENUM(NOTE_TYPES::NT_UNKNOWN))
.value(PY_ENUM(NOTE_TYPES::NT_GNU_ABI_TAG))
.value(PY_ENUM(NOTE_TYPES::NT_GNU_HWCAP))
@@ -1099,7 +1185,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(NOTE_TYPES::NT_CRASHPAD));
LIEF::enum_<NOTE_TYPES_CORE>(m, "NOTE_TYPES_CORE")
enum_<NOTE_TYPES_CORE>(m, "NOTE_TYPES_CORE")
.value(PY_ENUM(NOTE_TYPES_CORE::NT_CORE_UNKNOWN))
.value(PY_ENUM(NOTE_TYPES_CORE::NT_PRSTATUS))
.value(PY_ENUM(NOTE_TYPES_CORE::NT_PRFPREG))
@@ -1121,7 +1207,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(NOTE_TYPES_CORE::NT_386_XSTATE));
LIEF::enum_<NOTE_ABIS>(m, "NOTE_ABIS")
enum_<NOTE_ABIS>(m, "NOTE_ABIS")
.value(PY_ENUM(NOTE_ABIS::ELF_NOTE_UNKNOWN))
.value(PY_ENUM(NOTE_ABIS::ELF_NOTE_OS_LINUX))
.value(PY_ENUM(NOTE_ABIS::ELF_NOTE_OS_GNU))
@@ -1131,14 +1217,14 @@ void init_enums(py::module& m) {
.value(PY_ENUM(NOTE_ABIS::ELF_NOTE_OS_SYLLABLE));
LIEF::enum_<RELOCATION_PURPOSES>(m, "RELOCATION_PURPOSES")
enum_<RELOCATION_PURPOSES>(m, "RELOCATION_PURPOSES")
.value(PY_ENUM(RELOCATION_PURPOSES::RELOC_PURPOSE_NONE))
.value(PY_ENUM(RELOCATION_PURPOSES::RELOC_PURPOSE_PLTGOT))
.value(PY_ENUM(RELOCATION_PURPOSES::RELOC_PURPOSE_DYNAMIC))
.value(PY_ENUM(RELOCATION_PURPOSES::RELOC_PURPOSE_OBJECT));
LIEF::enum_<ARM_EFLAGS>(m, "ARM_EFLAGS", py::arithmetic())
enum_<ARM_EFLAGS>(m, "ARM_EFLAGS", nb::is_arithmetic())
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_SOFT_FLOAT))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_VFP_FLOAT))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_UNKNOWN))
@@ -1149,10 +1235,10 @@ void init_enums(py::module& m) {
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_VER5));
LIEF::enum_<PPC64_EFLAGS>(m, "PPC64_EFLAGS", py::arithmetic())
enum_<PPC64_EFLAGS>(m, "PPC64_EFLAGS", nb::is_arithmetic())
.value(PY_ENUM(PPC64_EFLAGS::EF_PPC64_ABI));
LIEF::enum_<MIPS_EFLAGS>(m, "MIPS_EFLAGS", py::arithmetic())
enum_<MIPS_EFLAGS>(m, "MIPS_EFLAGS", nb::is_arithmetic())
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_NOREORDER))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_PIC))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_CPIC))
@@ -1197,7 +1283,7 @@ void init_enums(py::module& m) {
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_32R6))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_64R6));
LIEF::enum_<HEXAGON_EFLAGS>(m, "HEXAGON_EFLAGS", py::arithmetic())
enum_<HEXAGON_EFLAGS>(m, "HEXAGON_EFLAGS", nb::is_arithmetic())
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V2))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V3))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V4))
@@ -1208,8 +1294,12 @@ void init_enums(py::module& m) {
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V4))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V5));
enum_<LOONGARCH_EFLAGS>(m, "LOONGARCH_EFLAGS", nb::is_arithmetic())
.value(PY_ENUM(LOONGARCH_EFLAGS::EF_LOONGARCH_ABI_SOFT_FLOAT))
.value(PY_ENUM(LOONGARCH_EFLAGS::EF_LOONGARCH_ABI_SINGLE_FLOAT))
.value(PY_ENUM(LOONGARCH_EFLAGS::EF_LOONGARCH_ABI_DOUBLE_FLOAT));
LIEF::enum_<IDENTITY>(m, "IDENTITY")
enum_<IDENTITY>(m, "IDENTITY")
.value(PY_ENUM(IDENTITY::EI_MAG0))
.value(PY_ENUM(IDENTITY::EI_MAG1))
.value(PY_ENUM(IDENTITY::EI_MAG2))
@@ -1223,21 +1313,21 @@ void init_enums(py::module& m) {
.value(PY_ENUM(IDENTITY::EI_NIDENT));
LIEF::enum_<SYMBOL_SECTION_INDEX>(m, "SYMBOL_SECTION_INDEX")
enum_<SYMBOL_SECTION_INDEX>(m, "SYMBOL_SECTION_INDEX")
.value(PY_ENUM(SYMBOL_SECTION_INDEX::SHN_UNDEF))
.value(PY_ENUM(SYMBOL_SECTION_INDEX::SHN_ABS))
.value(PY_ENUM(SYMBOL_SECTION_INDEX::SHN_COMMON))
.value(PY_ENUM(SYMBOL_SECTION_INDEX::SHN_HIRESERVE));
LIEF::enum_<DYNAMIC_FLAGS>(m, "DYNAMIC_FLAGS", py::arithmetic())
enum_<DYNAMIC_FLAGS>(m, "DYNAMIC_FLAGS", nb::is_arithmetic())
.value(PY_ENUM(DYNAMIC_FLAGS::DF_ORIGIN))
.value(PY_ENUM(DYNAMIC_FLAGS::DF_SYMBOLIC))
.value(PY_ENUM(DYNAMIC_FLAGS::DF_TEXTREL))
.value(PY_ENUM(DYNAMIC_FLAGS::DF_BIND_NOW))
.value(PY_ENUM(DYNAMIC_FLAGS::DF_STATIC_TLS));
LIEF::enum_<DYNAMIC_FLAGS_1>(m, "DYNAMIC_FLAGS_1", py::arithmetic())
enum_<DYNAMIC_FLAGS_1>(m, "DYNAMIC_FLAGS_1", nb::is_arithmetic())
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NOW))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_GLOBAL))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_GROUP))
@@ -1266,14 +1356,11 @@ void init_enums(py::module& m) {
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_SINGLETON))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_PIE));
LIEF::enum_<ELF_SYMBOL_VISIBILITY>(m, "SYMBOL_VISIBILITY")
enum_<ELF_SYMBOL_VISIBILITY>(m, "SYMBOL_VISIBILITY")
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_DEFAULT))
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_HIDDEN))
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_INTERNAL))
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_PROTECTED));
}
}
}
+23
View File
@@ -0,0 +1,23 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 PY_LIEF_ELF_ENUMS_H
#define PY_LIEF_ELF_ENUMS_H
#include "pyLIEF.hpp"
namespace LIEF::ELF::py {
void init_enums(nb::module_& m);
}
#endif
+112
View File
@@ -0,0 +1,112 @@
/* Copyright 2017 - 2023 R. Thomas
* Copyright 2017 - 2023 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 "ELF/init.hpp"
#include "ELF/enums.hpp"
#include "ELF/pyELF.hpp"
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include "LIEF/ELF/Builder.hpp"
#include "LIEF/ELF/DynamicEntry.hpp"
#include "LIEF/ELF/DynamicEntryArray.hpp"
#include "LIEF/ELF/DynamicEntryFlags.hpp"
#include "LIEF/ELF/DynamicEntryLibrary.hpp"
#include "LIEF/ELF/DynamicEntryRpath.hpp"
#include "LIEF/ELF/DynamicEntryRunPath.hpp"
#include "LIEF/ELF/DynamicSharedObject.hpp"
#include "LIEF/ELF/GnuHash.hpp"
#include "LIEF/ELF/Header.hpp"
#include "LIEF/ELF/Note.hpp"
#include "LIEF/ELF/NoteDetails.hpp"
#include "LIEF/ELF/NoteDetails/AndroidNote.hpp"
#include "LIEF/ELF/NoteDetails/NoteAbi.hpp"
#include "LIEF/ELF/NoteDetails/core/CoreAuxv.hpp"
#include "LIEF/ELF/NoteDetails/core/CoreFile.hpp"
#include "LIEF/ELF/NoteDetails/core/CorePrPsInfo.hpp"
#include "LIEF/ELF/NoteDetails/core/CorePrStatus.hpp"
#include "LIEF/ELF/NoteDetails/core/CoreSigInfo.hpp"
#include "LIEF/ELF/Parser.hpp"
#include "LIEF/ELF/Relocation.hpp"
#include "LIEF/ELF/Section.hpp"
#include "LIEF/ELF/Segment.hpp"
#include "LIEF/ELF/SymbolVersion.hpp"
#include "LIEF/ELF/SymbolVersionAux.hpp"
#include "LIEF/ELF/SymbolVersionAuxRequirement.hpp"
#include "LIEF/ELF/SymbolVersionDefinition.hpp"
#include "LIEF/ELF/SymbolVersionRequirement.hpp"
#include "LIEF/ELF/SysvHash.hpp"
#include "LIEF/ELF/utils.hpp"
#define CREATE(X,Y) create<X>(Y)
namespace LIEF::ELF::py {
void init_objects(nb::module_& m) {
CREATE(ParserConfig, m);
CREATE(Parser, m);
CREATE(SymbolVersion, m);
CREATE(Binary, m);
CREATE(Header, m);
CREATE(Section, m);
CREATE(Segment, m);
CREATE(Symbol, m);
CREATE(Relocation, m);
CREATE(SymbolVersionAux, m);
CREATE(SymbolVersionAuxRequirement, m);
CREATE(SymbolVersionDefinition,m );
CREATE(SymbolVersionRequirement, m);
CREATE(DynamicEntry, m);
CREATE(DynamicEntryLibrary, m);
CREATE(DynamicSharedObject, m);
CREATE(DynamicEntryArray, m);
CREATE(DynamicEntryRpath, m);
CREATE(DynamicEntryRunPath, m);
CREATE(DynamicEntryFlags, m);
CREATE(GnuHash, m);
CREATE(SysvHash, m);
CREATE(Builder, m);
CREATE(Note, m);
CREATE(NoteDetails, m);
CREATE(AndroidNote, m);
CREATE(NoteAbi, m);
CREATE(CorePrPsInfo, m);
CREATE(CoreFile, m);
CREATE(CoreFileEntry, m);
CREATE(CorePrStatus, m);
CREATE(CoreAuxv, m);
CREATE(CoreSigInfo, m);
}
inline void init_utils(nb::module_&) {
lief_mod->def("is_elf",
nb::overload_cast<const std::string&>(&is_elf),
"Check if the given file is an ``ELF``",
"filename"_a);
lief_mod->def("is_elf",
nb::overload_cast<const std::vector<uint8_t>&>(&is_elf),
"Check if the given raw data is an ``ELF``",
"raw"_a);
}
void init(nb::module_& m) {
nb::module_ elf_mod = m.def_submodule("ELF", "Python API for the ELF format");
init_utils(m);
init_enums(elf_mod);
init_objects(elf_mod);
}
}

Some files were not shown because too many files have changed in this diff Show More