Форум: "Система";
Текущий архив: 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