Page 6 of 10

Posted: Sun Mar 18, 2007 5:13 pm
by Ghost
Serge
Для APM кроме гашения экрана примеров нет, всё руки не доходят написать что нибудь сносное.
Идея не сохранять ds,es меня тоже посещала, но подумав что какая нибудь функция их использует (аля [ESP+44]/[ESP+48]) идея ушла (нужно проверить все функции). Ещё есть идея уйти от сохранения в стеке и "заворачивания" (зачем - вообще не понятно) всех регистров, т.к. многие функции почти не портят регистры, но для этого нужно перелатать всё ядро.

Posted: Sun Mar 18, 2007 9:27 pm
by Serge
Ghost

Я проверил работу без сохранения ds и es. Всё работает. На быстрых вызовах даёт заметный прирост. Сегменты можно было загружать всего один раз если бы не дурацкая осбенность IA32. Все дескрипторы проверяются при загрузке селектора и выдают ошибку сразу, а gdt[0] нельзя использовать но можно загружать без всяких проверок. Приходится в обработчиках прерываний явно перегружать селекторы.

Posted: Wed Mar 21, 2007 10:28 am
by Serge
Ghost

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

Верхние 4 Мб памяти приложения образуют область локальных данных потока. Каждый поток в многопоточном приложении сможет выделить там память для своих локальных переменных которые будут защищены от других потоков.
Вершину этой области займут системные данные. Сверху вниз: каталог таблиц страниц (PDBR), область сохранения FPU, точка входа ядра, стек. Все адреса будут фиксированными (по крайней мере пока ядро загруженно) Кроме того в зависимости от типа приложения на место точки входа будет копироваться соответствующий код. Таким образом каждая программа вызывая прерывание или fastcall попадёт именно на свою точку входа, а ядро сможет безопасно экспортировать для драйверов и сервисов функции к которым обычные программы не должны иметь доступ.

Адреса стека и входа будут опрделяться при загрузке ядра (будут задаваться константами) так что никаких вычислений делать не надо.

Надо подумать над передачей параметров для новых вызовов

Posted: Tue Mar 27, 2007 12:10 pm
by N†OSKRNL
мега-кул, ребята! ваши иследования помогли разобраться в теме int vs sysenter..
вобщем, тоже вот крутилась в голове идея на тему "служебных входов" в kmode в win2k, без особо лишних телодвижений (иногда довольно тесно приходится общаться с железяками, в связке с SoftICE).

И хотя это было не особо актуально - ну какбы усё боле-менее работало через драйвера, а вот решил заюзать прерывания - всетаки, как никак инструкция CPU, а не какие нить, системные функции (в которых я мало рублю, да и так, надебажив, этак с километр, пропадет охота там чето юзать).

что получилось.. поскрёб тут по сусекам в поисках DPL3 backdor'ов, и ага! int 2Ah, вроде как без дела торчит, с софт-айсом выйти на код обработчика, трабл особо никаких. не долго думая меняю обработчик забитый в глубинах
ntoskrnl следующим макаром.

Code: Select all

   xchg ecx, esp
   jmp  ecx
и.. бугага, бугага, бугага, код пашет так как и планировалось - в ring3 проге, обрабатываю прерывания.

Code: Select all

function int2A (_eax, _edx, _ecx :integer):integer;
asm
         pop   ecx  //  eip to return in r3
         int $2A 
         nop
         nop
         nop
         nop
         iretd;
end;
Потом мне этого показалось маловато, решил зохавать и sysenter. Вот, нарисовалась тестовая прога.
{$apptype console}
program test; uses windows;
const
count = 20000000;
MSR_SYSENTER_CS = $174;
MSR_SYSENTER_ESP = $175;
MSR_SYSENTER_EIP = $176;

var i, dwStart : integer;

function sys_enter:integer;
asm
sti
sysexit
end;

function sysenter(_eax, _edx, _ecx :integer):integer;
asm

pop edx // eip to return in r3
mov ecx, esp // esp to return in r3
sysenter
end;

function int2A (_eax, _edx, _ecx :integer):integer;
asm
pop ecx // eip to return in r3
int $2A
nop
nop
nop
nop
iretd;
end;


procedure setup_MSR;
asm
pop ecx
mov ebp, esp
int $2A

xor edx, edx
lea eax, sys_enter //загрузить указатель обработчика
mov ecx, MSR_SYSENTER_EIP
wrmsr

mov ecx, MSR_SYSENTER_CS
mov eax, 8 //WinNT kmode selector
wrmsr

mov eax, ebp
mov ecx, MSR_SYSENTER_ESP
wrmsr
iretd
end;

begin
write ('Wait... ');
Setup_MSR;
dwStart := GetTickCount;
for i:= 0 to count do int2A(0,0,0);
Write('int test: ', GetTickCount - dwStart, ', ');

