Skip to content
Open
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
69 changes: 68 additions & 1 deletion PortableExecutable.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "PortableExecutable.h"
#include "PortableExecutable.h"

#include "Log.h"

Expand Down Expand Up @@ -173,3 +173,70 @@ IMAGE_SECTION_HEADER const* PortableExecutable::FindSection(
return &(*found);
}
}


std::unordered_map<std::string, DWORD> PortableExecutable::GetExportSymbols() const noexcept
{
std::unordered_map<std::string, DWORD> exportSymbols;

IMAGE_DATA_DIRECTORY const& exportTable = uPEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (exportTable.Size == 0) {
return exportSymbols;
}
DWORD rawExportAddress = VirtualToRaw(exportTable.VirtualAddress);
if (rawExportAddress == 0) {
return exportSymbols;
}
IMAGE_EXPORT_DIRECTORY exportDir;
if (!ReadBytes(rawExportAddress, sizeof(IMAGE_EXPORT_DIRECTORY), &exportDir)) {
return exportSymbols;
}
std::string moduleName;
if (!ReadCString(VirtualToRaw(exportDir.Name), moduleName))
{
moduleName = "";
}

std::vector<DWORD> addressOfFunctions;
size_t funcCount = exportDir.NumberOfFunctions;
addressOfFunctions.resize(funcCount);
if (!ReadBytes(VirtualToRaw(exportDir.AddressOfFunctions), sizeof(DWORD) * funcCount, addressOfFunctions.data())) {
return exportSymbols;
}

std::vector<DWORD> addressOfNames;
size_t nameCount = exportDir.NumberOfNames;
addressOfNames.resize(nameCount);
if (!ReadBytes(VirtualToRaw(exportDir.AddressOfNames), sizeof(DWORD) * nameCount, addressOfNames.data())) {
return exportSymbols;
}

std::vector<WORD> addressOfNameOrdinals;
addressOfNameOrdinals.resize(nameCount);
if (!ReadBytes(VirtualToRaw(exportDir.AddressOfNameOrdinals), sizeof(WORD) * nameCount, addressOfNameOrdinals.data())) {
return exportSymbols;
}

for (size_t i = 0; i < nameCount; ++i) {
DWORD nameRVA = addressOfNames[i];
DWORD rawNameAddress = VirtualToRaw(nameRVA);
if (rawNameAddress == 0) {
continue;
}

std::string nameANSI;
if (!ReadCString(rawNameAddress, nameANSI)) {
continue;
}

WORD ordinal = addressOfNameOrdinals[i];
if (ordinal >= funcCount) {
continue; // 无效序号
}

DWORD functionRVA = addressOfFunctions[ordinal];
exportSymbols[nameANSI] = functionRVA;
}

return exportSymbols;
}
5 changes: 4 additions & 1 deletion PortableExecutable.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// A class to parse PE files
// A class to parse PE files
#pragma once

#define WIN32_LEAN_AND_MEAN
Expand All @@ -10,6 +10,7 @@
#include <string>
#include <string_view>
#include <vector>
#include <unordered_map>

#include <windows.h>

Expand Down Expand Up @@ -109,6 +110,8 @@ class PortableExecutable
IMAGE_SECTION_HEADER const* FindSection(
std::string_view name) const noexcept;

std::unordered_map<std::string, DWORD> GetExportSymbols() const noexcept;

private:
bool ReadFile();
};
8 changes: 7 additions & 1 deletion SyringeDebugger.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "SyringeDebugger.h"
#include "SyringeDebugger.h"

#include "CRC32.h"
#include "FindFile.h"
Expand Down Expand Up @@ -1053,6 +1053,10 @@ void SyringeDebugger::FindDLLs()
PortableExecutable const DLL{ fn };
HookBuffer buffer;

auto AlwaysLoad = false;
auto Export = DLL.GetExportSymbols();
if (Export.count("SyringeForceLoad"))AlwaysLoad = true;

auto canLoad = false;
if (auto const hooks = DLL.FindSection(".syhks00"))
{
Expand All @@ -1063,6 +1067,8 @@ void SyringeDebugger::FindDLLs()
canLoad = ParseInjFileHooks(fn, buffer);
}

if (AlwaysLoad)canLoad = true;

if (canLoad)
{
Log::WriteLine(__FUNCTION__ ": Recognized DLL: \"%.*s\"", printable(fn));
Expand Down