Мое почтение всем. Пришла в голову мысль немного поизвращаться -- "протащить" в Win, например, свой сегмент, например, во время загрузки. Осуществить желаемое решил так: получить управление до boot-загрузчика Win, установить свой обработчик прерывания 0x1 (он жил по адресу 0x0:0x600), выставить флаг TF и передать управление оригинальному загрузчику. В самом обработчике смотреть на след. команду -- если это 'popf(d)', устанавливать в стеке выполнявшегося кода флаг TF (чтобы не снять трассировку раньше времени), а также ждать 'lgdt', чтобы поправить GDT как мне хочется. Когда lgdt найдена -- флаг TF можно снять. Все это я сделал, правда, добавить свой сегмент не получится без глобальных перестановок -- сразу за GDT идет IDT. Интереса ради попробовал уменьшить кол-во сегментов -- вычел из поля GDT_SIZE 0x8. Эти изменения тоже "не дожили". Натравил на NTLDR IDA -- NTLDR проделывает несколько операций с GDT. Но. Если он проделывает операции с GDT "по-умному", используя 'sgdt' и не считая размер GDT константой, то должно получиться. Беда в том, что в NTLDR содержит смешанный код 16/32 и дизассемблировать его трудно. Средств автоматизировать это дело, думаю, нет. М.б. кто-то разобрался с NTLDR более детально? Или я что-то не учел, вылавливая 'lgdt' и меняя ее параметер? Или еще какой-нибудь способ есть править GDT без драйвера?
Если честно, просто интересно. Ну, +это даст возможность получать доступ к нулевому кольцу без драйвера, например. Тут уж кто во что горазд .
я делал так находил форматтер таблицы страниц и все страницы делал USER NT4 грузилась и работала, был доступ ко всему ядру напрямую из ring3 правда падала через какое-то время в синьку
До такого не додумался, если честно. Вариант с GDT казался самым простым, но оказался не рабочим. А подобное на 2K/XP не пробовали? Просто интересно, будет ли BSOD?
нет но ntldr вобще мало изменяли насколько я знаю 100% будет но загрузиться и поработать минут 5 должон я сам был когда-то удивлен тем что защита памяти ядра защищает от багов а не чего-то другого
Код (Text): void MempCopyGdt() { static xdtr_t gdtr,idtr; idt_gate* a; __asm sgdt gdtr __asm sidt idtr if (gdtr.addr + gdtr.limit + 1 != idtr.addr) { BlPrint("ERROR - GDT and IDT are not contiguous!\n"); BlPrint("GDT - %lx (%x) IDT - %lx (%x)\n",gdt.addr,gdt.limit,id t.addr,idt.limit); for (;;) ; } esi = (gdtr.addr + gdtr.limit + 0x1001)>>12; edi = FwAllocateHeapPermanent(esi); if (!edi) return 0x10; memmove(edi, gdtr.addr, esi<<12); gdtr.addr = edi; idtr.addr = edi + gdtr.limit + 1; a = (idt_gate*)idtr.addr; a[1].offset_1 = (USHORT)(ULONG)&BdTrap01; a[1].offset_2 = (USHORT)((ULONG)&BdTrap01 >> 16); a[3].offset_1 = (USHORT)(ULONG)&BdTrap03; a[3].offset_2 = (USHORT)((ULONG)&BdTrap03 >> 16); a[0xD].offset_1 = (USHORT)(ULONG)&BdTrap0d; // 0xD = #GP a[0xD].offset_2 = (USHORT)((ULONG)&BdTrap0d >> 16); // General Prot a[0xE].offset_1 = (USHORT)(ULONG)&BdTrap0e; // 0xE = #PF a[0xE].offset_2 = (USHORT)((ULONG)&BdTrap0e >> 16); // Page Fault a[1].sel = 8; a[1].type = 0x8E00; // 32-bit interrupt gate, DPL=0, Present=1 a[3].sel = 8; a[3].type = 0x8E00; a[0xD].sel = 8; a[0xD].type = 0x8E00; a[0xE].sel = 8; a[0xE].type = 0x8E00; a[0x2D].offset_1 = (USHORT)(ULONG)&BdTrap2d; a[0x2D].sel = 8; a[0x2D].type = 0x8E00; a[0x2D].offset_2 = (USHORT)((ULONG)&BdTrap2d >> 16); __asm lgdt gdtr __asm lidt idtr BdInitDebugger(OsLoaderName,OsLoaderBase,0); return 0; }
diamond Не совсем понятно, что за ф-ия "BdInitDebugger"? MSDN молчит, Google вообще ни одной ссылки не вернул... И почему процессор разрешает делать lgdt/lidt с третьего кольца?
Mika0x65 Это не код 3-кольца, а декомпилированный фрагмент части ntldr. Который как раз и отвечает за копирование и загрузку GDT/IDT.
diamond Вот как. Если не секрет, откуда? Т.е. это работа какого-то декомпилятора (если да, то какого?) или же фрагмент из source?
BUGOR Не угадал В пробегавших какое-то время назад исходниках 2k загрузчика нету. Mika0x65 Это работа мозга, которому помогала IDA. Ещё некоторые процедуры из OsLoader - 32-битной части ntldr - декомпилированы и находятся на http://diamondz.land.ru/osloader.7z