
un PE Loader et un traceur d'API Windows. Utile dans l'analyse de malwares.
Ce projet a été créé pour faciliter le processus d'analyse de logiciels malveillants. L'objectif est de créer un binaire activateur dont le but est de charger un binaire défini par l'utilisateur et de surveiller l'exécution en utilisant des hooks de l'API Win32. Les données pertinentes sont ensuite sauvegardées sur le disque. Le code prend en charge les binaires x86 et x64.
J'ai écrit un article de blog expliquant son fonctionnement : http://antonioparata.blogspot.com/2022/06/thematrix-process-inspection-tool-aimed.html
Pour surveiller un nouveau binaire, il est nécessaire de créer un activateur. L'activateur va charger et surveiller un binaire saisi par l'utilisateur. Pour créer un activateur, utilisez l'option -add. Un exemple d'utilisation est le suivant :
c:\>TheMatrix.exe -add c:\path\to\my\binary.dll
Activator file created
c:\>regsvr32.exe TheMatrix.build.dll
Cette commande créera un nouveau fichier PE représentant l'activateur. L'activateur aura le même format (DLL ou EXE) que le binaire d'entrée.
Une fois créé, vous pouvez simplement l'exécuter de la manière que vous préférez (pour une DLL, la méthode suggérée est d'utiliser l'utilitaire rundll32.exe).
Pendant l'exécution, les données générées par les fonctions surveillées sont sauvegardées dans ./Desktop/thematrix/[ID du processus]/ (cela dépend de la fonction log_data implémentée dans utility.c).
Limitation :
Le projet modifie la structure PEB.Ldr pour permettre à certaines API de fonctionner correctement (telles que GetModuleHandle, ...). Si vous exécutez l'activateur sur un système WOW64 (binaire x86 sur un OS x64), seul le PEB.Ldr x86 est modifié (les processus WOW64 ont à la fois un PEB x86 et x64). Lorsque le CPU passe en mode x64, les API natives Windows (ntdll.dll) utiliseront la version x64 de PEB.Ldr. Cela implique que l'activateur pourrait ne pas fonctionner correctement. Pour être sûr que le x86 fonctionne, exécutez le binaire sur un OS x86.
Le fichier nouvellement créé n'exporte pas toutes les méthodes et ne contient pas les ressources du fichier d'origine. Cela peut entraîner des erreurs possibles, par exemple si une DLL appelle GetModuleFileName -> LoadLibrary -> FindResource. Ce chemin de code chargera la DLL TheMatrix d'origine qui ne contient pas la ressource souhaitée.
Ajouter de nouvelles fonctions au moniteur est une tâche facile, jetez un œil au fichier hooks.c pour quelques exemples de hooks de Kernel32.dll et bcrypt.dll. Pour ajouter un nouveau hook, il suffit d'appeler la fonction hook_add. Ci-dessous un exemple de création de hook est présenté :
LPVOID __stdcall hook_BCryptEncrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, VOID* pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG* pcbResult, ULONG dwFlags)
{
// save plain data
if (cbInput) {
char name[MAX_PATH] = { 0 };
snprintf(name, sizeof(name), "BCryptEncrypt_%llx_%d", (uint64_t)pbInput, cbInput);
log_data(cbInput, pbInput, name);
}
LPVOID ret = call_original(
hKey,
pbInput,
cbInput,
pPaddingInfo,
pbIV,
cbIV,
pbOutput,
cbOutput,
pcbResult,
dwFlags
);
return ret;
}
hook_add("Bcrypt.dll", "BCryptEncrypt", hook_BCryptEncrypt);
La fonction doit avoir la même signature que la fonction hookée. La fonction call_original est utilisée pour appeler la fonction originale. Il suffit d'appeler cette fonction avec les paramètres d'entrée de la fonction originale, le framework fera tout le travail lourd pour vous afin d'appeler la bonne fonction ;) L'appel à la fonction call_original doit être effectué dans le même thread qui exécute le hook, sinon le processus plantera.