Цель - выставить флаг T в слове флагов задачи __asm{ str ax mov fs, ax mov edi, 0x64 mov ax, fs:[edi] or ax, 1 mov fs:[edi], ax } Вместо этого получаю bugcheck. Выполняется все естественно в kernel mode. Обработчик int 1 есть и проверен на TF, int 1 и бряках. Я куда-то не туда лезу?
Ichetnick Через селектор ТSS ни читать ни писать нельзя! Тебе нужно перенастроить другой селектор на область памяти, где хранится TSS. И через него уже читать. Я делал вот так, через 23й селектор - Код (Text): mov ax, 23h mov ds, ax mov ax, 10h mov gs, ax sub esp, 08h sgdt fword ptr [esp] str ax //get TSS selector movzx eax, ax add eax, dword ptr [esp + 2] mov edx, dword ptr [eax] mov dword ptr [temp_new_descrp], edx mov edx, dword ptr [eax + 4] mov dword ptr [temp_new_descrp + 4], edx mov ax, 20h //means 23h selector movzx eax, ax add eax, dword ptr [esp + 2] mov edx, dword ptr [eax] mov dword ptr [temp_old_descrp], edx mov edx, dword ptr [eax + 4] mov dword ptr [temp_old_descrp + 4], edx shr edx, 8 mov byte ptr [temp_new_descrp + 4 + 1], dl shr edx, 8 and dl, 11000000b mov byte ptr [temp_new_descrp + 4 + 2], dl mov edx, dword ptr [temp_new_descrp] //patch GDT mov dword ptr [eax], edx mov edx, dword ptr [temp_new_descrp + 4] mov dword ptr [eax + 4], edx mov dx, 23h //reload shadow part in ds mov ds, dx mov edx, dword ptr ds:[4] mov dword ptr gs:[original_esp0], edx mov dword ptr ds:[4], ecx //patch ESP0 value at TSS mov edx, dword ptr gs:[temp_old_descrp] //patch GDT mov dword ptr gs:[eax], edx mov edx, dword ptr gs:[temp_old_descrp + 4] mov dword ptr gs:[eax + 4], edx mov dx, 23h mov ds, dx add esp, 08h pop gs pop ds вроде работает
А почему выбраны селекторы 23 и 10? Просто у меня код для kernel mode в Windows и предопределить значения селекторов я не смогу. Как я понимаю gs (0x10) - это селектор данных?
Не работает... Переработал код до такого UCHAR lpGDT[8]; UCHAR new_descriptor[8]; UCHAR old_descriptor[8]; __asm { cli pushad mov ax, 0x23 mov ds, ax mov ax, 0x10 mov gs, ax sgdt fword ptr [lpGDT] str ax movzx eax, ax add eax, dword ptr [lpGDT+2] ; now eax points to TSS data descriptor mov edx, dword ptr [eax] mov dword ptr [new_descriptor], edx mov edx, dword ptr [eax+4] mov dword ptr [new_descriptor+4], edx ; now new_descriptor saved mov ax, 0x20 movzx eax, ax add eax, dword ptr [lpGDT+2] ; now eax points to our data descriptor mov edx, dword ptr [eax] mov dword ptr [old_descriptor], edx mov edx, dword ptr [eax + 4] mov dword ptr [old_descriptor + 4], edx ; now old_descriptor backuped shr edx, 8 mov byte ptr [new_descriptor + 4 + 1], dl shr edx, 8 and dl, 11000000b mov byte ptr [new_descriptor + 4 + 2], dl ; now new_descriptor patched mov edx, dword ptr [new_descriptor] mov dword ptr [eax], edx mov edx, dword ptr [new_descriptor + 4] mov dword ptr [eax + 4], edx ; patch GDT mov dx, 0x23 ; reload shadow part mov ds, dx mov dx, word ptr ds:[0x64] or dx, 1 mov word ptr ds:[0x64],dx //patch Task Flags mov edx, dword ptr [old_descriptor] mov dword ptr gs:[eax], edx mov edx, dword ptr [old_descriptor+4] mov dword ptr gs:[eax + 4], edx ; restore GDT backup mov dx, 23h mov ds, dx popad sti }; Не позволяет читать с 0x64
На лицо (...лице ) явные баги! Во первых, что это значит: Просто у меня код для kernel mode в Windows и предопределить значения селекторов я не смогу ?!?! глупость! - kernel mode (т.е. ring0) - абсолютная власть! - делаеш что хочеш. Возможно ты не совсем еще рулиш в уровнях привелегий кода и пр хр. (Правда я сам не рулю в этом как надо ) А почему выбраны селекторы 23 и 10? ...Как я понимаю gs (0x10) - это селектор данных? Эти селекторы выбраны на фонарь я мог использовать любые другие. 23h - это селектор данных для ринг3. 10h - это селектор данных для ринг0 (точнее это селектор указателя стека SS, но это не важно) Теперь вопиющее безобразие Что это? - Код (Text): mov edx, dword ptr [old_descriptor] mov dword ptr gs:[eax], edx mov edx, dword ptr [old_descriptor+4] mov dword ptr gs:[eax + 4], edx а должно быть так: Код (Text): mov edx, dword ptr [b]gs:[/b][old_descriptor] mov dword ptr gs:[eax], edx mov edx, dword ptr [b]gs:[/b][old_descriptor+4] mov dword ptr gs:[eax + 4], edx т.е. ты же получается читал old_descriptor через ds, т.е. из самой TSS!!? Ну и далее - что ты читаеш по смещению 0x64? Посмотри на структуру TSS - по смещению 0x64 находится "I/O Map Base Address" Регистр флагов текущей задачи находится по смещению 0x24 Проверь все внимательно - должно работать, вот правда когда я с TSS ковырялся, я заметил что в текущей TSS по смещению 0x24 будет находится не текущий EFLAGS!, а ноль! Что вообщем-то мне пока не понятно. Но это уже другой вопрос...
Насчет gs спасибо.. Сейчас попробую... Насчет 64h - по Зубкову там 2 байта слово флагов задачи (не EFLAGS!) А порты идут следующими. Насчет селекторов спасибо... предопределить значения селекторов я не смогу имелось ввиду что я не смогу засатвить винду использовать селектор 23h для данных ring0. Вопрос был к тому что в коде захардкоден 23h в ds, так что если другая версия винды будет использовать другой селектор для данных то мы грохнемся на этом коде при попытке сохранить данные перед модификацией дескриптора... Сейчас запущу VMWare экспериментировать... Извиняюсь за свою тупизну - но асм видел в прошлый раз 3 года назад, а тут такая подстава... И тем более защищенный режим, в котором я хронически туплю...
Вопрос был к тому что в коде захардкоден 23h в ds, так что если другая версия винды будет использовать другой селектор для данных то мы грохнемся на этом коде при попытке сохранить данные перед модификацией дескриптора... У всей линейки NT предназначения селекторов данных и кода одинаковы и соответственно одинаковы их значения. На это можно положится, по крайней мере на сегодняшний день. На счет Зубкова - может быть, не знаю...