Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if certificateTable overlaps a section and export the information #986

Merged
merged 5 commits into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class CertificateTable
{
public:
std::vector<DigitalSignature> signatures;
// if the certificates overlap any section then they are not visible for windows
bool isOutsideImage = false;

CertificateTable(std::vector<DigitalSignature> signatures);
CertificateTable() = default;
Expand Down
6 changes: 6 additions & 0 deletions include/retdec/pelib/SecurityDirectory.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@
#ifndef RETDEC_PELIB_SECURITYDIRECTORY_H
#define RETDEC_PELIB_SECURITYDIRECTORY_H

#include <cstdint>

namespace PeLib
{
class SecurityDirectory
{
private:
LoaderError m_ldrError;
std::vector<PELIB_IMAGE_CERTIFICATE_ENTRY> m_certs;
std::uint64_t offset = 0;
std::uint64_t size = 0;
public:
/// Constructor
SecurityDirectory();
std::uint64_t getOffset() const;
std::uint64_t getSize() const;
/// Number of certificates in the directory.
unsigned int calcNumberOfCertificates() const; // EXPORT
/// Returns certificate at specified index.
Expand Down
35 changes: 31 additions & 4 deletions src/fileformat/file_format/pe/pe_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1798,16 +1798,43 @@ void PeFormat::loadResources()
*/
void PeFormat::loadCertificates()
{
const auto& securityDir = file->securityDir();
if (securityDir.calcNumberOfCertificates() == 0) {
const SecurityDirectory& securityDir = file->securityDir();
if (securityDir.calcNumberOfCertificates() == 0)
{
return;
}

// We always take the first one, there might be more WIN_CERT structures tho
auto certBytes = securityDir.getCertificate(0);
const std::vector<unsigned char>& certBytes = securityDir.getCertificate(0);

authenticode::Authenticode authenticode(certBytes);

certificateTable = new CertificateTable(authenticode.getSignatures(this));
this->certificateTable = new CertificateTable(authenticode.getSignatures(this));

std::uint64_t dirOffset = securityDir.getOffset();
std::uint64_t dirSize = securityDir.getSize();

std::vector<Section*> sections = getSections();

certificateTable->isOutsideImage = true;
// check if the SecurityDir overlaps with any real part of section
// if it does, Windows ignores the certificates
for (const Section* sec : sections)
{
std::uint64_t realSize = sec->getSizeInFile();
std::uint64_t realOffset = sec->getOffset();
if (!realSize)
{
continue;
}
std::uint64_t realEndOffset = realOffset + realSize;
std::uint64_t dirEndOffset = dirOffset + dirOffset;
// if the intervals overlap
if (dirOffset < realEndOffset && realOffset < dirEndOffset)
{
certificateTable->isOutsideImage = false;
}
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/fileinfo/file_presentation/json_presentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,12 @@ void WriteSignature(JsonPresentation::Writer& writer, const DigitalSignature& si
void JsonPresentation::presentCertificates(Writer& writer) const
{

if(!fileinfo.certificateTable)
if (!fileinfo.certificateTable || !fileinfo.certificateTable->isOutsideImage)
{
return;
}

writer.String("digitalSignatures");

writer.StartObject();
writer.Key("numberOfSignatures");
writer.Int64(fileinfo.certificateTable->signatures.size());
Expand Down
7 changes: 5 additions & 2 deletions src/fileinfo/file_presentation/plain_presentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,16 +770,19 @@ static void printSignature(const DigitalSignature& signature, int indent)
void PlainPresentation::presentSignatures() const
{
const CertificateTable* table = fileinfo.certificateTable;
if (!table) {
if (!table || !table->isOutsideImage)
{
return;
}
Log::info() << "\n";
Log::info() << "Digital Signatures\n";
Log::info() << "------------------\n\n";
int indent = 4;

Log::info() << std::string(indent, ' ') << "Signature count: " << table->signatureCount() << "\n";

for (int idx = 0; idx < table->signatureCount(); idx++) {
for (int idx = 0; idx < table->signatureCount(); idx++)
{
Log::info() << std::string(indent, ' ') << "Signature #" << idx << ":\n";
printSignature(table->signatures[idx], indent + 4);
Log::info() << "\n";
Expand Down
14 changes: 14 additions & 0 deletions src/pelib/SecurityDirectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ namespace PeLib
m_certs.push_back(cert);
}

// save the offset and size for future checks
this->offset = uiOffset;
this->size = size;

return ERROR_NONE;
}

std::uint64_t SecurityDirectory::getOffset() const
{
return offset;
}

std::uint64_t SecurityDirectory::getSize() const
{
return size;
}
}