From a6901814557489557104f66aa722e6d4d75aec34 Mon Sep 17 00:00:00 2001 From: Manuel Bischof Date: Wed, 20 Sep 2023 14:38:47 +0200 Subject: [PATCH] Add readme section for extraction logging --- plugins/apitracing/Readme.md | 67 +++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/plugins/apitracing/Readme.md b/plugins/apitracing/Readme.md index 35c5dcce..e17c2350 100644 --- a/plugins/apitracing/Readme.md +++ b/plugins/apitracing/Readme.md @@ -88,4 +88,69 @@ type *LPPROCESS_INFORMATION*. For example the parameter *hProcess* is of the type *HANDLE*. Depending on the address width of the process it gets resolved to either *unsigned int* or *unsigned _int64*. Those are *BackingParameterTypes* so either 8 or 4 byte are read when -extracting this structure from the heap. \ No newline at end of file +extracting this structure from the heap. + +## Extraction Format + +Function call traces are logged in an unindented json format which is illustrated indented below for better visibility. +The parameter extraction logs are identified by the *key* ```Parameterlist:```. +Its *value* is a list of all function call parameters, whereby the parameter names form the *keys* of the contained *key:value* pairs. +Each *value* is either the value of the parameter as integer or string value, or it is a list containing +the *key:value* pairs of backing parameters if it's a pointer to a struct. + +```json +Parameterlist: [ + {"FileHandle":[ + {"HANDLE":45}]}, + {"DesiredAccess":1180063}, + {"ObjectAttributes":[ + {"Length":48}, + {"RootDirectory":0}, + {"ObjectName":"\\Device\\ConDrv\\Server"}, + {"Attributes":66}, + {"SecurityDescriptor":0}, + {"SecurityQualityOfService":0}]}, + {"IoStatusBlock":958106952720}, + {"AllocationSize":0}, + {"FileAttributes":0}, + {"ShareAccess":7}, + {"CreateDisposition":2}, + {"CreateOptions":0}, + {"EaBuffer":0}, + {"EaLength":0}] +``` + +The log example above is a function call from *NtCreateFile* with these parameters: + +``` +__kernel_entry NTSTATUS NtCreateFile( + [out] PHANDLE FileHandle, + [in] ACCESS_MASK DesiredAccess, + [in] POBJECT_ATTRIBUTES ObjectAttributes, + [out] PIO_STATUS_BLOCK IoStatusBlock, + [in, optional] PLARGE_INTEGER AllocationSize, + [in] ULONG FileAttributes, + [in] ULONG ShareAccess, + [in] ULONG CreateDisposition, + [in] ULONG CreateOptions, + [in] PVOID EaBuffer, + [in] ULONG EaLength +); +``` + +*FileHandle, DesiredAccess, ObjectAttributues, IOStatusBlocck,AllocationSize, FileAttributes,ShareAccess, CreateDisposition, +CreateOptions, EaBuffer* and *EaLength* are members of the list in parameterlist *value*. + +``` +typedef struct _OBJECT_ATTRIBUTES { + ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} OBJECT_ATTRIBUTES; +``` + +*ObjectAttributes* is a pointer to a struct, so its value is a list containing the backing parameters. +The parameter *ObjectName* is a pointer, but strings are extracted right away to keep the structure more flat.