Получение адреса LoadLibrary в ядре

Тема в разделе "WASM.NT.KERNEL", создана пользователем katrus, 23 фев 2010.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Есть ли надежный (работающий от ХР до 7) механизм получения LoadLibrary в автономном драйвере не имеющем userspace компоненты?

    Пока, что смотрю на таблицу USER32!apfnDispatch для которой можно собрать таблицы со всех версий винды, но не совсем очевидно как заполучить адрес кетой таблицы, так как она не экспортируется.
     
  2. retmas

    retmas New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2005
    Сообщения:
    100
    ZwCreateSection, ZwMapViewOfSection (SEC_IMAGE), пройтись по export table, получить смещение и виртуальный адрес.
     
  3. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    retmas
    Только, как я понимаю такой метод не будет работать в семерке?
     
  4. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    ZwQueryInformationProcess

    ProcessInfo.PebBaseAddress как отсюда достать знаешь ?
     
  5. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Понял! Черезе РЕВ легко добраться до apfnDispatch. Немного поразмыслив, понял, что помимо LoadLibrary мне нужен GetProcAddress. Придется наверное искать через экспорты :dntknw:
     
  6. retmas

    retmas New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2005
    Сообщения:
    100
    katrus, почему не будет?
     
  7. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Вообще-то есть альтернативные функции предназначенные для режима ядра, а также экспортируемый ntdll - к примеру LdrGetProcedureAddress.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    katrus
    Тоесть вам функа из пользовательского модуля нужна ?
    Тогда проецируйте с диска в память его. База Kernel32.dll во всех процессах одинакова(до, нэйтив не позволяет выполнить релокацию для него). Причём тут шадов совсем не понятно.
     
  9. retmas

    retmas New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2005
    Сообщения:
    100
    Clerk, вот это я и предлагал.. не устраивает, видимо, автора:)
     
  10. b000bs

    b000bs New Member

    Публикаций:
    0
    Регистрация:
    23 дек 2009
    Сообщения:
    11
    найти модуль в нужном процессе
    пропарсить экспорт и получить адрес
    в чем суть вопроса то?
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    katrus
    Огласите задачу, тоесть зачем эти функи нужны.
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ищем эксплорер, аттачимся, получаем его PEB, перебираем модули, ищем kernel32.dll, перебираем экспорты и вуаля!

    Код (Text):
    1. PVOID
    2. NTEXAPI
    3. GetSystemInformation (
    4.                       SYSTEM_INFORMATION_CLASS InfoClass
    5.                       )
    6. {
    7.   NTSTATUS Status;
    8.   PVOID Buffer;
    9.   ULONG Size = PAGE_SIZE * 4;
    10.  
    11.   PAGED_CODE();
    12.  
    13.   do
    14.   {
    15.     ULONG t;
    16.  
    17.     Buffer = ExAllocatePool (PagedPool, Size);
    18.  
    19.     if (!Buffer)
    20.     {
    21.       KdPrint(("!!!NOT ENOUGH MEMORY!!! PoolSize %lx\n", Size));
    22.       return NULL;
    23.     }
    24.  
    25.     Status = ZwQuerySystemInformation ( InfoClass,
    26.       Buffer,
    27.       Size,
    28.       &t );
    29.  
    30.     if (!NT_SUCCESS(Status))
    31.       ExFreePool (Buffer);
    32.  
    33.     Size = Size + PAGE_SIZE*4;
    34.   }
    35.   while (Status == STATUS_INFO_LENGTH_MISMATCH);
    36.  
    37.   if (!NT_SUCCESS(Status))
    38.   {
    39.     return NULL;
    40.   }
    41.  
    42.   return Buffer;
    43. }
    44.  
    45. PVOID
    46. NTEXAPI
    47. GetProcedureAddressEx(
    48.                       IN PVOID Base,
    49.                       IN PCHAR FunctionName OPTIONAL,
    50.                       IN PVOID FunctionEntry OPTIONAL
    51.                       )
    52. {
    53.   PIMAGE_DOS_HEADER mz;
    54.   PIMAGE_FILE_HEADER pfh;
    55.   PIMAGE_OPTIONAL_HEADER poh;
    56.   PIMAGE_EXPORT_DIRECTORY pexd;
    57.   PULONG AddressOfFunctions;
    58.   PULONG AddressOfNames;
    59.   PUSHORT AddressOfNameOrdinals;
    60.   ULONG i;
    61.  
    62.   // Get headers
    63.   *(PUCHAR*)&mz = (PUCHAR)Base;
    64.   *(PUCHAR*)&pfh = (PUCHAR)Base + mz->e_lfanew + sizeof(IMAGE_NT_SIGNATURE);
    65.   *(PIMAGE_FILE_HEADER*)&poh = pfh + 1;
    66.  
    67.   // Get export
    68.   *(PUCHAR*)&pexd = (PUCHAR)Base + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    69.   *(PUCHAR*)&AddressOfFunctions = (PUCHAR)Base + pexd->AddressOfFunctions;
    70.   *(PUCHAR*)&AddressOfNames = (PUCHAR)Base + pexd->AddressOfNames;
    71.   *(PUCHAR*)&AddressOfNameOrdinals = (PUCHAR)Base + pexd->AddressOfNameOrdinals;
    72.  
    73.   // Find function
    74.   for( i=0; i<pexd->NumberOfNames; i++ )
    75.   {
    76.     PCHAR name = ((char*)Base + AddressOfNames[i]);
    77.     PVOID addr = (PVOID*)((ULONG)Base + AddressOfFunctions[AddressOfNameOrdinals[i]]);
    78.  
    79.     if (ARGUMENT_PRESENT (FunctionName))
    80.     {
    81.       if( !strcmp( name, FunctionName ) )
    82.       {
    83.         return addr;
    84.       }
    85.     }
    86.     else if (ARGUMENT_PRESENT (FunctionEntry))
    87.     {
    88.       if (FunctionEntry == addr)
    89.         return name;
    90.     }
    91.     else
    92.     {
    93.       ASSERTMSG ("SHOULD NOT REACH HERE", ARGUMENT_PRESENT(FunctionName) || ARGUMENT_PRESENT(FunctionEntry));
    94.     }
    95.   }
    96.  
    97.   return NULL;
    98. }
    99.  
    100. PEPROCESS
    101. NTEXAPI
    102. GetProcessByNameAndSessionId(
    103.                              PWCHAR wszProcessName,
    104.                              PULONG RequiredSessionId OPTIONAL,
    105.                              PULONG SessionIdReturned OPTIONAL
    106.                              )
    107. {
    108.     PSYSTEM_PROCESSES_INFORMATION Processes;
    109.   NTSTATUS Status = STATUS_NOT_FOUND;
    110.   PEPROCESS Process;
    111.  
    112.   PAGED_CODE();
    113.  
    114.   Processes = (PSYSTEM_PROCESSES_INFORMATION) GetSystemInformation (SystemProcessesAndThreadsInformation);
    115.  
    116.   if (Processes)
    117.   {
    118.         PSYSTEM_PROCESSES_INFORMATION Proc;
    119.  
    120.     for (Proc=Processes; ; *(ULONG*)&Proc += Proc->NextEntryDelta)
    121.     {
    122.       BOOLEAN sessionIdOk = true;
    123.  
    124.       if (ARGUMENT_PRESENT(RequiredSessionId))
    125.       {
    126.         sessionIdOk = (Proc->SessionId == *RequiredSessionId);
    127.       }
    128.  
    129.       if (Proc->ProcessName.Buffer &&
    130.         !_wcsicmp (Proc->ProcessName.Buffer, wszProcessName) &&
    131.         sessionIdOk)
    132.       {
    133.         Status = PsLookupProcessByProcessId ((PVOID) Proc->ProcessId, &Process);
    134.  
    135.         if(NT_SUCCESS(Status))
    136.         {
    137.           if (ARGUMENT_PRESENT(SessionIdReturned))
    138.             *SessionIdReturned = Proc->SessionId;
    139.           ExFreePool (Processes);
    140.           return Process;
    141.         }
    142.  
    143.         break;
    144.       }
    145.  
    146.       if (!Proc->NextEntryDelta) break;
    147.     }
    148.  
    149.     ExFreePool (Processes);
    150.  
    151.     return NULL;
    152.   }
    153.  
    154.   return NULL;
    155. }
    156.  
    157. // thnx to Twister
    158. PPEB NTEXAPI GetProcessPeb(HANDLE hProcess)
    159. /**
    160. Get PEB of current process
    161. */
    162. {    
    163.   PROCESS_BASIC_INFORMATION    pbi;
    164.   NTSTATUS                    status;
    165.   PPEB                        result = NULL;
    166.  
    167.   PAGED_CODE();
    168.  
    169.   status = ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
    170.   if (NT_SUCCESS(status))
    171.     {
    172.     result = pbi.PebBaseAddress;
    173.   }
    174.  
    175.   return result;
    176. }
    177.  
    178. // thnx to Twister
    179. PVOID NTEXAPI UserFindModule (PWSTR ModuleName)
    180. /**
    181. Find user module (kernel-mode version for GetModuleHandle)
    182. */
    183. {
    184.   PLIST_ENTRY             Next;
    185.   PPEB                    Peb;
    186.   PLDR_DATA_TABLE_ENTRY   Entry;
    187.   UNICODE_STRING          us;
    188.  
    189.   PAGED_CODE();
    190.  
    191.   Peb = GetProcessPeb (NtCurrentProcess());
    192.   if (Peb)
    193.   {
    194.     RtlInitUnicodeString(&us, ModuleName);
    195.  
    196.     Next = Peb->Ldr->InMemoryOrderModuleList.Flink;
    197.     while (Next != &Peb->Ldr->InMemoryOrderModuleList)
    198.     {
    199.       Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, MemoryOrder);
    200.  
    201.       if(!RtlCompareUnicodeString(&Entry->ModuleName, &us, TRUE))
    202.       {
    203.         return Entry->ModuleBaseAddress;
    204.       }
    205.  
    206.       Next = Next->Flink;
    207.     }
    208.   }
    209.  
    210.   return NULL;
    211. }
    использовать

    Код (Text):
    1. ULONG SessionId = 0;
    2. PEPROCESS pExplorer = GetProcessByNameAndSessionId (L"explorer.exe", &SessionId, 0);
    3. if (pExplorer != NULL)
    4. {
    5.     KAPC_STATE ApcState;
    6.     KeStackAttachProcess ((PKPROCESS)pExplorer, &ApcState);
    7.    
    8.     PVOID hKernel32 = UserFindModule ("kernel32.dll");
    9.     if (hKernel32)
    10.     {
    11.         PVOID pLoadLibraryA = GetProcedureAddressEx (hKernel32, "LoadLibraryA", NULL);
    12.         PVOID pGetProcAddress = GetProcedureAddressEx (hKernel32, "GetProcAddress", NULL);
    13.        
    14.         KdPrint(("LoadLibraryA=%p, GetProcAddress=%p\n", pLoadLibraryA, pGetProcAddress));
    15.     }
    16.    
    17.     KeUnstackDetachProcess (&ApcState);
    18.     ObDereferenceObject (pExplorer);
    19. }
    вместо эксплорера можно взять любой процесс, куда заведомо промаплена kernel32
    ну что, что сложного то? лентяй!
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Great
    Автор хотел apfn юзать, вероятно для загрузки модуля(KeUserModeCallback(_ClientLoadLibrary)). Зачем тогда искать Kernel32 не ясно, если есть нэйтив..
     
  14. krol

    krol New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2011
    Сообщения:
    19
    А зачем нужен
    Код (Text):
    1. ObDereferenceObject (pExplorer);
    ??
     
  15. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    krol
    Это требование ф-ии PsLookupProcessByProcessId -- она увеличивает счетчик ссылок объекта.