Skip to content

Instantly share code, notes, and snippets.

@stevemk14ebr
Last active January 21, 2022 16:08
Show Gist options
  • Save stevemk14ebr/0b27d719833be8d7ead4f3fd073442e7 to your computer and use it in GitHub Desktop.
Save stevemk14ebr/0b27d719833be8d7ead4f3fd073442e7 to your computer and use it in GitHub Desktop.
ApiSet section 010 template
// Parses .apiset PE section for apiset forwarder dlls
// From: https://lucasg.github.io/2017/10/15/Api-set-resolution/
// which itself uses Alex Ionescu's documented structures (at least in part)
//------------------------------------------------
//--- 010 Editor v8.0 Binary Template
//
// File:
// Authors:
// Version:
// Purpose:
// Category:
// File Mask:
// ID Bytes:
// History:
//------------------------------------------------
// Api namespace header
typedef struct {
ULONG Version;
ULONG Size <format=hex>;
ULONG Flags;
ULONG Count <format=hex>;
ULONG EntryOffset <format=hex>;
ULONG HashOffset <format=hex>;
ULONG HashFactor <format=hex>;
} API_SET_NAMESPACE;
typedef struct {
ULONG Hash;
ULONG Index;
} API_SET_HASH_ENTRY;
typedef struct {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG HashedLength;
ULONG ValueOffset;
ULONG ValueCount;
} API_SET_NAMESPACE_ENTRY;
typedef struct {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG ValueOffset;
ULONG ValueLength;
} API_SET_VALUE_ENTRY;
typedef struct {
for (i=0; i<ApiSetMap.Count; i++) {
API_SET_NAMESPACE_ENTRY Entry;
}
} API_SET_NAMESPACE_ENTRIES;
typedef struct {
for (i=0; i<ApiSetMap.Count; i++) {
API_SET_HASH_ENTRY HashEntry;
}
} API_SET_NAMESPACE_HASH_ENTRIES;
typedef struct (API_SET_VALUE_ENTRY &ValueEntry) {
local int StartAddress = FTell();
local int ValueLength = ValueEntry.ValueLength;
CHAR Value[ValueEntry.ValueLength + 2];
} API_SET_ENTRY_VALUE;
typedef struct (API_SET_NAMESPACE_ENTRY& Entry) {
local int ValueCount = Entry.ValueCount;
local int NameLength = Entry.NameLength;
local int StartAddress = FTell();
local int HasValues = false;
CHAR Name[Entry.NameLength + 2];
FSeek(StartAddr + Entry.ValueOffset);
API_SET_VALUE_ENTRY ValueEntry;
FSeek(StartAddr + ValueEntry.ValueOffset);
if (ValueEntry.ValueOffset)
{
HasValues = true;
for (j = 0; j < Entry.ValueCount;j++)
{
API_SET_ENTRY_VALUE ValueName(ValueEntry);
}
}
if (i < ApiSetMap.Count - 1){
FSeek(StartAddr + Entries.Entry[i+1].NameOffset);
}
else {
FSeek(StartAddr + ApiSetMap.Size);
}
} API_SET_ENTRY_PARSED <read=ReadApiSetEntry>;
string ReadApiSetEntry(API_SET_ENTRY_PARSED & ParsedEntry)
{
local string sApiSetName = ReadWString(ParsedEntry.StartAddress, ParsedEntry.NameLength);
if (ParsedEntry.HasValues) {
local string sApiSetValue = ReadWString(ParsedEntry.ValueName[0].StartAddress, ParsedEntry.ValueName[0].ValueLength/2);
return sApiSetName + " -> " + sApiSetValue;
}
return sApiSetName;
}
// main entry point
LittleEndian();
Printf("Parse api set schema Begin.\n");
local int StartAddr = FTell();
local int i =0;
local int j =0;
API_SET_NAMESPACE ApiSetMap <fgcolor=cGreen>;
FSeek(StartAddr + ApiSetMap.EntryOffset);
// Enumerate API_SET_NAMESPACE_ENTRY entries
API_SET_NAMESPACE_ENTRIES Entries <fgcolor=cPurple>;
// Traverse API_SET_NAMESPACE_ENTRY entries and retrieve
// corresponding API_SET_VALUE_ENTRY entry in order to dump
// api-set and hosts library names.
for (i=0; i<ApiSetMap.Count; i++) {
FSeek(StartAddr + Entries.Entry[i].NameOffset);
API_SET_ENTRY_PARSED ParsedEntry(Entries.Entry[i]) <fgcolor=cBlue>;
}
// Enumerate API_SET_HASH_ENTRY entries
FSeek(StartAddr + ApiSetMap.HashOffset);
API_SET_NAMESPACE_HASH_ENTRIES HashEntries <fgcolor=cRed>;
Printf("Parse api set schema End.\n");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment