Skip to main content


Quick Start

If you’re already familiar with scripting languages and/or SQL, you’ll more than likely be able to get started just by skim-reading this document and looking at some of the examples. If that’s the case, here’s a quick summary of the language which should help:

  • The language is interpreted, and mixes SQL SELECT statements with "method" calls on "modules" found in the Functions and Methods Reference.

  • The SQL SELECT support is provided by an enhanced version of the SQLite engine.

  • Additional custom SQL functions and Agent functions are described below.

  • The language is case sensitive (although case sensitivity is more relaxed within SQL SELECT statements) and is not whitespace sensitive.

  • Statements in the language must be terminated by a semi-colon (;)The Tachyon Agent takes advantage of SQLite extensibility by providing a further "application defined functions" that are built-in to the Agent and can also be used in SELECT statements

  • Variables within the language are written as "@myTableName" they are always tables of data that can have one or more rows and one or more columns.

  • The output of method calls and SQL SELECTs can be assigned to @tables and can be SELECTed from

  • The output of the instruction is always the last set of data produced by a statement, that is the final SELECT statement or method call.

  • If a statement produces an error, execution of the instruction terminates immediately with an Exit Code. Any changes made by the Agent are not rolled back.

  • There is some simple flow control with FOREACH looping (new in v3.0) and IF/ELSE/ENDIF conditional branching (new in v3.3).

  • You can use the "EVALUATE" statement to break out of an instruction at any point if the last statement produced an empty set of data; it is in effect "continue if data available".

  • RETURN, NOCONTENT, ERROR, and NOTIMPLEMENTED (new in v3.3) allows Early exit termination of the instruction with different Exit Codes.

  • Use double-quotes (") to enclose string literals, and in strings use the sequences backslash-double-quote (\") and backslash-backslash (\\) to escape literal double-quotes (") and a literal backslashes (\) respectively.

  • Use C-style comments in Agent language. Both the block and single-line; e.g. /* This is a comment until the block is closed */ and // This is a comment until the end of the line.

  • Use SQL-style comments in SQL statements. Both the block and single-line; e.g. /* This is a comment until the block is closed */ and -- This is a comment until the end of the line.

Here’s an example demonstrating some of the key features of the language – it brings back a row for each loaded DLL/EXE by any running process, the file version info data for that binary, and its MD5 hash. Since the example uses WMI, it will run on Windows only.

Example - query file version info and MD5 hash for loaded binaries

/* Get all the loaded DLLs and EXEs using a WMI query */
@binaries = NativeServices.RunWmiQuery(Namespace: "root\\cimv2", Query: "SELECT * FROM CIM_ProcessExecutable");

/* Extract the filename and count the number of times its loaded */
@binaryNames = SELECT   COUNT(1) AS LoadedCount
               ,        LOWER(REPLACE(REGEXPREPLACE("(.*)Name=\"(.*)\"", Antecedent, "$2"), "\\\\", "\\")) AS FileName
               FROM     @binaries
               GROUP BY FileName;

/* For each loaded binary, get the file version info */
@binaryInfo = FOREACH @r IN @binaryNames DO
  FileSystem.GetVersionInfo(FileName: @r.FileName);

/* Then, for each loaded binary, get the MD5 hash */
@hashes = FOREACH @r IN @binaryNames DO
  FileSystem.GetHash(FileName: @r.FileName, Algorithm: "MD5");

/* Then bring everything together */
SELECT     I.*
,          H.FileHash
,          N.LoadedCount
FROM       @binaryInfo AS I
INNER JOIN @hashes AS H      ON I.FileName = H.FileName
INNER JOIN @binaryNames AS N ON I.FileName = N.FileName;