dwStart := GetTickCount;
for i:= 0 to count do sysenter(0,0,0);
Writeln('sysenter test: ', GetTickCount - dwStart);

end.
результаты (на cel-1300):
Wait... int test: 4204, sysenter test: 1031

в принципе, с пивком потянет.

Так, веду кой какие разработки DOSx расширителя (по мотивам WDOSx & FreeDOS32),
вот.. ну а эNTяа2k, довольно ничего так полигон, для обкатки решений..
боле-менее на DOS начал смахивать, (хыы, а вместо Turbo Pascal7 - Turbo Delphi)... вотъ...

Posted: Tue Mar 27, 2007 12:40 pm
by N†OSKRNL
ой.. сори очепятался с esp... ну конечно же

Code: Select all

00064DBC: 870C24      xchg        ecx,[esp]
00064DBF:  FFE1           jmp         ecx
00064DC1:  90              nop
смещения для ntoskrnl for win2ksp2 (ProductVersion 5.00.2195.2951)...
реальная тачка несравниться с VMWARE или VirtPC ;) не тот драйв...

Posted: Tue Mar 27, 2007 3:56 pm
by Ghost
N†OSKRNL
Про SYSENTER + win2k : http://www.anticracking.sk/EliCZ/infos/syscall.zip
Это конечно здорово, но в рамках Колибри оффтоп )

Posted: Tue Mar 27, 2007 5:37 pm
by N†OSKRNL
Ghost - спасибо, комрад, супер семпл! просто когда темой занялся, гоогл вот к вам забросил, чему я весьма признателен... ну вы монстры!))) Serge - мега респект!

а селекторных регистров , воистину нужно избегать, всеми путями.. да уж
если бы не дурацкая осбенность IA32
которые так и прут, особено в экстримальнейших местах, таких как обработка прерываний или исключений.

вон скажем, тот же int 2a думал юзать без лишних регистровых
затрат, на передачу тогоже pop ecx .. однако в итоге пришлось таких огородов
городить (навроде откопать указатель из стека, нормализовать данные), что пришлось таки отказаться, от такого казалосьбы, небольшого удобства.. (да и не поместилось оно в очень сжатых рамках обработчика =(((

Posted: Wed Mar 28, 2007 3:45 pm
by Maxis
Это глюк или так и должно быть: тест syscal при ядре из файла flat.7z показывает ускорение по сравнению с прерыванием, но в ядре svn 429 syscall уже в несколько раз медленее чем прерывание. При использовании обновленного syscall test выполняется только часть тестов.

Posted: Wed Mar 28, 2007 4:25 pm
by Ghost
Прирост производительности будет только на плоском ядре и на реальном железе.

Posted: Thu Mar 29, 2007 4:34 pm
by diamond
Heavyiron wrote:Кстати, обнаружил некоторую странность: начиная с какой-то ревизии (и в официальном и во flat-kernel) на доске отладки во вкладке USER есть надписи, типа "cess - done", иногда просто буква "e", иногда "New process: loadind" (в зависимости от того, где запускаю). Так и должно быть или это глюк?
Это вызвано тем, что размер буфера под данные доски отладки кто-то увеличил до 4096 байт (svn утверждает, что последним к соответствующей строчке прикасался mike.dld в ревизии 373), а приложение board при запуске очищает только 1024 байт.

Posted: Fri Mar 30, 2007 9:19 pm
by <Lrz>
Новые тесты с новой ревизией #442 на Barton 2500+ (K7):
69bdc73-> SYSENTER
880128C-> SYSCALL
BDbfC06-> Interrupt

Для сравнения результаты от Heavyiron

тест с новой ревизией #400 на Sempron 2500+ (K7):
880B78B -> SYSENTER
9E0104C -> SYSCALL
DE18A36 -> Interrupt

Posted: Sun Apr 29, 2007 7:34 am
by Heavyiron
Новые тесты на новом железе:
7F0C850 -> SYSENTER
9D87F5C -> SYSCALL
E6142A9 -> INT 0x40

Posted: Thu May 10, 2007 5:48 pm
by Heavyiron
Все, для выбора варианта компиляции нужно изменить в svn\programs\config.inc значение переменной на "р5", "р6" либо "k6" для вызовов через прерывание, sysenter или syscall соответственно. После этого можно компилить старыми скриптами или же использовать build_all.bat, который спросит и все сделает сам, даже по папкам раскинет в \bin-е :)

Posted: Thu May 10, 2007 7:10 pm
by diamond
Угу, и скомпилированные с "p6" и "k6" программы вообще не будут работать на старых компах до каких-то-там пней.

Posted: Thu May 10, 2007 7:16 pm
by diamond
...и размерчик у выходных файлов с "p6"/"k6" заметно побольше будет...