Skip to content

Instantly share code, notes, and snippets.

@t94j0
Last active July 8, 2024 02:39
Show Gist options
  • Save t94j0/0dbc79179ffca4b96d34552115bfbfc3 to your computer and use it in GitHub Desktop.
Save t94j0/0dbc79179ffca4b96d34552115bfbfc3 to your computer and use it in GitHub Desktop.
ADExplorer Snapshot - 010 Editor Parsed
//------------------------------------------------
//--- 010 Editor v2.0 Binary Template
//
// File: ADExplorerSnapshot.bt
// Authors: Max Harley, Claude AI
// Version: 1.8
// Purpose: Parse ADExplorer snapshot files including attributes
// Category: Database
// File Mask: *.snapshotdb
// ID Bytes: 41 44 45 58 50 4C 52 44 42 // ADEXPLRDB
// History:
// 1.1 2023-07-07 Updated to handle Attributes
// 1.0 2023-07-05 Initial version
//------------------------------------------------
#define COLOR_HEADER 0xC0FFA0
#define COLOR_OBJECT 0xA0C0FF
#define COLOR_PROPERTY 0xFFA0A0
#define COLOR_CLASS 0xFFD700
#define COLOR_RIGHT 0xA0FFA0
#define COLOR_ATTRIBUTE 0xFFB6C1
typedef enum <uint32> {
ADSTYPE_INVALID = 0,
ADSTYPE_DN_STRING = 1,
ADSTYPE_CASE_EXACT_STRING = 2,
ADSTYPE_CASE_IGNORE_STRING = 3,
ADSTYPE_PRINTABLE_STRING = 4,
ADSTYPE_NUMERIC_STRING = 5,
ADSTYPE_BOOLEAN = 6,
ADSTYPE_INTEGER = 7,
ADSTYPE_OCTET_STRING = 8,
ADSTYPE_UTC_TIME = 9,
ADSTYPE_LARGE_INTEGER = 10,
ADSTYPE_PROV_SPECIFIC = 11,
ADSTYPE_OBJECT_CLASS = 12,
ADSTYPE_CASEIGNORE_LIST = 13,
ADSTYPE_OCTET_LIST = 14,
ADSTYPE_PATH = 15,
ADSTYPE_POSTALADDRESS = 16,
ADSTYPE_TIMESTAMP = 17,
ADSTYPE_BACKLINK = 18,
ADSTYPE_TYPEDNAME = 19,
ADSTYPE_HOLD = 20,
ADSTYPE_NETADDRESS = 21,
ADSTYPE_REPLICAPOINTER = 22,
ADSTYPE_FAXNUMBER = 23,
ADSTYPE_EMAIL = 24,
ADSTYPE_NT_SECURITY_DESCRIPTOR = 25,
ADSTYPE_UNKNOWN = 26,
ADSTYPE_DN_WITH_BINARY = 27,
ADSTYPE_DN_WITH_STRING = 28
} ADSTYPE;
typedef struct {
char winAdSig[10];
int32 marker;
uint64 filetime;
wchar_t optionalDescription[260];
wchar_t server[260];
uint32 numObjects;
uint32 numAttributes;
uint32 fileoffsetLow;
uint32 fileoffsetHigh;
uint32 fileoffsetEnd;
int32 unk0x43a;
} Header <bgcolor=COLOR_HEADER>;
typedef struct {
uint32 attrIndex;
int32 attrOffset;
} MappingEntry;
typedef struct {
wstring value;
} StringValue;
typedef struct(uint32 length) {
char octetString[length];
} OctetStringValue;
typedef struct (ADSTYPE adsType) {
local uint64 attributeStart = FTell();
uint32 numValues;
if (numValues > 0) {
switch (adsType) {
case ADSTYPE_DN_STRING:
case ADSTYPE_CASE_IGNORE_STRING:
case ADSTYPE_CASE_EXACT_STRING:
case ADSTYPE_PRINTABLE_STRING:
case ADSTYPE_NUMERIC_STRING:
case ADSTYPE_OBJECT_CLASS:
uint32 offsets[numValues];
local int i;
for (i = 0; i < numValues; i++) {
FSeek(attributeStart + offsets[i]);
StringValue value;
}
break;
case ADSTYPE_OCTET_STRING:
uint32 lengths[numValues];
local int j;
for (j = 0; j < numValues; j++) {
OctetStringValue value(lengths[j]);
}
break;
case ADSTYPE_BOOLEAN:
uint32 boolValue;
break;
case ADSTYPE_INTEGER:
uint32 intValues[numValues];
break;
case ADSTYPE_LARGE_INTEGER:
int64 largeIntValues[numValues];
break;
case ADSTYPE_UTC_TIME:
struct {
uint16 wYear;
uint16 wMonth;
uint16 wDayOfWeek;
uint16 wDay;
uint16 wHour;
uint16 wMinute;
uint16 wSecond;
uint16 wMilliseconds;
} dateTime;
break;
case ADSTYPE_NT_SECURITY_DESCRIPTOR:
uint32 lenDescriptorBytes;
char descriptorBytes[lenDescriptorBytes];
break;
default:
Printf("Unhandled ADSTYPE: %d\n", adsType);
break;
}
}
} AttributeValue <bgcolor=COLOR_ATTRIBUTE>;
typedef struct {
uint32 lenPropName;
wchar_t propName[lenPropName/2];
int32 unk1;
ADSTYPE adsType;
uint32 lenDN;
wchar_t DN[lenDN/2];
GUID schemaIDGUID;
GUID attributeSecurityGUID;
char blob[4];
} Property <bgcolor=COLOR_PROPERTY>;
typedef struct (struct Properties &props) {
local uint64 startPos = FTell();
local uint32 numProperties = props.numProperties;
uint32 objSize;
uint32 tableSize;
MappingEntry mappingTable[tableSize];
local int k;
local ADSTYPE adsType;
for (k = 0; k < tableSize; k++) {
FSeek(startPos + mappingTable[k].attrOffset);
if (mappingTable[k].attrIndex >= numProperties) {
continue; // Skip this entry and continue with the next one
}
// Access the Property directly using its index
adsType = props.property[mappingTable[k].attrIndex].adsType;
AttributeValue attribute(adsType);
}
FSeek(startPos + objSize);
} Object <bgcolor=COLOR_OBJECT>;
typedef struct {
uint32 lenSystemPossSuperior;
wchar_t systemPossSuperior[lenSystemPossSuperior/2];
} SystemPossSuperior;
typedef struct {
uint32 lenAuxiliaryClass;
wchar_t auxiliaryClass[lenAuxiliaryClass/2];
} AuxiliaryClasses;
typedef struct {
uint32 unk1;
uint32 unk2;
wchar_t unk3[unk2/2];
} Block;
typedef struct {
local uint i;
uint32 lenClassName;
wchar_t className[lenClassName/2];
uint32 lenDN;
wchar_t DN[lenDN/2];
uint32 lenCommonClassName;
wchar_t commonClassName[lenCommonClassName/2];
uint32 lenSubClassOf;
wchar_t subClassOf[lenSubClassOf/2];
local string guidString;
char schemaIDGUID[16];
guidString = GUIDToString(schemaIDGUID);
uint32 offsetToNumBlocks;
char unk2 [offsetToNumBlocks];
uint32 numBlocks;
for (i = 0; i < numBlocks; i++)
Block block <optimize=false>;
uint32 numUnknown;
for (i = 0; i < numUnknown*0x10; i++)
char unknown;
uint32 numSystemPossSuperiors;
for (i = 0; i < numSystemPossSuperiors; i++) {
SystemPossSuperior systemPossSuperiors;
}
uint32 numAuxiliaryClasses;
for (i = 0; i < numAuxiliaryClasses; i++) {
AuxiliaryClasses auxiliaryClasses;
}
} Class <bgcolor=COLOR_CLASS>;
typedef struct {
uint32 lenName;
wchar_t name[lenName/2];
uint32 lenDesc;
wchar_t desc[lenDesc/2];
char blob[20];
} Right <bgcolor=COLOR_RIGHT>;
struct {
Header header;
struct Properties {
FSeek((uint64)header.fileoffsetHigh << 32 | header.fileoffsetLow);
uint32 numProperties;
local int i;
for (i = 0; i < numProperties; i++) {
Property property;
}
} properties;
local uint64 offsetProperties = FTell();
// Objects
FSeek(0x43e);
struct {
local uint32 i;
for (i = 0; i < header.numObjects; i++) {
Object object(properties);
}
} objects;
FSeek(offsetProperties);
struct {
uint32 numClasses;
if (numClasses > 0 && numClasses <= 10000) { // Sanity check
local uint32 k;
for (k = 0; k < numClasses; k++) {
if (FTell() < FileSize()) {
Class class;
} else {
Printf("Error: Reached end of file while parsing Class %d at offset 0x%X\n", k+1, FTell());
break;
}
}
} else {
Printf("Error: Invalid numClasses: %d at offset 0x%X\n", numClasses, FTell());
}
} Classes;
// Rights
if (FTell() < FileSize()) {
struct {
uint32 numRights;
local uint32 m;
for (m = 0; m < numRights; m++) {
Right right;
}
} Rights;
}
} ADExplorerSnapshot;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment