Add new formats: OAT, DEX, VDEX, ART

This commit is contained in:
Romain Thomas 2018-05-04 12:46:28 +02:00
parent 6b8f8c11d3
commit 4ef1bb845f
265 changed files with 20975 additions and 157 deletions

View File

@ -187,6 +187,7 @@ endif()
if (LIEF_LOGGING)
add_definitions(-DELPP_NO_DEFAULT_LOG_FILE)
add_definitions(-DVDEBUG=9)
add_definitions(-DELPP_FEATURE_CRASH_LOG)
set(ENABLE_LOGGING_SUPPORT 1)
else()
set(ENABLE_LOGGING_SUPPORT 0)
@ -201,6 +202,48 @@ if (LIEF_FROZEN_ENABLED)
list(APPEND LIEF_PRIVATE_INCLUDE_DIR "${FROZEN_INCLUDE_DIR}")
endif()
# OAT part
# ========
if (LIEF_OAT)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/OAT/CMakeLists.txt)
set(ENABLE_OAT_SUPPORT 1)
else()
set(ENABLE_OAT_SUPPORT 0)
endif()
# DEX part
# ========
if (LIEF_DEX)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/DEX/CMakeLists.txt)
set(ENABLE_DEX_SUPPORT 1)
else()
set(ENABLE_DEX_SUPPORT 0)
endif()
# VDEX part
# =========
if (LIEF_VDEX)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/VDEX/CMakeLists.txt)
set(ENABLE_VDEX_SUPPORT 1)
else()
set(ENABLE_VDEX_SUPPORT 0)
endif()
# ART part
# ========
if (LIEF_ART)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/ART/CMakeLists.txt)
set(ENABLE_ART_SUPPORT 1)
else()
set(ENABLE_ART_SUPPORT 0)
endif()
# Platforms
# =========
include(${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/CMakeLists.txt)
# LIEF includes
# =============
configure_file(

View File

@ -0,0 +1,20 @@
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}/pyIterators.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyFile.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}/../")

View File

@ -0,0 +1,65 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/ART/File.hpp"
#include "LIEF/ART/hash.hpp"
#include "pyART.hpp"
namespace LIEF {
namespace ART {
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);
template<>
void create<File>(py::module& m) {
// 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;
});
}
}
}

View File

@ -0,0 +1,114 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/ART/Header.hpp"
#include "LIEF/ART/hash.hpp"
#include "pyART.hpp"
namespace LIEF {
namespace ART {
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, LIEF::Object>(m, "Header", "ART Header representation")
.def_property_readonly("magic",
static_cast<getter_t<Header::magic_t>>(&Header::magic)
)
.def_property_readonly("version",
static_cast<getter_t<art_version_t>>(&Header::version)
)
.def_property_readonly("image_begin",
static_cast<getter_t<uint32_t>>(&Header::image_begin)
)
.def_property_readonly("image_size",
static_cast<getter_t<uint32_t>>(&Header::image_size)
)
.def_property_readonly("oat_checksum",
static_cast<getter_t<uint32_t>>(&Header::oat_checksum)
)
.def_property_readonly("oat_file_begin",
static_cast<getter_t<uint32_t>>(&Header::oat_file_begin)
)
.def_property_readonly("oat_file_end",
static_cast<getter_t<uint32_t>>(&Header::oat_file_end)
)
.def_property_readonly("oat_data_end",
static_cast<getter_t<uint32_t>>(&Header::oat_data_end)
)
.def_property_readonly("patch_delta",
static_cast<getter_t<int32_t>>(&Header::patch_delta)
)
.def_property_readonly("image_roots",
static_cast<getter_t<uint32_t>>(&Header::image_roots)
)
.def_property_readonly("pointer_size",
static_cast<getter_t<uint32_t>>(&Header::pointer_size)
)
.def_property_readonly("compile_pic",
static_cast<getter_t<bool>>(&Header::compile_pic)
)
.def_property_readonly("nb_sections",
static_cast<getter_t<uint32_t>>(&Header::nb_sections)
)
.def_property_readonly("nb_methods",
static_cast<getter_t<uint32_t>>(&Header::nb_methods)
)
.def_property_readonly("boot_image_begin",
static_cast<getter_t<uint32_t>>(&Header::boot_image_begin)
)
.def_property_readonly("boot_image_size",
static_cast<getter_t<uint32_t>>(&Header::boot_image_size)
)
.def_property_readonly("boot_oat_begin",
static_cast<getter_t<uint32_t>>(&Header::boot_oat_begin)
)
.def_property_readonly("boot_oat_size",
static_cast<getter_t<uint32_t>>(&Header::boot_oat_size)
)
.def_property_readonly("storage_mode",
static_cast<getter_t<STORAGE_MODES>>(&Header::storage_mode)
)
.def_property_readonly("data_size",
static_cast<getter_t<uint32_t>>(&Header::data_size)
)
.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;
});
}
}
}

View File

@ -0,0 +1,81 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyART.hpp"
#include "LIEF/ART/Parser.hpp"
#include <string>
namespace LIEF {
namespace ART {
template<>
void create<Parser>(py::module& m) {
// Parser (Parser)
m.def("parse",
static_cast<File* (*) (const std::string&)>(&Parser::parse),
"Parse the given filename and return an " RST_CLASS_REF(lief.ART.File) " object"
"filename"_a,
py::return_value_policy::take_ownership);
m.def("parse",
static_cast<File* (*) (const std::vector<uint8_t>&, const std::string&)>(&Parser::parse),
"Parse the given raw data and return an " RST_CLASS_REF(lief.ART.File) " object\n\n"
"raw"_a, py::arg("name") = "",
py::return_value_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) {
auto&& io = py::module::import("io");
auto&& RawIOBase = io.attr("RawIOBase");
auto&& BufferedIOBase = io.attr("BufferedIOBase");
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);
}
}
}

38
api/python/ART/pyART.cpp Normal file
View File

@ -0,0 +1,38 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyART.hpp"
namespace LIEF {
namespace ART {
void init_python_module(py::module& m) {
py::module LIEF_ART_module = m.def_submodule("ART", "Python API for ART format");
init_enums(LIEF_ART_module);
init_iterators(LIEF_ART_module);
init_objects(LIEF_ART_module);
init_utils(LIEF_ART_module);
}
void init_objects(py::module& m) {
CREATE(Parser, m);
CREATE(File, m);
CREATE(Header, m);
}
}
}

55
api/python/ART/pyART.hpp Normal file
View File

@ -0,0 +1,55 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_ART_H_
#define PY_LIEF_ART_H_
#include "LIEF/ART.hpp"
#include "pyLIEF.hpp"
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
namespace ART {
template<class T>
void create(py::module&);
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_iterators(py::module&);
void init_enums(py::module&);
void init_utils(py::module&);
SPECIALIZE_CREATE(Parser);
SPECIALIZE_CREATE(File);
SPECIALIZE_CREATE(Header);
}
}
#endif

View File

@ -0,0 +1,34 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyART.hpp"
#include "LIEF/ART/Structures.hpp"
#include "LIEF/ART/enums.hpp"
#include "LIEF/ART/EnumToString.hpp"
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace ART {
void init_enums(py::module& m) {
py::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));
}
}
}

View File

@ -0,0 +1,28 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyART.hpp"
#include "pyIterators.hpp"
#include "LIEF/ART/type_traits.hpp"
namespace LIEF {
namespace ART {
void init_iterators(py::module& m) {
}
}
}

View File

@ -0,0 +1,54 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyART.hpp"
#include "LIEF/ART/utils.hpp"
namespace LIEF {
namespace ART {
void init_utils(py::module& m) {
m.def("is_art",
static_cast<bool (*)(const std::string&)>(&is_art),
"Check if the **file** given in parameter is an ART",
"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",
"raw"_a);
m.def("version",
static_cast<art_version_t (*)(const std::string&)>(&version),
"Return the ART version of the **file** given in parameter",
"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",
"raw"_a);
m.def("android_version",
&android_version,
"Return the " RST_CLASS_REF(lief.Android.ANDROID_VERSIONS) " associated with the given ART version ",
"art_version"_a);
}
}
}

View File

@ -46,6 +46,7 @@ set(LIEF_PYTHON_BASIC_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/pyIterators.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyExceptions.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyLogger.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyHash.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/pyObject.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/encoding.cpp"
)
@ -98,6 +99,24 @@ if(LIEF_MACHO)
include("${CMAKE_CURRENT_SOURCE_DIR}/MachO/CMakeLists.txt")
endif()
if(LIEF_OAT)
include("${CMAKE_CURRENT_SOURCE_DIR}/OAT/CMakeLists.txt")
endif()
if(LIEF_DEX)
include("${CMAKE_CURRENT_SOURCE_DIR}/DEX/CMakeLists.txt")
endif()
if(LIEF_VDEX)
include("${CMAKE_CURRENT_SOURCE_DIR}/VDEX/CMakeLists.txt")
endif()
if(LIEF_ART)
include("${CMAKE_CURRENT_SOURCE_DIR}/ART/CMakeLists.txt")
endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/platforms/CMakeLists.txt")
target_compile_features(pyLIEF PRIVATE cxx_attribute_deprecated)

View File

@ -0,0 +1,27 @@
set(LIEF_PYTHON_DEX_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyDEX.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyIterators.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/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"
)
set(LIEF_PYTHON_DEX_HDR
"${CMAKE_CURRENT_LIST_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}/../")

View File

@ -0,0 +1,110 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/Class.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.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);
template<>
void create<Class>(py::module& m) {
py::class_<Class, LIEF::Object>(m, "Class", "DEX Class representation")
.def_property_readonly("fullname",
&Class::fullname,
"Mangled class name (e.g. ``Lcom/example/android/MyActivity;``")
.def_property_readonly("pretty_name",
&Class::pretty_name,
"Demangled class name (e.g. ``com.example.android.MyActivity``")
.def_property_readonly("name",
&Class::name,
"Class name (e.g. ``MyActivity``")
.def_property_readonly("source_filename",
&Class::source_filename,
"Original filename")
.def_property_readonly("package_name",
&Class::package_name,
"Package Name (e.g. ``com.example.android``")
.def_property_readonly("has_parent",
&Class::has_parent,
"True if the current class extends another one")
.def_property_readonly("parent",
static_cast<no_const_getter_t<Class&>>(&Class::parent),
"" RST_CLASS_REF(lief.DEX.Class) " parent class")
.def_property_readonly("methods",
static_cast<no_const_getter_t<it_methods>>(&Class::methods),
"Iterator over " RST_CLASS_REF(lief.DEX.Method) " implemented in this class")
.def("get_method",
static_cast<it_methods(Class::*)(const std::string&)>(&Class::methods),
"Iterator over " RST_CLASS_REF(lief.DEX.Method) " (s) having the given name",
"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_property_readonly("dex2dex_info",
&Class::dex2dex_info,
"De-optimize information")
.def_property_readonly("index",
&Class::index,
"Original index in the DEX class pool")
.def("has",
static_cast<bool(Class::*)(ACCESS_FLAGS) const>(&Class::has),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present",
"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();
});
}
}
}

View File

@ -0,0 +1,55 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/CodeInfo.hpp"
#include "LIEF/DEX/hash.hpp"
#include "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);
template<>
void create<CodeInfo>(py::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();
});
}
}
}

View File

@ -0,0 +1,129 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/File.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
namespace LIEF {
namespace DEX {
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);
template<>
void create<File>(py::module& m) {
py::class_<File, LIEF::Object>(m, "File", "DEX File representation")
.def_property_readonly("version",
&File::version,
"Dex version")
.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_property_readonly("classes",
static_cast<no_const_getter_t<it_classes>>(&File::classes),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Class) "")
.def("has_class",
&File::has_class,
"Check if a class with a name given in parameter exists",
"classname"_a)
.def("get_class",
static_cast<Class&(File::*)(const std::string&)>(&File::get_class),
"classname"_a,
py::return_value_policy::reference)
.def("get_class",
static_cast<Class&(File::*)(size_t)>(&File::get_class),
"classname"_a,
py::return_value_policy::reference)
.def_property_readonly("methods",
static_cast<no_const_getter_t<it_methods>>(&File::methods),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Method) "")
.def_property_readonly("strings",
static_cast<no_const_getter_t<it_strings>>(&File::strings),
"Iterator over Dex strings")
.def_property_readonly("types",
static_cast<no_const_getter_t<it_types>>(&File::types),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Type) "")
.def_property_readonly("prototypes",
static_cast<no_const_getter_t<it_protypes>>(&File::prototypes),
"Iterator over Dex " RST_CLASS_REF(lief.DEX.Prototype) "")
.def_property_readonly("map",
static_cast<no_const_getter_t<MapList&>>(&File::map),
"Dex " RST_CLASS_REF(lief.DEX.MapList) "")
.def("raw",
&File::raw,
"Original raw file",
"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_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_property_readonly("dex2dex_info",
// &File::dex2dex_info)
.def_property_readonly("dex2dex_json_info",
&File::dex2dex_json_info)
.def("save",
&File::save,
"Save the **original** file into the file given in first parameter",
"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();
});
}
}
}

View File

@ -0,0 +1,122 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/Header.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
namespace LIEF {
namespace DEX {
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, LIEF::Object>(m, "Header", "DEX Header")
.def_property_readonly("magic",
static_cast<getter_t<magic_t>>(&Header::magic),
"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_property_readonly("signature",
static_cast<getter_t<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_property_readonly("file_size",
static_cast<getter_t<uint32_t>>(&Header::file_size),
"Size of the current DEX file")
.def_property_readonly("header_size",
static_cast<getter_t<uint32_t>>(&Header::header_size),
"Size of this header. Should be ``0x70``")
.def_property_readonly("endian_tag",
static_cast<getter_t<uint32_t>>(&Header::endian_tag),
"Endianness tag. Should be ``ENDIAN_CONSTANT``")
.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_property_readonly("strings",
static_cast<getter_t<Header::location_t>>(&Header::strings),
"String identifiers")
.def_property_readonly("link",
static_cast<getter_t<Header::location_t>>(&Header::link),
"Link (raw data)")
.def_property_readonly("types",
static_cast<getter_t<Header::location_t>>(&Header::types),
"Type identifiers")
.def_property_readonly("prototypes",
static_cast<getter_t<Header::location_t>>(&Header::prototypes),
"Prototypes identifiers")
.def_property_readonly("fields",
static_cast<getter_t<Header::location_t>>(&Header::fields),
"Fields identifiers")
.def_property_readonly("methods",
static_cast<getter_t<Header::location_t>>(&Header::methods),
"Methods identifiers")
.def_property_readonly("classes",
static_cast<getter_t<Header::location_t>>(&Header::classes),
"Classess identifiers")
.def_property_readonly("data",
static_cast<getter_t<Header::location_t>>(&Header::data),
"Raw data. Should be align on 32-bits")
.def_property_readonly("nb_classes",
static_cast<getter_t<uint32_t>>(&Header::nb_classes),
"Number of classes in the current DEX")
.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();
});
}
}
}

View File

@ -0,0 +1,93 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/MapItem.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#include "pyDEX.hpp"
namespace LIEF {
namespace DEX {
#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);
template<>
void create<MapItem>(py::module& m) {
py::class_<MapItem, LIEF::Object> mapitem(m, "MapItem", "DEX MapItem representation");
py::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))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::PROTO_ID))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::FIELD_ID))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::METHOD_ID))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::CLASS_DEF))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::CALL_SITE_ID))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::METHOD_HANDLE))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::MAP_LIST))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::TYPE_LIST))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::ANNOTATION_SET_REF_LIST))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::ANNOTATION_SET))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::CLASS_DATA))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::CODE))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::STRING_DATA))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::DEBUG_INFO))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::ANNOTATION))
.value(PY_ENUM(LIEF::DEX::MapItem::TYPES::ENCODED_ARRAY))
.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_property_readonly("offset",
static_cast<getter_t<uint32_t>>(&MapItem::offset),
"Offset from the start of the file to the items in question")
.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("__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();
});
}
}
}

View File

@ -0,0 +1,76 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/MapList.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
#include "pyIterators.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);
template<>
void create<MapList>(py::module& m) {
init_ref_iterator<MapList::it_items_t>(m, "lief.DEX.MapList.it_items_t");
py::class_<MapList, LIEF::Object>(m, "MapList", "DEX MapList representation")
.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("has",
&MapList::has,
"Check if the given " RST_CLASS_REF(lief.DEX.MapItem.TYPES) " is present",
"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("__getitem__",
static_cast<MapItem&(MapList::*)(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();
});
}
}
}

View File

@ -0,0 +1,100 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/Method.hpp"
#include "LIEF/DEX/hash.hpp"
#include "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);
template<>
void create<Method>(py::module& m) {
py::class_<Method, LIEF::Object>(m, "Method", "DEX Method representation")
.def_property_readonly("name",
&Method::name,
"Method's name")
.def_property_readonly("index",
&Method::index,
"Original DEX file index of the method")
.def_property_readonly("has_class",
&Method::has_class,
"True if a class is associated with this method")
.def_property_readonly("cls",
static_cast<no_const_getter_t<Class&>>(&Method::cls),
"" RST_CLASS_REF(lief.DEX.Class) " associated with this method")
.def_property_readonly("code_offset",
static_cast<getter_t<uint64_t>>(&Method::code_offset),
"Offset to the Dalvik Bytecode")
.def_property_readonly("bytecode",
static_cast<getter_t<const Method::bytecode_t&>>(&Method::bytecode),
"Dalvik Bytecode as a list of bytes")
.def_property_readonly("is_virtual",
&Method::is_virtual,
"True if the method is a virtual (not **private**, **static**, **final**, **constructor**)")
.def_property_readonly("prototype",
static_cast<no_const_getter_t<Prototype&>>(&Method::prototype),
"" RST_CLASS_REF(lief.DEX.Prototype) " of this method")
.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("has",
static_cast<bool(Method::*)(ACCESS_FLAGS) const>(&Method::has),
"Check if the given " RST_CLASS_REF(lief.DEX.ACCESS_FLAGS) " is present",
"flag"_a)
.def("insert_dex2dex_info",
&Method::insert_dex2dex_info,
"Insert de-optimization information",
"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();
});
}
}
}

View File

@ -0,0 +1,80 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyDEX.hpp"
#include "LIEF/DEX/Parser.hpp"
#include <string>
namespace LIEF {
namespace DEX {
template<>
void create<Parser>(py::module& m) {
m.def("parse",
static_cast<File* (*) (const std::string&)>(&Parser::parse),
"Parse the given filename and return a " RST_CLASS_REF(lief.DEX.File) " object"
"filename"_a,
py::return_value_policy::take_ownership);
m.def("parse",
static_cast<File* (*) (const std::vector<uint8_t>&, const std::string&)>(&Parser::parse),
"Parse the given raw data and return a " RST_CLASS_REF(lief.DEX.File) " object\n\n"
"raw"_a, py::arg("name") = "",
py::return_value_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) {
auto&& io = py::module::import("io");
auto&& RawIOBase = io.attr("RawIOBase");
auto&& BufferedIOBase = io.attr("BufferedIOBase");
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);
}
}
}

View File

@ -0,0 +1,66 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/Prototype.hpp"
#include "LIEF/DEX/hash.hpp"
#include "pyDEX.hpp"
#include "pyIterators.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);
template<>
void create<Prototype>(py::module& m) {
init_ref_iterator<Prototype::it_params>(m, "lief.DEX.Prototype.it_params");
py::class_<Prototype, LIEF::Object>(m, "Prototype", "DEX Prototype representation")
.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_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();
});
}
}
}

View File

@ -0,0 +1,125 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/DEX/Type.hpp"
#include "LIEF/DEX/hash.hpp"
#include "LIEF/DEX/EnumToString.hpp"
#include "pyDEX.hpp"
#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);
template<>
void create<Type>(py::module& m) {
py::class_<Type, LIEF::Object> pytype(m, "Type", "DEX Type representation");
py::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")
.value(PY_ENUM(Type::PRIMITIVES::VOID_T))
.value(PY_ENUM(Type::PRIMITIVES::BOOLEAN))
.value(PY_ENUM(Type::PRIMITIVES::BYTE))
.value(PY_ENUM(Type::PRIMITIVES::SHORT))
.value(PY_ENUM(Type::PRIMITIVES::CHAR))
.value(PY_ENUM(Type::PRIMITIVES::INT))
.value(PY_ENUM(Type::PRIMITIVES::LONG))
.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_property_readonly("value",
[] (Type& type) -> py::object {
switch (type.type()) {
case Type::TYPES::ARRAY:
{
return py::cast(type.array());
}
case Type::TYPES::CLASS:
{
return py::cast(type.cls());
}
case Type::TYPES::PRIMITIVE:
{
return py::cast(type.primitive());
}
case Type::TYPES::UNKNOWN:
default:
{
return py::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)
.def_property_readonly("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_static("pretty_name",
&Type::pretty_name,
"Pretty name of primitives",
"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();
});
}
}
}

45
api/python/DEX/pyDEX.cpp Normal file
View File

@ -0,0 +1,45 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyDEX.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");
init_enums(LIEF_DEX_module);
init_iterators(LIEF_DEX_module);
init_objects(LIEF_DEX_module);
init_utils(LIEF_DEX_module);
}
void init_objects(py::module& m) {
CREATE(Parser, m);
CREATE(File, m);
CREATE(Header, m);
CREATE(Class, m);
CREATE(Method, m);
CREATE(Prototype, m);
CREATE(Type, m);
CREATE(MapList, m);
CREATE(MapItem, m);
CREATE(CodeInfo, m);
}
}
}

62
api/python/DEX/pyDEX.hpp Normal file
View File

@ -0,0 +1,62 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_H_
#define PY_LIEF_DEX_H_
#include "LIEF/DEX.hpp"
#include "pyLIEF.hpp"
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
namespace DEX {
template<class T>
void create(py::module&);
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_iterators(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(Prototype);
SPECIALIZE_CREATE(Type);
SPECIALIZE_CREATE(MapList);
SPECIALIZE_CREATE(MapItem);
SPECIALIZE_CREATE(CodeInfo);
}
}
#endif

View File

@ -0,0 +1,53 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyDEX.hpp"
#include "LIEF/DEX/Structures.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) {
py::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))
.value(PY_ENUM(ACCESS_FLAGS::ACC_PROTECTED))
.value(PY_ENUM(ACCESS_FLAGS::ACC_STATIC))
.value(PY_ENUM(ACCESS_FLAGS::ACC_FINAL))
.value(PY_ENUM(ACCESS_FLAGS::ACC_SYNCHRONIZED))
.value(PY_ENUM(ACCESS_FLAGS::ACC_VOLATILE))
.value(PY_ENUM(ACCESS_FLAGS::ACC_BRIDGE))
.value(PY_ENUM(ACCESS_FLAGS::ACC_TRANSIENT))
.value(PY_ENUM(ACCESS_FLAGS::ACC_VARARGS))
.value(PY_ENUM(ACCESS_FLAGS::ACC_NATIVE))
.value(PY_ENUM(ACCESS_FLAGS::ACC_INTERFACE))
.value(PY_ENUM(ACCESS_FLAGS::ACC_ABSTRACT))
.value(PY_ENUM(ACCESS_FLAGS::ACC_STRICT))
.value(PY_ENUM(ACCESS_FLAGS::ACC_SYNTHETIC))
.value(PY_ENUM(ACCESS_FLAGS::ACC_ANNOTATION))
.value(PY_ENUM(ACCESS_FLAGS::ACC_ENUM))
.value(PY_ENUM(ACCESS_FLAGS::ACC_CONSTRUCTOR))
.value(PY_ENUM(ACCESS_FLAGS::ACC_ABSTRACT))
.value(PY_ENUM(ACCESS_FLAGS::ACC_DECLARED_SYNCHRONIZED))
.export_values();
}
}
}

View File

@ -0,0 +1,32 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyDEX.hpp"
#include "pyIterators.hpp"
#include "LIEF/DEX/type_traits.hpp"
namespace LIEF {
namespace DEX {
void init_iterators(py::module& m) {
init_ref_iterator<it_dex_files>(m, "lief.DEX.it_dex_files");
init_ref_iterator<it_classes>(m, "lief.DEX.it_classes");
init_ref_iterator<it_methods>(m, "lief.DEX.it_methods");
init_ref_iterator<it_strings>(m, "lief.DEX.it_strings");
}
}
}

View File

@ -0,0 +1,49 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyDEX.hpp"
#include "LIEF/DEX/utils.hpp"
namespace LIEF {
namespace DEX {
void init_utils(py::module& m) {
m.def("is_dex",
static_cast<bool (*)(const std::string&)>(&is_dex),
"Check if the **file** given in parameter is an DDEX",
"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",
"raw"_a);
m.def("version",
static_cast<dex_version_t (*)(const std::string&)>(&version),
"Return the DEX version of the **file** given in parameter",
"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",
"raw"_a);
}
}
}

View File

@ -0,0 +1,32 @@
set(LIEF_PYTHON_OAT_OBJECTS_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDexFile.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyClass.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyMethod.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBinary.cpp"
)
set(LIEF_PYTHON_OAT_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyOAT.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyIterators.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyOpaqueTypes.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyUtils.cpp"
)
set(LIEF_PYTHON_OAT_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyOAT.hpp")
list(APPEND LIEF_PYTHON_OAT_SRC ${LIEF_PYTHON_OAT_OBJECTS_SRC})
source_group("Source Files\\OAT" FILES ${LIEF_PYTHON_OAT_SRC})
source_group("Header Files\\OAT" FILES ${LIEF_PYTHON_OAT_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_OAT_SRC}" "${LIEF_PYTHON_OAT_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/../")

View File

@ -0,0 +1,102 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/OAT/Binary.hpp"
#include "LIEF/OAT/hash.hpp"
#include "LIEF/ELF/Binary.hpp"
#include "pyOAT.hpp"
namespace LIEF {
namespace OAT {
template<class T>
using no_const_getter = T (Binary::*)(void);
template<class T, class P>
using no_const_func = T (Binary::*)(P);
template<class T>
using getter_t = T (Binary::*)(void) const;
template<class T>
using setter_t = void (Binary::*)(T);
template<>
void create<Binary>(py::module& m) {
// Binary object
py::class_<Binary, LIEF::ELF::Binary>(m, "Binary", "OAT binary representation")
.def_property_readonly("header",
static_cast<no_const_getter<Header&>>(&Binary::header),
"Return the OAT " RST_CLASS_REF(lief.OAT.Header) "",
py::return_value_policy::reference)
.def_property_readonly("dex_files",
static_cast<no_const_getter<LIEF::DEX::it_dex_files>>(&Binary::dex_files),
"Return an iterator over " RST_CLASS_REF(lief.DEX.File) "")
.def_property_readonly("oat_dex_files",
static_cast<no_const_getter<it_dex_files>>(&Binary::oat_dex_files),
"Return an iterator over " RST_CLASS_REF(lief.OAT.DexFile) "")
.def_property_readonly("classes",
static_cast<no_const_getter<it_classes>>(&Binary::classes),
"Return an iterator over " RST_CLASS_REF(lief.OAT.Class) "",
py::return_value_policy::reference)
.def_property_readonly("methods",
static_cast<no_const_getter<it_methods>>(&Binary::methods),
"Return an iterator over " RST_CLASS_REF(lief.OAT.Method) "",
py::return_value_policy::reference)
.def_property_readonly("has_class",
&Binary::has_class,
"Check if the class if the given name is present in the current OAT binary")
.def("get_class",
static_cast<no_const_func<Class&, const std::string&>>(&Binary::get_class),
"Return the " RST_CLASS_REF(lief.OAT.Class) " from its name",
"class_name"_a,
py::return_value_policy::reference)
.def("get_class",
static_cast<no_const_func<Class&, size_t>>(&Binary::get_class),
"Return the " RST_CLASS_REF(lief.OAT.Class) " from its **index**",
"class_index"_a,
py::return_value_policy::reference)
.def_property_readonly("dex2dex_json_info",
&Binary::dex2dex_json_info)
.def("__eq__", &Binary::operator==)
.def("__ne__", &Binary::operator!=)
.def("__hash__",
[] (const Binary& bin) {
return Hash::hash(bin);
})
.def("__str__",
[] (const Binary& binary)
{
std::ostringstream stream;
stream << binary;
return stream.str();
});
}
}
}

View File

@ -0,0 +1,89 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/OAT/Class.hpp"
#include "LIEF/OAT/hash.hpp"
#include "pyOAT.hpp"
namespace LIEF {
namespace OAT {
template<class T>
using getter_t = T (Class::*)(void) const;
template<class T>
using setter_t = void (Class::*)(T);
template<class T>
using no_const_getter = T (Class::*)(void);
template<>
void create<Class>(py::module& m) {
py::class_<Class, LIEF::Object>(m, "Class", "OAT Class representation")
.def(py::init<>())
.def("has_dex_class",
&Class::has_dex_class)
.def_property_readonly("status",
&Class::status)
.def_property_readonly("type",
&Class::type)
.def_property_readonly("fullname",
&Class::fullname)
.def_property_readonly("index",
&Class::index)
.def_property_readonly("methods",
static_cast<no_const_getter<it_methods>>(&Class::methods))
.def_property_readonly("bitmap",
&Class::bitmap)
.def("is_quickened",
static_cast<bool(Class::*)(const LIEF::DEX::Method&) const>(&Class::is_quickened))
.def("is_quickened",
static_cast<bool(Class::*)(uint32_t relative_index) const>(&Class::is_quickened))
.def("method_offsets_index",
static_cast<uint32_t(Class::*)(const LIEF::DEX::Method&) const>(&Class::method_offsets_index))
.def("method_offsets_index",
static_cast<uint32_t(Class::*)(uint32_t relative_index) const>(&Class::method_offsets_index))
.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();
});
}
}
}

View File

@ -0,0 +1,74 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/OAT/DexFile.hpp"
#include "LIEF/OAT/hash.hpp"
#include "pyOAT.hpp"
namespace LIEF {
namespace OAT {
template<class T>
using getter_t = T (DexFile::*)(void) const;
template<class T>
using setter_t = void (DexFile::*)(T);
template<class T>
using no_const_getter = T (DexFile::*)(void);
template<>
void create<DexFile>(py::module& m) {
py::class_<DexFile, LIEF::Object>(m, "DexFile", "OAT DexFile representation")
.def(py::init<>())
.def_property("location",
static_cast<getter_t<const std::string&>>(&DexFile::location),
static_cast<setter_t<const std::string&>>(&DexFile::location))
.def_property("checksum",
static_cast<getter_t<uint32_t>>(&DexFile::checksum),
static_cast<setter_t<uint32_t>>(&DexFile::checksum))
.def_property("dex_offset",
static_cast<getter_t<uint32_t>>(&DexFile::dex_offset),
static_cast<setter_t<uint32_t>>(&DexFile::dex_offset))
.def_property_readonly("has_dex_file",
&DexFile::has_dex_file)
.def_property_readonly("dex_file",
static_cast<no_const_getter<LIEF::DEX::File&>>(&DexFile::dex_file))
.def("__eq__", &DexFile::operator==)
.def("__ne__", &DexFile::operator!=)
.def("__hash__",
[] (const DexFile& dex_file) {
return Hash::hash(dex_file);
})
.def("__str__",
[] (const DexFile& dexfile) {
std::ostringstream stream;
stream << dexfile;
return stream.str();
});
}
}
}

View File

@ -0,0 +1,149 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/OAT/Header.hpp"
#include "LIEF/OAT/hash.hpp"
#include "pyOAT.hpp"
namespace LIEF {
namespace OAT {
template<class T>
using getter_t = T (Header::*)(void) const;
template<class T>
using setter_t = void (Header::*)(T);
template<class T>
using no_const_getter = T (Header::*)(void);
template<>
void create<Header>(py::module& m) {
py::class_<Header, LIEF::Object>(m, "Header", "OAT Header representation")
.def(py::init<>())
.def_property_readonly("key_values",
static_cast<no_const_getter<Header::it_key_values_t>>(&Header::key_values),
py::return_value_policy::reference_internal
)
.def_property_readonly("keys",
&Header::keys,
py::return_value_policy::reference_internal
)
.def_property_readonly("values",
&Header::values,
py::return_value_policy::move
)
.def_property_readonly("magic",
static_cast<getter_t<Header::magic_t>>(&Header::magic))
.def_property_readonly("version",
static_cast<getter_t<oat_version_t>>(&Header::version))
.def_property_readonly("checksum",
static_cast<getter_t<uint32_t>>(&Header::checksum))
.def_property_readonly("instruction_set",
static_cast<getter_t<INSTRUCTION_SETS>>(&Header::instruction_set))
.def_property_readonly("nb_dex_files",
static_cast<getter_t<uint32_t>>(&Header::nb_dex_files))
.def_property_readonly("oat_dex_files_offset",
static_cast<getter_t<uint32_t>>(&Header::oat_dex_files_offset))
.def_property_readonly("executable_offset",
static_cast<getter_t<uint32_t>>(&Header::executable_offset))
.def_property_readonly("i2i_bridge_offset",
static_cast<getter_t<uint32_t>>(&Header::i2i_bridge_offset))
.def_property_readonly("i2c_code_bridge_offset",
static_cast<getter_t<uint32_t>>(&Header::i2c_code_bridge_offset))
.def_property_readonly("jni_dlsym_lookup_offset",
static_cast<getter_t<uint32_t>>(&Header::jni_dlsym_lookup_offset))
.def_property_readonly("quick_generic_jni_trampoline_offset",
static_cast<getter_t<uint32_t>>(&Header::quick_generic_jni_trampoline_offset))
.def_property_readonly("quick_imt_conflict_trampoline_offset",
static_cast<getter_t<uint32_t>>(&Header::quick_imt_conflict_trampoline_offset))
.def_property_readonly("quick_resolution_trampoline_offset",
static_cast<getter_t<uint32_t>>(&Header::quick_resolution_trampoline_offset))
.def_property_readonly("quick_to_interpreter_bridge_offset",
static_cast<getter_t<uint32_t>>(&Header::quick_to_interpreter_bridge_offset))
.def_property_readonly("image_patch_delta",
static_cast<getter_t<int32_t>>(&Header::image_patch_delta))
.def_property_readonly("image_file_location_oat_checksum",
static_cast<getter_t<uint32_t>>(&Header::image_file_location_oat_checksum))
.def_property_readonly("image_file_location_oat_data_begin",
static_cast<getter_t<uint32_t>>(&Header::image_file_location_oat_data_begin))
.def_property_readonly("key_value_size",
static_cast<getter_t<uint32_t>>(&Header::key_value_size))
.def("get",
static_cast<const std::string& (Header::*)(HEADER_KEYS) const>(&Header::get),
"key"_a,
py::return_value_policy::move)
.def("set",
static_cast<Header& (Header::*)(HEADER_KEYS, const std::string&)>(&Header::set),
"key"_a, "value"_a,
py::return_value_policy::reference)
.def("__getitem__",
static_cast<const std::string& (Header::*)(HEADER_KEYS) const>(&Header::operator[]),
"",
py::return_value_policy::move)
.def("__setitem__",
static_cast<Header& (Header::*)(HEADER_KEYS, const std::string&)>(&Header::set),
"",
py::return_value_policy::reference)
.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();
});
}
}
}

View File

@ -0,0 +1,87 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/OAT/Method.hpp"
#include "LIEF/OAT/hash.hpp"
#include "pyOAT.hpp"
namespace LIEF {
namespace OAT {
template<class T>
using getter_t = T (Method::*)(void) const;
template<class T>
using setter_t = void (Method::*)(T);
template<class T>
using no_const_getter = T (Method::*)(void);
template<>
void create<Method>(py::module& m) {
py::class_<Method, LIEF::Object>(m, "Method", "OAT Method representation")
.def(py::init<>())
.def_property_readonly("name",
&Method::name,
"Method's name")
.def_property_readonly("oat_class",
static_cast<no_const_getter<Class&>>(&Method::oat_class),
"" RST_CLASS_REF(lief.OAT.Class) " associated with the method",
py::return_value_policy::reference)
.def_property_readonly("dex_method",
static_cast<no_const_getter<LIEF::DEX::Method&>>(&Method::dex_method),
"Mirrored " RST_CLASS_REF(lief.DEX.Method) " associated with the OAT method",
py::return_value_policy::reference)
.def_property_readonly("has_dex_method",
&Method::has_dex_method,
"Check if a " RST_CLASS_REF(lief.DEX.Method) " is associated with the OAT method",
py::return_value_policy::reference)
.def_property_readonly("is_dex2dex_optimized",
&Method::is_dex2dex_optimized,
"True if the optimization is **DEX**")
.def_property_readonly("is_compiled",
&Method::is_compiled,
"True if the optimization is **native**")
.def_property("quick_code",
static_cast<getter_t<const Method::quick_code_t&>>(&Method::quick_code),
static_cast<setter_t<const Method::quick_code_t&>>(&Method::quick_code),
"Quick code associated with the method")
.def("__eq__", &Method::operator==)
.def("__ne__", &Method::operator!=)
.def("__hash__",
[] (const Method& method) {
return Hash::hash(method);
})
.def("__str__",
[] (const Method& method) {
std::ostringstream stream;
stream << method;
return stream.str();
});
}
}
}

View File

@ -0,0 +1,86 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyOAT.hpp"
#include "LIEF/OAT/Parser.hpp"
#include <string>
namespace LIEF {
namespace OAT {
template<>
void create<Parser>(py::module& m) {
// Parser (Parser)
m.def("parse",
static_cast<Binary* (*) (const std::string&)>(&Parser::parse),
"Parse the given OAT file and return a " RST_CLASS_REF(lief.OAT.Binary) " object"
"oat_file"_a,
py::return_value_policy::take_ownership);
m.def("parse",
static_cast<Binary* (*) (const std::string&, const std::string&)>(&Parser::parse),
"Parse the given OAT with its VDEX file and return a " RST_CLASS_REF(lief.OAT.Binary) " object"
"oat_file"_a, "vdex_file"_a,
py::return_value_policy::take_ownership);
m.def("parse",
static_cast<Binary* (*) (const std::vector<uint8_t>&, const std::string&)>(&Parser::parse),
"Parse the given raw data and return a " RST_CLASS_REF(lief.OAT.Binary) " object\n\n"
"raw"_a, py::arg("name") = "",
py::return_value_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) {
auto&& io = py::module::import("io");
auto&& RawIOBase = io.attr("RawIOBase");
auto&& BufferedIOBase = io.attr("BufferedIOBase");
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::OAT::Parser::parse(std::move(raw), name);
},
"io"_a,
"name"_a = "",
py::return_value_policy::take_ownership);
}
}
}

View File

@ -0,0 +1,79 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyOAT.hpp"
#include "LIEF/OAT/Structures.hpp"
#include "LIEF/OAT/enums.hpp"
#include "LIEF/OAT/EnumToString.hpp"
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace OAT {
void init_enums(py::module& m) {
py::enum_<OAT_CLASS_TYPES>(m, "OAT_CLASS_TYPES")
.value(PY_ENUM(OAT_CLASS_TYPES::OAT_CLASS_ALL_COMPILED))
.value(PY_ENUM(OAT_CLASS_TYPES::OAT_CLASS_SOME_COMPILED))
.value(PY_ENUM(OAT_CLASS_TYPES::OAT_CLASS_NONE_COMPILED))
.export_values();
py::enum_<OAT_CLASS_STATUS>(m, "OAT_CLASS_STATUS")
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_RETIRED))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_ERROR))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_NOTREADY))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_IDX))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_LOADED))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_RESOLVING))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_RESOLVED))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_VERIFYING))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_RETRY_VERIFICATION_AT_RUNTIME))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_VERIFYING_AT_RUNTIME))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_VERIFIED))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_INITIALIZING))
.value(PY_ENUM(OAT_CLASS_STATUS::STATUS_INITIALIZED))
.export_values();
py::enum_<HEADER_KEYS>(m, "HEADER_KEYS")
.value(PY_ENUM(HEADER_KEYS::KEY_IMAGE_LOCATION))
.value(PY_ENUM(HEADER_KEYS::KEY_DEX2OAT_CMD_LINE))
.value(PY_ENUM(HEADER_KEYS::KEY_DEX2OAT_HOST))
.value(PY_ENUM(HEADER_KEYS::KEY_PIC))
.value(PY_ENUM(HEADER_KEYS::KEY_HAS_PATCH_INFO))
.value(PY_ENUM(HEADER_KEYS::KEY_DEBUGGABLE))
.value(PY_ENUM(HEADER_KEYS::KEY_NATIVE_DEBUGGABLE))
.value(PY_ENUM(HEADER_KEYS::KEY_COMPILER_FILTER))
.value(PY_ENUM(HEADER_KEYS::KEY_CLASS_PATH))
.value(PY_ENUM(HEADER_KEYS::KEY_BOOT_CLASS_PATH))
.value(PY_ENUM(HEADER_KEYS::KEY_CONCURRENT_COPYING))
.export_values();
py::enum_<INSTRUCTION_SETS>(m, "INSTRUCTION_SETS")
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_NONE))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_ARM))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_ARM_64))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_THUMB2))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_X86))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_X86_64))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_MIPS))
.value(PY_ENUM(INSTRUCTION_SETS::INST_SET_MIPS_64))
.export_values();
}
}
}

View File

@ -0,0 +1,68 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyOAT.hpp"
#include "pyIterators.hpp"
#include "pyOpaqueTypes.hpp"
#include "LIEF/OAT/type_traits.hpp"
template<>
void init_ref_iterator<LIEF::OAT::Header::it_key_values_t>(py::module& m, const std::string& it_name) {
py::class_<LIEF::OAT::Header::it_key_values_t>(m, it_name.c_str())
.def("__getitem__",
[] (LIEF::OAT::Header::it_key_values_t& v, size_t i) -> LIEF::OAT::Header::it_key_values_t::value_type {
if (i >= v.size())
throw py::index_error();
return v[i];
},
py::return_value_policy::reference_internal)
.def("__len__",
[](LIEF::OAT::Header::it_key_values_t& v) {
return v.size();
})
.def("__iter__",
[](LIEF::OAT::Header::it_key_values_t& v) -> LIEF::OAT::Header::it_key_values_t {
return std::begin(v);
}, py::return_value_policy::reference_internal)
.def("__next__",
[] (LIEF::OAT::Header::it_key_values_t& v) -> LIEF::OAT::Header::it_key_values_t::value_type {
if (v == std::end(v)) {
throw py::stop_iteration();
}
return *(v++);
}, py::return_value_policy::reference_internal);
}
namespace LIEF {
namespace OAT {
void init_iterators(py::module& m) {
init_ref_iterator<Header::it_key_values_t>(m, "Header.it_key_values_t");
init_ref_iterator<it_methods>(m, "lief.OAT.it_methods");
init_ref_iterator<it_classes>(m, "lief.OAT.it_classes");
init_ref_iterator<it_dex_files>(m, "lief.OAT.it_dex_files");
}
}
}

43
api/python/OAT/pyOAT.cpp Normal file
View File

@ -0,0 +1,43 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyOAT.hpp"
namespace LIEF {
namespace OAT {
void init_python_module(py::module& m) {
py::module LIEF_OAT_module = m.def_submodule("OAT", "Python API for OAT format");
init_opaque_types(LIEF_OAT_module);
init_enums(LIEF_OAT_module);
init_iterators(LIEF_OAT_module);
init_utils(LIEF_OAT_module);
init_objects(LIEF_OAT_module);
}
void init_objects(py::module& m) {
CREATE(Parser, m);
CREATE(Binary, m);
CREATE(Header, m);
CREATE(DexFile, m);
CREATE(Class, m);
CREATE(Method, m);
}
}
}

58
api/python/OAT/pyOAT.hpp Normal file
View File

@ -0,0 +1,58 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_OAT_H_
#define PY_LIEF_OAT_H_
#include "LIEF/OAT.hpp"
#include "pyLIEF.hpp"
#include "pyOpaqueTypes.hpp"
#include <pybind11/stl.h>
#include <functional>
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
namespace OAT {
template<class T>
void create(py::module&);
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_iterators(py::module&);
void init_opaque_types(py::module&);
void init_enums(py::module&);
void init_utils(py::module&);
SPECIALIZE_CREATE(Parser);
SPECIALIZE_CREATE(Binary);
SPECIALIZE_CREATE(Header);
SPECIALIZE_CREATE(DexFile);
SPECIALIZE_CREATE(Class);
SPECIALIZE_CREATE(Method);
}
}
#endif

View File

@ -0,0 +1,44 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyOAT.hpp"
#include "LIEF/OAT/type_traits.hpp"
namespace LIEF {
namespace OAT {
void init_opaque_types(py::module& m) {
py::class_<LIEF::OAT::Header::it_key_values_t::value_type>(m, "LIEF.OAT.Header.it_key_values_t.value_type")
.def_property_readonly("key",
[] (Header::it_key_values_t::reference p) {
return p.first;
}, py::return_value_policy::reference_internal)
.def_property("value",
[] (Header::it_key_values_t::reference p) {
return p.second;
},
[] (Header::it_key_values_t::reference p, const std::string& value) {
std::string& ref_value = p.second;
ref_value = value;
},
py::return_value_policy::reference_internal);
}
}
}

View File

@ -0,0 +1,27 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_OAT_OPAQUES_TYPES_H_
#define PY_LIEF_OAT_OPAQUES_TYPES_H_
#include "LIEF/OAT.hpp"
#include "pyLIEF.hpp"
#include <pybind11/stl.h>
#include <functional>
PYBIND11_MAKE_OPAQUE(LIEF::OAT::Header::it_key_values_t::value_type); // std::pair<HEADER_KEYS, ref<std::string>>
#endif

