Головна сторінка
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.62 MB
Час: 0.033 c
3-74569
Oleg_Em
2002-12-04 13:41
2002.12.23
виклик функції в запиті ....


1-74754
Верховний
2002-12-13 12:54
2002.12.23
Цикл для призначення властивостей безлічі Компаненти.


4-75056
вигнутий
2002-11-10 06:56
2002.12.23
Ка дізнатися повний шлях до файлу?


1-74690
Fernis
2002-12-13 04:32
2002.12.23
Свій коллекшен Айтем ...


3-74542
Evyshka
2002-12-03 16:50
2002.12.23
Пошук по записах





африкаанс албанський арабська вірменин азербайджанець баскський білоруський болгарська каталонський Китайська (спрощене письмо) Китайський традиційний) хорватський чеська данську мову нідерландський Ukranian естонець Філіппінська фінську мову французький
галісійська грузинський німецький грецький гаїтянський креольський давньоєврейську хінді угорський ісландський індонезієць ірландський італійський японський корейський латиська литовець македонець малайський мальтійський норвежець
перс полірування португальська румунський російська сербський словацький словенський іспанська суахілі шведську мову тайський турецька український урду в'єтнамський валлійський ідиш бенгальський боснійський
кебуано есперанто гуджараті хауса хмонг ігбо яванський каннада кхмерская Лао латинь маорі маратхі монгольський непальська панджабі сомалійський тамільська телугу йоруба
зулуський
Англійська Французький Німецький Італійський Португальська Русский Іспанська