Guest User

Untitled

a guest
Dec 19th, 2012
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.78 KB | None | 0 0
  1. /* http://forum.sysinternals.com/topic18892.html */
  2. #ifndef UNICODE
  3. #define UNICODE
  4. #endif
  5.  
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <TlHelp32.h>
  9.  
  10. #ifndef NTAPI
  11. #define NTAPI __stdcall
  12. #endif
  13.  
  14. #ifndef NTSTATUS
  15. #define NTSTATUS LONG
  16. #endif
  17.  
  18. #define NT_SUCCESS(x) ((x) >= 0)
  19. #define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
  20.  
  21. #define SystemHandleInformation 16
  22. #define ObjectBasicInformation 0
  23. #define ObjectNameInformation 1
  24. #define ObjectTypeInformation 2
  25.  
  26. typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
  27.     ULONG SystemInformationClass,
  28.     PVOID SystemInformation,
  29.     ULONG SystemInformationLength,
  30.     PULONG ReturnLength);
  31.  
  32. typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
  33.     HANDLE SourceProcessHandle,
  34.     HANDLE SourceHandle,
  35.     HANDLE TargetProcessHandle,
  36.     PHANDLE TargetHandle,
  37.     ACCESS_MASK DesiredAccess,
  38.     ULONG Attributes,
  39.     ULONG Options
  40.     );
  41.  
  42. typedef NTSTATUS (NTAPI *_NtQueryObject)(
  43.     HANDLE ObjectHandle,
  44.     ULONG ObjectInformationClass,
  45.     PVOID ObjectInformation,
  46.     ULONG ObjectInformationLength,
  47.     PULONG ReturnLength
  48.     );
  49.  
  50. typedef struct _UNICODE_STRING
  51. {
  52.     USHORT Length;
  53.     USHORT MaximumLength;
  54.     PWSTR Buffer;
  55. } UNICODE_STRING, *PUNICODE_STRING;
  56.  
  57. typedef struct _SYSTEM_HANDLE
  58. {
  59.     ULONG ProcessId;
  60.     BYTE ObjectTypeNumber;
  61.     BYTE Flags;
  62.     USHORT Handle;
  63.     PVOID Object;
  64.     ACCESS_MASK GrantedAccess;
  65. } SYSTEM_HANDLE, *PSYSTEM_HANDLE;
  66.  
  67. typedef struct _SYSTEM_HANDLE_INFORMATION
  68. {
  69.     ULONG HandleCount;
  70.     SYSTEM_HANDLE Handles[1];
  71. } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
  72.  
  73.  
  74. typedef enum _POOL_TYPE
  75. {
  76.     NonPagedPool,
  77.     PagedPool,
  78.     NonPagedPoolMustSucceed,
  79.     DontUseThisType,
  80.     NonPagedPoolCacheAligned,
  81.     PagedPoolCacheAligned,
  82.     NonPagedPoolCacheAlignedMustS
  83. } POOL_TYPE, *PPOOL_TYPE;
  84.  
  85. typedef struct _OBJECT_TYPE_INFORMATION
  86. {
  87.     UNICODE_STRING Name;
  88.     ULONG TotalNumberOfObjects;
  89.     ULONG TotalNumberOfHandles;
  90.     ULONG TotalPagedPoolUsage;
  91.     ULONG TotalNonPagedPoolUsage;
  92.     ULONG TotalNamePoolUsage;
  93.     ULONG TotalHandleTableUsage;
  94.     ULONG HighWaterNumberOfObjects;
  95.     ULONG HighWaterNumberOfHandles;
  96.     ULONG HighWaterPagedPoolUsage;
  97.     ULONG HighWaterNonPagedPoolUsage;
  98.     ULONG HighWaterNamePoolUsage;
  99.     ULONG HighWaterHandleTableUsage;
  100.     ULONG InvalidAttributes;
  101.     GENERIC_MAPPING GenericMapping;
  102.     ULONG ValidAccess;
  103.     BOOLEAN SecurityRequired;
  104.     BOOLEAN MaintainHandleCount;
  105.     USHORT MaintainTypeList;
  106.     POOL_TYPE PoolType;
  107.     ULONG PagedPoolUsage;
  108.     ULONG NonPagedPoolUsage;
  109. } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
  110.  
  111. PVOID GetLibraryProcAddress(LPSTR LibraryName, LPSTR ProcName);
  112.  
  113. PVOID GetLibraryProcAddress(LPSTR LibraryName, LPSTR ProcName) {
  114.     return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
  115. }
  116.  
  117. HANDLE GetProcessHandle(LPWSTR exeName, DWORD *pid) {
  118.     HANDLE pHandle = NULL;
  119.     PROCESSENTRY32 pe32;
  120.     HANDLE hProcSnap;
  121.  
  122.     if ((hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
  123.         return NULL;
  124.  
  125.     pe32.dwSize = sizeof(PROCESSENTRY32);
  126.  
  127.     if (!Process32First(hProcSnap, &pe32)) {
  128.         CloseHandle(hProcSnap);
  129.         return NULL;
  130.     }
  131.  
  132.     do {
  133.         if (wcscmp(pe32.szExeFile, exeName) == 0) {
  134.             *pid = pe32.th32ProcessID;
  135.         }
  136.     } while (Process32Next(hProcSnap, &pe32));
  137.  
  138.     pHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, *pid);
  139.  
  140.     return pHandle;
  141. }
  142.  
  143. const wchar_t *MUTEXNAME = L"mtxsscont";
  144.  
  145. int main(int argc, char *argv[]) {
  146.     _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
  147.     _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
  148.     _NtQueryObject NtQueryObject = (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
  149.     PSYSTEM_HANDLE_INFORMATION handleInfo;
  150.     ULONG handleInfoSize = 0x10000;
  151.     NTSTATUS status;
  152.     HANDLE hProcess;
  153.     HANDLE hMutex;
  154.     DWORD pid;
  155.     ULONG i;
  156.  
  157.     PROCESS_INFORMATION procInfo = {0};
  158.     STARTUPINFOA startupInfo = {sizeof(STARTUPINFOA)};
  159.  
  160.     if (argc < 2)
  161.         return 1;
  162.  
  163.     if (!CreateProcessA(argv[1], NULL, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, 0, &startupInfo, &procInfo)) {
  164.         fprintf(stderr, "Error creating process. %d\n", GetLastError());
  165.         return 1;
  166.     }
  167.    
  168.     hProcess = procInfo.hProcess;
  169.     pid = procInfo.dwProcessId;
  170.  
  171.     // Sleep while waiting for mutex to be created
  172.     while (!(hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEXNAME))) Sleep(1);
  173.  
  174.     CloseHandle(hMutex);
  175.    
  176.     // Get process handle for respawned process
  177.     if (!(hProcess = GetProcessHandle(L"Continuum.exe", &pid))) {
  178.         fprintf(stderr, "Error getting Continuum.exe process handle.\n");
  179.         return 1;
  180.     }
  181.    
  182.     handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
  183.  
  184.     /* Why not just query number of handles? */
  185.     while ((status = NtQuerySystemInformation(
  186.             SystemHandleInformation, handleInfo,
  187.             handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
  188.         handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
  189.  
  190.     if (!NT_SUCCESS(status)) {
  191.         fprintf(stderr, "NtQuerySystemInformation() failed.\n");
  192.         return 1;
  193.     }
  194.  
  195.     for (i = 0; i < handleInfo->HandleCount; i++)
  196.     {
  197.         SYSTEM_HANDLE handle = handleInfo->Handles[i];
  198.         POBJECT_TYPE_INFORMATION objectTypeInfo;
  199.         UNICODE_STRING objectName;
  200.         HANDLE dupHandle = NULL;
  201.         PVOID objectNameInfo;
  202.         ULONG returnLength;
  203.  
  204.         if (handle.ProcessId != pid)
  205.             continue;
  206.  
  207.         /* Duplicate the handle so we can query it. */
  208.         if (!NT_SUCCESS(NtDuplicateObject(
  209.             hProcess,
  210.             (HANDLE)handle.Handle,
  211.             GetCurrentProcess(),
  212.             &dupHandle,
  213.             0,
  214.             0,
  215.             0
  216.             )))
  217.         {
  218.        //     fprintf(stderr, "[%#x] Error!\n", handle.Handle);
  219.             continue;
  220.         }
  221.  
  222.         /* Query the object type. */
  223.         objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
  224.         if (!NT_SUCCESS(NtQueryObject(
  225.             dupHandle,
  226.             ObjectTypeInformation,
  227.             objectTypeInfo,
  228.             0x1000,
  229.             NULL
  230.             )))
  231.         {
  232.            // fprintf(stderr, "[%#x] Error!\n", handle.Handle);
  233.             CloseHandle(dupHandle);
  234.             continue;
  235.         }
  236.  
  237.         /* Query the object name (unless it has an access of
  238.            0x0012019f, on which NtQueryObject could hang. */
  239.         if (handle.GrantedAccess == 0x0012019f)
  240.         {
  241.             /* We have the type, so display that. */
  242.        /*     printf(
  243.                 "[%#x] %.*S: (did not get name)\n",
  244.                 handle.Handle,
  245.                 objectTypeInfo->Name.Length / 2,
  246.                 objectTypeInfo->Name.Buffer
  247.                 );*/
  248.             free(objectTypeInfo);
  249.             CloseHandle(dupHandle);
  250.             continue;
  251.         }
  252.  
  253.         objectNameInfo = malloc(0x1000);
  254.         if (!NT_SUCCESS(NtQueryObject(
  255.             dupHandle,
  256.             ObjectNameInformation,
  257.             objectNameInfo,
  258.             0x1000,
  259.             &returnLength
  260.             )))
  261.         {
  262.             /* Reallocate the buffer and try again. */
  263.             objectNameInfo = realloc(objectNameInfo, returnLength);
  264.             if (!NT_SUCCESS(NtQueryObject(
  265.                 dupHandle,
  266.                 ObjectNameInformation,
  267.                 objectNameInfo,
  268.                 returnLength,
  269.                 NULL
  270.                 )))
  271.             {
  272.                 /* We have the type name, so just display that. */
  273.          /*       printf(
  274.                     "[%#x] %.*S: (could not get name)\n",
  275.                     handle.Handle,
  276.                     objectTypeInfo->Name.Length / 2,
  277.                     objectTypeInfo->Name.Buffer
  278.                     );*/
  279.                 free(objectTypeInfo);
  280.                 free(objectNameInfo);
  281.                 CloseHandle(dupHandle);
  282.                 continue;
  283.             }
  284.         }
  285.  
  286.         /* Cast our buffer into an UNICODE_STRING. */
  287.         objectName = *(PUNICODE_STRING)objectNameInfo;
  288.  
  289.         /* Print the information! */
  290.         if (objectName.Length)
  291.         {
  292.             /* The object has a name. */
  293.        /*     printf(
  294.                 "[%#x] %.*S: %.*S\n",
  295.                 handle.Handle,
  296.                 objectTypeInfo->Name.Length / 2,
  297.                 objectTypeInfo->Name.Buffer,
  298.                 objectName.Length / 2,
  299.                 objectName.Buffer
  300.                 );
  301.         */     
  302.             if (wcsstr(objectName.Buffer, MUTEXNAME) != NULL) {
  303.                 printf("Closing mutex.\n");
  304.                 DuplicateHandle(hProcess, (HANDLE)handle.Handle, NULL, NULL, 0, FALSE, 1);
  305.             }
  306.         }
  307.  
  308.         free(objectTypeInfo);
  309.         free(objectNameInfo);
  310.         CloseHandle(dupHandle);
  311.     }
  312.  
  313.     free(handleInfo);
  314.     CloseHandle(hProcess);
  315.  
  316.     return 0;
  317. }
Advertisement
Add Comment
Please, Sign In to add comment