Здравствуйте уважаемые. Каким образом я могу перечислить все существующие Mutex'ы в системе? Спасибо за внимание.
sideX NtQuerySystemInformation с флагом перечисления описателей. Потом поиск по массиву объектов с соответствующим ID.
o NtQueryObject(ObjectAllTypesInformation) o Находите там описатель типа "Mutant" по имени. Индекс описателя является индексом типа. o Получаете слепок(для описателей SystemHandleInformation, для обьектов SystemObjectInformation), енумите его и сравниваете индекс типа с полученным.
Чтото я не очень понял с NtQuerySystemInformation.. вот код: Код (Text): ... SYSTEM_HANDLE_INFORMATION struct ProcessId DWORD ? ObjectTypeNumber BYTE ? Flags BYTE ? Handle DWORD ? Object DWORD ? GrantedAccess DWORD ? SYSTEM_HANDLE_INFORMATION ends SYSTEM_HANDLE_INFORMATION_EX STRUCT NumberOfHandles DWORD ? Information SYSTEM_HANDLE_INFORMATION 1 dup (<>) SYSTEM_HANDLE_INFORMATION_EX ENDS ... GetMutexData proc uses edi LOCAL lpSysInfo : DWORD mov lpSysInfo, 0 xinvoke ZwQuerySystemInformation, 16, 0, 0, offset dwBytes cmp eax, 0C0000004h ; STATUS_INFO_LENGTH_MISMATCH jnz _done @@: add dwBytes, 1000h .IF (lpSysInfo != 0) invoke LocalFree, lpSysInfo .ENDIF invoke LocalAlloc, LPTR, dwBytes mov lpSysInfo, eax xinvoke ZwQuerySystemInformation, 16, lpSysInfo, dwBytes, 0 cmp eax, 0C0000004h ; STATUS_INFO_LENGTH_MISMATCH jz @B _done: mov edi, lpSysInfo assume edi : ptr SYSTEM_HANDLE_INFORMATION_EX mov ecx, [edi].NumberOfHandles ; кол-во хендлов add edi, 4 assume edi : ptr SYSTEM_HANDLE_INFORMATION xor edx, edx .WHILE (edx <= ecx) mov eax, [edi].ProcessId inc edx add edi, sizeof SYSTEM_HANDLE_INFORMATION .ENDW invoke LocalFree, lpSysInfo ret GetMutexData endp я неправильно обрабатываю список, т.к. в Код (Text): mov eax, [edi].ProcessId после второго и далее вызовов в еах неправильные данные. никто не подскажет где ошибся?
sideX У этой структуры размер 16 байт: Код (Text): typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
еще небольшой вопрос. SYSTEM_HANDLE_INFORMATION.ObjectTypeNumber для мьютекса всегда = 0Bh? для любой версии ОС?
вы будете смеяться, но я снова зашол в тупик.. делаю так: Код (Text): xor ebx, ebx mov bx, word ptr [edi].Handle xinvoke ZwQueryObject, ebx, 3, 0, 0, offset dwBytes .IF (eax == 0C0000004h) invoke LocalAlloc, LPTR, dwBytes mov lpObjectName, eax xinvoke ZwQueryObject, ebx, 3, lpObjectName, dwBytes, offset dwBytes .IF (eax == 0) push edi mov edi, lpObjectName assume edi : ptr OBJECT_ALL_INFORMATION mov ecx, [edi].NumberOfObjectsTypes add edi, 4 assume edi : ptr OBJECT_TYPE_INFORMATION xor edx, edx .WHILE (edx <= ecx) lea eax, [edi]._Name assume eax : ptr UNICODE_STRING mov esi, [eax].Buffer invoke MessageBoxW,0,esi,esi,0 inc edx add edi, sizeof OBJECT_TYPE_INFORMATION .ENDW pop edi .ENDIF invoke LocalFree, lpObjectName .ENDIF в итоге в мессаджбоксе постоянно выводится слово Type
sideX Както так: Код (Text): xCompareStringSensitiveInternal proc uses ebx UnicodeString:PUNICODE_STRING, AnsiString:PSTR, StringLength:ULONG mov ebx,StringLength mov edx,UnicodeString lea eax,[ebx*2] assume edx:PUNICODE_STRING cmp [edx]._Length,ax jne Exit mov ecx,AnsiString mov edx,[edx].Buffer @@: movzx eax,byte ptr [ecx + ebx - 1] cmp word ptr [edx + ebx*2 - 2],ax jne Exit dec ebx jnz @b xor eax,eax Exit: ret xCompareStringSensitiveInternal endp BASE_REGION_SIZE equ 10000H xQueryObject proc uses ebx esi edi ObjectTypeName:PSTR Local SystemInformation:PVOID, SystemInformationLength:ULONG Local ObjectTypeNameLength:ULONG cld xor eax,eax mov ecx,MAX_PATH mov edi,ObjectTypeName repne scasb mov SystemInformationLength,eax not ecx lea edx,SystemInformationLength add ecx,MAX_PATH mov SystemInformation,eax mov ObjectTypeNameLength,ecx invoke ZwQueryObject, Eax, ObjectAllTypesInformation, Eax, Eax, Edx cmp eax,STATUS_INFO_LENGTH_MISMATCH lea ecx,SystemInformationLength lea edx,SystemInformation .if !Zero? ; def. 224 bytes. mov SystemInformationLength,PAGE_SIZE .endif invoke ZwAllocateVirtualMemory, NtCurrentProcess, Edx, 0, Ecx, MEM_COMMIT, PAGE_READWRITE test eax,eax jnz Exit invoke ZwQueryObject, Eax, ObjectAllTypesInformation, SystemInformation, SystemInformationLength, Eax test eax,eax mov edi,SystemInformation jnz Parse mov esi,OBJECT_ALL_TYPES_INFORMATION.NumberOfTypes[edi] mov ebx,esi add edi,4 assume edi:POBJECT_TYPE_INFORMATION @@: invoke xCompareStringSensitiveInternal, Edi, ObjectTypeName, ObjectTypeNameLength movzx ecx,[edi].TypeName._Length je Parse and ecx,NOT(3) mov edi,[edi].TypeName.Buffer lea edi,[edi + ecx + 4] dec esi jnz @b mov eax,STATUS_UNSUCCESSFUL Parse: push eax invoke ZwFreeVirtualMemory, NtCurrentProcess, addr SystemInformation, addr SystemInformationLength, MEM_RELEASE sub ebx,esi ; ID pop eax mov esi,BASE_REGION_SIZE test eax,eax jnz Exit inc ebx NextRegion: mov SystemInformationLength,esi mov SystemInformation,NULL lea ecx,SystemInformationLength lea edx,SystemInformation invoke ZwAllocateVirtualMemory, NtCurrentProcess, Edx, 0, Ecx, MEM_COMMIT, PAGE_READWRITE test eax,eax jnz Exit invoke ZwQuerySystemInformation, SystemHandleInformation, SystemInformation, SystemInformationLength, Eax test eax,eax jz ParseInfo push eax invoke ZwFreeVirtualMemory, NtCurrentProcess, addr SystemInformation, addr SystemInformationLength, MEM_RELEASE pop eax cmp eax,STATUS_INFO_LENGTH_MISMATCH jnz Exit add esi,BASE_REGION_SIZE cmp esi,32*BASE_REGION_SIZE jb NextRegion jmp Exit ParseInfo: mov esi,SystemInformation ; mov ecx,fs:[TEB.Cid.UniqueProcess] mov edi,dword ptr [esi] add esi,4 NextEntry: assume esi:PSYSTEM_HANDLE_INFORMATION ; cmp [esi].ProcessId,ecx ; CreatorBackTraceIndex = NULL(def.) ; jne @f cmp [esi].ObjectTypeNumber,bl jne @f ; ... @@: add esi,sizeof(SYSTEM_HANDLE_INFORMATION) dec edi jnz NextEntry mov eax,STATUS_NOT_FOUND ParseError: push eax invoke ZwFreeVirtualMemory, NtCurrentProcess, addr SystemInformation, addr SystemInformationLength, MEM_RELEASE pop eax Exit: ret xQueryObject endp
пробовал также через OBJECT_NAME_INFORMATION. код: Код (Text): ... OBJECT_NAME_INFORMATION STRUCT _Name UNICODE_STRING <?> OBJECT_NAME_INFORMATION ENDS ... xor ebx, ebx mov bx, word ptr [edi].Handle xinvoke ZwQueryObject, ebx, 3, 0, 0, offset dwBytes .IF (eax == 0C0000004h) invoke LocalAlloc, LPTR, dwBytes mov lpObjectName, eax xinvoke ZwQueryObject, ebx, 1, lpObjectName, dwBytes, offset dwBytes .IF (eax == 0) mov eax, lpObjectName assume eax : ptr OBJECT_NAME_INFORMATION assume eax : ptr UNICODE_STRING lea esi, [eax].Buffer invoke MessageBoxW,0,esi,esi,0 .ENDIF invoke LocalFree, lpObjectName .ENDIF ... в итоге выводит всякий мусор..
а, не. это я там затупил. сделал: Код (Text): mov esi, [eax].Buffer сейчас выводится нормально. правда выводятся не все почемуто. при обработке некоторых элементов в esi оказывается 0, хотя Process Explorer показывает что нужный мне хендл имеет имя (это конкретный мьютекс на котором тестирую). почему так происходит - не могу понять
Кстате у вас будут траблы в выравниванием имён. Используйте способ как у меня: Код (Text): movzx ecx,[edi].TypeName._Length and ecx,NOT(3) mov edi,[edi].TypeName.Buffer lea edi,[edi + ecx + 4]
вобщем все получилось. если кому интересно: Код (Text): ;################################################################################################################ ; FindMutexByPID - поиск полного имени мьютекса указанного процесса по имени или его части ; IN: dwPID - ID процесса ; szMutexName - имя мьютекса или его часть ; lpOutMutex - буфер для полного имени мьютекса ; OUT: возвращает длину имени мьютекса или 0 в случае неудачи ;################################################################################################################ FindMutexByPID proc uses edi dwPID, szMutexName, lpOutMutex : DWORD LOCAL lpSysInfo : DWORD LOCAL lpObjectName : DWORD LOCAL hProcess : DWORD LOCAL hDuplicate : DWORD xor ebx, ebx xinvoke OpenProcess, PROCESS_DUP_HANDLE, 0, dwPID test eax, eax jz _return mov hProcess, eax mov lpSysInfo, 0 xinvoke ZwQuerySystemInformation, 16, 0, 0, offset dwBytes cmp eax, 0C0000004h ; STATUS_INFO_LENGTH_MISMATCH jnz _enum_handles @@: add dwBytes, 1000h .IF (lpSysInfo != 0) invoke LocalFree, lpSysInfo .ENDIF invoke LocalAlloc, LPTR, dwBytes mov lpSysInfo, eax xinvoke ZwQuerySystemInformation, 16, lpSysInfo, dwBytes, 0 cmp eax, 0C0000004h ; STATUS_INFO_LENGTH_MISMATCH jz @B _enum_handles: mov edi, lpSysInfo assume edi : ptr SYSTEM_HANDLE_INFORMATION_EX mov ecx, [edi].NumberOfHandles ; кол-во хендлов add edi, 4 assume edi : ptr SYSTEM_HANDLE_INFORMATION xor edx, edx .WHILE (edx <= ecx) mov eax, [edi].ProcessId .IF (eax == dwPID) push edx push ecx push edi xor ebx, ebx mov bx, word ptr [edi].Handle lea eax, hDuplicate xinvoke ZwDuplicateObject, hProcess, ebx, 0FFFFFFFFh, eax, 0, 0, 0 .IF (eax == 0) xinvoke ZwQueryObject, hDuplicate, 1, 0, 0, offset dwBytes .IF (eax == 0C0000004h) invoke LocalAlloc, LPTR, dwBytes mov lpObjectName, eax xinvoke ZwQueryObject, hDuplicate, 1, lpObjectName, dwBytes, offset dwBytes .IF (eax == 0) mov eax, lpObjectName assume eax : ptr OBJECT_NAME_INFORMATION assume eax : ptr UNICODE_STRING mov esi, [eax].Buffer .IF (esi != 0) mov edi, lpOutMutex @@: lodsw test ax, ax jz @F stosb loop @B @@: stosb invoke StringPos, 0, lpOutMutex, szMutexName inc eax .IF (eax != 0) invoke StrLength, lpOutMutex xchg ebx, eax jmp _done .ENDIF .ENDIF .ENDIF invoke LocalFree, lpObjectName .ENDIF invoke CloseHandle, hDuplicate .ENDIF pop edi pop ecx pop edx .ENDIF inc edx add edi, 16 .ENDW xor ebx, ebx _done: invoke LocalFree, lpSysInfo invoke CloseHandle, hProcess _return: xchg ebx, eax ret FindMutexByPID endp
при преобразовании WideString -> AnsiString лучше сделать так: Код (Text): ... assume eax : ptr UNICODE_STRING mov esi, [eax].Buffer ; строка ... xor ecx, ecx mov cx, word ptr [eax] shr ecx, 1 ; размер / 2 mov edi, lpOutMutex @@: lodsw stosb loop @B xchg al, ah ; завершающий 0 stosb
Clerk Код (Text): movzx ecx,[edi].TypeName._Length and ecx,NOT(3) mov edi,[edi].TypeName.Buffer lea edi,[edi + ecx + 4] Формально этот код содержит баг. Необходимыми условиями для верной отработки становятся выравненность значения TypeName.Buffer на 4 и нуль-терминированность строки ровно одним символом. Окей, может быть эти условия и выполняются всегда, но при чтении кода возникает диссонанс.