странности Zw и проч

Тема в разделе "WASM.WIN32", создана пользователем _basmp_, 30 окт 2008.

  1. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Странно выглядят все Zw и проч функи с переходами на KiFast.. KiInt.. Они, часом не автогенерируются при загрузке оси? Если да, то чем?
     
  2. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    _basmp_
    а чем конкретно странно?
     
  3. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    не автогенерируются
     
  4. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    Откуда такие мысли? Открой ntdll.dll в IDA и посмотри. Меняется только содержимое 7FFE0300.
    Полагаю в MS этот код макросами генерили.
     
  5. barton

    barton New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2008
    Сообщения:
    164
    Адрес:
    Czechoslovakia
    че-то я не особо понял.. Zw в ядре - это ядерные переходники к Nt-сервисам, каждая Zw-оболочка небольшая..
     
  6. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    barton
    r3
     
  7. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    посмотри ntdll.dll и ntoskrnl.exe под дизассемблером и все поймешь.
     
  8. PE_Kill

    PE_Kill New Member

    Публикаций:
    0
    Регистрация:
    16 янв 2006
    Сообщения:
    107
    _basmp_ каждый переходник дергает сервис по его номеру вот и всё.
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    _basmp_
    не понял в чем вопрос?
     
  10. barton

    barton New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2008
    Сообщения:
    164
    Адрес:
    Czechoslovakia
    ну и?) в р3 никакой разницы между Zw и Nt нет. в экспортах ntdll они указывают на одну и туже функцию

    > Они, часом не автогенерируются при загрузке оси? Если да, то чем?

    автогенерируются?... ну вообще-то они в файле присутствуют физически как-бы.
    вообще странный топик какой-то
     
  11. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    функи, не только zw, интерфейсные к ядру все имеют один формат

    mov eax, <номер сервиса>
    mov edx, 7FFE0300
    call dword [edx]

    возник вопрос, почему так с edx? Это не компилерная оптимизация. Во всяком случае не мсвс. если писано на асме, то почему так с edx, ведь он дальше не используется? Вот и возник вопрос, а что если это автогенератор и гдето есть компактно список номеров сервисов и соответствие их интерфейсам.
     
  12. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    R0 режим:
    Zw функции ядра, и соответвенно все поинтеры передаваемые им могут быть как r3 так и r0
    Nt функции юзермоде, и передаваемые им поинтеры зависят от PreviousMode треда. Обычно r3 поинтеры.
     
  13. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    макрос для стабов в юзермоде
    Код (Text):
    1. USRSTUBS_ENTRY1 macro ServiceNumber, Name, NumArgs
    2. cPublicProc     _Zw&Name, NumArgs
    3. PUBLICP _Nt&Name, NumArgs
    4. LABELP  _Nt&Name, NumArgs
    5. .FPO ( 0, NumArgs, 0, 0, 0, 0 )
    6.         mov     eax, ServiceNumber      ; (eax) = service number
    7.         mov     edx, MM_SHARED_USER_DATA_VA+UsSystemCall
    8.         call    [edx]
    9.         stdRET  _Zw&Name
    10. stdENDP _Zw&Name
    11. endm
    макрос для стабов в р0
    Код (Text):
    1. SYSSTUBS_ENTRY1 macro ServiceNumber, Name, NumArgs
    2. cPublicProc _Zw&Name,NumArgs
    3. .FPO ( 0, NumArgs, 0, 0, 0, 0 )
    4.         extrn   _KiSystemService:PROC
    5.         mov     eax, ServiceNumber      ; (eax) = service number
    6.         lea     edx, [esp]+4            ; (edx) -> arguments
    7.         pushfd                          ; EFLAGS to trap frame
    8.         push    KGDT_R0_CODE            ; CS to trap frame
    9.         call    _KiSystemService        ; EIP to trap frame and enter handler
    10.         stdRET  _Zw&Name
    11. stdENDP _Zw&Name
    12. endm
     
  14. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Автогенерируется вектор UsSystemCall и UsSystemCallReturn на фазе инициализации ядра #1. Первое поле указывает на заглушку KiFastSystemCall/KiIntSystemCall, второе поле - указывает на адрес возврата по Sysexit.
    PspInitPhase1() -> PspInitializeSystemDll() -> PspLookupKernelUserEntryPoints(). Определяется поддерживается ли инструкция Sysenter, если поддерживается, то определяется адрес в ntdll точки KiFastSystemCall, иначе определяется адрес KiIntSystemCall и этот указатель(RVA + OH.ImageBase) загружается в UserSharedData. Поле UsSystemCallReturn заполняется аналогично(экспорт ntdll как KiFastSystemCallRet).
    Код загружающий указатели:
    Код (Text):
    1. PspLookupKernelUserEntryPoints(
    2.     [...]
    3.     if (KeFeatureBits & KF_FAST_SYSCALL) {
    4.  
    5.         //
    6.         // Get the addresses of the fast system call code.
    7.         //
    8.  
    9.         EntryName = "KiFastSystemCall";
    10.         Status = PspLookupSystemDllEntryPoint(EntryName,
    11.                                               (PVOID *)&SharedUserData->SystemCall);
    12.  
    13.         if (!NT_SUCCESS(Status)) {
    14.             KdPrint(("Ps: Cannot find fast system call address\n"));
    15.             return Status;
    16.         }
    17.  
    18.         //
    19.         // Get the addresses of the fast system call return code.
    20.         //
    21.  
    22.         EntryName = "KiFastSystemCallRet";
    23.         Status = PspLookupSystemDllEntryPoint(EntryName,
    24.                                               (PVOID *)&SharedUserData->SystemCallReturn);
    25.  
    26.         if (!NT_SUCCESS(Status)) {
    27.             KdPrint(("Ps: Cannot find fast system call return address\n"));
    28.             return Status;
    29.         }
    30.  
    31.     } else {
    32.  
    33.         //
    34.         // Get the addresses of the fast system call code.
    35.         //
    36.  
    37.         EntryName = "KiIntSystemCall";
    38.         Status = PspLookupSystemDllEntryPoint(EntryName,
    39.                                               (PVOID *)&SharedUserData->SystemCall);
    40.  
    41.         if (!NT_SUCCESS(Status)) {
    42.             KdPrint(("Ps: Cannot find int2e system call address\n"));
    43.             return Status;
    44.         }
    45.     }
    46.  
    47.     //
    48.     // Ret instruction to test no execute state of shared user data.
    49.     //
    50.  
    51.     SharedUserData->TestRetInstruction = 0xc3;
    Для возврата в юзермод по Int/Sysexit проверка не выполняется, а используется самомодификация кода ядра.
    Код (Text):
    1. KiSystemCallExitBranch:
    2.       jnz short KiSystemCallExit
    3.       pop edx
    4.       pop ecx
    5.       popfd
    6.       jmp edx
    7. KiSystemCallExit:
    8.       iretd
    9. KiSystemCallExit2:
    10.       test dword ptr [esp+8], EFLAGS_TF
    11.       jne short KiSystemCallExit
    12.       pop edx
    13.       add esp, 4
    14.       and dword ptr [esp], NOT EFLAGS_INTERRUPT_MASK
    15.       popfd
    16.       pop ecx
    17.       sti
    18.       sysexit
    По умолчанию инструкция перехода в KiSystemCallExitBranch направлена на KiSystemCallExit, при разрешении использования sysexit смещение в инструкции увеличивается, направляя тем самым обработку на KiSystemCallExit2.