View File

@ -0,0 +1,64 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyOAT.hpp"
#include "LIEF/OAT/utils.hpp"
namespace LIEF {
namespace OAT {
void init_utils(py::module& m) {
m.def("is_oat",
static_cast<bool (*)(const LIEF::ELF::Binary&)>(&is_oat),
"Check if the " RST_CLASS_REF(lief.ELF.Binary) " given in parameter is a OAT one",
"binary"_a);
m.def("is_oat",
static_cast<bool (*)(const std::string&)>(&is_oat),
"Check if the **file** given in parameter is a OAT one",
"path"_a);
m.def("is_oat",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&is_oat),
"Check if the **raw data** given in parameter is a OAT one",
"raw"_a);
m.def("version",
static_cast<oat_version_t (*)(const LIEF::ELF::Binary&)>(&version),
"Return the OAT version of the " RST_CLASS_REF(lief.ELF.Binary) " given in parameter",
"binary"_a);
m.def("version",
static_cast<oat_version_t (*)(const std::string&)>(&version),
"Return the OAT version of the **file** given in parameter",
"file"_a);
m.def("version",
static_cast<oat_version_t (*)(const std::vector<uint8_t>&)>(&version),
"Return the OAT version of the **raw data** given in parameter",
"raw"_a);
m.def("android_version",
&android_version,
"Return a " );
}
}
}

View File

@ -16,6 +16,7 @@
#include "pyPE.hpp"
#include "LIEF/PE/hash.hpp"
#include "LIEF/utils.hpp"
#include "LIEF/PE/ResourceNode.hpp"
#include <string>
@ -50,7 +51,7 @@ void init_PE_ResourceNode_class(py::module& m) {
.def_property("name",
[] (const ResourceNode& node) {
return safe_string_converter(u16tou8(node.name()));
return safe_string_converter(LIEF::u16tou8(node.name()));
},
static_cast<void (ResourceNode::*)(const std::string&)>(&ResourceNode::name),
"Resource name")

View File

@ -18,6 +18,7 @@
#include <sstream>
#include "LIEF/PE/hash.hpp"
#include "LIEF/utils.hpp"
#include "LIEF/PE/signature/AuthenticatedAttributes.hpp"
#include "pyPE.hpp"
@ -44,7 +45,7 @@ void init_PE_AuthenticatedAttributes_class(py::module& m) {
.def_property_readonly("program_name",
[] (const AuthenticatedAttributes& authenticated_attributes) {
return safe_string_converter(u16tou8(authenticated_attributes.program_name()));
return safe_string_converter(LIEF::u16tou8(authenticated_attributes.program_name()));
},
"Return the program description (if any)")

View File

@ -0,0 +1,20 @@
set(LIEF_PYTHON_VDEX_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyVDEX.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyIterators.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"
)
set(LIEF_PYTHON_VDEX_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyVDEX.hpp")
source_group("Source Files\\VDEX" FILES ${LIEF_PYTHON_VDEX_SRC})
source_group("Header Files\\VDEX" FILES ${LIEF_PYTHON_VDEX_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_VDEX_SRC}" "${LIEF_PYTHON_VDEX_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/../")

View File

@ -0,0 +1,75 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/VDEX/File.hpp"
#include "LIEF/VDEX/hash.hpp"
#include "pyVDEX.hpp"
namespace LIEF {
namespace VDEX {
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);
template<>
void create<File>(py::module& m) {
// File object
py::class_<File, LIEF::Object>(m, "File", "VDEX File representation")
.def_property_readonly("header",
static_cast<no_const_getter<Header&>>(&File::header),
"Return the VDEX " RST_CLASS_REF(lief.VDEX.Header) "",
py::return_value_policy::reference)
.def_property_readonly("dex_files",
static_cast<no_const_getter<LIEF::DEX::it_dex_files>>(&File::dex_files),
"Return an iterator over " RST_CLASS_REF(lief.DEX.File) "",
py::return_value_policy::reference)
.def_property_readonly("dex2dex_json_info",
&File::dex2dex_json_info)
.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;
});
}
}
}

View File

@ -0,0 +1,78 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/VDEX/Header.hpp"
#include "LIEF/VDEX/hash.hpp"
#include "pyVDEX.hpp"
namespace LIEF {
namespace VDEX {
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, LIEF::Object>(m, "Header", "VDEX Header representation")
.def_property_readonly("magic",
static_cast<getter_t<Header::magic_t>>(&Header::magic),
"Magic value used to identify VDEX")
.def_property_readonly("version",
static_cast<getter_t<vdex_version_t>>(&Header::version),
"VDEX version number")
.def_property_readonly("nb_dex_files",
static_cast<getter_t<uint32_t>>(&Header::nb_dex_files),
"Number of " RST_CLASS_REF(lief.DEX.File) " files registered")
.def_property_readonly("dex_size",
static_cast<getter_t<uint32_t>>(&Header::dex_size),
"Size of **all** " RST_CLASS_REF(lief.DEX.File) "")
.def_property_readonly("verifier_deps_size",
static_cast<getter_t<uint32_t>>(&Header::verifier_deps_size),
"Size of verifier deps section")
.def_property_readonly("quickening_info_size",
static_cast<getter_t<uint32_t>>(&Header::quickening_info_size),
"Size of quickening info section")
.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;
});
}
}
}

View File

@ -0,0 +1,80 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyVDEX.hpp"
#include "LIEF/VDEX/Parser.hpp"
#include <string>
namespace LIEF {
namespace VDEX {
template<>
void create<Parser>(py::module& m) {
// Parser (Parser)
m.def("parse",
static_cast<File* (*) (const std::string&)>(&Parser::parse),
"Parse the given filename and return a " RST_CLASS_REF(lief.VDEX.File) " object"
"filename"_a,
py::return_value_policy::take_ownership);
m.def("parse",
static_cast<File* (*) (const std::vector<uint8_t>&, const std::string&)>(&Parser::parse),
"Parse the given raw data and return a " RST_CLASS_REF(lief.VDEX.File) " object\n\n"
"raw"_a, py::arg("name") = "",
py::return_value_policy::take_ownership);
m.def("parse",
[] (py::object byteio, const std::string& name) {
auto&& io = py::module::import("io");
auto&& RawIOBase = io.attr("RawIOBase");
auto&& BufferedIOBase = io.attr("BufferedIOBase");
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::VDEX::Parser::parse(std::move(raw), name);
},
"io"_a,
"name"_a = "",
py::return_value_policy::take_ownership);
}
}
}

View File

@ -0,0 +1,31 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyVDEX.hpp"
#include "LIEF/VDEX/Structures.hpp"
#include "LIEF/VDEX/enums.hpp"
#include "LIEF/VDEX/EnumToString.hpp"
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace VDEX {
void init_enums(py::module& m) {
}
}
}

View File

@ -0,0 +1,27 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyVDEX.hpp"
#include "pyIterators.hpp"
#include "LIEF/VDEX/type_traits.hpp"
namespace LIEF {
namespace VDEX {
void init_iterators(py::module& m) {
}
}
}

View File

@ -0,0 +1,53 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyVDEX.hpp"
#include "LIEF/VDEX/utils.hpp"
namespace LIEF {
namespace VDEX {
void init_utils(py::module& m) {
m.def("is_vdex",
static_cast<bool (*)(const std::string&)>(&is_vdex),
"Check if the **file** given in parameter is an VDEX",
"path"_a);
m.def("is_vdex",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&is_vdex),
"Check if the **raw data** given in parameter is a VDEX",
"raw"_a);
m.def("version",
static_cast<vdex_version_t (*)(const std::string&)>(&version),
"Return the VDEX version of the **file** given in parameter",
"file"_a);
m.def("version",
static_cast<vdex_version_t (*)(const std::vector<uint8_t>&)>(&version),
"Return the VDEX version of the **raw data** given in parameter",
"raw"_a);
m.def("android_version",
&android_version,
"Return the " RST_CLASS_REF(lief.Android.ANDROID_VERSIONS) " associated with the given VDEX version ",
"vdex_version"_a);
}
}
}

View File

@ -0,0 +1,38 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyVDEX.hpp"
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_enums(LIEF_VDEX_module);
init_iterators(LIEF_VDEX_module);
init_objects(LIEF_VDEX_module);
init_utils(LIEF_VDEX_module);
}
void init_objects(py::module& m) {
CREATE(Parser, m);
CREATE(File, m);
CREATE(Header, m);
}
}
}

View File

@ -0,0 +1,55 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_VDEX_H_
#define PY_LIEF_VDEX_H_
#include "LIEF/VDEX.hpp"
#include "pyLIEF.hpp"
#define SPECIALIZE_CREATE(X) \
template<> \
void create<X>(py::module&)
#define CREATE(X,Y) create<X>(Y)
namespace LIEF {
namespace VDEX {
template<class T>
void create(py::module&);
void init_python_module(py::module& m);
void init_objects(py::module&);
void init_iterators(py::module&);
void init_enums(py::module&);
void init_utils(py::module&);
SPECIALIZE_CREATE(Parser);
SPECIALIZE_CREATE(File);
SPECIALIZE_CREATE(Header);
}
}
#endif

View File

@ -7,15 +7,26 @@ from _pylief import *
__version__ = _pylief.__version__
if @ENABLE_PE_SUPPORT@:
sys.modules["lief.PE"] = _pylief.PE
sys.modules.setdefault("lief.PE", _pylief.PE)
if @ENABLE_ELF_SUPPORT@:
sys.modules["lief.ELF"] = _pylief.ELF
sys.modules.setdefault("lief.ELF", _pylief.ELF)
sys.modules["lief.ELF.ELF32"] = _pylief.ELF.ELF32
sys.modules["lief.ELF.ELF64"] = _pylief.ELF.ELF64
sys.modules.setdefault("lief.ELF.ELF32", _pylief.ELF.ELF32)
sys.modules.setdefault("lief.ELF.ELF64", _pylief.ELF.ELF64)
if @ENABLE_MACHO_SUPPORT@:
sys.modules["lief.MachO"] = _pylief.MachO
sys.modules.setdefault("lief.MachO", _pylief.MachO)
if @ENABLE_OAT_SUPPORT@:
sys.modules.setdefault("lief.OAT", _pylief.OAT)
if @ENABLE_DEX_SUPPORT@:
sys.modules.setdefault("lief.DEX", _pylief.DEX)
if @ENABLE_VDEX_SUPPORT@:
sys.modules.setdefault("lief.VDEX", _pylief.VDEX)
if @ENABLE_VDEX_SUPPORT@:
sys.modules.setdefault("lief.ART", _pylief.ART)

View File

@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/android/CMakeLists.txt")

View File

@ -0,0 +1,14 @@
set(LIEF_PYTHON_ANDROID_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyAndroid.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyVersion.cpp"
)
set(LIEF_PYTHON_ANDROID_HDR
"${CMAKE_CURRENT_LIST_DIR}/pyAndroid.hpp")
source_group("Source Files\\Android" FILES ${LIEF_PYTHON_ANDROID_SRC})
source_group("Header Files\\Android" FILES ${LIEF_PYTHON_ANDROID_HDR})
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_ANDROID_SRC}" "${LIEF_PYTHON_ANDROID_HDR}")
target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/../../")

View File

@ -0,0 +1,29 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyAndroid.hpp"
namespace LIEF {
namespace Android {
void init_python_module(py::module& m) {
py::module lief_android_module = m.def_submodule("Android", "Python API for Android platform");
init_versions(lief_android_module);
}
}
}

View File

@ -0,0 +1,31 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_ANDROID_H_
#define PY_LIEF_ANDROID_H_
#include "LIEF/platforms/android.hpp"
#include "pyLIEF.hpp"
namespace LIEF {
namespace Android {
void init_python_module(py::module&);
void init_versions(py::module&);
}
}
#endif

View File

@ -0,0 +1,50 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyAndroid.hpp"
#include "LIEF/platforms/android/version.hpp"
#define PY_ENUM(x) to_string(x), x
namespace LIEF {
namespace Android {
void init_versions(py::module& m) {
py::enum_<ANDROID_VERSIONS>(m, "ANDROID_VERSIONS")
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_UNKNOWN))
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_601))
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_700))
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_710))
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_712))
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_800))
.value(PY_ENUM(ANDROID_VERSIONS::VERSION_810));
m.def("code_name",
&code_name,
"Return the Android code associated with a " RST_CLASS_REF(lief.Android.ANDROID_VERSIONS) ".\n"
"For example: ``Nougat``",
"version"_a);
m.def("version_string",
&version_string,
"Return the Android version as a string.\n"
"For example: ``7.0.1``",
"version"_a);
}
}
}

24
api/python/pyHash.cpp Normal file
View File

@ -0,0 +1,24 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/config.h"
#include "LIEF/hash.hpp"
#include "pyLIEF.hpp"
void init_hash_functions(py::module& m) {
m.def("hash", static_cast<size_t(*)(const LIEF::Object&)>(&LIEF::hash));
m.def("hash", static_cast<size_t(*)(const std::vector<uint8_t>&)>(&LIEF::hash));
}

View File

