Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Доступ в Ring0 под Windows 9x


Автор: jungle 26.6.2006, 10:37
Хэллоу, друзья! 

Помогите корректно перевести сишный сорсис для доступа в привилегированный режим ядра Windows 9x – Ring0. Мой перевод, увы, пока не работает. Может быть кто-то силён в Си и Delphi (паскаль) одновременно? Исходный cpp код в прикреплении.

Код

unit Ring09x;

interface

uses
  Windows;

  function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
  procedure Ring0ReadMSR; cdecl;

implementation

type

  TGDT_DESCRIPTOR = record
    Limit_0_15  : Word;
    Base_0_15   : Word;
    Base_16_23  : Byte;
    Type1       : Byte;
    System1     : Byte;
    DPL         : Byte;
    Present     : Byte;
    Limit_16_19 : Byte;
    Available   : Byte;
    Reserved    : Byte;
    D_B         : Byte;
    Granularity : Byte;
    Base_24_31  : Byte;
  end;

  TCALLGATE_DESCRIPTOR = record
    Offset_0_15 : Word;
    Selector    : Word;
    ParamCount  : Word;
    Unused      : Word;
    Type1       : Word;
    System1     : Word;
    DPL         : Word;
    Present     : Word;
    Offset_16_31: Word;
  end;

  TGDTR = record
    wGDTLimit : Word;
    dwGDTBase : Word;
  end;

procedure Ring0ReadMSR; cdecl;
asm
  rdmsr
  mov [ebx],eax
  mov [edi],edx
end;

procedure Ring0WriteMSR; cdecl;
asm
  mov eax,[ebx]
  mov edx,[edi]
  wrmsr
end;

function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
var
  pGDTDescriptor : ^TGDT_DESCRIPTOR;
  pCallgate : ^TCALLGATE_DESCRIPTOR;
  gdtr: TGDTR;
  wGDTIndex : Integer;
  CallgateAddr : array [0..2] of Word;
begin
  with pGDTDescriptor^ do begin
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
    Limit_16_19:=4;
    Available:=1;
    Reserved:=1;
    D_B:=1;
    Granularity:=1;
  end;
  with pCallgate^ do begin
    ParamCount:=5;
    Unused:=3;
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
  end;
  asm sgdt [gdtr] end;
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);
  wGDTIndex:=1;
  while wGDTIndex < (gdtr.wGDTLimit div 8) do
    begin
      if (pGDTDescriptor.Type1 = 0) and (pGDTDescriptor.System1 = 0) and
        (pGDTDescriptor.DPL = 0)  and (pGDTDescriptor.Present = 0) then
        begin
          pCallgate:=Addr(pGDTDescriptor);
          pCallgate.Offset_0_15:=LoWord(pvRing0FuncAddr);
          pCallgate.Selector:=$28;
          pCallgate.ParamCount:=0;
          pCallgate.Unused:=0;
          pCallgate.Type1:=$0C;
          pCallgate.System1:=0;
          pCallgate.DPL:=3;
          pCallgate.Present:=1;
          pCallgate.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr));
          CallgateAddr[0]:=0;
          CallgateAddr[1]:=0;
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;
          asm
            mov ebx, pulEAX
            mov edi, pulEDX
            mov ecx, ulECX
            call dword ptr [CallgateAddr]
          end;
          ZeroMemory(pGDTDescriptor, 8);
        end;
      Inc(pGDTDescriptor);
      Inc(wGDTIndex);
    end;
end;

end.


 

Автор: Romikgy 26.6.2006, 11:16
Код

type
CALLGATE_DESCRIPTOR=^TCALLGATE_DESCRIPTOR;

function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
var    
  pGDTDescriptor : ^TGDT_DESCRIPTOR;    
  pCallgate : ^TCALLGATE_DESCRIPTOR;    
  gdtr: TGDTR;    
  wGDTIndex : Integer;    
  CallgateAddr : array [0..2] of Word;    
