From ea2a8705eb42af9522f0dd8dbf1ebd5f341a6e45 Mon Sep 17 00:00:00 2001 From: John Parent Date: Fri, 30 Jan 2026 19:05:30 -0500 Subject: [PATCH] Coff Parser Improvements * Adds api calls for obtaining the PE names stored in coff files Supports both short and long names, or detecting both. Typically only one is defined in an import library, so whichever is returned first. * Adds access guards to coff reading Signed-off-by: John Parent --- src/coff_parser.cxx | 39 ++++++++++++++++++++++++++++++++++++-- src/coff_parser.h | 3 +++ src/coff_reader_writer.cxx | 22 ++++++++++++++++++--- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/coff_parser.cxx b/src/coff_parser.cxx index 25f4b28..4cee1f0 100644 --- a/src/coff_parser.cxx +++ b/src/coff_parser.cxx @@ -46,8 +46,9 @@ CoffParser::CoffParser(CoffReaderWriter* coff_reader) */ bool CoffParser::Parse() { if (!this->coffStream_->Open()) { - std::cerr << "Unable to open coff file for reading: " - << reportLastError() << "\n"; + std::cerr << "Unable to open coff file: " + << this->coffStream_->get_file() + << " for reading: " << reportLastError() << "\n"; return false; } int const invalid_valid_sig = @@ -578,6 +579,40 @@ void CoffParser::ReportLongName(const char* data) { std::cout << "DLL: " << data << "\n"; } +std::string CoffParser::GetLongName() const { + // TODO(johnwparent): I think we can access the + // 2nd index of the members vec to get the long + // name + for (auto mem : this->coff_.members) { + if (mem.member->is_longname) { + return std::string(mem.member->data); + } + } + return std::string(); +} + +std::string CoffParser::GetShortName() const { + for (auto mem : this->coff_.members) { + if (mem.header->Name[0] != '/') { + int i = 0; + while (mem.header->Name[i] != '/') { + ++i; + } + return std::string(reinterpret_cast(mem.header->Name), + i); + } + } + return std::string(); +} + +std::string CoffParser::GetName() const { + std::string maybe_name = this->GetLongName(); + if (maybe_name.empty()) { + maybe_name = this->GetShortName(); + } + return maybe_name; +} + void CoffParser::Report() { for (auto mem : this->coff_.members) { if (mem.member->is_longname) { diff --git a/src/coff_parser.h b/src/coff_parser.h index 6cf7728..e485af0 100644 --- a/src/coff_parser.h +++ b/src/coff_parser.h @@ -43,6 +43,9 @@ class CoffParser { bool NormalizeName(std::string& name); void Report(); int Verify(); + std::string GetLongName() const; + std::string GetShortName() const; + std::string GetName() const; static int Validate(std::string& coff); }; diff --git a/src/coff_reader_writer.cxx b/src/coff_reader_writer.cxx index cbab86f..6e34736 100644 --- a/src/coff_reader_writer.cxx +++ b/src/coff_reader_writer.cxx @@ -6,6 +6,7 @@ #include "coff_reader_writer.h" #include "coff.h" +#include "utils.h" #include #include @@ -13,16 +14,31 @@ #include #include #include +#include #include +#include #include CoffReaderWriter::CoffReaderWriter(std::string const& file) : file_(std::move(file)) {} bool CoffReaderWriter::Open() { - this->pe_stream_.open(this->file_, - std::ios::in | std::ios::out | std::ios::binary); - return this->pe_stream_.is_open(); + std::wstring coff_file; + try { + coff_file = ConvertASCIIToWide(this->file_); + } catch (std::overflow_error& e) { + return false; + } + try { + ScopedFileAccess const obtain_write(coff_file, GENERIC_ALL); + this->pe_stream_.open(this->file_, + std::ios::in | std::ios::out | std::ios::binary); + return this->pe_stream_.is_open(); + } catch (std::system_error& e) { + std::cerr << "Could not obtain write access: " << e.what() + << " (Error Code: " << e.code().value() << ")" << '\n'; + return false; + } } bool CoffReaderWriter::Close() {