Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 2002.12.23;
Скачать: [xml.tar.bz2];

Вниз

Помогите с векторами прерываний...!   Найти похожие ветки 

 
Youriy   (2002-10-03 21:12) [0]

Help! Как мне в Дэлфи изменить вектора прерываний на свой обработчик? Заранее благодарен.


 
Заранее   (2002-10-04 04:28) [1]

не за что. Поскольку тебя ожидает полный (почти) облом.


 
Digitman   (2002-10-04 08:18) [2]


unit PM;

interface

uses Windows;

const
// mask of TI-bit in selector
TI_GDT = 0;
TI_LDT = 4;
SYSDESC_ACCESS_TYPE_MASK = $0F;

type
TSysTableKind = (tkGDT, tkLDT, tkIDT);
TSysSegDescType = ( stUnused,
stTSS,
stLDT,
stTSS_BUSY,
stGATE_16,
stTASKGATE,
stINTRPT_16,
stEXCEPT_16,
stWRONG_TYPE,
stTSS_32,
stRESERVED1,
TSS_32_BUSY,
stGATE_32,
stRESERVED2,
stINTRPT_32,
stTRAP_32
);

TBaseLo = packed record
LoWord: Word;
LoByteHiWord: byte;
end;
PBaseLo = ^TBaseLo;

TSegmentDescriptor = packed record
LimitLo: Word;
BaseLo: TBaseLo;
ARPL: byte;
LimitHi: byte;
BaseHi: byte;
end;
PSegmentDescriptor = ^TSegmentDescriptor;

TLDTEntry = TSegmentDescriptor;
TGDTEntry = TSegmentDescriptor;
PLDTEntry = PSegmentDescriptor;
PGDTEntry = PSegmentDescriptor;

TIDTEntry = packed record
OffsetLo: Word;
Selector: Word;
Params: Byte;
Access: Byte;
OffsetHi: Word;
end;
PIDTEntry = ^TIDTEntry;

TSegmentInfo = packed record
Limit: Word;
Base: DWord;
end;
PSegmentInfo = ^TSegmentInfo;

function GetSegmentInfo(Selector: Word): PSegmentInfo;
function GetSegmentDesc(Selector: Word): PSegmentDescriptor;
function GetInterruptDesc(const InterruptNumber: Byte): PIDTEntry;
function GetSysTableCapacity(const SysTable: TSysTableKind): Integer;

implementation

var
GDTInfo, LDTInfo, IDTInfo: TSegmentInfo;
LDTSelector: Word;

procedure ReadWin9xSysTableInfo;
asm
sgdt [GDTInfo]
sidt [IDTInfo]
sldt eax
mov [LDTSelector], ax
and ax, $FFF8
add eax, [GDTInfo.Base]
mov dl, [eax + TGDTEntry.BaseLo.LoByteHiWord]
mov dh, [eax + TGDTEntry.BaseHi]
shl edx, 16
mov dx, [eax + TGDTEntry.BaseLo.LoWord]
mov [LDTInfo.Base], edx
mov dx, [eax + TGDTEntry.LimitLo]
mov [LDTInfo.Limit], dx
end;

function GetSegmentInfo(Selector: Word): PSegmentInfo;
var
DescAddr: DWord;
begin
Result := nil;
DescAddr := Selector and $FFF8;
case Selector and TI_LDT of
TI_GDT:
if DescAddr < GDTInfo.Limit then begin
DescAddr := DescAddr + GDTInfo.Base;
New(Result);
with Result^, PGDTEntry(DescAddr)^ do begin
Limit := LimitLo;
Base := (BaseHi shl 8 + BaseLo.LoByteHiWord) shl 16 + BaseLo.LoWord;
end;
end;
TI_LDT:
if DescAddr < LDTInfo.Limit then begin
DescAddr := DescAddr + LDTInfo.Base;
New(Result);
with Result^, PLDTEntry(DescAddr)^ do begin
Limit := LimitLo;
Base := (BaseHi shl 8 + BaseLo.LoByteHiWord) shl 16 + BaseLo.LoWord;
end;
end;
end;
end;

function GetSegmentDesc(Selector: Word): PSegmentDescriptor;
begin
Result := nil;
case Selector and TI_LDT of
TI_GDT:
begin
New(Result);
CopyMemory(Result, PGDTEntry((Selector and $FFF8) + GDTInfo.Base), SizeOf(TGDTEntry));
end;
TI_LDT:
begin
New(Result);
CopyMemory(Result, PLDTEntry((Selector and $FFF8) + LDTInfo.Base), SizeOf(TLDTEntry));
end;
end;
end;

