Skip to content

Commit

Permalink
Add support for GNU_PROPERTY_AARCH64_FEATURE_PAUTH
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Oct 26, 2024
1 parent 086c49f commit 27be4e6
Show file tree
Hide file tree
Showing 19 changed files with 250 additions and 14 deletions.
8 changes: 8 additions & 0 deletions api/python/lief/ELF.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ class AArch64Feature(NoteGnuProperty.Property):
@property
def features(self) -> list[lief.ELF.AArch64Feature.FEATURE]: ...

class AArch64PAuth(NoteGnuProperty.Property):
def __init__(self, *args, **kwargs) -> None: ...
@property
def platform(self) -> int: ...
@property
def version(self) -> int: ...

class ARCH:
AARCH64: ClassVar[ARCH] = ...
ALPHA: ClassVar[ARCH] = ...
Expand Down Expand Up @@ -1455,6 +1462,7 @@ class NoteGnuProperty(Note):
class Property:
class TYPE:
AARCH64_FEATURES: ClassVar[NoteGnuProperty.Property.TYPE] = ...
AARCH64_PAUTH: ClassVar[NoteGnuProperty.Property.TYPE] = ...
GENERIC: ClassVar[NoteGnuProperty.Property.TYPE] = ...
NEEDED: ClassVar[NoteGnuProperty.Property.TYPE] = ...
NO_COPY_ON_PROTECTED: ClassVar[NoteGnuProperty.Property.TYPE] = ...
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target_sources(pyLIEF PRIVATE
pyAArch64Feature.cpp
pyAArch64PAuth.cpp
pyGeneric.cpp
pyNoteNoCopyOnProtected.cpp
pyX86Features.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void create<AArch64Feature>(nb::module_& m) {
nb::class_<AArch64Feature, NoteGnuProperty::Property>
Class(m, "AArch64Feature",
R"doc(
This class represents the `GNU_PROPERTY_AARCH64_FEATURE_1_AND` note.
This class represents the ``GNU_PROPERTY_AARCH64_FEATURE_1_AND`` note.
)doc"_doc);

Class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Copyright 2017 - 2024 R. Thomas
* Copyright 2017 - 2024 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 <string>
#include <sstream>

#include "ELF/pyELF.hpp"

#include "LIEF/ELF/NoteDetails/properties/AArch64PAuth.hpp"

namespace LIEF::ELF::py {

template<>
void create<AArch64PAuth>(nb::module_& m) {
nb::class_<AArch64PAuth, NoteGnuProperty::Property>
Class(m, "AArch64PAuth",
R"doc(
This class represents the ``GNU_PROPERTY_AARCH64_FEATURE_PAUTH`` note.
.. note::
If both: :attr:`.AArch64PAuth.platform` and :attr:`.AArch64PAuth.version` are set to
0, this means that the binary is incompatible with PAuth ABI extension.
)doc"_doc);

Class
.def_prop_ro("platform", &AArch64PAuth::platform,
R"doc(
64-bit value that specifies the platform vendor.
A ``0`` value is associated with an *invalid* platform while the value ``1``
is associated with a baremetal platform.
)doc"_doc)

.def_prop_ro("version", &AArch64PAuth::version,
R"doc(
64-bit value that identifies the signing schema used by the ELF file.
)doc"_doc)
;

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void create<NoteNoCopyOnProtected>(nb::module_& m) {
nb::class_<NoteNoCopyOnProtected, NoteGnuProperty::Property> Class(
m, "NoteNoCopyOnProtected",
R"doc(
This class provides an interface over the `GNU_PROPERTY_NO_COPY_ON_PROTECTED`
This class provides an interface over the ``GNU_PROPERTY_NO_COPY_ON_PROTECTED``
property. This property indicates that the linker shouldn't copy relocations
against protected symbols.
)doc"_doc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ template<>
void create<StackSize>(nb::module_& m) {
nb::class_<StackSize, NoteGnuProperty::Property>(m, "StackSize",
R"doc(
This class provides an interface over the `GNU_PROPERTY_STACK_SIZE` property
This class provides an interface over the ``GNU_PROPERTY_STACK_SIZE`` property
This property can be used by the loader to raise the stack limit.
)doc")
.def_prop_ro("stack_size", &StackSize::stack_size);
Expand Down
3 changes: 3 additions & 0 deletions api/python/src/ELF/objects/NoteDetails/pyNoteGnuProperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "LIEF/ELF/NoteDetails/NoteGnuProperty.hpp"
#include "LIEF/ELF/NoteDetails/properties/AArch64Feature.hpp"
#include "LIEF/ELF/NoteDetails/properties/AArch64PAuth.hpp"
#include "LIEF/ELF/NoteDetails/properties/X86Feature.hpp"
#include "LIEF/ELF/NoteDetails/properties/X86ISA.hpp"
#include "LIEF/ELF/NoteDetails/properties/StackSize.hpp"
Expand Down Expand Up @@ -56,6 +57,7 @@ void create<NoteGnuProperty>(nb::module_& m) {
ENTRY(UNKNOWN)
ENTRY(GENERIC)
ENTRY(AARCH64_FEATURES)
ENTRY(AARCH64_PAUTH)
ENTRY(STACK_SIZE)
ENTRY(NO_COPY_ON_PROTECTED)
ENTRY(X86_ISA)
Expand All @@ -65,6 +67,7 @@ void create<NoteGnuProperty>(nb::module_& m) {
# undef ENTRY

create<AArch64Feature>(m);
create<AArch64PAuth>(m);
create<X86Features>(m);
create<X86ISA>(m);
create<StackSize>(m);
Expand Down
5 changes: 5 additions & 0 deletions doc/sphinx/_cross_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@
:py:meth:`lief.ELF.Binary.write`
:cpp:func:`LIEF::ELF::Binary::write`

.. |lief-elf-aarch64pauth| lief-api:: lief.ELF.AArch64PAuth

:py:class:`lief.ELF.AArch64PAuth`
:cpp:class:`LIEF::ELF::AArch64PAuth`

.. Mach-O ======================================================================
.. |lief-macho-binary| lief-api:: lief.MachO.Binary
Expand Down
20 changes: 10 additions & 10 deletions doc/sphinx/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
0.16.0 - Not Released Yet
-------------------------

:Abstract:
:Abstraction:

* Add |get_int_from_virtual_address| to read an **integer** value
at a specific virtual address
Expand Down Expand Up @@ -35,6 +35,13 @@
elf: &lief::elf::Binary
let value: i16 = elf.get_int_from_virtual_address::<i16>(0x401126).unwrap();
* Global code cleaning (especially, |lief-header-architectures| and
|lief-header-modes| is now more meaningful)
* Re-scope ``lief.ARCHITECTURES`` into |lief-header-architectures|
* Re-scope ``lief.MODES`` into |lief-header-modes|
* Re-scope ``lief.OBJECT_TYPES`` into |lief-header-object-types|
* Re-scope ``lief.ENDIANNESS`` into |lief-header-endianness|


:MachO:

Expand Down Expand Up @@ -67,6 +74,8 @@

:ELF:

* Add support for ``GNU_PROPERTY_AARCH64_FEATURE_PAUTH`` GNU property note:
|lief-elf-aarch64pauth|.
* Add |lief-elf-binary-target-android| to check if an ELF targets Android
* Fix a critical error when rewriting ELF file with ``DT_RELR`` relocations.
This error leads to a crash of the modified binary.
Expand Down Expand Up @@ -156,15 +165,6 @@
* Upgrade MbedTLS from ``3.2.1`` to ``3.6.1``
:Abstraction:
* Global code cleaning (especially, |lief-header-architectures| and
|lief-header-modes| is now more meaningful)
* Re-scope ``lief.ARCHITECTURES`` into |lief-header-architectures|
* Re-scope ``lief.MODES`` into |lief-header-modes|
* Re-scope ``lief.OBJECT_TYPES`` into |lief-header-object-types|
* Re-scope ``lief.ENDIANNESS`` into |lief-header-endianness|
:doc:
* Global restructuring of the documentation
Expand Down
8 changes: 8 additions & 0 deletions doc/sphinx/formats/elf/cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ AArch64 Feature

.. doxygenclass:: LIEF::ELF::AArch64Feature

----------

AArch64 PAuth
***************

.. doxygenclass:: LIEF::ELF::AArch64PAuth


----------

No Copy on Protected
Expand Down
13 changes: 13 additions & 0 deletions doc/sphinx/formats/elf/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,19 @@ AArch64 Feature

----------

AArch64 PAuth
***************

.. lief-inheritance:: lief._lief.ELF.AArch64PAuth
:top-classes: lief._lief.ELF.NoteGnuProperty.Property
:parts: 2

.. autoclass:: lief.ELF.AArch64PAuth

----------



No Copy on Protected
********************

Expand Down
1 change: 1 addition & 0 deletions include/LIEF/ELF/NoteDetails/NoteGnuProperty.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class LIEF_API NoteGnuProperty : public Note {
UNKNOWN = 0,
GENERIC, ///< Property that dont' have special implementation
AARCH64_FEATURES, ///< Mirror of `GNU_PROPERTY_AARCH64_FEATURE_1_AND`
AARCH64_PAUTH, ///< Mirror of `GNU_PROPERTY_AARCH64_FEATURE_PAUTH`
STACK_SIZE, ///< Mirror of `GNU_PROPERTY_STACK_SIZE`
NO_COPY_ON_PROTECTED, ///< Mirror of `GNU_PROPERTY_NO_COPY_ON_PROTECTED`
X86_ISA, ///< Mirror of `GNU_PROPERTY_X86_ISA_1_*` and `GNU_PROPERTY_X86_COMPAT_*`
Expand Down
1 change: 1 addition & 0 deletions include/LIEF/ELF/NoteDetails/Properties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define LIEF_ELF_NOTE_DETAILS_PROPERTIES_H

#include "LIEF/ELF/NoteDetails/properties/AArch64Feature.hpp"
#include "LIEF/ELF/NoteDetails/properties/AArch64PAuth.hpp"
#include "LIEF/ELF/NoteDetails/properties/Needed.hpp"
#include "LIEF/ELF/NoteDetails/properties/NoteNoCopyOnProtected.hpp"
#include "LIEF/ELF/NoteDetails/properties/X86ISA.hpp"
Expand Down
76 changes: 76 additions & 0 deletions include/LIEF/ELF/NoteDetails/properties/AArch64PAuth.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* Copyright 2017 - 2024 R. Thomas
* Copyright 2017 - 2024 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_ELF_NOTE_DETAILS_PROPERTIES_AARCH64_PAUTH_H
#define LIEF_ELF_NOTE_DETAILS_PROPERTIES_AARCH64_PAUTH_H

#include "LIEF/visibility.h"
#include "LIEF/ELF/NoteDetails/NoteGnuProperty.hpp"

namespace LIEF {
class BinaryStream;

namespace ELF {


/// This class represents the `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` property.
///
/// \note If both: AArch64PAuth::platform and AArch64PAuth::version are set to
/// 0, this means that the binary is incompatible with PAuth ABI extension.
class LIEF_API AArch64PAuth : public NoteGnuProperty::Property {
public:
/// 64-bit value that specifies the platform vendor.
///
/// A `0` value is associated with an *invalid* platform while the value `1`
/// is associated with a baremetal platform.
uint64_t platform() const {
return platform_;
}

/// 64-bit value that identifies the signing schema used by the ELF file.
uint64_t version() const {
return version_;
}

static bool classof(const NoteGnuProperty::Property* prop) {
return prop->type() == NoteGnuProperty::Property::TYPE::AARCH64_PAUTH;
}

static std::unique_ptr<AArch64PAuth> create(BinaryStream& stream);

void dump(std::ostream &os) const override;

~AArch64PAuth() override = default;

protected:
AArch64PAuth() :
NoteGnuProperty::Property(NoteGnuProperty::Property::TYPE::AARCH64_PAUTH)
{}

AArch64PAuth(uint64_t platform, uint64_t version) :
NoteGnuProperty::Property(NoteGnuProperty::Property::TYPE::AARCH64_PAUTH),
platform_(platform),
version_(version)
{}

uint64_t platform_ = 0;
uint64_t version_ = 0;
};

}
}


#endif
7 changes: 6 additions & 1 deletion src/ELF/NoteDetails/NoteGnuProperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "LIEF/ELF/NoteDetails/NoteGnuProperty.hpp"
#include "LIEF/ELF/NoteDetails/properties/Generic.hpp"
#include "LIEF/ELF/NoteDetails/properties/AArch64Feature.hpp"
#include "LIEF/ELF/NoteDetails/properties/AArch64PAuth.hpp"
#include "LIEF/ELF/NoteDetails/properties/StackSize.hpp"
#include "LIEF/ELF/NoteDetails/properties/X86Feature.hpp"
#include "LIEF/ELF/NoteDetails/properties/X86ISA.hpp"
Expand Down Expand Up @@ -84,6 +85,10 @@ parse_property(ARCH arch, SpanStream& stream) {
if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
return AArch64Feature::create(content);
}

if (type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
return AArch64PAuth::create(content);
}
return Generic::create(type);
}
}
Expand Down Expand Up @@ -177,13 +182,13 @@ void NoteGnuProperty::accept(Visitor& visitor) const {
visitor.visit(*this);
}


const char* to_string(NoteGnuProperty::Property::TYPE type) {
#define ENTRY(X) std::pair(NoteGnuProperty::Property::TYPE::X, #X)
STRING_MAP enums2str {
ENTRY(UNKNOWN),
ENTRY(GENERIC),
ENTRY(AARCH64_FEATURES),
ENTRY(AARCH64_PAUTH),
ENTRY(STACK_SIZE),
ENTRY(NO_COPY_ON_PROTECTED),
ENTRY(X86_ISA),
Expand Down
39 changes: 39 additions & 0 deletions src/ELF/NoteDetails/properties/AArch64PAuth.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright 2017 - 2024 R. Thomas
* Copyright 2017 - 2024 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/ELF/NoteDetails/properties/AArch64PAuth.hpp"
#include "LIEF/BinaryStream/BinaryStream.hpp"

#include "frozen.hpp"
#include "fmt_formatter.hpp"

namespace LIEF {
namespace ELF {

std::unique_ptr<AArch64PAuth> AArch64PAuth::create(BinaryStream& stream) {
uint64_t platform = stream.read<uint64_t>().value_or(0);
uint64_t version = stream.read<uint64_t>().value_or(0);

return std::unique_ptr<AArch64PAuth>(new AArch64PAuth(platform, version));
}

void AArch64PAuth::dump(std::ostream &os) const {
os << fmt::format("Platform: 0x{:04x}, Version: 0x{:04x}",
platform(), version());
}


}
}
Loading

0 comments on commit 27be4e6

Please sign in to comment.