Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Кто изменил реестр?


Автор: pseudor 22.5.2007, 15:32
Пишу утилитку, которая висит в виде сервиса и проверяет, кто, когда и какие приложения устанавливал/удалял. Я использовал Msi.lib, а теперь добавил проверку чтением списка из подключа SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall - если событие было, а список, полученный от MSI, не изменился - самое время читать реестр. Теперь одна проблема у меня, наверное, самая крупная - это как определить, какой пользователь производит установку/удаление, основываясь на том факте, что в результате его действий были внесены изменения в реестр?

Автор: SenkraD 22.5.2007, 15:49
Вот несколько скорых вариантов:
1. Читать системный журнал событий
2. Ловить обращения к реестру, а также определять текущего юзверя и писать это дело в свой лог

Автор: pseudor 22.5.2007, 15:55
С этого места, пожалуйста, подробнее про первый вариант.
Во втором мне помогут хуки. А как определить текущего пользователя? Не того, от имени которого запущена моя утилитка. А если этот пользователь работает с помощью удалённого терминала?  smile 

Автор: SenkraD 22.5.2007, 16:17
Цитата(pseudor @  22.5.2007,  15:55 Найти цитируемый пост)
А если этот пользователь работает с помощью удалённого терминала?

 в любом случае это будет текущий юзер, кажись. 

А на счёт прочитки сислога? Вот пример с MSDN:
Код

#include <windows.h>
#include <stdio.h>

#define BUFFER_SIZE 1024*64

void DisplayEntries( )
{
    HANDLE h;
    EVENTLOGRECORD *pevlr; 
    BYTE bBuffer[BUFFER_SIZE]; 
    DWORD dwRead, dwNeeded, dwThisRecord; 
 
    // Open the Application event log. 
 
    h = OpenEventLog( NULL,    // use local computer
             "Application");   // source name
    if (h == NULL) 
    {
        printf("Could not open the Application event log."); 
        return;
    }
 
    pevlr = (EVENTLOGRECORD *) &bBuffer; 
 
    // Get the record number of the oldest event log record.

    GetOldestEventLogRecord(h, &dwThisRecord);

    // Opening the event log positions the file pointer for this 
    // handle at the beginning of the log. Read the event log records 
    // sequentially until the last record has been read. 
 
    while (ReadEventLog(h,                // event log handle 
                EVENTLOG_FORWARDS_READ |  // reads forward 
                EVENTLOG_SEQUENTIAL_READ, // sequential read 
                0,            // ignored for sequential reads 
                pevlr,        // pointer to buffer 
                BUFFER_SIZE,  // size of buffer 
                &dwRead,      // number of bytes read 
                &dwNeeded))   // bytes in next record 
    {
        while (dwRead > 0) 
        { 
            // Print the record number, event identifier, type, 
            // and source name. 
 
            printf("%03d  Event ID: 0x%08X  Event type: ", 
                dwThisRecord++, pevlr->EventID); 

            switch(pevlr->EventType)
            {
                case EVENTLOG_ERROR_TYPE:
                    printf("EVENTLOG_ERROR_TYPE\t  ");
                    break;
                case EVENTLOG_WARNING_TYPE:
                    printf("EVENTLOG_WARNING_TYPE\t  ");
                    break;
                case EVENTLOG_INFORMATION_TYPE:
                    printf("EVENTLOG_INFORMATION_TYPE  ");
                    break;
                case EVENTLOG_AUDIT_SUCCESS:
                    printf("EVENTLOG_AUDIT_SUCCESS\t  ");
                    break;
                case EVENTLOG_AUDIT_FAILURE:
                    printf("EVENTLOG_AUDIT_FAILURE\t  ");
                    break;
                default:
                    printf("Unknown ");
                    break;
            }

            printf("Event source: %s\n", 
                (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD))); 
 
            dwRead -= pevlr->Length; 
            pevlr = (EVENTLOGRECORD *) 
                ((LPBYTE) pevlr + pevlr->Length); 
        } 
 
        pevlr = (EVENTLOGRECORD *) &bBuffer; 
    } 
 
    CloseEventLog(h); 
}




Автор: pseudor 22.5.2007, 16:54
Извините, а виндовая утилита Программы-Администрирование-Просмотр_событий читает весь журнал? Если да - то тогда такое решение не подходит - записи об установке без использования MSI туда не попали.

Автор: SenkraD 22.5.2007, 16:57
Цитата(pseudor @  22.5.2007,  16:54 Найти цитируемый пост)
Извините, а виндовая утилита Программы-Администрирование-Просмотр_событий читает весь журнал?

На сколько я знаю, то да.

Тогда получается только через хуки.

Автор: Smarts 22.5.2007, 18:27
Есть подобная утилита под названием RegMon, и более новая - Process Monitor: http://www.microsoft.com/technet/sysinternals/ProcessesAndThreads/processmonitor.mspx
посмотри как они работают, тебе надо просто перехватить все функции реестра и добавлять в лог при каждом вызове

Автор: pseudor 23.5.2007, 09:32
Так события изменения уже отлавливаются, проблема в определении имени пользователя, который производил установку/удаление.

Автор: pseudor 23.5.2007, 12:13
Пойду таким путём - буду использовать хук на RegCreateKey и RegDeleteKey, в котором буду определять вызвавшего пользователя, если эти функции будут относиться к SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall.

Если есть какие-то напутствия - очень буду рад услышать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)