begin    

  asm sgdt [gdtr] end;    
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);    
  for wGDTIndex:=1 to (gdtr.wGDTLimit/8) do
    begin    
      if (pGDTDescriptor^.Type1 = 0) and (pGDTDescriptor^.System1 = 0) and
        (pGDTDescriptor^.DPL = 0)  and (pGDTDescriptor^.Present = 0) then
        begin    
          pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor);
          pCallgate^.Offset_0_15:=LoWord(pvRing0FuncAddr);
          pCallgate^.Selector:=$28;
          pCallgate^.ParamCount:=0;
          pCallgate^.Unused:=0;
          pCallgate^.Type1:=$0C;
          pCallgate^.System1:=0;
          pCallgate^.DPL:=3;
          pCallgate^.Present:=1;
          pCallgate^.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr));
          CallgateAddr[0]:=0;    
          CallgateAddr[1]:=0;    
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;    
          asm    
            mov ebx, pulEAX    
            mov edi, pulEDX    
            mov ecx, ulECX    
            call dword ptr [CallgateAddr]    
          end;    
          ZeroMemory(pGDTDescriptor, 8);    
          CallRing0:=1;
          exit;
        end;    
      Inc(pGDTDescriptor);    
      //Inc(wGDTIndex);
    end;    
    CallRing0:=0;
end;

Имхо так smile 
вроде не ошибся 

Автор: jungle 26.6.2006, 11:39
Romikgy
Пишет Incompatible types для строчки pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor); smile  

О! Надо просто было объявить переменную pCallgate : CALLGATE_DESCRIPTOR;

Сейчас заценим под Windows 9x на другой машине…

Добавлено @ 11:51 
Romikgy

Неа, не катит - исключение "ошибка доступа... Запись данных по адресу". Код обновил.

Код

unit Ring09x;

interface

uses
  Windows;

  function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
  procedure Ring0ReadMSR; cdecl;

implementation

type

  TGDT_DESCRIPTOR = record
    Limit_0_15  : Word;
    Base_0_15   : Word;
    Base_16_23  : Byte;
    Type1       : Byte;
    System1     : Byte;
    DPL         : Byte;
    Present     : Byte;
    Limit_16_19 : Byte;
    Available   : Byte;
    Reserved    : Byte;
    D_B         : Byte;
    Granularity : Byte;
    Base_24_31  : Byte;
  end;

  TCALLGATE_DESCRIPTOR = record
    Offset_0_15 : Word;
    Selector    : Word;
    ParamCount  : Word;
    Unused      : Word;
    Type1       : Word;
    System1     : Word;
    DPL         : Word;
    Present     : Word;
    Offset_16_31: Word;
  end;
  CALLGATE_DESCRIPTOR=^TCALLGATE_DESCRIPTOR;

  TGDTR = record
    wGDTLimit : Word;
    dwGDTBase : Word;
  end;

procedure Ring0ReadMSR; cdecl;
asm
  rdmsr
  mov [ebx],eax
  mov [edi],edx
end;

procedure Ring0WriteMSR; cdecl;
asm
  mov eax,[ebx]
  mov edx,[edi]
  wrmsr
end;

function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
var
  pGDTDescriptor : ^TGDT_DESCRIPTOR;
  pCallgate : CALLGATE_DESCRIPTOR;
  gdtr: TGDTR;
  wGDTIndex : Integer;    
  CallgateAddr : array [0..2] of Word;
begin
  with pGDTDescriptor^ do begin
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
    Limit_16_19:=4;
    Available:=1;
    Reserved:=1;
    D_B:=1;
    Granularity:=1;
  end;
  with pCallgate^ do begin
    ParamCount:=5;
    Unused:=3;
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
  end;
  asm sgdt [gdtr] end;    
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);    
  for wGDTIndex:=1 to (gdtr.wGDTLimit div 8) do
    begin    
      if (pGDTDescriptor^.Type1 = 0) and (pGDTDescriptor^.System1 = 0) and
        (pGDTDescriptor^.DPL = 0)  and (pGDTDescriptor^.Present = 0) then
        begin
          pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor);
          pCallgate^.Offset_0_15:=LoWord(pvRing0FuncAddr);
          pCallgate^.Selector:=$28;
          pCallgate^.ParamCount:=0;
          pCallgate^.Unused:=0;
          pCallgate^.Type1:=$0C;
          pCallgate^.System1:=0;
          pCallgate^.DPL:=3;
          pCallgate^.Present:=1;
          pCallgate^.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr));
          CallgateAddr[0]:=0;
          CallgateAddr[1]:=0;    
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;    
          asm    
            mov ebx, pulEAX    
            mov edi, pulEDX    
            mov ecx, ulECX    
            call dword ptr [CallgateAddr]    
          end;    
          ZeroMemory(pGDTDescriptor, 8);    
          CallRing0:=1;
          exit;
        end;
      Inc(pGDTDescriptor);
    end;    
    CallRing0:=0;
end;

end.
 

Автор: Romikgy 26.6.2006, 12:24
Цитата(jungle @  26.6.2006,  10:39 Найти цитируемый пост)
 исключение "ошибка доступа... Запись данных по адресу".

Это где?
И я не понял , ты делаешь прогу не под 98, а запускаешь под 98?

Добавлено @ 12:34 
И вопрос который меня мучает в этой теме :
НА КОЙ ТЕБЕ ПОД 98 НУЖНО НУЛЕВОЕ КОЛЬЦО?????

Имхо в 98 проблем с асмом нет, нулевое кольцо нужно для планки виндов НТ 

Автор: jungle 26.6.2006, 13:37
Romikgy

Исходный код компилируется отлично. Как самый простейший пример – вызов функции CallRing0 я передаю в обработчике нажатия кнопки. Так вот после нажатия кнопки вываливается ошибка «Access violation at address XXXXX in module Project1.exe.Write of address XXXXX»

Нулевое кольцо под Windows 98 мне нужно для чтения привилегированных MSR-регистров процессора, в частности, для вызова инструкции rdmsr. Конечно, это цивилизованно делается через vxd-драйвер, который ещё нужно грамотно написать, но, увы, нет желания постигать устаревшую «грамоту».
 

Автор: Romikgy 26.6.2006, 14:59
jungle, покажи как используешь 
Цитата(jungle @  26.6.2006,  12:37 Найти цитируемый пост)
функции CallRing0 я передаю в обработчике нажатия кнопки

 smile 
Я дома проверю на 98 

Автор: jungle 26.6.2006, 15:14
Romikgy

Испоьзую очень просто: CallRing0(@Ring0ReadMSR,$10,0,0);

MSR $00000010 - счетчик тактов процессора TSC.

Я б Delphi на ту машину с Win98 поставил бы да  в отладчике прозвонил бы, да вот места на харде нет.
 

Автор: Romikgy 26.6.2006, 15:20
Цитата(jungle @  26.6.2006,  14:14 Найти цитируемый пост)
Ring0ReadMSR

какой структуры? 

Автор: jungle 26.6.2006, 15:36
Ring0ReadMSR - это процедура чтения MSR регистра, адрес которой должен передаваться в функцию CallRing0 для выполнения Ring0ReadMSR в нулевом кольце. 

Автор: Romikgy 26.6.2006, 16:12
Что должно быть после выполнения этой функции? 

Автор: jungle 26.6.2006, 16:43
Число, которое, увеличивается при каждом повторном считывании TSC регистра (адрес $10).

Добавлено @ 16:49 
Хотя не принципиально, какая функция должна быть выполнена в нулевом кольце. Можно, например, написать функцию чтения портов или любую другую и передать ее адрес в функцию CallRing0 в качестве первого параметра. Просто процедура чтения MSR регистров Ring0ReadMSR как раз та, которая мне нужна. 

Автор: Damarus 26.6.2006, 18:49
Я конечно не очень разбираюсь в Delphi, но моё мнение: структуры TGDT_DESCRIPTOR, TCALLGATE_DESCRIPTOR, TGDTR описаны не верно. 

