mirror of
https://github.com/QuasarApp/macdependency.git
synced 2025-04-27 12:54:31 +00:00
- Applied all recommended XCode (8) settings. - Removed boost and replaced that code by standard functions. - Implemented name mangling via abi::__cxa_demangle instead of running an external process to use c++filt. - Enabled C++11. Min deployment target is now OSX 10.7. - Some code clean up (e.g. formatting, std namespace).
103 lines
3.1 KiB
C++
103 lines
3.1 KiB
C++
#include "machofile.h"
|
|
#include "machoexception.h"
|
|
#include "internalfile.h"
|
|
|
|
MachOFile::MachOFile(const std::string& filename,const MachOFile* parent, bool reversedByteOrder) :
|
|
file(InternalFile::create(filename)), position(0), reversedByteOrder(reversedByteOrder), parent(parent)
|
|
{
|
|
if (parent) {
|
|
executablePath = parent->executablePath;
|
|
} else {
|
|
executablePath = getPath();
|
|
}
|
|
}
|
|
|
|
MachOFile::MachOFile(const MachOFile& file, bool reversedByteOrder) :
|
|
file(InternalFile::create(file.file)), position(file.position), reversedByteOrder(reversedByteOrder), parent(file.parent), executablePath(file.executablePath)
|
|
{
|
|
}
|
|
|
|
MachOFile::~MachOFile() {
|
|
file->release();
|
|
}
|
|
|
|
std::string MachOFile::getPath() const {
|
|
return file->getPath();
|
|
}
|
|
|
|
std::string MachOFile::getName() const {
|
|
std::string filename = file->getName();
|
|
return filename;
|
|
}
|
|
std::string MachOFile::getTitle() const { return file->getTitle(); }
|
|
unsigned long long MachOFile::getSize() const { return file->getSize(); }
|
|
time_t MachOFile::getLastModificationTime() const { return file->getLastModificationTime(); }
|
|
|
|
uint32_t MachOFile::readUint32() {
|
|
unsigned int temp;
|
|
readBytes((char*)&temp, sizeof(temp));
|
|
return getUint32(temp);
|
|
}
|
|
|
|
uint32_t MachOFile::readUint32LE() {
|
|
unsigned int temp;
|
|
readBytes((char*)&temp, sizeof(temp));
|
|
return getUint32LE(temp);
|
|
}
|
|
|
|
uint32_t MachOFile::readUint32BE() {
|
|
unsigned int temp;
|
|
readBytes((char*)&temp, sizeof(temp));
|
|
return getUint32BE(temp);
|
|
}
|
|
|
|
uint32_t MachOFile::getUint32BE(uint32_t data) {
|
|
return convertByteOrder((char*)&data, true, sizeof(data));
|
|
}
|
|
|
|
uint32_t MachOFile::getUint32LE(uint32_t data) {
|
|
return convertByteOrder((char*)&data, false, sizeof(data));
|
|
}
|
|
|
|
void MachOFile::readBytes(char* result, size_t size) {
|
|
if (file->getPosition() != position) {
|
|
file->seek(position);
|
|
}
|
|
if (file->read(result, size) != size)
|
|
throw MachOException("File '" + file->getName() + "' not big enough. Probably no valid Mach-O!");
|
|
position += size;
|
|
}
|
|
|
|
// convert from big endian or little endian to native format (Intel=little endian) and return as unsigned int (32bit)
|
|
unsigned int MachOFile::convertByteOrder(char* data, bool isBigEndian, unsigned int numberOfBytes) {
|
|
|
|
assert(numberOfBytes> 0);
|
|
assert(numberOfBytes <= 4); // max 4 byte
|
|
|
|
unsigned int result = 0;
|
|
|
|
// big endian extract (most significant byte first) (will work on little and big-endian computers)
|
|
unsigned int numberOfShifts = isBigEndian ? numberOfBytes - 1 : 0;
|
|
|
|
for (unsigned int n = 0; n < numberOfBytes; n++) {
|
|
result |= static_cast<unsigned char>(data[n]) << (8 * numberOfShifts); // the bit shift will do the correct byte order for you
|
|
numberOfShifts += isBigEndian ? -1 : +1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
uint32_t MachOFile::reverseByteOrder(uint32_t data) {
|
|
char* sourceData = (char*)&data;
|
|
uint32_t result;
|
|
char* destData = (char*)&result;
|
|
|
|
destData[3] = sourceData[0];
|
|
destData[2] = sourceData[1];
|
|
destData[1] = sourceData[2];
|
|
destData[0] = sourceData[3];
|
|
|
|
return result;
|
|
}
|
|
|
|
|