function GetInterruptDesc(const InterruptNumber: Byte): PIDTEntry;
begin
Result := nil;
if InterruptNumber <= (IDTInfo.Limit + 1) shr 3 then begin
New(Result);
CopyMemory(Result, PIDTEntry(InterruptNumber shl 3 + IDTInfo.Base), SizeOf(TIDTEntry));
end;
end;

function GetSysTableCapacity(const SysTable: TSysTableKind): Integer;
begin
case SysTable of
tkGDT: Result := (GDTInfo.Limit + 1) shr 3;
tkLDT: Result := (LDTInfo.Limit + 1) shr 3;
tkIDT: Result := (IDTInfo.Limit + 1) shr 3;
else
Result := 0;
end;
end;

end.



 
Digitman   (2002-10-04 08:18) [3]


//***********************************************
program Ring0demo;

uses
Windows,
PM in "PM.pas";

var
idtr: TSegmentInfo;
old_gate, new_gate: TIDTEntry;
VerInfo: DWord;
IsNTplatform: Boolean;
MajorVersion, MinorVersion: Byte;
BuildNo: Word;
VerInfoStr: String;

//обработчик прерывания - процедура шлюза - выполняется с PL0
//маленький видеоэффект, демонстрирующий прямую работу с портами
procedure VideoMemScrolling;
asm
push eax
push ebx
push ecx
push edx
push esi

mov edx, $3D4
mov al, $C
out dx,al
mov edx, $3D5
in al, dx
mov bh, al
mov edx, $3D4
mov al, $D
out dx,al
mov edx, $3D5
in al, dx
mov bl, al
mov esi, ebx

sub ebx,ebx
mov ecx, 3000

@demo:
mov edx, $3D4
mov al, $C
out dx,al
mov edx, $3D5
mov al, bh
out dx,al
mov edx, $3D4
mov al, $D
out dx,al
mov edx, $3D5
mov al, bl
out dx,al
inc ebx
push ecx
mov ecx, $10000
@@1:
loop @@1
pop ecx
loop @demo

mov ebx, esi
mov edx, $3D4
mov al, $C
out dx,al
mov edx, $3D5
mov al, bh
out dx,al
mov edx, $3D4
mov al, $D
out dx,al
mov edx, $3D5
mov al, bl
out dx,al

pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
end;

function IntToStr(Value: Integer): String;
var
Remainder: Integer;
begin
Result := "";
repeat
Remainder := Value mod 10;
Value := Value div 10;
Result := char(Remainder + 48) + Result;
until Value = 0;
end;


begin
//чтение информации о версии ОС
VerInfo := GetVersion;
IsNTplatform := VerInfo < $80000000;
VerInfo := VerInfo and $7FFFFFFF;
MajorVersion := LoByte(LoWord(VerInfo));
MinorVersion := HiByte(LoWord(VerInfo));
BuildNo := HiWord(VerInfo);
VerInfoStr := "OS platform : ";
if IsNTplatform then
VerInfoStr := VerInfoStr + "NT"
else begin
VerInfoStr := VerInfoStr + "Win32";
if MajorVersion < 4 then
VerInfoStr := VerInfoStr + "s (with Win 3.x)"
else begin
VerInfoStr := VerInfoStr + "s (Win9x)";
BuildNo := 0;
end;
end;
VerInfoStr := VerInfoStr + #10"MajorVersion : " + IntToStr(MajorVersion);
VerInfoStr := VerInfoStr + #10"MinorVersion : " + IntToStr(MinorVersion);
VerInfoStr := VerInfoStr + #10"BuildNumber : " + IntToStr(BuildNo);
if IsNTplatform then
VerInfoStr := VerInfoStr + #10#10"Для работы приложения требуется ОС Win9x !"
else
VerInfoStr := VerInfoStr + #10#10"Нажмите ОК для старта демо...";
MessageBox(0, PChar(VerInfoStr), "Ring0 demo", MB_OK);
if IsNTplatform or (MajorVersion < 4) then
Exit;

// с ОС - порядок, начинаем подготовку к переходу на PL0
asm
//--------сохраним регистры ---------------------------
push ebx
push esi
push edi
//--------готовим новый дескриптор шлюза -----------------
mov eax, offset VideoMemScrolling
mov [new_gate.OffsetLo], ax
shr eax,16
mov [new_gate.OffsetHi], ax
mov [new_gate.Selector], $28
mov [new_gate.Params], 0
mov [new_gate.Access], $EE
//--------читаем инф-цию о сегменте IDT---------------------
sidt idtr
mov ebx, [idtr.Base]
add ebx, 8 * 9 // 9-е прерывание взято "от фонаря"
//--------сохраняем старый вектор прерывания ---------------
mov edi, offset old_gate
mov esi, ebx
cld
movsd
movsd
//--------устанавливаем новый вектор прерывания ---------------
mov edi, ebx
mov esi, offset new_gate
movsd
movsd
//--------входим в шлюз, в котором на PL0 будет выполнена --------
//--------процедура-обработчик VideoMemScrolling -----------------
int 9
//--------вышли из шлюза - мы снова на PL3 -----------------
mov edi,ebx
mov esi, offset old_gate
cld
movsd
movsd
//--------восстановим регистры -------------------------
pop edi
pop esi
pop ebx
end;
end.


 
RV   (2002-10-04 10:27) [4]

Digitman © - КРУТ!!!


 
Digitman   (2002-10-04 11:08) [5]

Ключевой код - не мой. Это - просто для примера, под руку попался ..


 
Tano   (2002-10-05 00:11) [6]

Круто! Сурово и сердито. Я думал такое из области системной фантастики :-) Thanks!


 
Tano   (2002-10-05 00:21) [7]

Только надо пояснить Youriy, что суть перехвата существенно отличается от DOSовской. Это видно и по коду и вытекает из принципов работы Windows, точнее защищенного режима.
Алаверды:
а как насчет NT? Не подскажит кто ссылочки на метериал либо пример. Везде натыкаюсь на Win9x-ориентированное, но там ассемблеру везде дорога, только применяй. NT более трепетно следит за PL0, а в свете популяризации WinXP вопрос начинает вставать остро.
Еще раз Thanks.


 
apay   (2002-10-20 16:55) [8]

Конечно можно, но в Ring0 соваться... Вообще то не очень рекомендуется... Лучше взять DDK и сделять маленькую VxD или Sys (для NT), можно и без ASM, изпользуя нечто вроде MSVC5


 
REA   (2002-10-21 11:59) [9]

Там вроде везде CopyMemory и т.п. - а как добраться не до виртуальной памяти не вылезая в кольцо 0? Или я чего то не понимаю? Весь код лень смотреть - в какой строке прикол то?


 
Игорь Шевченко   (2002-10-21 13:15) [10]

Я дико извиняюсь,

//--------вышли из шлюза - мы снова на PL3 -----------------
mov edi,ebx
mov esi, offset old_gate
cld
movsd
movsd

А что, в PL3 возможна запись в эти ячейки ?

Что-то не верится :-)))


 
Digitman   (2002-10-21 14:38) [11]

>Игорь Шевченко

Дык это ж - самая что ни на есть "сладкая" маздайная "дыра" !! ))) ..

Прочие "дыры" ни в какое сравнение не идут с этой замечательной лазейкой - только ленивый в нее еще не "лазил"

Попробуй сам - тебе понравится))


 
Игорь Шевченко   (2002-10-21 14:47) [12]

Digitman © (21.10.02 14:38)

Спасибо!

Вот потому я и не пользую потребительских версий Windows :-(

С уважением,


 
Digitman   (2002-10-21 14:59) [13]

>Игорь Шевченко

Я тоже. Только - винтукей.


 
REA   (2002-10-21 15:41) [14]

Нифига не понял. Пора наверно опять ассемблер учить.


 
Digitman   (2002-10-21 16:01) [15]

>REA

В любом случае - это оч даже не помешает



Страницы: 1 вся ветка

Форум: "Система";
Текущий архив: 2002.12.23;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.009 c
14-74981
Romychk
2002-11-29 11:32
2002.12.23
Вирусы


1-74767
Андрей М
2002-12-10 23:55
2002.12.23
Фейс ХР


4-75058
Василий
2002-11-06 18:01
2002.12.23
Как програмно инсталировать шрифт ?


7-75014
Sergey V. Shadrin
2002-10-16 17:52
2002.12.23
свободное место


4-75055
_pavel_
2002-11-11 11:09
2002.12.23
Handle





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский