Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* http://forum.sysinternals.com/topic18892.html */
- #ifndef UNICODE
- #define UNICODE
- #endif
- #include <windows.h>
- #include <stdio.h>
- #include <TlHelp32.h>
- #ifndef NTAPI
- #define NTAPI __stdcall
- #endif
- #ifndef NTSTATUS
- #define NTSTATUS LONG
- #endif
- #define NT_SUCCESS(x) ((x) >= 0)
- #define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
- #define SystemHandleInformation 16
- #define ObjectBasicInformation 0
- #define ObjectNameInformation 1
- #define ObjectTypeInformation 2
- typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
- ULONG SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength);
- typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
- HANDLE SourceProcessHandle,
- HANDLE SourceHandle,
- HANDLE TargetProcessHandle,
- PHANDLE TargetHandle,
- ACCESS_MASK DesiredAccess,
- ULONG Attributes,
- ULONG Options
- );
- typedef NTSTATUS (NTAPI *_NtQueryObject)(
- HANDLE ObjectHandle,
- ULONG ObjectInformationClass,
- PVOID ObjectInformation,
- ULONG ObjectInformationLength,
- PULONG ReturnLength
- );
- typedef struct _UNICODE_STRING
- {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
- } UNICODE_STRING, *PUNICODE_STRING;
- typedef struct _SYSTEM_HANDLE
- {
- ULONG ProcessId;
- BYTE ObjectTypeNumber;
- BYTE Flags;
- USHORT Handle;
- PVOID Object;
- ACCESS_MASK GrantedAccess;
- } SYSTEM_HANDLE, *PSYSTEM_HANDLE;
- typedef struct _SYSTEM_HANDLE_INFORMATION
- {
- ULONG HandleCount;
- SYSTEM_HANDLE Handles[1];
- } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
- typedef enum _POOL_TYPE
- {
- NonPagedPool,
- PagedPool,
- NonPagedPoolMustSucceed,
- DontUseThisType,
- NonPagedPoolCacheAligned,
- PagedPoolCacheAligned,
- NonPagedPoolCacheAlignedMustS
- } POOL_TYPE, *PPOOL_TYPE;
- typedef struct _OBJECT_TYPE_INFORMATION
- {
- UNICODE_STRING Name;
- ULONG TotalNumberOfObjects;
- ULONG TotalNumberOfHandles;
- ULONG TotalPagedPoolUsage;
- ULONG TotalNonPagedPoolUsage;
- ULONG TotalNamePoolUsage;
- ULONG TotalHandleTableUsage;
- ULONG HighWaterNumberOfObjects;
- ULONG HighWaterNumberOfHandles;
- ULONG HighWaterPagedPoolUsage;
- ULONG HighWaterNonPagedPoolUsage;
- ULONG HighWaterNamePoolUsage;
- ULONG HighWaterHandleTableUsage;
- ULONG InvalidAttributes;
- GENERIC_MAPPING GenericMapping;
- ULONG ValidAccess;
- BOOLEAN SecurityRequired;
- BOOLEAN MaintainHandleCount;
- USHORT MaintainTypeList;
- POOL_TYPE PoolType;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
- } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
- PVOID GetLibraryProcAddress(LPSTR LibraryName, LPSTR ProcName);
- PVOID GetLibraryProcAddress(LPSTR LibraryName, LPSTR ProcName) {
- return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
- }
- HANDLE GetProcessHandle(LPWSTR exeName, DWORD *pid) {
- HANDLE pHandle = NULL;
- PROCESSENTRY32 pe32;
- HANDLE hProcSnap;
- if ((hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
- return NULL;
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (!Process32First(hProcSnap, &pe32)) {
- CloseHandle(hProcSnap);
- return NULL;
- }
- do {
- if (wcscmp(pe32.szExeFile, exeName) == 0) {
- *pid = pe32.th32ProcessID;
- }
- } while (Process32Next(hProcSnap, &pe32));
- pHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, *pid);
- return pHandle;
- }
- const wchar_t *MUTEXNAME = L"mtxsscont";
- int main(int argc, char *argv[]) {
- _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
- _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
- _NtQueryObject NtQueryObject = (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
- PSYSTEM_HANDLE_INFORMATION handleInfo;
- ULONG handleInfoSize = 0x10000;
- NTSTATUS status;
- HANDLE hProcess;
- HANDLE hMutex;
- DWORD pid;
- ULONG i;
- PROCESS_INFORMATION procInfo = {0};
- STARTUPINFOA startupInfo = {sizeof(STARTUPINFOA)};
- if (argc < 2)
- return 1;
- if (!CreateProcessA(argv[1], NULL, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, 0, &startupInfo, &procInfo)) {
- fprintf(stderr, "Error creating process. %d\n", GetLastError());
- return 1;
- }
- hProcess = procInfo.hProcess;
- pid = procInfo.dwProcessId;
- // Sleep while waiting for mutex to be created
- while (!(hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEXNAME))) Sleep(1);
- CloseHandle(hMutex);
- // Get process handle for respawned process
- if (!(hProcess = GetProcessHandle(L"Continuum.exe", &pid))) {
- fprintf(stderr, "Error getting Continuum.exe process handle.\n");
- return 1;
- }
- handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
- /* Why not just query number of handles? */
- while ((status = NtQuerySystemInformation(
- SystemHandleInformation, handleInfo,
- handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
- handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
- if (!NT_SUCCESS(status)) {
- fprintf(stderr, "NtQuerySystemInformation() failed.\n");
- return 1;
- }
- for (i = 0; i < handleInfo->HandleCount; i++)
- {
- SYSTEM_HANDLE handle = handleInfo->Handles[i];
- POBJECT_TYPE_INFORMATION objectTypeInfo;
- UNICODE_STRING objectName;
- HANDLE dupHandle = NULL;
- PVOID objectNameInfo;
- ULONG returnLength;
- if (handle.ProcessId != pid)
- continue;
- /* Duplicate the handle so we can query it. */
- if (!NT_SUCCESS(NtDuplicateObject(
- hProcess,
- (HANDLE)handle.Handle,
- GetCurrentProcess(),
- &dupHandle,
- 0,
- 0,
- 0
- )))
- {
- // fprintf(stderr, "[%#x] Error!\n", handle.Handle);
- continue;
- }
- /* Query the object type. */
- objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
- if (!NT_SUCCESS(NtQueryObject(
- dupHandle,
- ObjectTypeInformation,
- objectTypeInfo,
- 0x1000,
- NULL
- )))
- {
- // fprintf(stderr, "[%#x] Error!\n", handle.Handle);
- CloseHandle(dupHandle);
- continue;
- }
- /* Query the object name (unless it has an access of
- 0x0012019f, on which NtQueryObject could hang. */
- if (handle.GrantedAccess == 0x0012019f)
- {
- /* We have the type, so display that. */
- /* printf(
- "[%#x] %.*S: (did not get name)\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer
- );*/
- free(objectTypeInfo);
- CloseHandle(dupHandle);
- continue;
- }
- objectNameInfo = malloc(0x1000);
- if (!NT_SUCCESS(NtQueryObject(
- dupHandle,
- ObjectNameInformation,
- objectNameInfo,
- 0x1000,
- &returnLength
- )))
- {
- /* Reallocate the buffer and try again. */
- objectNameInfo = realloc(objectNameInfo, returnLength);
- if (!NT_SUCCESS(NtQueryObject(
- dupHandle,
- ObjectNameInformation,
- objectNameInfo,
- returnLength,
- NULL
- )))
- {
- /* We have the type name, so just display that. */
- /* printf(
- "[%#x] %.*S: (could not get name)\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer
- );*/
- free(objectTypeInfo);
- free(objectNameInfo);
- CloseHandle(dupHandle);
- continue;
- }
- }
- /* Cast our buffer into an UNICODE_STRING. */
- objectName = *(PUNICODE_STRING)objectNameInfo;
- /* Print the information! */
- if (objectName.Length)
- {
- /* The object has a name. */
- /* printf(
- "[%#x] %.*S: %.*S\n",
- handle.Handle,
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer,
- objectName.Length / 2,
- objectName.Buffer
- );
- */
- if (wcsstr(objectName.Buffer, MUTEXNAME) != NULL) {
- printf("Closing mutex.\n");
- DuplicateHandle(hProcess, (HANDLE)handle.Handle, NULL, NULL, 0, FALSE, 1);
- }
- }
- free(objectTypeInfo);
- free(objectNameInfo);
- CloseHandle(dupHandle);
- }
- free(handleInfo);
- CloseHandle(hProcess);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment