Проблема с переходом в ринг0 из приложения

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

  1. marty

    marty New Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2006
    Сообщения:
    4
    Здравствуйте!

    Перевел код перехода в ринг0 (описан тут - http://www.wasm.ru/article.php?article=apihook_3) с Дельфи на C. Все отрабатывает до
    call far [FarCall], и падает в BSOD c KMODE_EXCEPTION_NOT_HANDLED. Видимо что-то я все же не так сделал, либо шлюз неправильно настроил, либо call far либо еще что-то. В оригинальном коде непонятно, как шлюз настраивать - код заполнения дескриптора непонятно что делает, и не слишком вяжется с описанием дескриптора - http://wasm.ru/article.php?article=pipm02. Мой код в аттаче
     
  2. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Для начала, все процессорные структуры должны быть выравнены по 1 байту:
    Код (Text):
    1. #pragma pack(push,1)
    2. typedef struct _TAG_GDT_INFO
    3. {
    4.     WORD    Limit;
    5.     LPVOID  Base;
    6.  
    7. } GDT_INFO, *PGDT_INFO;
    8. #pragma pack(pop)
    Так же для FAR_CALL, GATE_DESCRIPTOR и CALL_THUNK
     
  3. marty

    marty New Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2006
    Сообщения:
    4
    Да, они все выровнены так:
    Код (Text):
    1. #include <PshPack1.h>
    2. typedef struct _TAG_CALL_THUNK
    3. {
    4.     // call far [FarCall]
    5.     BYTE   callFar1; //0xFF
    6.     BYTE   callFar2; //0x1D
    7.     DWORD  offsetFarCall;
    8.     BYTE   retCode; // 0xC3
    9.  
    10. } CALL_THUNK, *PCALL_THUNK;
    11. #include <PopPack.h>
    PshPack1.h и PopPack.h содержат, насколько я знаю, прагмы pragma push и pragma pop соответственно.
     
  4. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Функция quasiMmGetPhysicalAddress получает физический адрес для маленьких страниц памяти. А если в системе 256 и больше Мб оперативки, то ядро маппится на большую страницу. Соответственно, получаешь неверный физический адрес и пишешь callgate не в ту область памяти.
    Либо отключи большие страницы, либо по-другому получай физический адрес.

    ЗЫ: Кроме того, возможно включено PAE. Тогда опять же получение физического адреса отличается
     
  5. marty

    marty New Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2006
    Сообщения:
    4
    Да, памяти больше, чем 256. Большие страницы - это по 4 мб? Разве такое бывает? В том смысле, разве такое используется? А как это обойти? :derisive:
    Опять же, как проверить и как обойти?
     
  6. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Чтобы выключить PAE надо в boot.ini прописать
    Код (Text):
    1. /nopae /noexecute=alwaysoff
    А большие страницы бывают и очень даже широко используются :)
    Код (Text):
    1. \HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management
    DWORD LargePageMinimum определяет минимальный объем ОЗУ, при котором включать LargePages. Его забить в 0xFFFFFFFF
     
  7. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    кстати код проверки PAE:

    if( IsProcessorFeaturePresent( PF_PAE_ENABLED ) )
     
  8. marty

    marty New Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2006
    Сообщения:
    4
    Попробовал. Не помогло ;-(
    Ошибка все там же
     
  9. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
    Снова хотелось бы возродить тему, т.к ответы топикстартеру не удовлетворили моего любопытства :)

    Код (Text):
    1. CurrentGate := PGateDescriptor(DWORD(ptrGDT) + offset);
    2.   repeat
    3.     CurrentGate := PGateDescriptor(DWORD(CurrentGate) + SizeOf(TGateDescriptor));
    4.     if (CurrentGate.Attributes and $FF00) = 0 then
    5.       begin
    6.         OldGate := CurrentGate^;
    7.         CurrentGate.Selector   := $08; // ring0 code selector              ?????
    8.         CurrentGate.OffsetLo   := DWORD(@Ring0CallProc);                ???
    9.         CurrentGate.OffsetHi   := DWORD(@Ring0CallProc) shr 16;        ???
    10.         CurrentGate.Attributes := $EC00;                                         ???
    11.         FarCall.Offset   := 0;
    12.         FarCall.Selector := DWORD(CurrentGate) - DWORD(ptrGDT) - offset;
    13.         Break;
    14.       end;
    15.   until DWORD(CurrentGate) >= DWORD(ptrGDT) + gdt.limit + offset;
    Извиняйте, что на [censored] delph-е, не хотел перебивать пока, заюзал код оригинала. Код из статьи MS-Rem-а про переход в 0 кольцо, используя прописывание своего дескриптора в GDT. Собственно интересуют строчки, помеченные вопросами, а в особенности - строчка с 5-ю вопросами. То ли я ламер и не так понял что-либо, то ли в 2 младшие байта адреса базы сегмента заносится 0x08, а в 2 младших байта лимита сегмента заносятся 2 младших байта адреса функции Ring0CallProc???
     
  10. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    http://www.sasm.narod.ru/docs/pm/pm_pr/chap_4.htm
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    там же все понятно записано. в поле Selector (там селектор, логично?) заносится 8.
    в поле Offset, двумя порциями заносятся младшие и старшие части оффсета (адреса). сначала в OffsetLo, потом в OffsetHi.
    и в атрибуты заносится ec00

    тут уже не маны читать на проц надо, а учебник по дельфи
     
  12. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
    CrystalIC

    То, что нужно, thanks

    Great

    Меня просто глюкануло, я не подумал, насколько дескриптор шлюза вызова отличается от дескриптора кода или данных...

    ЗЫ. в поле Selector (там селектор, логично?)
    Для меня нет связи между авторским названием поля cтруктуры или переменной и тем, что автор может туда запихнуть.

    тут уже не маны читать на проц надо, а учебник по дельфи
    Спасибо, но лучше не стоит :)))
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Так почитай все-таки маны на проц и устройство шлюзов. Intel Architectures Software Developer's Manual творит чудеса