Автор: Romikgy 26.6.2006, 19:29
Цитата(Damarus @  26.6.2006,  17:49 Найти цитируемый пост)
Я конечно не очень разбираюсь в Delphi, но моё мнение: структуры TGDT_DESCRIPTOR, TCALLGATE_DESCRIPTOR, TGDTR описаны не верно.  

хмммм.....
jungle, тогда хедерный файл в студию, а то в твоем архиве оба сишных, по внутреностям 

Автор: Damarus 26.6.2006, 20:30
Romikgy, думаю хедерный файл не поможет. Мне кожется они и в нём описаны не верно. Моё мнение основано на этом:

IA-32 Intel® Architecture Software Developer’s Manual Volume 3:
System Programming Guide

Цитата

2.4. MEMORY-MANAGEMENT REGISTERS

The processor provides four memory-management registers (GDTR, LDTR, IDTR, and TR)
that specify the locations of the data structures which control segmented memory management
(see Figure 2-4). Special instructions are provided for loading and storing these registers.

System Table Registers

Код

      47                        16 15                 0
      ---------------------------- --------------------
GDTR | 32-bit Linear Base Address | 16-Bit Table Limit |
      ---------------------------- --------------------
IDTR | 32-bit Linear Base Address | 16-Bit Table Limit |
      ---------------------------- --------------------



Цитата

4.8.3. Call Gates

Call gates facilitate controlled transfers of program control between different privilege levels.
They are typically used only in operating systems or executives that use the privilege-level
protection mechanism. Call gates are also useful for transferring program control between 16-bit
and 32-bit code segments, as described in Section 17.4., “Transferring Control Among Mixed-
Size Code Segments”.

Figure 4-7 shows the format of a call-gate descriptor. A call-gate descriptor may reside in the
GDT or in an LDT, but not in the interrupt descriptor table (IDT). It performs six functions:

  • It specifies the code segment to be accessed.
  • It defines an entry point for a procedure in the specified code segment.
  • It specifies the privilege level required for a caller trying to access the procedure.

Код

                               14
 31                     16  15  13  12 11            8 7    6    5 4      0
 ------------------------- --- --- --- --------------- ----------- --------
|                         |   | D |   |               |           |        |
| Offset in Segment 31:16 | P | P | 0 |      Type     | 0   0   0 | Param. |
|                         |   | L |   | 1 | 1 | 0 | 0 |           | Count  |
 ------------------------- --- --- --- --------------- ----------- --------

 31                     16 15                                             0
 ------------------------- --- --- --- --------------- ----------- --------
|                         |                                                |
|    Segment Selector     |         Offset in Segment 15:00                |
|                         |                                                |
 ------------------------- --- --- --- --------------- ----------- --------
        DPL Descriptor Privilege Level
        P   Gate Valid


  • If a stack switch occurs, it specifies the number of optional parameters to be copied
    between stacks.
  • It defines the size of values to be pushed onto the target stack: 16-bit gates force 16-bit
    pushes and 32-bit gates force 32-bit pushes.
  • It specifies whether the call-gate descriptor is valid.

The segment selector field in a call gate specifies the code segment to be accessed. The offset
field specifies the entry point in the code segment. This entry point is generally to the first
instruction of a specific procedure. The DPL field indicates the privilege level of the call gate,
which in turn is the privilege level required to access the selected procedure through the gate.
The P flag indicates whether the call-gate descriptor is valid. (The presence of the code segment
to which the gate points is indicated by the P flag in the code segment’s descriptor.) The parameter
count field indicates the number of parameters to copy from the calling procedures stack to
the new stack if a stack switch occurs (see Section 4.8.5., “Stack Switching”). The parameter
count specifies the number of words for 16-bit call gates and doublewords for 32-bit call gates.
 

Автор: jungle 27.6.2006, 08:35
Romikgy

Вот хедер:

Код

#ifndef __MSR_9X_H__
#define __MSR_9X_H__

#include <windows.h>

int CallRing0(PVOID pvRing0FuncAddr,ULONG ulECX,ULONG* ulEAX,ULONG* ulEDX);
void Ring0ReadMSR();
void Ring0WriteMSR();

#pragma pack(1)

struct GDT_DESCRIPTOR
{
    WORD Limit_0_15;
    WORD Base_0_15;
    BYTE Base_16_23;
    BYTE Type         : 4;
    BYTE System       : 1;
    BYTE DPL          : 2;
    BYTE Present      : 1;
    BYTE Limit_16_19  : 4;
    BYTE Available    : 1;
    BYTE Reserved     : 1;
    BYTE D_B          : 1;
    BYTE Granularity  : 1;
    BYTE Base_24_31;
};

struct CALLGATE_DESCRIPTOR
{
    WORD Offset_0_15;
    WORD Selector;
    WORD ParamCount   : 5;
    WORD Unused       : 3;
    WORD Type         : 4;
    WORD System       : 1;
    WORD DPL          : 2;
    WORD Present      : 1;
    WORD Offset_16_31;
};

struct GDTR
{
    WORD wGDTLimit;
    DWORD dwGDTBase;
};

#pragma pack()

#endif // __MSR_9X_H__
 

Автор: Romikgy 27.6.2006, 10:46
Код

                         unit Ring09x; 
interface 
uses 
  Windows; 
  function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer; 
  procedure Ring0ReadMSR; cdecl; 
implementation 
type 
  TGDT_DESCRIPTOR = record 
    Limit_0_15  : Word; 
    Base_0_15   : Word; 
    Base_16_23  : Byte; 
    Type_System_DPL_Present     : Byte;
    Limit_16_19_Available_Reserved_D_B_Granularity : Byte;
    Base_24_31  : Byte; 
  end; 
  TCALLGATE_DESCRIPTOR = record 
    Offset_0_15 : Word; 
    Selector    : Word; 
    ParamCount_Unused       : byte;
    Type_System_DPL_Present     : byte;
    Offset_16_31: Word; 
  end; 
  CALLGATE_DESCRIPTOR=^TCALLGATE_DESCRIPTOR; 
  TGDTR = record 
    wGDTLimit : Word; 
    dwGDTBase : dWord;
  end; 
procedure Ring0ReadMSR; cdecl; 
asm 
  rdmsr 
  mov [ebx],eax 
  mov [edi],edx 
end; 
procedure Ring0WriteMSR; cdecl; 
asm 
  mov eax,[ebx] 
  mov edx,[edi] 
  wrmsr 
end; 
function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer; 
var 
  pGDTDescriptor : ^TGDT_DESCRIPTOR; 
  pCallgate : CALLGATE_DESCRIPTOR; 
  gdtr: TGDTR; 
  wGDTIndex : Integer;     
  CallgateAddr : array [0..2] of Word; 
begin 
  with pGDTDescriptor^ do begin 
    Type1:=4; 
    System1:=1; 
    DPL:=2; 
    Present:=1; 
    Limit_16_19:=4; 
    Available:=1; 
    Reserved:=1; 
    D_B:=1; 
    Granularity:=1; 
  end; 
  with pCallgate^ do begin 
    ParamCount:=5; 
    Unused:=3; 
    Type1:=4; 
    System1:=1; 
    DPL:=2; 
    Present:=1; 
  end; 
  asm sgdt [gdtr] end;     
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);     
  for wGDTIndex:=1 to (gdtr.wGDTLimit div 8) do 
    begin     
      if (pGDTDescriptor^.Type_System_DPL_Present = 0)  then
        begin 
          pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor); 
          pCallgate^.Offset_0_15:=LoWord(pvRing0FuncAddr); 
          pCallgate^.Selector:=$28; 
          pCallgate^.ParamCount_Unused:=0;
          //pCallgate^.Unused:=0;
          pCallgate^.Type_System_DPL_Present:=$EC;

          pCallgate^.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr)); 
          CallgateAddr[0]:=0; 
          CallgateAddr[1]:=0;     
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;     
          asm     
            mov ebx, pulEAX     
            mov edi, pulEDX     
            mov ecx, ulECX     
            call dword ptr [CallgateAddr]     
          end;     
          ZeroMemory(pGDTDescriptor, 8);     
          CallRing0:=1; 
          exit; 
        end; 
      Inc(pGDTDescriptor); 
    end;     
    CallRing0:=0; 
