получение информации о процессе

Тема в разделе "WASM.NT.KERNEL", создана пользователем rpy3uH, 10 окт 2010.

  1. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    Меня интересует получение полного пути к имени исполняемого файла процесса. Мне не надо знать как его получить, мне надо знать какой вариант наиболее оптимальный. Я знаю два варианта получения имени файла процесса
    1. Используя функцию PsGetProcessImageFileName() мы получим указатель на ANSI строку
    2. Используя ZwQueryInformationProcess(ProcessImageFileName) мы получим UNICODE строку
    3. Ещё вариант получить имя через PEB (ZwQueryInformationProcess) но я думаю это не вариант
    Почитал WDK там нет описания ни одной из этих функций. Именно это меня и смутило
    Допустим у меня есть EPROCESS, какой наиболее правильный метод получения имени файла? Чтобы работало на XP/Vista/Se7en
     
  2. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    Можно так (vista,7,xp проверялось)
    EPROCESS.SeAuditProcessCreationInfo->Name.Buffer (нужно прописать смещение SeAuditProcessCreationInfo). Там нормализованное имя, по желанию можно преобразовать в другой формат.
     
  3. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    Лазить в недокументированных структурах вместо использования недокументированных функций это шило на мыло
     
  4. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Да ну?
    ZwQueryInformationProcess().
    До Vista эта функция возвращает путь только в Native-формате.
    Начиная с Vista есть ещё класс ProcessImageFileNameWin32, на выходе путь в DOS-формате.
    Я сам использую другой способ, но думаю тебе хватит и этого, попробуй, если всё таки не - пиши, подскажу.
     
  5. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    Но тамже красным цветом написано
    это меня и смутило

    функцию ZwQueryInformationProcess я рассматривал как наиболее приемлемый вариант
     
  6. rpy3uH

    rpy3uH New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    503
    для повышения собственной образованности
    а где узнать смещение элемента SeAuditProcessCreationInfo и смещение элемента Name в ней?
     
  7. AES256

    AES256 New Member

    Публикаций:
    0
    Регистрация:
    23 авг 2010
    Сообщения:
    15
    Вот мой вариант с PEB-ом, если что
    Код (Text):
    1. #ifdef _X86_
    2. #define PEB_PROCESS_PARAMS_OFFSET           0x10
    3. #define PROCESS_PARAMS_FLAGS_OFFSET         0x08
    4. #define PROCESS_PARAMS_IMAGE_NAME_OFFSET    0x38
    5. #elif _AMD64_
    6. #define PEB_PROCESS_PARAMS_OFFSET           0x20
    7. #define PROCESS_PARAMS_FLAGS_OFFSET         0x08
    8. #define PROCESS_PARAMS_IMAGE_NAME_OFFSET    0x60
    9. #endif
    10.  
    11. #define PROCESS_PARAMETERS_NORMALIZED   1   // pointers are absolute (not self-relative)
    12.  
    13. BOOLEAN GetProcessFullImagePath(PEPROCESS Process, PUNICODE_STRING ImagePath)
    14. {
    15.     BOOLEAN bRet = FALSE;
    16.     HANDLE hProcess = NULL;
    17.    
    18.     // get handle to target process
    19.     NTSTATUS ns = ObOpenObjectByPointer(
    20.         Process,
    21.         OBJ_KERNEL_HANDLE,
    22.         NULL,
    23.         0,
    24.         NULL,
    25.         KernelMode,
    26.         &hProcess
    27.     );
    28.     if (NT_SUCCESS(ns))
    29.     {
    30.         PROCESS_BASIC_INFORMATION ProcessInfo;    
    31.  
    32.         // get address of PEB
    33.         ns = ZwQueryInformationProcess(
    34.             hProcess,
    35.             ProcessBasicInformation,
    36.             &ProcessInfo,
    37.             sizeof(ProcessInfo),
    38.             NULL
    39.         );
    40.         if (NT_SUCCESS(ns))
    41.         {
    42.             KAPC_STATE ApcState;
    43.  
    44.             // change context to target process
    45.             KeStackAttachProcess(Process, &ApcState);
    46.  
    47.             __try
    48.             {
    49.                 PUCHAR Peb = (PUCHAR)ProcessInfo.PebBaseAddress;
    50.                 if (Peb)
    51.                 {
    52.                     // get pointer to RTL_USER_PROCESS_PARAMETERS
    53.                     PUCHAR ProcessParams = *(PUCHAR *)(Peb + PEB_PROCESS_PARAMS_OFFSET);
    54.                     if (ProcessParams)
    55.                     {
    56.                         // get image path
    57.                         PUNICODE_STRING ImagePathName = (PUNICODE_STRING)
    58.                             (ProcessParams + PROCESS_PARAMS_IMAGE_NAME_OFFSET);
    59.  
    60.                         if (ImagePathName->Buffer && ImagePathName->Length > 0)
    61.                         {
    62.                             // allocate string
    63.                             if (AllocUnicodeString(ImagePath, ImagePathName->Length))
    64.                             {
    65.                                 PWSTR lpwcName = NULL;
    66.                                 ULONG Flags = *(PULONG)(ProcessParams + PROCESS_PARAMS_FLAGS_OFFSET);
    67.  
    68.                                 if (Flags & PROCESS_PARAMETERS_NORMALIZED)
    69.                                 {
    70.                                     // pointer to buffer is absolute address
    71.                                     lpwcName = ImagePathName->Buffer;
    72.                                 }
    73.                                 else
    74.                                 {
    75.                                     // pointer to buffer is relative address
    76.                                     lpwcName = (PWSTR)(ProcessParams + (ULONGLONG)ImagePathName->Buffer);
    77.                                 }
    78.  
    79.                                 if (AppendUnicodeToString(ImagePath, lpwcName, ImagePathName->Length))
    80.                                 {
    81.                                     bRet = TRUE;
    82.                                 }
    83.                                 else
    84.                                 {
    85.                                     DbgMsg(__FILE__, __LINE__, "AppendUnicodeToString() ERROR\n");
    86.                                 }
    87.                             }
    88.                             else
    89.                             {
    90.                                 DbgMsg(__FILE__, __LINE__, "AllocUnicodeString() ERROR\n");
    91.                             }
    92.                         }
    93.                     }
    94.                 }
    95.             }
    96.             __except (EXCEPTION_EXECUTE_HANDLER)
    97.             {
    98.                 DbgMsg(__FILE__, __LINE__, __FUNCTION__"() EXCEPTION\n");
    99.             }
    100.            
    101.             KeUnstackDetachProcess(&ApcState);
    102.         }
    103.         else
    104.         {
    105.             // Can't query information about process, probably 'System' or rootkit activity
    106.         }        
    107.  
    108.         ZwClose(hProcess);
    109.     }
    110.     else
    111.     {
    112.         DbgMsg(__FILE__, __LINE__, "ObOpenObjectByPointer() fails; status: 0x%.8x\n", ns);
    113.     }
    114.  
    115.     return bRet;
    116. }
     
  8. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    >>а где узнать смещение элемента SeAuditProcessCreationInfo и смещение элемента Name в ней?

    В windbg

    dt _EPROCESS. Там и будет смещение. А в структуре SE_AUDIT_PROCESS_CREATION_INFO содержиться только указатель на документированную OBJECT_NAME_INFORMATION, поэтому нужно всего 1 смещение.
     
  9. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    eprocess->sectionObject->segment->controlArea->filePointer
     
  10. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    В данном случае можно не обращать внимания, вплоть до Windows 7 оно работает.

    Да, только я ещё раз напоминаю, что эта функция до Vista умеет возвращать только путь в Native-формате, т.е. например, \Device\HarddiskVolume1\Windows\Notepad.exe. Чтобы получить букву диска, придётся приложить некоторые усилия, чтобы распарсить полученную строку. Кроме того, я не гарантирую, что полученный путь не будет содержать символьных ссылок. Это, конечно, маловероятно, но всё таки. Плюс заморочки с сетевыми путями тоже могут иметь место. Но тут смотри сам, если устраивает такой вариант - используй.
     
  11. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Здравствуйте!
    У меня возникла похожая проблема - никак не могу найти решения...
    Используя ZwQueryInformationProcess(ProcessImageFileName) мы получим UNICODE строку - выдает "???????"...
    Пробуя другие варианты, найденные в сети - получаю либо короткое имя (notepad.exe), либо BSOD :). Некоторый код не получается скомпилить (правда, может быть, косяк в том, что стоит старая ntddk (многие структуры в найденных кодах есть в ntifs (не знаю откуда скачанном), если подключить этот ntifs, при подключенном ntddk, получаем следующее:
    driver.c(39) : error C2040: 'KeServiceDescriptorTable' : 'struct sdt ' differs in levels of indirection from 'struct _SERVICE_DESCRIPTOR_TABLE *'
    Здесь я делаю перехваты функций - не компилится... Если же выдергивать просто объявление структур из ntifs - слишком много ссылок на другие структуры (толком нельзя разобрать все связи) - и опять не компилится... Может это проблема из-за использования старой ntddk? Пока проверить не могу - wdk стоит только дома.
    Вот такой код работает, но выдает только имя, без пути:
    Код (Text):
    1. void GetCurrentProcessName(CHAR *name)
    2. {
    3.     PEPROCESS   proc;
    4.     char        *ptr;
    5.  
    6.     if( ProcessNameOffset )
    7.     {
    8.         proc = PsGetCurrentProcess();
    9.         ptr = (PCHAR) proc + ProcessNameOffset;
    10.         strcpy( name, ptr);
    11.     }
    12.     else
    13.     {
    14.         strcpy(name,"(unknown process)");
    15.     }
    16. }
    Кто сможет помочь разобраться - буду очень благодарен.
     
  12. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Не должно быть такого, код показывай.
     
  13. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    x64
    Многое перепробовал, нашел вроде вариант, который толком собирается :), но теперь пишет путь: (null).
    Код:
    Код (Text):
    1. #define MAX_BUFFER_SZ 1024
    2.  
    3. NTSYSAPI
    4. NTSTATUS
    5. NTAPI
    6. ZwOpenProcess (
    7.     OUT PHANDLE             ProcessHandle,
    8.     IN ACCESS_MASK          DesiredAccess,
    9.     IN POBJECT_ATTRIBUTES   ObjectAttributes,
    10.     IN PCLIENT_ID           ClientId OPTIONAL
    11. );
    12. NTSYSAPI
    13. NTSTATUS
    14. NTAPI
    15. ZwQueryInformationProcess (
    16.     IN HANDLE           ProcessHandle,
    17.     IN PROCESSINFOCLASS ProcessInformationClass,
    18.     OUT PVOID           ProcessInformation,
    19.     IN ULONG            ProcessInformationLength,
    20.     OUT PULONG          ReturnLength OPTIONAL
    21. );
    22. ...
    23. void
    24.     GetCurrentProcessName
    25.     (
    26.         CHAR *name
    27.     )
    28. {
    29.     NTSTATUS Status=STATUS_SUCCESS;
    30.     ULONG retLen;
    31.     PVOID buf=NULL;
    32.     CLIENT_ID clientId;
    33.     OBJECT_ATTRIBUTES objAttr;
    34.     HANDLE hProcess = NULL;
    35.  
    36.     clientId.UniqueProcess = PsGetCurrentProcessId();
    37.     clientId.UniqueThread = NULL;
    38.  
    39.     InitializeObjectAttributes(
    40.         &objAttr,
    41.         NULL,
    42.         0,
    43.         NULL,
    44.         NULL);
    45.     Status = ZwOpenProcess(
    46.                 &hProcess,
    47.                 PROCESS_ALL_ACCESS,
    48.                 &objAttr,
    49.                 &clientId);
    50.  
    51.     if( !NT_SUCCESS(Status) )
    52.     {
    53.         DbgPrint(("ZwOpenProcess failed\n"));
    54.         return Status;
    55.     }
    56.     Status = ZwQueryInformationProcess( hProcess,
    57.                                         ProcessImageFileName,
    58.                                         buf,
    59.                                         MAX_BUFFER_SZ * sizeof (WCHAR),
    60.                                         &retLen);
    61.     DbgPrint("Test path: %s", buf);
    62.     if( !NT_SUCCESS(Status) )
    63.     {
    64.         ZwClose(hProcess);
    65.         return 0;
    66.     }
    67.  
    68.     ZwClose(hProcess);
    69.     return 0;
    70. }
    Что я сделал не так?
    Заранее благодарен.
     
  14. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    В buf у тебя будет записана UNICODE_STRING, следовательно, выводить через DbgPrint() надо так:

    Код (Text):
    1. DbgPrint ("Process Image Name = %wZ\r\n", buf);
     
  15. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Спасибо за такой быстрый ответ.
    Теперь выдает вот что:
    Process Image Name = (null)
    Видимо, что-то не так при определении пути (ZwQuery...)
     
  16. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Ты память под буфер не выделяешь вообще, он у тебя NULL как был так и остался. Системные сервисы память, как правило, не выделяют вообще под такие буфера. Правильно сначала вызвать ZwQueryInformationProcess() с 4-ым параметром = 0, тогда в 5-ом параметре получишь необходимый размер буфера. Дальше уже выделяешь буфер этого размера и вызываешь ZwQueryInformationProcess() снова, но теперь уже передаёшь указатель на буфер и его размер.
     
  17. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Есть! Все работает, спасибо!
     
  18. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    rpy3uH
    Внедрить DLL в процесс, получить штатным образом и отправить обратно любым стандартным способом IPC. Недокументятину и прочее хэккерство - ф газенваген.
     
  19. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Внедрение .dll для данной задачи есть ещё больший хак, нежели ZwQueryInformationProcess().

    К счастью, некоторые недокументированные вещи весьма стабильны и в умелых руках опасности не представляют.
     
  20. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    CyberManiac
    Зачем чтото внедрять, если можно просто прочитать из UPP или LDR, изменить там инфу тоже можно.

    Кстате MemorySectionName тоже юзать можно.