|
|
|
@ -28,6 +28,57 @@ namespace lnk
|
|
|
|
|
return result - sym.section_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto get_objs(std::string lib_path, std::vector<obj_buffer_t>& objs) -> bool
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::uint8_t> lib_file;
|
|
|
|
|
utils::open_binary_file(lib_path, lib_file);
|
|
|
|
|
|
|
|
|
|
// archive header magic bytes are not correct...
|
|
|
|
|
if (strncmp((char*)lib_file.data(),
|
|
|
|
|
IMAGE_ARCHIVE_START, sizeof IMAGE_ARCHIVE_START - 1))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto archive_headers =
|
|
|
|
|
reinterpret_cast<PIMAGE_ARCHIVE_MEMBER_HEADER>(
|
|
|
|
|
lib_file.data() + sizeof IMAGE_ARCHIVE_START - 1);
|
|
|
|
|
|
|
|
|
|
// loop over members...
|
|
|
|
|
while ((std::uint8_t*)archive_headers < lib_file.data() + lib_file.size())
|
|
|
|
|
{
|
|
|
|
|
// refer to https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#archive-member-headers
|
|
|
|
|
// for details on the "name" field... in short `/` means its a linker header
|
|
|
|
|
// `//` means that it is the string table, and finally `/n` n being the index into the string table...
|
|
|
|
|
// so in short: if the first byte isnt a `/` and the second byte is not a space or the first byte
|
|
|
|
|
// is not a forward slash then this archive header is for an obj...
|
|
|
|
|
if ((archive_headers->Name[0] == '/' &&
|
|
|
|
|
archive_headers->Name[1] != '\x20' &&
|
|
|
|
|
archive_headers->Name[1] != '/') || archive_headers->Name[0] != '/')
|
|
|
|
|
{
|
|
|
|
|
const auto obj_size = std::atoi(
|
|
|
|
|
reinterpret_cast<const char*>(archive_headers->Size));
|
|
|
|
|
|
|
|
|
|
if (!obj_size)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
const auto obj_begin = reinterpret_cast<void*>(
|
|
|
|
|
reinterpret_cast<std::uintptr_t>(archive_headers) +
|
|
|
|
|
sizeof IMAGE_ARCHIVE_MEMBER_HEADER);
|
|
|
|
|
|
|
|
|
|
std::vector<std::uint8_t> obj;
|
|
|
|
|
obj.resize(obj_size);
|
|
|
|
|
|
|
|
|
|
memcpy(obj.data(), obj_begin, obj_size);
|
|
|
|
|
objs.push_back(obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
archive_headers = reinterpret_cast<PIMAGE_ARCHIVE_MEMBER_HEADER>(
|
|
|
|
|
reinterpret_cast<std::uintptr_t>(archive_headers) +
|
|
|
|
|
std::atoi((char*)archive_headers->Size) + sizeof IMAGE_ARCHIVE_MEMBER_HEADER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace section
|
|
|
|
|
{
|
|
|
|
|
auto get_header(obj_buffer_t& obj, const char* section_name) -> PIMAGE_SECTION_HEADER
|
|
|
|
@ -175,10 +226,6 @@ namespace lnk
|
|
|
|
|
std::string(string_table +
|
|
|
|
|
symbol_table[idx].N.Name.Long);
|
|
|
|
|
|
|
|
|
|
// skip over aux symbols...
|
|
|
|
|
if (symbol_table[idx].NumberOfAuxSymbols)
|
|
|
|
|
++idx;
|
|
|
|
|
|
|
|
|
|
symbol.file_offset = section_headers[symbol_table[
|
|
|
|
|
idx].SectionNumber - 1].PointerToRawData + symbol_table[idx].Value;
|
|
|
|
|
|
|
|
|
|