end; 
end.

Так попробуй 

Автор: jungle 27.6.2006, 13:55
Нет, не катит. Пишет "Access violation at address.... Read of address....".  

Автор: Romikgy 27.6.2006, 15:27
jungle, после какой команды это? 

Автор: SergeCpp 27.6.2006, 15:50
Что касается RDTSC (MSR#10h), то он читается и без перехода в 0 кольцо...

В DOS-овской программе, работающей в Win9x-окне, правда не проходит... 

Автор: jungle 27.6.2006, 16:01
Romikgy
Цитата(Romikgy @  27.6.2006,  15:27 Найти цитируемый пост)
jungle, после какой команды это?  

Откуда ж мне знать? smile Я ж говорю, на тачке с Windows 98 нет свободного места для Delphi 6.0, чтобы продебажить код. Поэтому запустил скомпилированный EXE-файл и получил очередной облом. А почему структуры TGDT_DESCRIPTOR и TCALLGATE_DESCRIPTOR почиканы и не заполнены?  ИМХО инициализация большинства переменных обязательна. Сейчас припоминаю код из книжки «Программирование аппаратных средств под Windows», дык там тоже переменные инициализировались. Вечером сверюсь.

Цитата(SergeCpp @  27.6.2006,  15:50 Найти цитируемый пост)
Что касается RDTSC (MSR#0), то он читается и без перехода в 0 кольцо...  

Мне не нужна инструкция RDTSC, хотя и ее тоже можно сделать привилегированной через установку единственного бита CR-регистр процессора. TSC регистр взят в качестве совместимого как для всех AMD, так и Intel процессоров.

Добавлено @ 16:04 
Цитата(SergeCpp @  27.6.2006,  15:50 Найти цитируемый пост)
Что касается RDTSC (MSR#10h), то он читается и без перехода в 0 кольцо...


RDTSC - типичная инструкция процессора, а MSR 10h - регистр процессора, т.е. это абсолютно разные вещи. 

Автор: Romikgy 27.6.2006, 16:32
jungle,  дай весь исходник , что компилируешь, я дома проверю 

Автор: jungle 27.6.2006, 16:57
Romikgy, наиболее корректный: http://forum.vingrad.ru/index.php?showtopic=101839&st=0# (моё второе сообщение в этой ветке) 
Код, с учетом твоих последних поправок, также не рабочий. Поэтому код надо юзать тот, что указан по ссылке выше.
  

Автор: Romikgy 27.6.2006, 17:01
jungle,  нда , трудно было свой проект сжать и сюда закинуть ?
Или ты считаешь , что 
Цитата(jungle @  27.6.2006,  15:57 Найти цитируемый пост)
Поэтому код надо юзать тот, что указан по ссылке выше.

у меня этого кода нет?
Странный ты , тебе помочь , хочу, а ты не шивелишься smile
Как знаешь , сегодня я уже домой иду, буду в нете (нормальном) только послезавтра) бывай smile 

Автор: jungle 27.6.2006, 17:11
Лови!

Добавлено @ 17:14 
Надеюсь успел smile   

Автор: jungle 29.6.2006, 11:45
Здарова!

Заново переписал аналогичный сишный код, позаимствованный из книжки «Программирование аппаратных средств в Windows». Код отличается тем, что функция вызывает в нулевом кольце процедуры не чтения MSR-регистров, а чтения-записи портов. Сама суть поиска свободных дескрипторов та же самая. Прилагаемый архив содержит 4 страницы подробного сишного кода из вышеназванной книги и почти завершенный Delphi проект. Однако полагаю, что проблема как раз с передачей адреса вызываемой процедуры:

call fword ptr [CallgateAddr]

В Delphi типа fword не существует. Т.е. проблема с переводом кода на Delphi уже решена, остаётся только найти конкретную ошибку.
 

Автор: Romikgy 29.6.2006, 11:49
Цитата(jungle @  27.6.2006,  16:11 Найти цитируемый пост)
Надеюсь успел

нет
У меня все работает, кроме:
эти асм команды не воспринимаются

Цитата(jungle @  26.6.2006,  10:39 Найти цитируемый пост)
rdmsr


Цитата(jungle @  26.6.2006,  10:39 Найти цитируемый пост)
 wrmsr

,
немного помучился с SGDT ,
и его заюать получилось smile
но в ХР он ссылается на реальный участок памяти , в 98 в никуда smile

Что должно возращать эта команда?
и что за команды , которые не воспринимаются? с какого проца они есть ? у меня дома Атлон и или он не видит , или компилятор дельфей smile пробовал на 5 дельфе
Пробовал даже исходник на си запустить в си билдере, тоже не работает smile
отсель вопрос откуда код взят? и почему ты решил что он рабочий? 

Автор: jungle 29.6.2006, 14:26
Romikgy

Замени инструкции следующими эквивалентами в ассемблерной вставке

rdmsr – dw $320F
wrmsr – dw $300F

Инструкции rdmsr и wrmsr понимаются компилятором Delphi 6 и выше, иначе заменяй их опкодами, приведенными выше. 

Сорсис я нашел в инете – Гуглой по запросу Ring0+Delphi+Windows9x. Очень много ссылок приводилось на китайские сайты. С одного из них я и слил cpp и h-файл, ссылку, увы, не запомнил. Но сейчас я больше доверяю коду, который перевёл с книги, название которой я уже приводил.

Сейчас у меня проблема одна: компилятор Delphi 6 спотыкается на строчке
call fword ptr [CallgateAddr]
в ассемблерной вставке.
 

Автор: Romikgy 29.6.2006, 16:45
Цитата(jungle @  29.6.2006,  13:26 Найти цитируемый пост)
fword

А че это за тип такой? 

Автор: jungle 29.6.2006, 17:26
Похоже Паскальный аналог Int64 - 4 слова. 

Автор: dumb 30.6.2006, 01:57
не, не похоже smile
48 бит. селектор+оффсет

примерно так, чтобы не париться с компилером:
Код

push word ptr [CallgateAddr+4]
push dword ptr [CallgateAddr]
call fword ptr [esp]
add esp, 6

если что, заменить "call fword ptr [esp]" на "dd 90241cffh" 

Автор: Girder 30.6.2006, 09:08
Код

           Lea eax,CallgateAddr
           DB 0FFh, 018h
  

Автор: jungle 30.6.2006, 12:16
Вот в чем фигня:
Код

var
  pGDTHandle   : GDT_HANDLE;
begin
  GetMem(pGDTHandle,sizeOf(pGDTHandle));
  ZeroMemory(pGDTHandle,sizeOf(pGDTHandle));

  asm sgdt [gdt] end;
  pGDTHandle:=GDT_HANDLE(ptr(gdt.dwGDTBase + 8));
  showmessage(Inttostr(pGDTHandle^.IsRead)); //для отладки

  if (pGDTHandle^.IsRead = 0) and
     (pGDTHandle^.DPL = 0) and 
     (pGDTHandle^.SegType = 0) and
     (pGDTHandle^.Access = 0) then

end;

  
Процедура showmessage вызовет исключение, т.к. переменная pGDTHandle будет содержать только адрес gdt.dwGDTBase дескриптора, но не заполненную структуру GDT_HANDLE. А значит, при попытке обратиться к полям записи pGDTHandle будет всегда генерироваться ошибка чтения. 

Т.е. строчка 
Код
pGDTHandle:=GDT_HANDLE(ptr(gdt.dwGDTBase + 8));

Не заполняет поля переменной pGDTHandle содержанием полей дескриптора!  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)