Skip to content

Anti Analysis Operations

Ido Veltzman edited this page Jan 14, 2024 · 6 revisions

ETWTI Tampering

Disabling / Re-enabling ETW (Event tracing for Windows) threat intelligence provider.

Function Signature

NTSTATUS AntiAnalysis::EnableDisableEtwTI(bool enable)

enable	[bool]	   -- Whether to enable or disable ETWTI.

Usage Example

# Disable ETWTI
NidhoggClient.exe etwti disable

# Enable ETWTI
NidhoggClient.exe etwti enable

How It Works

The function begins by dynamically locating the KeInsertQueueApc system routine as a starting point to search for the ETWTI provider handle. If this routine cannot be found, the function returns STATUS_NOT_FOUND.

Next, the function attempts to find a specific pattern in memory (EtwThreatIntProvRegHandleSignature1 or EtwThreatIntProvRegHandleSignature2) within a certain distance from the KeInsertQueueApc address. If neither pattern is found, the function returns STATUS_NOT_FOUND.

The function then calculates the address of etwThreatIntProvRegHandle and gets the offset of the enableProviderInfo and etwThreatIntLock from this address. If either offset is unsuccessful, the function returns STATUS_UNSUCCESSFUL.

If the etwThreatIntLock was found, the function acquires an exclusive lock on it.

Depending on the enable parameter, the function either copies the value of this->PrevEtwTiValue to enableProviderInfo->IsEnabled and then sets this->PrevEtwTiValue to 0 (if enable is true), or reads the value of enableProviderInfo->IsEnabled into this->PrevEtwTiValue and then sets enableProviderInfo->IsEnabled to 0 (if enable is false).

Finally, if the etwThreatIntLock was acquired earlier, the function releases it and returns the status of the last operation.


Querying Kernel Callbacks

Querying kernel callbacks of other drivers including object callbacks, process and thread creation routines, image loading routines, and registry callbacks.

Function Signature

NTSTATUS AntiAnalysis::ListRegistryCallbacks(CmCallbacksList* Callbacks, ULONG64 ReplacerFunction, ULONG64 ReplacedFunction)

Callbacks	 [CallbacksList*] -- A pointer to a CmCallbacksList structure that will hold the list of registry callbacks.
ReplacerFunction [ULONG64]        -- If not null, the address of the function to replace.
ReplacedFunction [ULONG64]	  -- If not null, the address of the function to be replaced.

Usage Example

# List object callbacks
NidhoggClient.exe callbacks query ObThreadType
NidhoggClient.exe callbacks query ObProcessType

# List process / image load routines
NidhoggClient.exe callbacks query PsProcessType
NidhoggClient.exe callbacks query PsImageLoadType

# List registry callbacks
NidhoggClient.exe callbacks query CmRegistryType

How It Works

The function begins by locating the CmpRegisterCallbackInternal and CmpInsertCallbackInListByAltitude functions in memory using byte pattern matching. If either function cannot be found, the function returns STATUS_NOT_FOUND.

Next, the function locates the CallbackListHead and CmpCallBackCount in memory, again using byte pattern matching. If either cannot be found, the function returns STATUS_NOT_FOUND.

The function then acquires an exclusive lock on the CmpCallbackListLock.

If ReplacerFunction and ReplacedFunction are both non-zero, the function iterates over the list of callbacks. If it finds a callback whose function matches ReplacedFunction, it replaces that callback's function with ReplacerFunction.

If ReplacerFunction and ReplacedFunction are both zero, the function instead populates the Callbacks structure with the list of callbacks and their associated driver names.

Finally, the function releases the lock on CmpCallbackListLock and returns the status of the operation.


Removing And Restoring Callbacks

Removing by replacing the callback on the target driver with a dummy callback or restoring a callback to the original for the types mentioned above.

Function Signature

NTSTATUS AntiAnalysis::RestoreCallback(KernelCallback* Callback)

Callback [KernelCallback*] -- Callback to restore.
NTSTATUS AntiAnalysis::RemoveCallback(KernelCallback* Callback)

Callback [KernelCallback*] -- Callback to remove.

Usage Example

# Remove callback
NidhoggClient.exe callbacks remove <ADDR>

# Restore callback
NidhoggClient.exe callbacks restore <ADDR>

How It Works

Removing Callback

The function begins by checking the type of the callback. Depending on the type of the callback, the function then removes the callback in the appropriate manner. If the callback is of type ObProcessType or ObThreadType, it is removed from the object callback list. If the callback is of type PsCreateProcessType, PsCreateProcessTypeEx, PsCreateThreadType, PsCreateThreadTypeNonSystemThread, or PsImageLoadType, it is removed from the process or thread creation routines list. If the callback is of type CmRegistryType, it is removed from the registry callbacks list.

If the callback is successfully removed, it is then added to the list of disabled callbacks.

Finally, the function returns the status of the operation.

Restoring Callback

The function begins by getting the disabled callback. If the callback is not found, the function returns the status of the operation.

Depending on the type of the callback, the function then restores the callback in the appropriate manner. If the callback is of type ObProcessType or ObThreadType, it is restored in the object callback list. If the callback is of type PsCreateProcessType, PsCreateProcessTypeEx, PsCreateThreadType, or PsCreateThreadTypeNonSystemThread, it is restored in the process or thread creation routines list. If the callback is of type CmRegistryType, it is restored in the registry callbacks list.