NtMapViewOfSection/ZwMapViewOfSection

Тема в разделе "WASM.WIN32", создана пользователем souzz, 8 сен 2006.

  1. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Помогите, пожалуйста,
    Ставлю хук на ZwMapViewOfSection

    NTSTATUS
    NewZwMapViewOfSection(
    HANDLE SectionHandle,
    HANDLE ProcessHandle,
    PVOID *BaseAddress,
    ULONG ZeroBits,
    ULONG CommitSize,
    PLARGE_INTEGER SectionOffset OPTIONAL,
    PSIZE_T ViewSize,
    SECTION_INHERIT InheritDisposition,
    ULONG AllocationType,
    ULONG Protect
    )

    PVOID *BaseAddress = адрес данных, которые мне надо подменить. (в моем случае 0xCF0000)
    Как будет правильнее, подменить адрес на адрес другого буфера, или заменить сами данные?

    конструкция вида *BaseAddress = (PVOID)(*buf); у меня приводит к BSOD.
    BSOD с кодом maj=7F min=08

    Что не так?

    Спасибо.
     
  2. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    немного поправил задачку, сорри
     
  3. seeQ

    seeQ New Member

    Публикаций:
    0
    Регистрация:
    3 сен 2003
    Сообщения:
    71
  4. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Судя по коду ошибки, у тебя stack overflow в ядре
     
  5. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Разобрался, сделал подмену адреса перед вызовом оригинальной функции.

    //выставляю смещение на физ. адрес начала своего буфера
    newOfs=MmGetPhysicalAddress(&MyMemBuf);
    SectionOffset->LowPart=newOfs.LowPart;
    SectionOffset->HighPart=newOfs.HighPart;

    вызываю функцию:
    NTSTATUS status=OldZwMapViewOfSection(SectionHandle,ProcessHandle,BaseAddress,ZeroBits,CommitSize, SectionOffset,ViewSize,
    InheritDisposition,AllocationType,Protect
    );
    Потом все ок, только вот получаю мессагу в дебаггере:
    *******************************************************************************
    *
    * A driver is mapping physical memory 1A3D0000->1A3D0FFF
    * that it does not own. This can cause internal CPU corruption.
    * A checked build will stop in the kernel debugger
    * so this problem can be fully debugged.
    *
    *******************************************************************************
    MyMemBuf описана как константа в .h
    static UCHAR MyMemBuf[32768] = {....};
    Разве драйвер не хозяин своей памяти?
    Кстати, после второго обращения к функции, сообщение пропало.
    Может не до конца проинитилось что-то? Или буфер неверно создан?
     
  6. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    SectionOffset - смещение от базы секции, в виртуальных адресах. Так ты говоришь ей, что надо маппить, начиная с виртуального адреса (<начало_секции> + SectionOffset) и функция попадает вообще хрен знает куда. При проверке параметров она должна бы вывалить ошибку или замаппить 0 байт.

    Перед этим было более правильно: сначала вызов оригинальной функции, затем подмена возвращаемого адреса.

    Ошибка была похоже вызвана тем, что MyMemBuf находится в ядре, ну а юзерское-то приложение не может работать с ядерной памятью. Перед тем как вернуть BaseAddress = MyMemBuf надо замаппить ядерный адрес в юзер-мод:

    pMdl = IoAllocateMdl(MyMemBuf, ...);
    MmProbeAndLockPages(pMdl, ...);
    BaseAddress = MmMapLockedPagesSpecifyCache(pMdl, UserMode, ...);

    Этот код очень желательно обернуть в try/except
     
  7. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Спасибо, но не совсем так:
    В оригинале секция открыта и драйвер получает маппинг по смещению 0x00C0000, область видеобиоса. Меня устроит, если я подменю параметр на входе на другую область физической памяти (в данном случае, я хочу сделать непрерывный буфер и указать драйверу физический адрес начала его в памяти , по моему это возможно). Таким образом вызов оригинальной функции будет маппить память в области мне нужной., параметр SectionOffset у меня равен 0xC0000 в оргинале.
    т.е. я делаю что-то вида
    if ((SectionOffset->LowPart== 0xC0000)&& ( SectionOffset->HighPart==0x00000))
    {
    newOfs=MmGetPhysicalAddress(&MyMem[0]);
    SectionOffset->LowPart=newOfs.LowPart;
    SectionOffset->HighPart=newOfs.HighPart;
    };
    и собственно, вызываю оригинальную функцию:
    NTSTATUS status=OldZwMapViewOfSection(SectionHandle,ProcessHandle,BaseAddress,ZeroBits,CommitSize, SectionOffset,ViewSize,
    InheritDisposition,AllocationType,Protect);
    Вот, проблем в том, что возвращается буфер, по-моему не непрерывный.
     
  8. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    А можно посмотреть описание параметрофф ZwMapViewOfSection? Особенно интересно что такое BaseAddress - ? И нельзя ли дебагпринт того, что передается в оригинальную функцию и на что ты их меняешь?
     
  9. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Chingachguk
    BaseAddress - на входе желаемый адрес проекции (если NULL -на усмотрение системы), на выходе в случае успеха - виртуальный адрес проекции.

    souzz
    Буфер и не будет в таком случае непрерывным, так как MyMem сама разбита на несколько физических страниц памяти, которые совсем необязательно будут располагаться по соседству.
    Попробуй выделять память под свой буфер с помощью MmAllocateContiguousMemory
     
  10. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    NTSTATUS
    NewZwMapViewOfSection(
    HANDLE SectionHandle,
    HANDLE ProcessHandle,
    PVOID *BaseAddress,
    ULONG ZeroBits,
    ULONG CommitSize,
    PLARGE_INTEGER SectionOffset OPTIONAL,
    PSIZE_T ViewSize,
    SECTION_INHERIT InheritDisposition,
    ULONG AllocationType,
    ULONG Protect
    )

    дебаг:
    SectionHandle:0x000000A8;
    ProcessHandle:0xFFFFFFFF;
    BaseAddress:0x00000000;
    ZeroBits:0x00000000;
    CommitSize:0x00008000;
    SectionOffset:0x0012F830;//здесь хрантся адрес 0х000C0000 - видео BIOS например
    //именно *SectionOffset его я и подменяю ПЕРЕД
    //вызовом функции на адрес моего буфера в 32 кб.
    //адрес получен MmGetPhysicalAddress(&myBuf[0]);
    ViewSize:0x00008000; //размер области маппинга с оффсета
    InheritDisposition:0x00000001;
    AllocationType:0x00000000;
    Protect:0x00000002)
     
  11. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Мне кажется, gilg прав. Что если поправить также:

    CommitSize:0x00008000 -> 0x100

    И позвать функу? По идее 0x100 точно непрерывна.
     
  12. souzz

    souzz New Member

    Публикаций:
    0
    Регистрация:
    20 апр 2006
    Сообщения:
    17
    Адрес:
    Freedom
    Заработало,
    buf = MmAllocateContiguousMemory(0x8000,HighestAcceptable);

    if (buf != NULL) {
    RtlCopyMemory(buf,&MyMem[0],0x8000);
    newOfs=MmGetPhysicalAddress(buf);

    и пошел вызов оригинальной функции по новому смещению....

    Вопрос теперь, будет ли этот код работать под XP и под 98...

    Спасибо всем!
     
  13. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    под 98 нет