Получение имени модуля (а именно: имени exe)

Тема в разделе "WASM.NT.KERNEL", создана пользователем SpiritFire, 22 дек 2008.

  1. SpiritFire

    SpiritFire New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2008
    Сообщения:
    31
    Скажите, пожалуйста, возможло ли из режима ядра получить имя исполняемого файла по его PID-у, или для этого придется возвращаться в режим пользователя?

    Самостоятельно по ядру накопал только об имени процесса в EPROCESS, но даже не понял, зачем оно вообще там нужно, так как с ограничением имени символов в 16 (точно не считал) далеко не уедешь...
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Из PEB или ProcessImageNameInformation (кажется так) для ZwQueryInformationProcess
     
  3. genesis

    genesis New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2006
    Сообщения:
    43
    0. Получить EPROCESS по PID - PsLookupProcessByProcessId
    1. Получить объект секции.
    для хр и далее - SectionObject присутствует в EPROCESS, отличаются только смещения(0x138 для xpsp2 например)
    (для w2k чуть сложнее)
    3. дальше - (для всех кроме висты) - sectionObject->Segment->ControlAreal->FilePointer
     
  4. GMax

    GMax Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    218
    Win2k
    SectionObjectOffset=1ACh
    Win2k3 SP0
    SectionObjectOffset=114h
    Win2k3 SP1
    SectionObjectOffset=124h
    WinVista
    SectionObjectOffset=110h
    WinVista
    sectionObject->Segment->ControlAreal->FilePointer - 8

    P.S. RKU
     
  5. genesis

    genesis New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2006
    Сообщения:
    43
    не, для w2k там его нет вообще. ;) там есть SectionHandle. но он иногда невалидный, (иногда просто равен 4 - очень часто, а иногда - 0x3e8)
     
  6. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Не верно. 0x3F8.

    Код (Text):
    1. typedef struct _CONTROL_AREA {    
    2.     PVOID                       Segment; // 0x00
    3.     LIST_ENTRY                  DereferenceList; // 0x04
    4.     DWORD                       NumberOfSectionReferences; // 0x0c
    5.     DWORD                       NumberOfPfnReferences; // 0x10
    6.     DWORD                       NumberOfMappedViews; // 0x14
    7.     WORD                        NumberOfSubsections; // 0x18
    8.     WORD                        FlushInProgressCount; // 0x1a
    9.     DWORD                       NumberOfUserReferences; // 0x1c
    10.     DWORD                       Flags; // MMSECTION_FLAGS // 0x20
    11.     PFILE_OBJECT                FilePointer; // 0x24
    12.     PVOID                       WaitingForDeletion; // PEVENT_COUNTER // 0x28
    13.     WORD                        ModifiedWriteCount; // 0x2c
    14.     WORD                        NumberOfSystemCacheViews; // 0x2e
    15.     DWORD                       PagedPoolUsage; // 0x30
    16.     DWORD                       NonPagedPoolUsage; // 0x34
    17. } CONTROL_AREA,
    18. * PCONTROL_AREA;
    19.  
    20. typedef struct _SEGMENT {
    21.     PCONTROL_AREA               ControlArea; // 0x00
    22.     PVOID                       SegmentBaseAddress; // 0x04
    23.     DWORD                       TotalNumberOfPtes; // 0x08
    24.     DWORD                       NonExtendedPtes; // 0x0c
    25.     LARGE_INTEGER               SizeOfSegment; // 0x10
    26.     DWORD                       ImageCommitment; // 0x18
    27.     PVOID                       ImageInformation; // 0x1c PSECTION_IMAGE_INFORMATION
    28.     PVOID                       SystemImageBase; // 0x20
    29.     DWORD                       NumberOfCommittedPages; // 0x24
    30.     DWORD                       SegmentPteTemplate; // 0x28
    31.     PVOID                       BaseAddress; // 0x2c
    32.     PVOID/*PMMEXTEND_INFO*/     BaseAddrPae; // 0x30 if PAE enabled
    33.     PDWORD                      PrototypePte; // 0x34
    34.     DWORD                       ThePtes[1]; // 0x38
    35. } SEGMENT,
    36. * PSEGMENT;
    37.  
    38. typedef struct _MMADDRESS_NODE {
    39.     DWORD                       StartingVpn; // 0x00 ULONG_PTR
    40.     DWORD                       EndingVpn; // 0x04 ULONG_PTR
    41.     PVOID                       Parent; // 0x08 PTR MMADDRESS_NODE
    42.     PVOID                       LeftChild; // 0x0C PTR MMADDRESS_NODE
    43.     PVOID                       RightChild; // 0x10 PTR MMADDRESS_NODE
    44. } MMADDRESS_NODE,
    45. * PMMADDRESS_NODE;
    46.  
    47. typedef struct _SECTION_OBJECT {
    48.     MMADDRESS_NODE              Address; // 0x00
    49.     PSEGMENT                    Segment; // 0x14 PTR _SEGMENT
    50.     LARGE_INTEGER               SizeOfSection; // 0x18
    51.     DWORD                       Flags; // 0x20 MMSECTION_FLAGS
    52.     DWORD                       InitialPageProtection; // 0x24
    53. } SECTION_OBJECT,
    54. * PSECTION_OBJECT;
    55.  
    56. PVOID
    57. GetProcessSectionObject(
    58.         IN PEPROCESS peproc)
    59. {
    60.     PVOID       result = NULL;
    61.     BOOL        bCurrentProcess;
    62.     KAPC_STATE  ApcState;
    63.     NTSTATUS    status;
    64.    
    65.     if (*NtBuildNumber == 2195) {
    66.         bCurrentProcess = PsGetCurrentProcess() == peproc;
    67.        
    68.         if (!bCurrentProcess) {
    69.             KeStackAttachProcess(peproc, &ApcState);
    70.             }
    71.        
    72.         // Первая попытка с хэндлом 0x0004
    73.         status = ObReferenceObjectByHandle((HANDLE)0x0004, SECTION_QUERY, *MmSectionObjectType, KernelMode, &result, NULL);
    74.         if (!NT_SUCCESS(status)) {
    75.             // Вторая попытка с хэндлом 0x03F8
    76.             status = ObReferenceObjectByHandle((HANDLE)0x03F8, SECTION_QUERY, *MmSectionObjectType, KernelMode, &result, NULL);
    77.             if (!NT_SUCCESS(status)) {
    78.                 // Третья попытка с хэндлом из EPROCESS->SectionHandle
    79.                 status = ObReferenceObjectByHandle(*(HANDLE*)((ULONG)peproc + 0x01AC), SECTION_QUERY, *MmSectionObjectType, KernelMode, &result, NULL);
    80.                 }
    81.             }
    82.        
    83.         if (NT_SUCCESS(status)) {
    84.             ObDereferenceObject(result);
    85.             }
    86.        
    87.         if (!bCurrentProcess) {
    88.             KeUnstackDetachProcess(&ApcState);
    89.             }
    90.         }
    91.     else {
    92.         /*
    93.           * SectionObject offset:
    94.           * xp      0x138
    95.           * 2k3     sp0 - 0x114, other - 0x124
    96.           * vista   0x110
    97.         */
    98.         result = *(PVOID*)((ULONG)peproc + offsSectionObject);
    99.         }
    100.     return result;
    101. }
    102.  
    103. VOID GetProcessEXEName(
    104.         IN  ULONG pid,
    105.         OUT PCHAR ExeName)
    106. {
    107.     NTSTATUS            status;
    108.     PSECTION_OBJECT     section_obj;
    109.     PFILE_OBJECT        file_obj;
    110.     ULONG               len;
    111.     PEPROCESS           peproc;
    112.     UNICODE_STRING      usDosName;
    113.     WCHAR               textbuf[MAX_PATH];
    114.    
    115.     __try {
    116.         status = PsLookupProcessByProcessId((HANDLE)pid, &peproc);
    117.         if (NT_SUCCESS(status)) {
    118.             section_obj = (PSECTION_OBJECT)GetProcessSectionObject(peproc);        
    119.             if (MmIsAddressValid(section_obj)) {
    120.                 if (MmIsAddressValid(section_obj->Segment)) {
    121.                     if (MmIsAddressValid(((PSEGMENT)section_obj->Segment)->ControlArea)) {
    122.                         file_obj = ((PSEGMENT)section_obj->Segment)->ControlArea->FilePointer;
    123.                         file_obj = (PFILE_OBJECT)((ULONG)file_obj & 0xfffffff8);                       
    124.                         if (MmIsAddressValid(file_obj)) {
    125.                             status = RtlVolumeDeviceToDosName(file_obj->DeviceObject, &usDosName);
    126.                             if (NT_SUCCESS(status)) {
    127.                                 RtlZeroMemory(&textbuf, MAX_PATH * sizeof(WCHAR));                             
    128.                                 wcsncpy(textbuf, usDosName.Buffer, usDosName.Length / sizeof(WCHAR));
    129.                                 ExFreePool(usDosName.Buffer);
    130.                                 wcsncat(textbuf, file_obj->FileName.Buffer, file_obj->FileName.Length / sizeof(WCHAR));                            
    131.                                 wcstombs(ExeName, textbuf, wcslen(textbuf) + 1);
    132.                                 }                                                      
    133.                             }
    134.                         }
    135.                     }
    136.                 }
    137.             }
    138.         }
    139.     __except(EXCEPTION_EXECUTE_HANDLER) {
    140.         }
    141. }
    Если GetProcessEXEName() вернула пустую строку, имя следует считать из EPROCESS, тут это не реализовано. Но думаю самому сделать это труда не составит. GetProcessEXEName() универсальна и работает везде, начиная от w2k вплоть до vista sp1 и w2k8 sp1.

    Enjoy ;)
     
  7. genesis

    genesis New Member

    Публикаций:
    0
    Регистрация:
    4 сен 2006
    Сообщения:
    43
    круто! особенно насчет NtBuildNumber == 2195 ))) мы это делаем для всех w2k - тоже как то работает.
    насчет 0x3e8 - пасип, обязательно проверю...
     
  8. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    О чём это ты?