shellext / SQL Export

SQL Export

SQL Export (frmSqlExport2) writes a full structured analysis of a file set to a SQLite database, prepared-statement style. It's the right-click hand-off when ad-hoc reporting from the listview menus isn't enough — once the data's in SQLite, you can answer arbitrary questions about a sample collection with a few SELECTs.

The dialog's init takes one of three parent forms:

Parent formSource
frmHashFolder listview. Selected Only checkbox is enabled.
frmFileHashSingle-file mode. Just the one row.
frmRecursiveHashFilesRecursive listview. Selected Only disabled (the recursive UI doesn't track selection the same way).
SQL Export dialog
Output DB path at top, table name and option checkboxes in the middle, build status log at the bottom. The default DB path is %Desktop%\<tablename>.db, refreshed as the table name changes (until you edit the path manually).

Options

OptionEffect
Table NameThe base name for the table set. Default files. The actual tables created are <name>, <name>_sects, <name>_res, <name>_exp.
Output DBPath to the .db file. Auto-fills as %Desktop%\<tablename>.db; click ... to browse or New to choose a fresh path.
w/ CreatesWhen checked (default), drops existing tables and recreates them before inserting. Uncheck to append to an existing schema.
Selected Only(frmHash only) Only export rows that are selected in the parent listview.
Section StatsPopulate the _sects child table with one row per PE section (entropy, CRC32, raw/virtual address and size, characteristics, EP-section flag).
Pe SignatureRun Authenticode verification per file and store the result, plus the signer's subject/issuer/serial.
DiERun Detect It Easy per file, store its output in the die column.
w/ ContentsRead text files into the contents column. Binary files (NUL byte in the first 1024 bytes) are stored as NULL. Files larger than 10 MB are skipped. UTF-8, UTF-16 LE, and UTF-16 BE BOMs are detected; no BOM defaults to UTF-8 (handles ASCII as a strict subset).

Schema

Four tables are created. The main table is one row per file; the three child tables join back via the hash column.

<tableName> — one row per file

ColumnTypeSource
firstSeen, ssz, vt, detects, subs, dateTEXT/INTReserved for VT enrichment — populated by the VT Lookup AllCopy → Sql Update chain in Hash Files, not by this dialog directly.
sizeINTFile size in bytes.
fnameTEXTBase file name.
pathTEXTFull path.
detailsTEXTReserved.
hash, sha256TEXTMD5 (primary join key) and SHA256.
compiledTEXTPE compile-date string (or content-type for non-PE).
sectCnt, sectsINT/TEXTPE section count and concatenated section-name list.
dieTEXTDetect It Easy output (when DiE option is on).
pdbTEXTPath from the debug directory.
expCnt, exportsINT/TEXTExport count and the dumped export-name list.
resCnt, resSize, resNamesINT/INT/TEXTResource count, total size, and concatenated names.
imphashTEXTMandiant-style import hash.
pever, fileProps, richTEXTPE version-info report, Win32 file-info dump, decoded Rich-header dump.
ep, epSect, epSectIndexTEXT/TEXT/INTEntry point, the section it lives in, and that section's index.
is32bit, isDotnet, isDllINTBool flags.
importDllsTEXTNewline-joined list of imported DLL names (no functions).
dotNetVerTEXT.NET runtime version when isDotnet=1.
sig, sigDetails, sig_serial, sig_subject, sig_issuerTEXTAuthenticode result (when Pe Signature option is on).
contentsTEXTDecoded text file contents (when w/ Contents is on); NULL for binaries.

<tableName>_sects — one row per PE section

ColumnDescription
hashJoins to main table.
iSection index.
nameSection name.
virtAddr, virtSzVA and size, hex strings.
rawOff, rawSzFile offset and raw size, hex strings.
flags, flagNamesCharacteristics as hex and as decoded flag names.
hasEP1 if this section contains the entry point.
entropy, crc32Per-section, computed on demand by the section accessor.

<tableName>_res — one row per resource

ColumnDescription
hashJoins to main table.
rva, size, ssizeRVA, byte size, and human-readable size.
codepageResource code page.
entropyPer-resource entropy.
pathResource type/name/lang path.

<tableName>_exp — one row per exported function

ColumnDescription
hashJoins to main table.
offsetFunction address (hex).
nameExported name.
ordinalExport ordinal.

How the export runs

The build is prepared-statement based for speed: one INSERT per table is prepared at the start, then re-bound and re-executed per file/section/resource/export. Errors per row are swallowed and logged into the bottom listbox — one bad file doesn't abort the run.

The progress bar tracks per-file progress; the listbox at the bottom is the running build log. The form caption shows processed / total while running.

Note: Statement-handle ordering matters. Column order in InsertMainRow binds positionally and must match the CREATE TABLE and the INSERT column list. Editing the schema means editing all three.

Example queries

-- which entry-point sections show up most often (PE packers / loaders)
SELECT epSect, COUNT(*) AS cnt
  FROM files
  GROUP BY epSect
  ORDER BY cnt DESC;

-- all imphash collisions (likely same-family code with different strings)
SELECT imphash, GROUP_CONCAT(hash, ', ') AS samples, COUNT(*) AS cnt
  FROM files
  GROUP BY imphash
  HAVING cnt > 1;

-- section names by frequency
SELECT name, COUNT(*) AS cnt
  FROM files_sects
  GROUP BY name
  ORDER BY cnt DESC;

-- find all signed .NET DLLs imported by anything in the set
SELECT fname, sha256, sig_subject
  FROM files
  WHERE isDll = 1 AND isDotnet = 1 AND sig IS NOT NULL;

See also