@ -31,8 +31,8 @@ namespace py = pybind11;
void init_LIEF_iterators(py::module&);
template<class T>
void init_ref_iterator(py::module& m) {
py::class_<T>(m, typeid(T).name())
void init_ref_iterator(py::module& m, const std::string& it_name = typeid(T).name()) {
py::class_<T>(m, it_name.c_str())
.def("__getitem__",
[](T& v, size_t i) -> typename T::reference {
if (i >= v.size())

View File

@ -17,11 +17,30 @@
#include "LIEF/version.h"
#include "pyLIEF.hpp"
#if defined(LIEF_OAT_SUPPORT)
#include "OAT/pyOAT.hpp"
#endif
#if defined(LIEF_VDEX_SUPPORT)
#include "VDEX/pyVDEX.hpp"
#endif
#if defined(LIEF_DEX_SUPPORT)
#include "DEX/pyDEX.hpp"
#endif
#if defined(LIEF_ART_SUPPORT)
#include "ART/pyART.hpp"
#endif
#include "platforms/android/pyAndroid.hpp"
py::module LIEF_module("_pylief", "Python API for LIEF");
PYBIND11_MODULE(_pylief, LIEF_module) {
LIEF_module.attr("__version__") = py::str(LIEF_VERSION);
init_LIEF_Object_class(LIEF_module);
@ -35,6 +54,8 @@ PYBIND11_MODULE(_pylief, LIEF_module) {
// Init the LIEF module
init_LIEF_module(LIEF_module);
init_hash_functions(LIEF_module);
// Init the ELF module
#if defined(LIEF_ELF_SUPPORT)
@ -51,6 +72,29 @@ PYBIND11_MODULE(_pylief, LIEF_module) {
init_MachO_module(LIEF_module);
#endif
// Init the OAT module
#if defined(LIEF_OAT_SUPPORT)
LIEF::OAT::init_python_module(LIEF_module);
#endif
// Init the VDEX module
#if defined(LIEF_VDEX_SUPPORT)
LIEF::VDEX::init_python_module(LIEF_module);
#endif
// Init the DEX module
#if defined(LIEF_DEX_SUPPORT)
LIEF::DEX::init_python_module(LIEF_module);
#endif
// Init the ART module
#if defined(LIEF_ART_SUPPORT)
LIEF::ART::init_python_module(LIEF_module);
#endif
LIEF::Android::init_python_module(LIEF_module);
// Init util functions
init_utils_functions(LIEF_module);

View File

@ -41,9 +41,19 @@ void init_LIEF_Object_class(py::module&);
void init_LIEF_Logger(py::module&);
void init_LIEF_exceptions(py::module&);
void init_LIEF_module(py::module&);
void init_hash_functions(py::module&);
#if defined(LIEF_ELF_SUPPORT)
void init_ELF_module(py::module&);
#endif
#if defined(LIEF_PE_SUPPORT)
void init_PE_module(py::module&);
#endif
#if defined(LIEF_MACHO_SUPPORT)
void init_MachO_module(py::module&);
#endif
void init_utils_functions(py::module&);
#if defined(LIEF_JSON_SUPPORT)

View File

@ -16,6 +16,7 @@
#include "LIEF/PE/utils.hpp"
#include "LIEF/MachO/utils.hpp"
#include "LIEF/ELF/utils.hpp"
#include "LIEF/OAT/utils.hpp"
#include "pyLIEF.hpp"
@ -76,4 +77,117 @@ void init_utils_functions(py::module& m) {
#endif
#if defined(LIEF_OAT_SUPPORT)
m.def("is_oat",
static_cast<bool (*)(const std::string&)>(&LIEF::OAT::is_oat),
"Check if the given file is an ``OAT`` (from filename)",
"filename"_a);
m.def("is_oat",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&LIEF::OAT::is_oat),
"Check if the given raw data is an ``OAT``",
"raw"_a);
m.def("is_oat",
static_cast<bool (*)(const LIEF::ELF::Binary&)>(&LIEF::OAT::is_oat),
"Check if the given " RST_CLASS_REF(lief.ELF.Binary) " is an ``OAT``",
"elf"_a);
m.def("oat_version",
static_cast<LIEF::OAT::oat_version_t (*)(const std::string&)>(&LIEF::OAT::version),
"Return the OAT version of the given file",
"filename"_a);
m.def("oat_version",
static_cast<LIEF::OAT::oat_version_t (*)(const std::vector<uint8_t>&)>(&LIEF::OAT::version),
"Return the OAT version of the raw data",
"raw"_a);
m.def("oat_version",
static_cast<LIEF::OAT::oat_version_t (*)(const LIEF::ELF::Binary&)>(&LIEF::OAT::version),
"Return the OAT version of the given " RST_CLASS_REF(lief.ELF.Binary) "",
"elf"_a);
#endif
#if defined(LIEF_DEX_SUPPORT)
m.def("is_dex",
static_cast<bool (*)(const std::string&)>(&LIEF::DEX::is_dex),
"Check if the given file is a ``DEX`` (from filename)",
"filename"_a);
m.def("is_dex",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&LIEF::DEX::is_dex),
"Check if the given raw data is a ``DEX``",
"raw"_a);
m.def("dex_version",
static_cast<LIEF::DEX::dex_version_t (*)(const std::string&)>(&LIEF::DEX::version),
"Return the OAT version of the given file",
"filename"_a);
m.def("dex_version",
static_cast<LIEF::DEX::dex_version_t (*)(const std::vector<uint8_t>&)>(&LIEF::DEX::version),
"Return the DEX version of the raw data",
"raw"_a);
#endif
#if defined(LIEF_VDEX_SUPPORT)
m.def("is_vdex",
static_cast<bool (*)(const std::string&)>(&LIEF::VDEX::is_vdex),
"Check if the given file is a ``VDEX`` (from filename)",
"filename"_a);
m.def("is_vdex",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&LIEF::VDEX::is_vdex),
"Check if the given raw data is a ``VDEX``",
"raw"_a);
m.def("vdex_version",
static_cast<LIEF::VDEX::vdex_version_t (*)(const std::string&)>(&LIEF::VDEX::version),
"Return the VDEX version of the given file",
"filename"_a);
m.def("vdex_version",
static_cast<LIEF::VDEX::vdex_version_t (*)(const std::vector<uint8_t>&)>(&LIEF::VDEX::version),
"Return the VDEX version of the raw data",
"raw"_a);
#endif
#if defined(LIEF_ART_SUPPORT)
m.def("is_art",
static_cast<bool (*)(const std::string&)>(&LIEF::ART::is_art),
"Check if the given file is an ``ART`` (from filename)",
"filename"_a);
m.def("is_art",
static_cast<bool (*)(const std::vector<uint8_t>&)>(&LIEF::ART::is_art),
"Check if the given raw data is an ``ART``",
"raw"_a);
m.def("art_version",
static_cast<LIEF::ART::art_version_t (*)(const std::string&)>(&LIEF::ART::version),
"Return the ART version of the given file",
"filename"_a);
m.def("art_version",
static_cast<LIEF::ART::art_version_t (*)(const std::vector<uint8_t>&)>(&LIEF::ART::version),
"Return the ART version of the raw data",
"raw"_a);
#endif
}

View File

@ -22,6 +22,10 @@ option(LIEF_DISABLE_FROZEN "Disable Frozen even if it is supported" OFF)
option(LIEF_ELF "Build LIEF with ELF module" ON)
option(LIEF_PE "Build LIEF with PE module" ON)
option(LIEF_MACHO "Build LIEF with MachO module" ON)
option(LIEF_OAT "Build LIEF with OAT module" ON)
option(LIEF_DEX "Build LIEF with DEX module" ON)
option(LIEF_VDEX "Build LIEF with VDEX module" ON)
option(LIEF_ART "Build LIEF with ART module" ON)
# Sanitizer
option(LIEF_ASAN "Enable Address sanitizer" OFF)

View File

@ -2016,6 +2016,8 @@ PREDEFINED = "protected=private" \
"LIEF_JSON_SUPPORT=1" \
"LIEF_PE_SUPPORT=1" \
"LIEF_MACHO_SUPPORT=1" \
"LIEF_MACHO_SUPPORT=1" \
"LIEF_OAT_SUPPORT=1" \
"LIEF_LOGGING_SUPPORT=1" \
__cplusplus
@ -2038,6 +2040,14 @@ EXPAND_AS_DEFINED += LIEF_MACHO_FORWARD
EXPAND_AS_DEFINED += LIEF_MACHO_VISITABLE
EXPAND_AS_DEFINED += LIEF_ABSTRACT_VISITABLE
EXPAND_AS_DEFINED += LIEF_ABSTRACT_FORWARD
EXPAND_AS_DEFINED += LIEF_OAT_VISITABLE
EXPAND_AS_DEFINED += LIEF_OAT_FORWARD
EXPAND_AS_DEFINED += LIEF_DEX_VISITABLE
EXPAND_AS_DEFINED += LIEF_DEX_FORWARD
EXPAND_AS_DEFINED += LIEF_VDEX_VISITABLE
EXPAND_AS_DEFINED += LIEF_VDEX_FORWARD
EXPAND_AS_DEFINED += LIEF_ART_VISITABLE
EXPAND_AS_DEFINED += LIEF_ART_FORWARD
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have

0
doc/sphinx/_static/tutorial/09/telegram.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -0,0 +1,38 @@
ART
---
Utilities
*********
.. doxygenfunction:: lief::ART::is_art
.. doxygenfunction:: lief::ART::version
.. doxygenfunction:: lief::ART::android_version
----------
Parser
*******
.. doxygenclass:: LIEF::ART::Parser
:project: lief
----------
File
****
.. doxygenclass:: LIEF::ART::File
:project: lief
----------
Header
******
.. doxygenclass:: LIEF::ART::Header
:project: lief

101
doc/sphinx/api/cpp/dex.rst Normal file
View File

@ -0,0 +1,101 @@
DEX
---
Utilities
*********
.. doxygenfunction:: lief::DEX::is_dex
.. doxygenfunction:: lief::DEX::version
----------
Parser
*******
.. doxygenclass:: LIEF::DEX::Parser
:project: lief
----------
File
****
.. doxygenclass:: LIEF::DEX::File
:project: lief
----------
Header
******
.. doxygenclass:: LIEF::DEX::Header
:project: lief
----------
Method
******
.. doxygenclass:: LIEF::DEX::Method
:project: lief
----------
Class
*****
.. doxygenclass:: LIEF::DEX::Class
:project: lief
----------
Code Info
*********
.. doxygenclass:: LIEF::DEX::CodeInfo
:project: lief
----------
Prototype
*********
.. doxygenclass:: LIEF::DEX::Prototype
:project: lief
----------
Type
****
.. doxygenclass:: LIEF::DEX::Type
:project: lief
----------
MapList
*******
.. doxygenclass:: LIEF::DEX::MapList
:project: lief
----------
MapItem
*******
.. doxygenclass:: LIEF::DEX::MapItem
:project: lief

View File

@ -10,6 +10,10 @@ C++
elf.rst
pe.rst
macho.rst
oat.rst
dex.rst
vdex.rst
art.rst
Exceptions
----------

View File

@ -0,0 +1,39 @@
OAT
---
Utilities
*********
.. doxygenfunction:: lief::OAT::is_oat
.. doxygenfunction:: lief::OAT::version
.. doxygenfunction:: lief::OAT::android_version
----------
Parser
*******
.. doxygenclass:: LIEF::OAT::Parser
:project: lief
----------
Binary
******
.. doxygenclass:: LIEF::OAT::Binary
:project: lief
----------
Header
******
.. doxygenclass:: LIEF::OAT::Header
:project: lief

View File

@ -410,12 +410,6 @@ Utilities
.. doxygenfunction:: LIEF::PE::is_pe(const std::vector< uint8_t > &)
:project: lief
.. doxygenfunction:: LIEF::PE::u16tou8
:project: lief
.. doxygenfunction:: LIEF::PE::u8tou16
:project: lief
.. doxygenfunction:: LIEF::PE::get_imphash
:project: lief

View File

@ -0,0 +1,38 @@
VDEX
----
Utilities
*********
.. doxygenfunction:: lief::VDEX::is_vdex
.. doxygenfunction:: lief::VDEX::version
.. doxygenfunction:: lief::VDEX::android_version
----------
Parser
*******
.. doxygenclass:: LIEF::VDEX::Parser
:project: lief
----------
File
****
.. doxygenclass:: LIEF::VDEX::File
:project: lief
----------
Header
******
.. doxygenclass:: LIEF::VDEX::Header
:project: lief

View File

@ -0,0 +1,43 @@
ART
---
Utilities
*********
.. autofunction:: lief.ART.is_art
.. autofunction:: lief.ART.version
.. autofunction:: lief.ART.android_version
----------
Parser
******
.. autofunction:: lief.ART.parse
----------
File
****
.. autoclass:: lief.ART.File
:members:
:inherited-members:
:undoc-members:
----------
Header
******
.. autoclass:: lief.ART.Header
:members:
:inherited-members:
:undoc-members:

View File

@ -0,0 +1,118 @@
DEX
---
Utilities
*********
.. autofunction:: lief.DEX.is_dex
.. autofunction:: lief.DEX.version
----------
Parser
*******
.. autofunction:: lief.DEX.parse
----------
File
****
.. autoclass:: lief.DEX.File
:members:
:inherited-members:
:undoc-members:
----------
Header
******
.. autoclass:: lief.DEX.Header
:members:
:inherited-members:
:undoc-members:
----------
Method
******
.. autoclass:: lief.DEX.Method
:members:
:inherited-members:
:undoc-members:
----------
Class
******
.. autoclass:: lief.DEX.Class
:members:
:inherited-members:
:undoc-members:
----------
Code Info
*********
.. autoclass:: lief.DEX.CodeInfo
:members:
:inherited-members:
:undoc-members:
----------
Prototype
*********
.. autoclass:: lief.DEX.Prototype
:members:
:inherited-members:
:undoc-members:
----------
Type
****
.. autoclass:: lief.DEX.Type
:members:
:inherited-members:
:undoc-members:
----------
MapList
*******
.. autoclass:: lief.DEX.MapList
:members:
:inherited-members:
:undoc-members:
----------
MapItem
*******
.. autoclass:: lief.DEX.MapItem
:members:
:inherited-members:
:undoc-members:

View File

@ -17,6 +17,10 @@ Python
elf.rst
pe.rst
macho.rst
oat.rst
dex.rst
vdex.rst
art.rst
Exceptions

View File

@ -0,0 +1,40 @@
OAT
---
Utilities
*********
.. autofunction:: lief.OAT.is_oat
.. autofunction:: lief.OAT.version
.. autofunction:: lief.OAT.android_version
----------
Parser
*******
.. autofunction:: lief.OAT.parse
----------
Binary
******
.. autoclass:: lief.OAT.Binary
:members:
:inherited-members:
:undoc-members:
----------
Header
******
.. autoclass:: lief.OAT.Header
:members:
:inherited-members:
:undoc-members:

View File

@ -7,6 +7,22 @@ Utilities
.. autofunction:: lief.is_macho
.. autofunction:: lief.is_oat
.. autofunction:: lief.oat_version
.. autofunction:: lief.is_dex
.. autofunction:: lief.dex_version
.. autofunction:: lief.is_vdex
.. autofunction:: lief.vdex_version
.. autofunction:: lief.is_art
.. autofunction:: lief.art_version
.. autofunction:: lief.shell
.. autofunction:: lief.breakp

View File

@ -0,0 +1,42 @@
VDEX
----
Utilities
*********
.. autofunction:: lief.VDEX.is_vdex
.. autofunction:: lief.VDEX.version
.. autofunction:: lief.VDEX.android_version
----------
Parser
******
.. autofunction:: lief.VDEX.parse
----------
File
****
.. autoclass:: lief.VDEX.File
:members:
:inherited-members:
:undoc-members:
----------
Header
******
.. autoclass:: lief.VDEX.Header
:members:
:inherited-members:
:undoc-members:

View File

@ -0,0 +1,15 @@
OAT Format
==========
OAT 64
------
OAT 79
------
Changes summerize
-----------------
In OAT Dex file the OAT no longer

View File

@ -7,19 +7,33 @@ set(LIEF_ELF_CPP_EXAMPLES
elf_symbols.cpp
)
set(LIEF_PE_CPP_EXAMPLES
pe_builder.cpp
pe_reader.cpp
)
set(LIEF_MACHO_CPP_EXAMPLES
macho_reader.cpp
macho_instrumentation.cpp
macho_builder.cpp
)
set(LIEF_OAT_CPP_EXAMPLES
oat_reader.cpp
)
set(LIEF_VDEX_CPP_EXAMPLES
vdex_reader.cpp
)
set(LIEF_ART_CPP_EXAMPLES
art_reader.cpp
)
set(LIEF_DEX_CPP_EXAMPLES
dex_reader.cpp
)
set(LIEF_CPP_EXAMPLES
abstract_reader.cpp
logging.cpp
@ -30,16 +44,30 @@ if (LIEF_ELF)
set(LIEF_CPP_EXAMPLES "${LIEF_CPP_EXAMPLES}" "${LIEF_ELF_CPP_EXAMPLES}")
endif()
if (LIEF_PE)
set(LIEF_CPP_EXAMPLES "${LIEF_CPP_EXAMPLES}" "${LIEF_PE_CPP_EXAMPLES}")
endif()
if (LIEF_MACHO)
set(LIEF_CPP_EXAMPLES "${LIEF_CPP_EXAMPLES}" "${LIEF_MACHO_CPP_EXAMPLES}")
endif()
if (LIEF_OAT)
set(LIEF_CPP_EXAMPLES ${LIEF_CPP_EXAMPLES} ${LIEF_OAT_CPP_EXAMPLES})
endif()
if (LIEF_VDEX)
set(LIEF_CPP_EXAMPLES ${LIEF_CPP_EXAMPLES} ${LIEF_VDEX_CPP_EXAMPLES})
endif()
if (LIEF_ART)
set(LIEF_CPP_EXAMPLES ${LIEF_CPP_EXAMPLES} ${LIEF_ART_CPP_EXAMPLES})
endif()
if (LIEF_DEX)
set(LIEF_CPP_EXAMPLES ${LIEF_CPP_EXAMPLES} ${LIEF_DEX_CPP_EXAMPLES})
endif()
foreach(example ${LIEF_CPP_EXAMPLES})
string(REGEX REPLACE ".cpp\$" "" output_name "${example}")

View File

@ -0,0 +1,42 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 <iostream>
#include <memory>
#include <LIEF/ART.hpp>
#include <LIEF/logging.hpp>
using namespace LIEF::ART;
int main(int argc, char **argv) {
LIEF::Logger::set_level(LIEF::LOGGING_LEVEL::LOG_DEBUG);
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <ART file>" << std::endl;
return EXIT_FAILURE;
}
std::unique_ptr<const File> file;
try {
file = std::unique_ptr<const File>{LIEF::ART::Parser::parse(argv[1])};
} catch (const LIEF::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
}

View File

@ -0,0 +1,42 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 <iostream>
#include <memory>
#include <LIEF/DEX.hpp>
#include <LIEF/logging.hpp>
using namespace LIEF::DEX;
int main(int argc, char **argv) {
LIEF::Logger::set_level(LIEF::LOGGING_LEVEL::LOG_DEBUG);
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <DEX file>" << std::endl;
return EXIT_FAILURE;
}
std::unique_ptr<const File> file;
try {
file = std::unique_ptr<const File>{LIEF::DEX::Parser::parse(argv[1])};
} catch (const LIEF::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
}

View File

@ -0,0 +1,43 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 <iostream>
#include <memory>
#include <LIEF/OAT.hpp>
#include <LIEF/logging.hpp>
using namespace LIEF::OAT;
int main(int argc, char **argv) {
LIEF::Logger::set_level(LIEF::LOGGING_LEVEL::LOG_DEBUG);
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <OAT file>" << std::endl;
return EXIT_FAILURE;
}
std::unique_ptr<const Binary> binary;
try {
binary = std::unique_ptr<const Binary>{LIEF::OAT::Parser::parse(argv[1])};
std::cout << *binary << std::endl;
} catch (const LIEF::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
}

View File

@ -0,0 +1,45 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 <iostream>
#include <memory>
#include <LIEF/VDEX.hpp>
#include <LIEF/logging.hpp>
using namespace LIEF::VDEX;
int main(int argc, char **argv) {
LIEF::Logger::set_level(LIEF::LOGGING_LEVEL::LOG_DEBUG);
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <VDEX file>" << std::endl;
return EXIT_FAILURE;
}
std::unique_ptr<const File> file;
try {
file = std::unique_ptr<const File>{LIEF::VDEX::Parser::parse(argv[1])};
for (auto&& f : file->dex_files()) {
std::cout << f.location() << std::endl;
}
} catch (const LIEF::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
}

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Description
# -----------
# Print information about a DEX file in the JSON format
import argparse
import sys
import lief
import json
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file', help='DEX binary')
args = parser.parse_args()
if not lief.DEX.is_dex(args.file):
print("{} is not a DEX file".format(args.file))
return 1
dexfile = lief.DEX.parse(args.file)
json_data = json.loads(lief.to_json(dexfile))
print(json.dumps(json_data, sort_keys = True, indent = 4))
if __name__ == "__main__":
sys.exit(main())

View File

@ -0,0 +1,197 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Description
# -----------
# Print information about Android DEX files
import sys
import os
import argparse
import traceback
import lief
from lief import DEX
from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.DEBUG)
EXIT_STATUS = 0
terminal_rows, terminal_columns = 100, 100
try:
terminal_rows, terminal_columns = os.popen('stty size', 'r').read().split()
except ValueError:
pass
class exceptions_handler(object):
func = None
def __init__(self, exceptions, on_except_callback=None):
self.exceptions = exceptions
self.on_except_callback = on_except_callback
def __call__(self, *args, **kwargs):
if self.func is None:
self.func = args[0]
return self
try:
return self.func(*args, **kwargs)
except self.exceptions as e:
global EXIT_STATUS
print("{} raised: {}".format(self.func.__name__, e))
EXIT_STATUS = 1
if self.on_except_callback is not None:
self.on_except_callback(e)
else:
print("-" * 60)
print("Exception in {}: {}".format(self.func.__name__, e))
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_tb(exc_traceback)
print("-" * 60)
@exceptions_handler(Exception)
def print_information(dexfile):
print("== Information ==")
format_str = "{:<30} {:<30}"
format_hex = "{:<30} 0x{:<28x}"
format_dec = "{:<30} {:<30d}"
version = dexfile.version
print("DEX File version: {}".format(version))
print("")
@exceptions_handler(Exception)
def print_header(dexfile):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
print("== Header ==")
header = dexfile.header
print(header)
@exceptions_handler(Exception)
def print_classes(dexfile):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
classes = dexfile.classes
print("== Classes ==")
for cls in classes:
print(cls)
@exceptions_handler(Exception)
def print_methods(dexfile):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
methods = dexfile.methods
print("== Methods ==")
for m in methods:
print(m)
@exceptions_handler(Exception)
def print_strings(dexfile):
print("== Strings ==")
for s in dexfile.strings:
print(s)
@exceptions_handler(Exception)
def print_types(dexfile):
print("== Types ==")
for t in dexfile.types:
print(t)
@exceptions_handler(Exception)
def print_prototypes(dexfile):
print("== Prototypes ==")
for t in dexfile.prototypes:
print(t)
@exceptions_handler(Exception)
def print_map(dexfile):
print("== Map ==")
print(dexfile.map)
def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] DEX files')
parser.add_argument('-a', '--all',
action='store_true', dest='show_all',
help='Show all information')
parser.add_argument('-H', '--header',
action='store_true', dest='show_header',
help='Display header')
parser.add_argument('-c', '--classes',
action='store_true', dest='show_classes',
help='Display classes')
parser.add_argument('-m', '--methods',
action='store_true', dest='show_methods',
help='Display Methods')
parser.add_argument('-s', '--strings',
action='store_true', dest='show_strings',
help='Display Strings')
parser.add_argument('-t', '--types',
action='store_true', dest='show_types',
help='Display Types')
parser.add_argument('-p', '--prototypes',
action='store_true', dest='show_prototypes',
help='Display Prototypes')
parser.add_argument('-M', '--map',
action='store_true', dest='show_map',
help='Display Map')
parser.add_argument("file",
metavar="<dex-file>",
help='Target DEX File')
args = parser.parse_args()
binary = None
try:
dexfile = DEX.parse(args.file)
except lief.exception as e:
print(e)
sys.exit(1)
print_information(dexfile)
if args.show_header or args.show_all:
print_header(dexfile)
if (args.show_classes or args.show_all) and len(dexfile.classes) > 0:
print_classes(dexfile)
if (args.show_methods or args.show_all) and len(dexfile.methods) > 0:
print_methods(dexfile)
if (args.show_strings or args.show_all) and len(dexfile.strings) > 0:
print_strings(dexfile)
if (args.show_types or args.show_all) and len(dexfile.types) > 0:
print_types(dexfile)
if (args.show_prototypes or args.show_all) and len(dexfile.prototypes) > 0:
print_prototypes(dexfile)
if args.show_map or args.show_all:
print_map(dexfile)
sys.exit(EXIT_STATUS)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,14 @@
import lief
import json
import sys
if len(sys.argv) != 2:
print("Usage: {} <file>".format(sys.argv[0]))
sys.exit(1)
obj = lief.parse(sys.argv[1])
json_data = json.loads(lief.to_json(obj))
print(json.dumps(json_data, sort_keys = True, indent = 4))

View File

@ -0,0 +1,173 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Description
# -----------
# Print information about a Android OAT files
import sys
import os
import argparse
import traceback
import lief
from lief import OAT
from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.DEBUG)
EXIT_STATUS = 0
terminal_rows, terminal_columns = 100, 100
try:
terminal_rows, terminal_columns = os.popen('stty size', 'r').read().split()
except ValueError:
pass
class exceptions_handler(object):
func = None
def __init__(self, exceptions, on_except_callback=None):
self.exceptions = exceptions
self.on_except_callback = on_except_callback
def __call__(self, *args, **kwargs):
if self.func is None:
self.func = args[0]
return self
try:
return self.func(*args, **kwargs)
except self.exceptions as e:
global EXIT_STATUS
print("{} raised: {}".format(self.func.__name__, e))
EXIT_STATUS = 1
if self.on_except_callback is not None:
self.on_except_callback(e)
else:
print("-" * 60)
print("Exception in {}: {}".format(self.func.__name__, e))
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_tb(exc_traceback)
print("-" * 60)
@exceptions_handler(Exception)
def print_information(binary):
print("== Information ==")
format_str = "{:<30} {:<30}"
format_hex = "{:<30} 0x{:<28x}"
format_dec = "{:<30} {:<30d}"
android_version = lief.OAT.android_version(binary.header.version)
code_name = lief.Android.code_name(android_version)
version = lief.Android.version_string(android_version)
print("Version: {} - Android {} {}".format(binary.header.version, version, code_name))
print("Number of dex files: {}".format(len(binary.oat_dex_files)))
print("Number of classes: {}".format(len(binary.classes)))
print("Number of methods: {}".format(len(binary.methods)))
print("")
@exceptions_handler(Exception)
def print_header(binary):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
print("== Header ==")
header = binary.header
print(header)
@exceptions_handler(Exception)
def print_dex_files(binary):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
oat_dex_files = binary.oat_dex_files
print("== Dex files ==")
for oat_dex in oat_dex_files:
print(oat_dex)
@exceptions_handler(Exception)
def print_classes(binary):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
classes = binary.classes
print("== Classes ==")
for cls in classes:
print(cls)
@exceptions_handler(Exception)
def print_methods(binary):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
methods = binary.methods
print("== Methods ==")
for m in methods:
print(m)
def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] oat files')
parser.add_argument('-a', '--all',
action='store_true', dest='show_all',
help='Show all information')
parser.add_argument('-H', '--header',
action='store_true', dest='show_header',
help='Display header')
parser.add_argument('-c', '--classes',
action='store_true', dest='show_classes',
help='Display classes')
parser.add_argument('-d', '--dex',
action='store_true', dest='show_dex',
help='Display Dex files')
parser.add_argument('-m', '--methods',
action='store_true', dest='show_methods',
help='Display Methods')
parser.add_argument('-x', '--extract',
action='store_true', dest='extract_dex',
help='Extract DEX files')
parser.add_argument("binary",
metavar="<oat-file>",
help='Target OAT File')
args = parser.parse_args()
binary = None
try:
binary = OAT.parse(args.binary)
except lief.exception as e:
print(e)
sys.exit(1)
print_information(binary)
if args.show_header or args.show_all:
print_header(binary)
if (args.show_dex or args.show_all) and len(binary.oat_dex_files) > 0:
print_dex_files(binary)
if args.show_classes and len(binary.classes) > 0:
print_classes(binary)
if args.show_methods and len(binary.methods) > 0:
print_methods(binary)
sys.exit(EXIT_STATUS)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Description
# -----------
# Print information about a DEX file in the JSON format
import argparse
import sys
import lief
import json
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file', help='VDEX file')
args = parser.parse_args()
if not lief.VDEX.is_vdex(args.file):
print("{} is not a VDEX file".format(args.file))
return 1
dexfile = lief.VDEX.parse(args.file)
json_data = json.loads(lief.to_json(dexfile))
print(json.dumps(json_data, sort_keys = True, indent = 4))
if __name__ == "__main__":
sys.exit(main())

View File

@ -0,0 +1,109 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Description
# -----------
# Print information about Android VDEX files
import sys
import os
import argparse
import traceback
import lief
from lief import VDEX
from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.DEBUG)
EXIT_STATUS = 0
terminal_rows, terminal_columns = 100, 100
try:
terminal_rows, terminal_columns = os.popen('stty size', 'r').read().split()
except ValueError:
pass
class exceptions_handler(object):
func = None
def __init__(self, exceptions, on_except_callback=None):
self.exceptions = exceptions
self.on_except_callback = on_except_callback
def __call__(self, *args, **kwargs):
if self.func is None:
self.func = args[0]
return self
try:
return self.func(*args, **kwargs)
except self.exceptions as e:
global EXIT_STATUS
print("{} raised: {}".format(self.func.__name__, e))
EXIT_STATUS = 1
if self.on_except_callback is not None:
self.on_except_callback(e)
else:
print("-" * 60)
print("Exception in {}: {}".format(self.func.__name__, e))
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_tb(exc_traceback)
print("-" * 60)
@exceptions_handler(Exception)
def print_information(vdexfile):
print("== Information ==")
format_str = "{:<30} {:<30}"
format_hex = "{:<30} 0x{:<28x}"
format_dec = "{:<30} {:<30d}"
version = vdexfile.header.version
print("VDEX File version: {}".format(version))
print("")
@exceptions_handler(Exception)
def print_header(vdexfile):
format_str = "{:<33} {:<30}"
format_hex = "{:<33} 0x{:<28x}"
format_dec = "{:<33} {:<30d}"
print("== Header ==")
header = vdexfile.header
print(header)
def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] VDEX files')
parser.add_argument('-a', '--all',
action='store_true', dest='show_all',
help='Show all information')
parser.add_argument('-H', '--header',
action='store_true', dest='show_header',
help='Display header')
parser.add_argument("file",
metavar="<dex-file>",
help='Target DEX File')
args = parser.parse_args()
vdexfile = None
try:
vdexfile = DEX.parse(args.file)
except lief.exception as e:
print(e)
sys.exit(1)
print_information(vdexfile)
if args.show_header or args.show_all:
print_header(vdexfile)
sys.exit(EXIT_STATUS)
if __name__ == "__main__":
main()

23
include/LIEF/ART.hpp Normal file
View File

@ -0,0 +1,23 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_H_
#define LIEF_ART_H_
#include "LIEF/ART/Parser.hpp"
#include "LIEF/ART/utils.hpp"
#include "LIEF/ART/File.hpp"
#endif

View File

@ -0,0 +1,40 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_ENUM_TO_STRING_H_
#define LIEF_ART_ENUM_TO_STRING_H_
#include "LIEF/visibility.h"
#include "LIEF/ART/enums.hpp"
namespace LIEF {
namespace ART {
LIEF_API const char* to_string(STORAGE_MODES e);
LIEF_API const char* to_string(ART_17::IMAGE_SECTIONS e);
LIEF_API const char* to_string(ART_29::IMAGE_SECTIONS e);
LIEF_API const char* to_string(ART_30::IMAGE_SECTIONS e);
LIEF_API const char* to_string(ART_17::IMAGE_METHODS e);
LIEF_API const char* to_string(ART_44::IMAGE_METHODS e);
LIEF_API const char* to_string(ART_17::IMAGE_ROOTS e);
LIEF_API const char* to_string(ART_44::IMAGE_ROOTS e);
} // namespace ART
} // namespace LIEF
#endif

59
include/LIEF/ART/File.hpp Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_FILE_H_
#define LIEF_ART_FILE_H_
#include <iostream>
#include "LIEF/ART/Header.hpp"
#include "LIEF/visibility.h"
#include "LIEF/Object.hpp"
#include "LIEF/DEX.hpp"
namespace LIEF {
namespace ART {
class Parser;
class LIEF_API File : public Object {
friend class Parser;
public:
File& operator=(const File& copy) = delete;
File(const File& copy) = delete;
const Header& header(void) const;
Header& header(void);
virtual void accept(Visitor& visitor) const override;
bool operator==(const File& rhs) const;
bool operator!=(const File& rhs) const;
virtual ~File(void);
LIEF_API friend std::ostream& operator<<(std::ostream& os, const File& art_file);
private:
File(void);
Header header_;
};
}
}
#endif

129
include/LIEF/ART/Header.hpp Normal file
View File

@ -0,0 +1,129 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_HEADER_H_
#define LIEF_ART_HEADER_H_
#include "LIEF/ART/type_traits.hpp"
#include "LIEF/ART/Structures.hpp"
#include "LIEF/visibility.h"
#include "LIEF/Object.hpp"
namespace LIEF {
namespace ART {
class Parser;
class LIEF_API Header : public Object {
friend class Parser;
public:
using magic_t = std::array<uint8_t, 4>;
Header(void);
template<class T>
LIEF_LOCAL Header(const T* header);
Header(const Header&);
Header& operator=(const Header&);
magic_t magic(void) const;
art_version_t version(void) const;
uint32_t image_begin(void) const;
uint32_t image_size(void) const;
uint32_t oat_checksum(void) const;
uint32_t oat_file_begin(void) const;
uint32_t oat_file_end(void) const;
uint32_t oat_data_begin(void) const;
uint32_t oat_data_end(void) const;
int32_t patch_delta(void) const;
uint32_t image_roots(void) const;
uint32_t pointer_size(void) const;
bool compile_pic(void) const;
uint32_t nb_sections(void) const;
uint32_t nb_methods(void) const;
uint32_t boot_image_begin(void) const;
uint32_t boot_image_size(void) const;
uint32_t boot_oat_begin(void) const;
uint32_t boot_oat_size(void) const;
STORAGE_MODES storage_mode(void) const;
uint32_t data_size(void) const;
virtual void accept(Visitor& visitor) const override;
bool operator==(const Header& rhs) const;
bool operator!=(const Header& rhs) const;
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Header& hdr);
virtual ~Header(void);
private:
magic_t magic_;
art_version_t version_;
uint32_t image_begin_;
uint32_t image_size_;
uint32_t oat_checksum_;
uint32_t oat_file_begin_;
uint32_t oat_file_end_;
uint32_t oat_data_begin_;
uint32_t oat_data_end_;
int32_t patch_delta_;
uint32_t image_roots_;
uint32_t pointer_size_;
bool compile_pic_;
uint32_t nb_sections_;
uint32_t nb_methods_;
bool is_pic_;
// From ART 29
// ===========
uint32_t boot_image_begin_;
uint32_t boot_image_size_;
uint32_t boot_oat_begin_;
uint32_t boot_oat_size_;
STORAGE_MODES storage_mode_;
uint32_t data_size_;
};
} // Namespace ART
} // Namespace LIEF
#endif

113
include/LIEF/ART/Parser.hpp Normal file
View File

@ -0,0 +1,113 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_PARSER_H_
#define LIEF_ART_PARSER_H_
#include <memory>
#include "LIEF/visibility.h"
#include "LIEF/BinaryStream/VectorStream.hpp"
#include "LIEF/ART/File.hpp"
namespace LIEF {
namespace ART {
//! @brief Class which parse an ART file and transform into a ART::File object
class LIEF_API Parser {
public:
static File* parse(const std::string& file);
static File* parse(const std::vector<uint8_t>& data, const std::string& name = "");
Parser& operator=(const Parser& copy) = delete;
Parser(const Parser& copy) = delete;
private:
Parser(void);
Parser(const std::string& file);
Parser(const std::vector<uint8_t>& data, const std::string& name);
virtual ~Parser(void);
void init(const std::string& name, art_version_t version);
template<typename ART_T>
void parse_file(void);
template<typename ART_T>
size_t parse_header(void);
template<typename ART_T, typename PTR_T>
void parse_sections(void);
template<typename ART_T, typename PTR_T>
void parse_roots(void);
template<typename ART_T, typename PTR_T>
void parse_methods(void);
// Section parsing
template<typename ART_T, typename PTR_T>
void parse_objects(size_t offset, size_t size);
template<typename ART_T, typename PTR_T>
void parse_art_fields(size_t offset, size_t size);
template<typename ART_T, typename PTR_T>
void parse_art_methods(size_t offset, size_t size);
template<typename ART_T, typename PTR_T>
void parse_interned_strings(size_t offset, size_t size);
// Parse an **Array** of java.lang.DexCache objects
template<typename ART_T, typename PTR_T>
void parse_dex_caches(size_t offset, size_t size);
// Parse a **Single** java.lang.DexCache object
template<typename ART_T, typename PTR_T>
void parse_dex_cache(size_t object_offset);
// Parse an **Array** of java.lang.Class objects
template<typename ART_T, typename PTR_T>
void parse_class_roots(size_t offset, size_t size);
// Parse java.lang.Class objects
template<typename ART_T, typename PTR_T>
void parse_class(size_t offset);
// Parse java.lang.String objects
template<typename ART_T, typename PTR_T>
void parse_jstring(size_t offset);
//// Parse a **Single** java.lang.DexCache object
//template<typename ART_T, typename PTR_T>
//void parse_class_roots(size_t object_offset);
LIEF::ART::File* file_;
std::unique_ptr<VectorStream> stream_;
uint32_t imagebase_;
};
} // namespace ART
} // namespace LIEF
#endif

View File

@ -0,0 +1,529 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_STRUCTURES_H_
#define LIEF_ART_STRUCTURES_H_
#include <cstring>
#include <tuple>
#include "LIEF/types.hpp"
#include "LIEF/ART/enums.hpp"
#include "LIEF/ART/type_traits.hpp"
#include "LIEF/ART/java_structures.hpp"
// ======================
// Android 6.0.0: ART 17
// Android 6.0.1: ART 17
//
// Android 7.0.0: ART 29
//
// Android 7.1.0: ART 30
// Android 7.1.1: ART 30
// Android 7.1.2: ART 30
//
// Android 8.0.0: ART 44
// Android 8.1.0: ART 46
// ======================
namespace LIEF {
//! @brief Namespace related to the LIEF's ART module
namespace ART {
static constexpr uint8_t art_magic[] = { 'a', 'r', 't', '\n' };
static constexpr art_version_t art_version = 0;
struct ALIGNED_(4) image_section_t {
uint32_t offset;
uint32_t size;
};
// ==============================
// ART 17
// - Android 6.0.0
// - Android 6.0.1
// ==============================
namespace ART_17 {
static constexpr art_version_t art_version = 17;
static constexpr uint32_t nb_sections = 5;
static constexpr uint32_t nb_image_methods = 6;
static constexpr uint32_t nb_image_roots = 2;
struct ALIGNED_(4) header {
uint8_t magic[4];
uint8_t version[4];
// Required base address for mapping the image.
uint32_t image_begin;
// Image size, not page aligned.
uint32_t image_size;
// Checksum of the oat file we link to for load time sanity check.
uint32_t oat_checksum;
// Start address for oat file. Will be before oat_data_begin_ for .so files.
uint32_t oat_file_begin;
// Required oat address expected by image Method::GetCode() pointers.
uint32_t oat_data_begin;
// End of oat data address range for this image file.
uint32_t oat_data_end;
// End of oat file address range. will be after oat_data_end_ for
// .so files. Used for positioning a following alloc spaces.
uint32_t oat_file_end;
// The total delta that this image has been patched.
int32_t patch_delta;
// Absolute address of an Object[] of objects needed to reinitialize from an image.
uint32_t image_roots;
// Pointer size, this affects the size of the ArtMethods.
uint32_t pointer_size;
// Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
uint32_t compile_pic;
// Image sections
image_section_t sections[nb_sections];
// Image methods.
uint64_t image_methods[nb_image_methods];
};
} // Namespace ART_17
// ==============================
// ART 29
// - Android 7.0.0
// ==============================
namespace ART_29 {
static constexpr art_version_t art_version = 29;
static constexpr uint32_t nb_sections = 9;
static constexpr uint32_t nb_image_methods = 6;
static constexpr uint32_t nb_image_roots = 2;
struct ALIGNED_(4) header {
uint8_t magic[4];
uint8_t version[4];
// Required base address for mapping the image.
uint32_t image_begin;
// Image size, not page aligned.
uint32_t image_size;
// Checksum of the oat file we link to for load time sanity check.
uint32_t oat_checksum;
// Start address for oat file. Will be before oat_data_begin_ for .so files.
uint32_t oat_file_begin;
// Required oat address expected by image Method::GetCode() pointers.
uint32_t oat_data_begin;
// End of oat data address range for this image file.
uint32_t oat_data_end;
// End of oat file address range. will be after oat_data_end_ for
// .so files. Used for positioning a following alloc spaces.
uint32_t oat_file_end;
// Boot image begin and end (app image headers only).
uint32_t boot_image_begin;
uint32_t boot_image_size;
// Boot oat begin and end (app image headers only).
uint32_t boot_oat_begin;
uint32_t boot_oat_size;
// The total delta that this image has been patched.
int32_t patch_delta;
// Absolute address of an Object[] of objects needed to reinitialize from an image.
uint32_t image_roots;
// Pointer size, this affects the size of the ArtMethods.
uint32_t pointer_size;
// Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
uint32_t compile_pic;
// Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to
// the .art file. Currently, app oat files do not depend on their app image. There are no pointers
// from the app oat code to the app image.
uint32_t is_pic;
// Image sections
image_section_t sections[nb_sections];
// Image methods.
uint64_t image_methods[nb_image_methods];
// Storage method for the image, the image may be compressed.
uint32_t storage_mode;
// Data size for the image data excluding the bitmap and the header. For compressed images, this
// is the compressed size in the file.
uint32_t data_size;
};
} // Namespace ART_29
// ==============================
// ART 30
// - Android 7.1.0
// - Android 7.1.1
// - Android 7.1.2
// ==============================
namespace ART_30 {
static constexpr art_version_t art_version = 30;
static constexpr uint32_t nb_sections = 10;
static constexpr uint32_t nb_image_methods = 6;
static constexpr uint32_t nb_image_roots = 2;
struct ALIGNED_(4) header {
uint8_t magic[4];
uint8_t version[4];
// Required base address for mapping the image.
uint32_t image_begin;
// Image size, not page aligned.
uint32_t image_size;
// Checksum of the oat file we link to for load time sanity check.
uint32_t oat_checksum;
// Start address for oat file. Will be before oat_data_begin_ for .so files.
uint32_t oat_file_begin;
// Required oat address expected by image Method::GetCode() pointers.
uint32_t oat_data_begin;
// End of oat data address range for this image file.
uint32_t oat_data_end;
// End of oat file address range. will be after oat_data_end_ for
// .so files. Used for positioning a following alloc spaces.
uint32_t oat_file_end;
// Boot image begin and end (app image headers only).
uint32_t boot_image_begin;
uint32_t boot_image_size;
// Boot oat begin and end (app image headers only).
uint32_t boot_oat_begin;
uint32_t boot_oat_size;
// The total delta that this image has been patched.
int32_t patch_delta;
// Absolute address of an Object[] of objects needed to reinitialize from an image.
uint32_t image_roots;
// Pointer size, this affects the size of the ArtMethods.
uint32_t pointer_size;
// Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
uint32_t compile_pic;
// Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to
// the .art file. Currently, app oat files do not depend on their app image. There are no pointers
// from the app oat code to the app image.
uint32_t is_pic;
// Image sections
image_section_t sections[nb_sections];
// Image methods.
uint64_t image_methods[nb_image_methods];
// Storage method for the image, the image may be compressed.
uint32_t storage_mode;
// Data size for the image data excluding the bitmap and the header. For compressed images, this
// is the compressed size in the file.
uint32_t data_size;
};
} // Namespace ART_30
// ==============================
// ART 44
// - Android 8.0.0
// ==============================
namespace ART_44 {
static constexpr art_version_t art_version = 44;
static constexpr uint32_t nb_sections = 10;
static constexpr uint32_t nb_image_methods = 7;
static constexpr uint32_t nb_image_roots = 3;
struct ALIGNED_(4) header {
uint8_t magic[4];
uint8_t version[4];
// Required base address for mapping the image.
uint32_t image_begin;
// Image size, not page aligned.
uint32_t image_size;
// Checksum of the oat file we link to for load time sanity check.
uint32_t oat_checksum;
// Start address for oat file. Will be before oat_data_begin_ for .so files.
uint32_t oat_file_begin;
// Required oat address expected by image Method::GetCode() pointers.
uint32_t oat_data_begin;
// End of oat data address range for this image file.
uint32_t oat_data_end;
// End of oat file address range. will be after oat_data_end_ for
// .so files. Used for positioning a following alloc spaces.
uint32_t oat_file_end;
// Boot image begin and end (app image headers only).
uint32_t boot_image_begin;
uint32_t boot_image_size;
// Boot oat begin and end (app image headers only).
uint32_t boot_oat_begin;
uint32_t boot_oat_size;
// The total delta that this image has been patched.
int32_t patch_delta;
// Absolute address of an Object[] of objects needed to reinitialize from an image.
uint32_t image_roots;
// Pointer size, this affects the size of the ArtMethods.
uint32_t pointer_size;
// Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
uint32_t compile_pic;
// Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to
// the .art file. Currently, app oat files do not depend on their app image. There are no pointers
// from the app oat code to the app image.
uint32_t is_pic;
// Image sections
image_section_t sections[nb_sections];
// Image methods.
uint64_t image_methods[nb_image_methods];
// Storage method for the image, the image may be compressed.
uint32_t storage_mode;
// Data size for the image data excluding the bitmap and the header. For compressed images, this
// is the compressed size in the file.
uint32_t data_size;
};
} // Namespace ART_44
// ==============================
// ART 46
// - Android 8.1.0
// ==============================
namespace ART_46 {
static constexpr art_version_t art_version = 46;
static constexpr uint32_t nb_image_roots = 3;
// No changes in the structure
using header = ART_44::header;
} // Namespace ART_46
class ART17 {
public:
using art_header_t = ART_17::header;
static constexpr art_version_t art_version = ART_17::art_version;
static constexpr uint32_t nb_image_roots = ART_17::nb_image_roots;
using IMAGE_SECTIONS = ART_17::IMAGE_SECTIONS;
using IMAGE_METHODS = ART_17::IMAGE_METHODS;
using IMAGE_ROOTS = ART_17::IMAGE_ROOTS;
// =====================
// Java
// =====================
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_17::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_17::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_17::Java::jclass_t<T>;
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_17::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_17::Java::jdex_cache_t<T>;
};
class ART29 {
public:
using art_header_t = ART_29::header;
static constexpr art_version_t art_version = ART_29::art_version;
static constexpr uint32_t nb_image_roots = ART_29::nb_image_roots;
using IMAGE_SECTIONS = ART_29::IMAGE_SECTIONS;
using IMAGE_METHODS = ART_29::IMAGE_METHODS;
using IMAGE_ROOTS = ART_29::IMAGE_ROOTS;
// =====================
// Java
// =====================
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_17::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_29::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_29::Java::jclass_t<T>;
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_29::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_29::Java::jdex_cache_t<T>;
};
class ART30 {
public:
using art_header_t = ART_30::header;
static constexpr art_version_t art_version = ART_30::art_version;
static constexpr uint32_t nb_image_roots = ART_30::nb_image_roots;
using IMAGE_SECTIONS = ART_30::IMAGE_SECTIONS;
using IMAGE_METHODS = ART_30::IMAGE_METHODS;
using IMAGE_ROOTS = ART_30::IMAGE_ROOTS;
// =====================
// Java
// =====================
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_30::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_30::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_30::Java::jclass_t<T>;
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_30::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_30::Java::jdex_cache_t<T>;
};
class ART44 {
public:
using art_header_t = ART_44::header;
static constexpr art_version_t art_version = ART_44::art_version;
static constexpr uint32_t nb_image_roots = ART_44::nb_image_roots;
using IMAGE_SECTIONS = ART_44::IMAGE_SECTIONS;
using IMAGE_METHODS = ART_44::IMAGE_METHODS;
using IMAGE_ROOTS = ART_44::IMAGE_ROOTS;
// =====================
// Java
// =====================
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_44::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_44::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_44::Java::jclass_t<T>;
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_44::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_44::Java::jdex_cache_t<T>;
};
class ART46 {
public:
using art_header_t = ART_46::header;
static constexpr art_version_t art_version = ART_46::art_version;
static constexpr uint32_t nb_image_roots = ART_46::nb_image_roots;
using IMAGE_SECTIONS = ART_46::IMAGE_SECTIONS;
using IMAGE_METHODS = ART_46::IMAGE_METHODS;
using IMAGE_ROOTS = ART_46::IMAGE_ROOTS;
// =====================
// Java
// =====================
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_46::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_46::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_46::Java::jclass_t<T>;
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_46::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_46::Java::jdex_cache_t<T>;
};
@LIEF_ART_STRUCTURES@
} /* end namespace ART */
} /* end namespace LIEF */
#endif

View File

@ -0,0 +1,136 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_ENUMS_H_
#define LIEF_ART_ENUMS_H_
namespace LIEF {
namespace ART {
enum STORAGE_MODES {
STORAGE_UNCOMPRESSED = 0,
STORAGE_LZ4 = 1,
STORAGE_LZ4HC = 2,
};
namespace ART_17 {
enum IMAGE_METHODS {
RESOLUTION_METHOD = 0,
IMT_CONFLICT_METHOD = 1,
IMT_UNIMPLEMENTED_METHOD = 2,
CALLEE_SAVE_METHOD = 3,
REFS_ONLY_SAVE_METHOD = 4,
REFS_AND_ARGS_SAVE_METHOD = 5,
};
enum IMAGE_SECTIONS {
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_INTERNED_STRINGS = 3,
SECTION_IMAGE_BITMAP = 4,
};
enum IMAGE_ROOTS {
DEX_CACHES = 0,
CLASS_ROOTS = 1,
};
} // Namespace ART_17
namespace ART_29 {
using ART_17::IMAGE_METHODS;
using ART_17::IMAGE_ROOTS;
enum IMAGE_SECTIONS {
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_RUNTIME_METHODS = 3, // New in ART 29
SECTION_IMT_CONFLICT_TABLES = 4, // New in ART 29
SECTION_DEX_CACHE_ARRAYS = 5, // New in ART 29
SECTION_INTERNED_STRINGS = 6,
SECTION_CLASS_TABLE = 7, // New in ART 29
SECTION_IMAGE_BITMAP = 8,
};
} // Namespace ART_29
namespace ART_30 {
using ART_29::IMAGE_METHODS;
using ART_29::IMAGE_ROOTS;
enum IMAGE_SECTIONS {
SECTION_OBJECTS = 0,
SECTION_ART_FIELDS = 1,
SECTION_ART_METHODS = 2,
SECTION_RUNTIME_METHODS = 3,
SECTION_IM_TABLES = 4, // New in ART 30
SECTION_IMT_CONFLICT_TABLES = 5,
SECTION_DEX_CACHE_ARRAYS = 6,
SECTION_INTERNED_STRINGS = 7,
SECTION_CLASS_TABLE = 8,
SECTION_IMAGE_BITMAP = 9,
};
} // Namespace ART_30
namespace ART_44 {
using ART_30::IMAGE_SECTIONS;
enum IMAGE_METHODS {
RESOLUTION_METHOD = 0,
IMT_CONFLICT_METHOD = 1,
IMT_UNIMPLEMENTED_METHOD = 2,
SAVE_ALL_CALLEE_SAVES_METHOD = 3, // New in ART 44
SAVE_REFS_ONLY_METHOD = 4, // New in ART 44
SAVE_REFS_AND_ARGS_METHOD = 5, // New in ART 44
SAVE_EVERYTHING_METHOD = 6, // New in ART 44
};
enum IMAGE_ROOTS {
DEX_CACHES = 0,
CLASS_ROOTS = 1,
CLASS_LOADER = 2, // New in ART 44
};
} // Namespace ART_44
namespace ART_46 {
using ART_30::IMAGE_SECTIONS;
using ART_30::IMAGE_METHODS;
using ART_30::IMAGE_ROOTS;
} // Namespace ART_46
@LIEF_ART_ENUMS@
}
}
#endif

View File

@ -0,0 +1 @@

44
include/LIEF/ART/hash.hpp Normal file
View File

@ -0,0 +1,44 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_HASH_H_
#define LIEF_ART_HASH_H_
#include "LIEF/visibility.h"
#include "LIEF/hash.hpp"
#include "LIEF/ART.hpp"
namespace LIEF {
namespace ART {
class LIEF_API Hash : public LIEF::Hash {
public:
static size_t hash(const Object& obj);
public:
using LIEF::Hash::Hash;
using LIEF::Hash::visit;
public:
virtual void visit(const File& file) override;
virtual void visit(const Header& header) override;
virtual ~Hash(void);
};
}
}
#endif

View File

@ -0,0 +1,365 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ART_JAVA_STRUCTURES_H_
#define LIEF_ART_JAVA_STRUCTURES_H_
#include <cstring>
#include <tuple>
#include "LIEF/types.hpp"
#include "LIEF/ART/enums.hpp"
#include "LIEF/ART/type_traits.hpp"
namespace LIEF {
//! @brief Namespace related to the LIEF's ART module
namespace ART {
struct no_brooks_read_barrier_t {};
// ======================
// Android 6.0.1 - ART 17
// ======================
namespace ART_17 {
//! @brief Namespace related to the Java part of ART 17
namespace Java {
using heap_reference_t = uint32_t;
struct brooks_read_barrier_t {
uint32_t x_rb_ptr;
uint32_t x_xpadding;
};
template<class T>
struct jobject_t {
heap_reference_t klass;
uint32_t monitor;
T brooks_read_barrier;
};
template<>
struct jobject_t<no_brooks_read_barrier_t> {
heap_reference_t klass;
uint32_t monitor;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jarray_t {
jobject_t<T> object;
int32_t length;
uint32_t* elements;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jclass_t {
jobject_t<T> object;
heap_reference_t class_loader;
heap_reference_t component_type;
heap_reference_t dex_cache;
heap_reference_t dex_cache_strings;
heap_reference_t iftable;
heap_reference_t name;
heap_reference_t super_class;
heap_reference_t verify_error_class;
heap_reference_t vtable;
uint32_t access_flags;
uint64_t direct_methods;
uint64_t ifields;
uint64_t sfields;
uint64_t virtual_methods;
uint32_t class_size;
uint32_t clinit_thread_id;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
uint32_t num_direct_methods;
uint32_t num_instance_fields;
uint32_t num_reference_instance_fields;
uint32_t num_reference_static_fields;
uint32_t num_static_fields;
uint32_t num_virtual_methods;
uint32_t object_size;
uint32_t primitive_type;
uint32_t reference_instance_offsets;
int32_t status;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jstring_t {
jobject_t<T> object;
int32_t count;
uint32_t hash_code;
uint16_t* value;
};
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jdex_cache_t {
jobject_t<T> object;
heap_reference_t dex;
heap_reference_t location;
heap_reference_t resolved_fields;
heap_reference_t resolved_methods;
heap_reference_t resolved_types;
heap_reference_t strings;
uint64_t dex_file;
};
} // Namespace Java
} // Namespace ART_17
// ======================
// Android 7.0.0 - ART 29
// ======================
namespace ART_29 {
//! @brief Namespace related to the Java part of ART 29
namespace Java {
using heap_reference_t = ART_17::Java::heap_reference_t;
using brooks_read_barrier_t = ART_17::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_17::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_17::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jclass_t {
jobject_t<T> object;
heap_reference_t annotation_type; // ADDED in ART 29
heap_reference_t class_loader;
heap_reference_t component_type;
heap_reference_t dex_cache;
// heap_reference_t dex_cache_strings; // REMOVED in ART 29
heap_reference_t iftable;
heap_reference_t name;
heap_reference_t super_class;
heap_reference_t verify_error; // Type CHANGED from Class to Object
heap_reference_t vtable;
uint32_t access_flags;
uint64_t dex_cache_strings; // direct_methods REPLACED with dex_cache_string
uint64_t ifields;
uint64_t methods; // ADDED in ART 29
uint64_t sfields;
uint32_t class_flags; // virtual_methods REPLACED with class_flags
uint32_t class_size;
uint32_t clinit_thread_id;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
// uint32_t num_direct_methods; // REMOVED in ART 29
// uint32_t num_instance_fields; // REMOVED in ART 29
uint32_t num_reference_instance_fields;
uint32_t num_reference_static_fields;
// uint32_t num_static_fields; // REMOVED in ART 29
// uint32_t num_virtual_methods; // REMOVED in ART 29
uint32_t object_size;
uint32_t primitive_type;
uint32_t reference_instance_offsets;
int32_t status;
uint16_t copied_methods_offset; // ADDED in ART 29
uint16_t virtual_methods_offset; // ADDED in ART 29
};
// No changes in jstring structure
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_17::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jdex_cache_t {
jobject_t<T> object;
heap_reference_t dex;
heap_reference_t location;
uint64_t dex_file; // LOCATION CHANGED
uint64_t resolved_fields; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t resolved_methods; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t resolved_types; // TYPE CHANGED from heap_reference_t to uint64_t
uint64_t strings; // TYPE CHANGED from heap_reference_t to uint64_t
uint32_t num_resolved_fields; // ADDED in ART 29
uint32_t num_resolved_methods; // ADDED in ART 29
uint32_t num_resolved_types; // ADDED in ART 29
uint32_t num_strings; // ADDED in ART 29
};
} // Namespace Java
} // Namespace ART_29
// ======================
// Android 7.1.X - ART 30
// ======================
namespace ART_30 {
//! @brief Namespace related to the Java part of ART 30
namespace Java {
using heap_reference_t = ART_29::Java::heap_reference_t;
using brooks_read_barrier_t = ART_29::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_29::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_29::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_29::Java::jclass_t<T>;
// No changes in jstring structure
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_29::Java::jstring_t<T>;
// No changes in jdex_cache structure
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_29::Java::jdex_cache_t<T>;
} // Namespace Java
} // Namespace ART_30
// ======================
// Android 8.0.0 - ART 44
// ======================
namespace ART_44 {
//! @brief Namespace related to the Java part of ART 44
namespace Java {
using heap_reference_t = ART_30::Java::heap_reference_t;
using brooks_read_barrier_t = ART_30::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_30::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_30::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jclass_t {
jobject_t<T> object;
// heap_reference_t annotation_type; // REMOVED in ART 44
heap_reference_t class_loader;
heap_reference_t component_type;
heap_reference_t dex_cache;
heap_reference_t ext_data; // ADDED in ART 44
heap_reference_t iftable;
heap_reference_t name;
heap_reference_t super_class;
// heap_reference_t verify_error; // REMOVED in ART 44
heap_reference_t vtable;
// uint32_t access_flags; // REMOVED in ART 44
// uint64_t dex_cache_strings; // REMOVED in ART 44
uint64_t ifields;
uint64_t methods;
uint64_t sfields;
uint32_t access_flags; // ADDED in ART 44
uint32_t class_flags;
uint32_t class_size;
uint32_t clinit_thread_id;
int32_t dex_class_def_idx;
int32_t dex_type_idx;
uint32_t num_reference_instance_fields;
uint32_t num_reference_static_fields;
uint32_t object_size;
uint32_t object_size_alloc_fast_path; // ADDED in ART 44
uint32_t primitive_type;
uint32_t reference_instance_offsets;
int32_t status;
uint16_t copied_methods_offset;
uint16_t virtual_methods_offset;
};
// No changes in jstring structure but string can be
// encoded as as char16_t or char (compressed)
// count[0] (LSB) == 1 ----> compressed
// count[0] (LSB) == 0 ----> chat16_t
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_30::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
struct ALIGNED_(4) jdex_cache_t {
jobject_t<T> object;
// heap_reference_t dex; // REMOVED in ART 44
heap_reference_t location;
uint32_t num_resolved_call_sites; // ADDED in ART 44 (related to DEX38 format)
uint64_t dex_file;
uint64_t resolved_call_sites; // ADDED in ART 44 (related to DEX38 format)
uint64_t resolved_fields;
uint64_t resolved_method_types; // ADDED in ART 44
uint64_t resolved_methods;
uint64_t resolved_types;
uint64_t strings;
uint32_t num_resolved_fields;
uint32_t num_resolved_methods_types; // ADDED in ART 44
uint32_t num_resolved_methods;
uint32_t num_resolved_types;
uint32_t num_strings;
};
} // Namespace Java
} // Namespace ART_44
// ======================
// Android 8.1.X - ART 46
// ======================
namespace ART_46 {
//! @brief Namespace related to the Java part of ART 46
namespace Java {
using heap_reference_t = ART_44::Java::heap_reference_t;
using brooks_read_barrier_t = ART_44::Java::brooks_read_barrier_t;
template<class T = no_brooks_read_barrier_t>
using jobject_t = ART_44::Java::jobject_t<T>;
template<class T = no_brooks_read_barrier_t>
using jarray_t = ART_44::Java::jarray_t<T>;
template<class T = no_brooks_read_barrier_t>
using jclass_t = ART_44::Java::jclass_t<T>;
template<class T = no_brooks_read_barrier_t>
using jstring_t = ART_44::Java::jstring_t<T>;
template<class T = no_brooks_read_barrier_t>
using jdex_cache_t = ART_44::Java::jdex_cache_t<T>;
} // Namespace Java
} // Namespace ART_46
} // Namespace ART
} // Namespace LIEF
#endif

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