Skip to content

Commit

Permalink
feat: Symbols may now be printed
Browse files Browse the repository at this point in the history
  • Loading branch information
macmade committed Mar 7, 2024
1 parent b1a4aa5 commit f0682ff
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Mach-O file parser.
-h / --help Shows this help dialog.
-i / --info Prints the detailed Mach-O structure.
-l / --libs Prints the list of linked libraries.
-f / --symbols Prints the list of symbols.
-s / --str Prints the list of strings from __cstring,
__oslogstring and __ustring.
-c / --objc-class Prints the list of Objective-C classes from
Expand Down
1 change: 1 addition & 0 deletions lib-macho/include/MachO.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <MachO/Section.hpp>
#include <MachO/Section64.hpp>
#include <MachO/SectionFlags.hpp>
#include <MachO/Symbol.hpp>
#include <MachO/Tool.hpp>
#include <MachO/ToString.hpp>

Expand Down
3 changes: 3 additions & 0 deletions lib-macho/include/MachO/File.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

namespace MachO
{
class Symbol;

class File: public XS::Info::Object
{
public:
Expand Down Expand Up @@ -78,6 +80,7 @@ namespace MachO

std::vector< std::reference_wrapper< LoadCommand > > loadCommands() const;
std::vector< std::string > linkedLibraries() const;
std::vector< Symbol > symbols() const;
std::vector< std::string > strings() const;
std::vector< std::string > objcClasses() const;
std::vector< std::string > objcMethods() const;
Expand Down
10 changes: 7 additions & 3 deletions lib-macho/include/MachO/LoadCommands/SymTab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include <MachO/LoadCommand.hpp>
#include <MachO/File.hpp>
#include <MachO/Symbol.hpp>
#include <XS.hpp>

namespace MachO
Expand All @@ -41,8 +42,8 @@ namespace MachO
class SymTab: public LoadCommand
{
public:
SymTab( uint32_t command, uint32_t size, File::Kind kind, XS::IO::BinaryStream & stream );

SymTab( uint32_t command, uint32_t size, File::Kind kind, XS::IO::BinaryStream & stream );
SymTab( const SymTab & o );
SymTab( SymTab && o ) noexcept;
~SymTab() override;
Expand All @@ -57,7 +58,10 @@ namespace MachO
uint32_t symbolCount() const;
uint32_t stringOffset() const;
uint32_t stringSize() const;


std::vector< std::string > strings() const;
std::vector< Symbol > symbols() const;

friend void swap( SymTab & o1, SymTab & o2 );

private:
Expand Down
72 changes: 72 additions & 0 deletions lib-macho/include/MachO/Symbol.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2020 Jean-David Gadina - www.xs-labs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/

/*!
* @header Symbol.hpp
* @copyright (c) 2020, Jean-David Gadina - www.xs-labs.com
*/

#ifndef MACHO_SYMBOL_HPP
#define MACHO_SYMBOL_HPP

#include <memory>
#include <algorithm>
#include <string>
#include <cstdint>
#include <XS.hpp>
#include <MachO/File.hpp>

namespace MachO
{
class Symbol: public XS::Info::Object
{
public:

Symbol( File::Kind kind, uint32_t stringTableOffset, XS::IO::BinaryStream & stream );
Symbol( const Symbol & o );
Symbol( Symbol && o ) noexcept;
virtual ~Symbol() override;

Symbol & operator =( Symbol o );

XS::Info getInfo() const override;

std::string name() const;
uint32_t nameIndex() const;
uint8_t type() const;
uint8_t section() const;
uint16_t description() const;
uint64_t value() const;

friend void swap( Symbol & o1, Symbol & o2 );

private:

class IMPL;

std::unique_ptr< IMPL > impl;
};
}

#endif /* MACHO_SYMBOL_HPP */
15 changes: 15 additions & 0 deletions lib-macho/source/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,21 @@ namespace MachO
return libs;
}

std::vector< Symbol > File::symbols() const
{
std::vector< Symbol > syms;

for( const auto & symTab: this->loadCommands< LoadCommands::SymTab >() )
{
for( const auto & sym: symTab.symbols() )
{
syms.push_back( sym );
}
}

return syms;
}

std::vector< std::string > File::strings() const
{
std::vector< std::vector< uint8_t > > cstrings;
Expand Down
33 changes: 30 additions & 3 deletions lib-macho/source/LoadCommands/SymTab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ namespace MachO
uint32_t _symbolCount;
uint32_t _stringOffset;
uint32_t _stringSize;

std::vector< std::string > _strings;
std::vector< Symbol > _symbols;
};

SymTab::SymTab( uint32_t command, uint32_t size, File::Kind kind, XS::IO::BinaryStream & stream ):
Expand Down Expand Up @@ -114,7 +117,17 @@ namespace MachO
{
return this->impl->_stringSize;
}


std::vector< std::string > SymTab::strings() const
{
return this->impl->_strings;
}

std::vector< Symbol > SymTab::symbols() const
{
return this->impl->_symbols;
}

void swap( SymTab & o1, SymTab & o2 )
{
using std::swap;
Expand All @@ -130,7 +143,19 @@ namespace MachO
_stringOffset( stream.readUInt32() ),
_stringSize( stream.readUInt32() )
{
( void )kind;
stream.seek( this->_stringOffset, XS::IO::BinaryStream::SeekDirection::Begin );

while( stream.tell() < this->_stringOffset + this->_stringSize )
{
this->_strings.push_back( stream.readNULLTerminatedString() );
}

stream.seek( this->_symbolOffset, XS::IO::BinaryStream::SeekDirection::Begin );

for( uint32_t i = 0; i < this->_symbolCount; i++ )
{
this->_symbols.push_back( { kind, this->_stringOffset, stream } );
}
}

SymTab::IMPL::IMPL( const IMPL & o ):
Expand All @@ -139,7 +164,9 @@ namespace MachO
_symbolOffset( o._symbolOffset ),
_symbolCount( o._symbolCount ),
_stringOffset( o._stringOffset ),
_stringSize( o._stringSize )
_stringSize( o._stringSize ),
_strings( o._strings ),
_symbols( o._symbols )
{}

SymTab::IMPL::~IMPL()
Expand Down
155 changes: 155 additions & 0 deletions lib-macho/source/Symbol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2020 Jean-David Gadina - www.xs-labs.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/

/*!
* @file Symbol.cpp
* @copyright (c) 2020, Jean-David Gadina - www.xs-labs.com
*/

#include <MachO/LoadCommands/SymTab.hpp>
#include <MachO/ToString.hpp>
#include <XS.hpp>

namespace MachO
{
class Symbol::IMPL
{
public:

IMPL( File::Kind kind, uint32_t stringTableOffset, XS::IO::BinaryStream & stream );
IMPL( const IMPL & o );
~IMPL();

std::string _name;
uint32_t _nameIndex;
uint8_t _type;
uint8_t _section;
uint16_t _description;
uint64_t _value;
};

Symbol::Symbol( File::Kind kind, uint32_t stringTableOffset, XS::IO::BinaryStream & stream ):
impl( std::make_unique< IMPL >( kind, stringTableOffset, stream ) )
{}

Symbol::Symbol( const Symbol & o ):
impl( std::make_unique< IMPL >( *( o.impl ) ) )
{}

Symbol::Symbol( Symbol && o ) noexcept:
impl( std::move( o.impl ) )
{}

Symbol::~Symbol()
{}

Symbol & Symbol::operator =( Symbol o )
{
swap( *( this ), o );

return *( this );
}

XS::Info Symbol::getInfo() const
{
XS::Info i( "Symbol" );

i.addChild( { "Name", this->name() } );
i.addChild( { "Name Index", XS::ToString::Hex( this->nameIndex() ) } );
i.addChild( { "Type", XS::ToString::Hex( this->type() ) } );
i.addChild( { "Section", XS::ToString::Hex( this->section() ) } );
i.addChild( { "Description", XS::ToString::Hex( this->description() ) } );
i.addChild( { "Value", XS::ToString::Hex( this->value() ) } );

return i;
}

std::string Symbol::name() const
{
return this->impl->_name;
}

uint32_t Symbol::nameIndex() const
{
return this->impl->_nameIndex;
}

uint8_t Symbol::type() const
{
return this->impl->_type;
}

uint8_t Symbol::section() const
{
return this->impl->_section;
}

uint16_t Symbol::description() const
{
return this->impl->_description;
}

uint64_t Symbol::value() const
{
return this->impl->_value;
}

void swap( Symbol & o1, Symbol & o2 )
{
using std::swap;

swap( o1.impl, o2.impl );
}

Symbol::IMPL::IMPL( File::Kind kind, uint32_t stringTableOffset, XS::IO::BinaryStream & stream ):
_nameIndex( stream.readUInt32() ),
_type( stream.readUInt8() ),
_section( stream.readUInt8() ),
_description( stream.readUInt16() ),
_value( kind == File::Kind::MachO32 ? stream.readUInt32() : stream.readUInt64() )
{
if( this->_nameIndex != 0 )
{
size_t offset = stream.tell();

stream.seek( stringTableOffset + this->_nameIndex, XS::IO::BinaryStream::SeekDirection::Begin );

this->_name = stream.readNULLTerminatedString();

stream.seek( offset, XS::IO::BinaryStream::SeekDirection::Begin );
}
}

Symbol::IMPL::IMPL( const IMPL & o ):
_name( o._name ),
_nameIndex( o._nameIndex ),
_type( o._type ),
_section( o._section ),
_description( o._description ),
_value( o._value )
{}

Symbol::IMPL::~IMPL()
{}
}
Loading

0 comments on commit f0682ff

Please sign in to comment.