Unit MainForm;

{
  Tento soubor zajistuje obsluhu udalosti grafickeho uzivatelskeho
  rozhrani programu SSDTInfo. Nachazi se v nem take metody na provedeni
  kontroly tabulek systemovych volani.
}

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes,
  Graphics, Controls, Forms, Utils, SSDT,
  Dialogs, Menus, StdCtrls, ComCtrls;

Type
  TForm1 = Class (TForm)
    MainMenu1: TMainMenu;
    FuleMenuItem: TMenuItem;
    ExitMenuItem: TMenuItem;
    TableMenuItem: TMenuItem;
    KeServiceDescriptorTable1: TMenuItem;
    KeServiceDescriptorTableShadow1: TMenuItem;
    N1: TMenuItem;
    RefreshMenuItem: TMenuItem;
    PageControl1: TPageControl;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    TabSheet4: TTabSheet;
    TabSheet5: TTabSheet;
    TabSheet6: TTabSheet;
    ListView1: TListView;
    ListView2: TListView;
    ListView3: TListView;
    ListView4: TListView;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    GroupBox2: TGroupBox;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    GroupBox3: TGroupBox;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    GroupBox4: TGroupBox;
    Label25: TLabel;
    Label26: TLabel;
    Label27: TLabel;
    Label28: TLabel;
    Label29: TLabel;
    Label30: TLabel;
    Label31: TLabel;
    Label32: TLabel;
    Label33: TLabel;
    Label34: TLabel;
    TabSheet1: TTabSheet;
    ListView5: TListView;
    CheckMenuItem: TMenuItem;
    Procedure ExitMenuItemClick(Sender: TObject);
    Procedure FormCreate(Sender: TObject);
    Procedure RefreshMenuItemClick(Sender: TObject);
    Procedure KeServiceDescriptorTable1Click(Sender: TObject);
    Procedure KeServiceDescriptorTableShadow1Click(Sender: TObject);
    Procedure CheckMenuItemClick(Sender: TObject);
  Private
    // Aktualni tabulka systemovych volani (normalni ci shadow)
    FTableType : Cardinal;
    // Adresy tabulek adres ystemovych sluzeb
    FAddressTables : Array [0..3] Of TLabel;
    // Adresy tabulek citacu
    FCounterTables : Array [0..3] Of TLabel;
    // Pocty systemovych sluzeb v jednotlivych subtabulkach
    FNumbersOfServices : Array [0..3] Of TLabel;
    // Adresy tabulek argumentu v jednotlivych systemovych sluzbach
    FArgumentTables : Array [0..3] Of TLabel;
    // Ovladaci prvky ListView pro zobrazovni obsahu jednotlivych
    // podtabulek
    FListViews : Array [0..3] Of TListView;
    Procedure SetMenu;
    Procedure CheckSSDT(Table:PSERVICE_TABLE; DriverNameList:TNameList; DriverBaseList:TPointerList; DriverSizeList:TIntegerList);
    Procedure CheckSSDTShadow(Table:PSERVICE_TABLE; DriverNameList:TNameList; DriverBaseList:TPointerList; DriverSizeList:TIntegerList);
    Procedure ShowSSDTInfo(Info:PSSDTInfo; DriverNameList:TNameList; DriverBaseList:TPointerList; DriverSizeList:TIntegerList);
  end;

Var
  Form1: TForm1;

Implementation

{$R *.DFM}

Procedure TForm1.SetMenu;
{
  Nastavi viditelnost ruznych prvku uzivatilskeho rozhrani v zavislosti
  na verzi operacniho systemu.
}
Var
  Major, Minor, Build : Cardinal;
begin
GetOSVersion(Major, Minor, Build);
TabSheet5.TabVisible := Not (Major = 6);
TabSheet6.TabVisible := Not (Major = 6);
GroupBox4.Enabled := Not (Major = 6);
GroupBox3.Enabled := Not (Major = 6);
GroupBox3.Visible := Not (Major = 6);
GroupBox4.Visible := Not (Major = 6);
end;

Procedure TForm1.CheckSSDT(Table:PSERVICE_TABLE; DriverNameList:TNameList; DriverBaseList:TPointerList; DriverSizeList:TIntegerList);
{
  Zkontroluje tabulku systemovych volani pouze hlavniho
  modulu jadra. Problemy zobrazi do ovladaciho prvku ListView
}
Var
  S : SERVICE_TABLE_ENTRY;
  AddressTableOwner : Integer;
  ArgumentTableOwner : Integer;
  pAddresses : PAddressTable;
  pOrigAddresses : PAddressTable;
  Size : Cardinal;
  Ret : Boolean;
  I : Integer;
  SubtablesCount : Cardinal;
begin
S := Table^.Subtables[0];
AddressTableOwner := GetAddressOwner(DriverBaseList, DriverSizeList, S.ServiceTable);
ArgumentTableOwner := GetAddressOwner(DriverBaseList, DriverSizeList, S.ArgumentTable);
if (AddressTableOwner = -1) Or
  (Not ((DriverNameList[AddressTableOwner] = GetSysDir + '\ntoskrnl.exe') Or
  (DriverNameList[AddressTableOwner] = GetSysDir + '\ntkrnlpa.exe'))) Then
  begin
  With ListView5.Items.Add Do
    begin
    Caption := 'KeServiceDescriptorTable';
    SubItems.Add('Adresa tabulky adres');
    if AddressTableOwner <> -1 Then
      SubItems.Add(DriverNameList[AddressTableOwner])
    Else SubItems.Add('N/A');
    SubItems.Add(Format('%s\ntoskrnl.exe', [GetSysDir]));
    end;
  end;

If (ArgumentTableOwner = -1) Or
  (Not ((DriverNameList[ArgumentTableOwner] = GetSysDir + '\ntoskrnl.exe') Or
  (DriverNameList[ArgumentTableOwner] = GetSysDir + '\ntkrnlpa.exe'))) Then
   begin
   With ListView5.Items.Add Do
     begin
     Caption := 'KeServiceDescriptorTable';
     SubItems.Add('Adresa tabulky argumentu');
     If ArgumentTableOwner <> -1 Then
       SubItems.Add(DriverNameList[ArgumentTableOwner])
     Else SubItems.Add('N/A');
     SubItems.Add(Format('%s\ntoskrnl.exe', [GetSysDir]));
     end;
   end;

If S.NumberOfServices >= 500 Then
  begin
  With ListView5.Items.Add Do
    begin
    Caption := 'KeServiceDescriptorTable';
    SubItems.Add('Prilis mnoho sluzeb');
    SubItems.Add(IntToStr(Int64(S.NumberOfServices)));
    SubItems.Add('Mene nez 500');
    end;
  end
Else begin
  Size := S.NumberOfServices * SizeOf(Pointer);
  pAddresses := MemAlloc(Size);
  If Assigned(pAddresses) Then
    begin
    Ret := SSDTGetAddressTable(0, pAddresses, Size);
    If Ret Then
      begin
      Size := S.NumberOfServices * SizeOf(Pointer);
      pOrigAddresses := MemAlloc(Size);
      If Assigned(pOrigAddresses) Then
        begin
        Ret := SSDTGetOriginalAddresses(@S, pOrigAddresses, Size);
        If Ret Then
          begin
          For I := 0 To S.NumberOfServices - 1 Do
            begin
            If (pAddresses^[I] <> pOrigAddresses^[I]) Then
              begin
              With ListView5.Items.Add Do
                begin
                Caption := ('KeServiceDescriptorTable');
                SubItems.Add(SSDTGetFunctionName(I));
                SubItems.Add(AddressToModuleName(pAddresses^[I], DriverNameList, DriverBaseList, DriverSizeList));
                SubItems.Add(AddressToModuleName(pOrigAddresses^[I], DriverNameList, DriverBaseList, DriverSizeList));
                end;
              end;
            end;
          end Else Error('Nepodarilo se ziskat originalni adresy sluzeb!');

        MemFree(pOrigAddresses);
        end;
      end Else Error('Nepodarilo se ziskat adresy KeServiceDescriptorTable!');

    MemFree(pAddresses);
    end;
  end;

SubtablesCount := SSDTGetSubtablesCount;
For I := 1 To SubtablesCount - 1 Do
  begin
  S := Table^.Subtables[I];
  If Assigned(S.ServiceTable) Then
    begin
    With ListView5.Items.Add DO
      begin
      Caption := 'KeServiceDescriptorTable';
      SubItems.Add(Format('Podtabulka %d: Tabulka adres', [I]));
      SubItems.Add(IntToHex(Int64(S.ServiceTable),8));
      SubItems.Add('00000000');
      end;
    end;

  if S.NumberOfServices > 0 Then
    begin
    With ListView5.Items.Add DO
      begin
      Caption := 'KeServiceDescriptorTable';
      SubItems.Add(Format('Podtabulka %d: Pocet sluzeb', [I]));
      SubItems.Add(IntToStr(Int64(S.NumberOfServices)));
      SubItems.Add('0');
      end;
    end;

  If Assigned(S.ArgumentTable) Then
    begin
    With ListView5.Items.Add DO
      begin
      Caption := 'KeServiceDescriptorTable';
      SubItems.Add(Format('Podtabulka %d: Tabulka argumentu', [I]));
      SubItems.Add(IntToHex(Int64(S.ArgumentTable),8));
      SubItems.Add('00000000');
      end;
    end;
  end;
end;

Procedure TForm1.CheckSSDTShadow(Table:PSERVICE_TABLE; DriverNameList:TNameList; DriverBaseList:TPointerList; DriverSizeList:TIntegerList);
{
  Zkontroluje stinovou tabulku systemovyh volani (obe jeji subtabulky).
  Vysledky kontroly zapise do ovalaciho prvku ListView
}
Var
  S : SERVICE_TABLE_ENTRY;
  AddressTableOwner : Integer;
  ArgumentTableOwner : Integer;
  pAddresses : PAddressTable;
  pOrigAddresses : PAddressTable;
  Size : Cardinal;
  Ret : Boolean;
  I : Integer;
  SubtablesCount : Cardinal;
begin
S := Table^.Subtables[0];
AddressTableOwner := GetAddressOwner(DriverBaseList, DriverSizeList, S.ServiceTable);
ArgumentTableOwner := GetAddressOwner(DriverBaseList, DriverSizeList, S.ArgumentTable);
if (AddressTableOwner = -1) Or
  (Not ((DriverNameList[AddressTableOwner] = GetSysDir + '\ntoskrnl.exe') Or
  (DriverNameList[AddressTableOwner] = GetSysDir + '\ntkrnlpa.exe'))) Then
  begin
  With ListView5.Items.Add Do
    begin
    Caption := 'KeServiceDescriptorTableShadow';
    SubItems.Add('Adresa tabulky adres');
    If AddressTableOwner <> -1 Then
      SubItems.Add(DriverNameList[AddressTableOwner])
    Else SubItems.Add('N/A');
    SubItems.Add(Format('%s\ntoskrnl.exe', [GetSysDir]));
    end;
  end;

If (ArgumentTableOwner = -1) Or
   (Not ((DriverNameList[ArgumentTableOwner] = GetSysDir + '\ntoskrnl.exe') Or
  (DriverNameList[ArgumentTableOwner] = GetSysDir + '\ntkrnlpa.exe'))) Then
  begin
  With ListView5.Items.Add Do
    begin
    Caption := 'KeServiceDescriptorTableShadow';
    SubItems.Add('Adresa tabulky argumentu');
    If ArgumentTableOwner <> -1 Then
      SubItems.Add(DriverNameList[ArgumentTableOwner])
    Else SubItems.Add('N/A');
    SubItems.Add(Format('%s\ntoskrnl.exe', [GetSysDir]));
    end;
  end;

If S.NumberOfServices >= 500 Then
  begin
  With ListView5.Items.Add Do
    begin
    Caption := 'KeServiceDescriptorTableShadow';
    SubItems.Add('Prilis mnoho sluzeb');
    SubItems.Add(IntToStr(Int64(S.NumberOfServices)));
    SubItems.Add('Mene nez 500');
    end;
  end
Else begin
  Size := S.NumberOfServices * SizeOf(Pointer);
  pAddresses := MemAlloc(Size);
  If Assigned(pAddresses) Then
    begin
    Ret := SSDTShadowGetAddressTable(0, pAddresses, Size);
    If Ret Then
      begin
      Size := S.NumberOfServices * SizeOf(Pointer);
      pOrigAddresses := MemAlloc(Size);
      If Assigned(pOrigAddresses) Then
        begin
        Ret := SSDTGetOriginalAddresses(@S, pOrigAddresses, Size);
        If Ret Then
          begin
          For I := 0 To S.NumberOfServices - 1 Do
            begin
            If (pAddresses^[I] <> pOrigAddresses^[I]) Then
              begin
              With ListView5.Items.Add Do
                begin
                Caption := ('KeServiceDescriptorTableShadow');
                SubItems.Add(SSDTGetFunctionName(I));
                SubItems.Add(AddressToModuleName(pAddresses^[I], DriverNameList, DriverBaseList, DriverSizeList));
                SubItems.Add(AddressToModuleName(pOrigAddresses^[I], DriverNameList, DriverBaseList, DriverSizeList));
                end;
              end;
            end;
          end Else Error('Nepodarilo se ziskat originalni adresy sluzeb!');

        MemFree(pOrigAddresses);
        end;
      end Else Error('Nepodarilo se ziskat adresy KeServiceDescriptorTable!');

    MemFree(pAddresses);
    end;
  end;

S := Table^.Subtables[1];
AddressTableOwner := GetAddressOwner(DriverBaseList, DriverSizeList, S.ServiceTable);
ArgumentTableOwner := GetAddressOwner(DriverBaseList, DriverSizeList, S.ArgumentTable);
if (AddressTableOwner = -1) Or
   (Not (DriverNameList[AddressTableOwner] = GetSysDir + '\win32k.sys')) Then
   begin
   With ListView5.Items.Add Do
     begin
     Caption := 'KeServiceDescriptorTableShadow';
     SubItems.Add('Adresa tabulky adres');
     if AddressTableOwner <> -1 Then
       SubItems.Add(DriverNameList[AddressTableOwner])
     Else SubItems.Add('N/A');
     SubItems.Add(Format('%s\win32k.sys', [GetSysDir]));
     end;
   end;

If (ArgumentTableOwner = -1) Or
   (Not (DriverNameList[ArgumentTableOwner] = GetSysDir + '\win32k.sys')) Then
   begin
   With ListView5.Items.Add Do
     begin
     Caption := 'KeServiceDescriptorTableShadow';
     SubItems.Add('Adresa tabulky argumentu');
     If ArgumentTableOwner <> -1 Then
       SubItems.Add(DriverNameList[ArgumentTableOwner])
     Else SubItems.Add('N/A');
     SubItems.Add(Format('%s\win32k.sys', [GetSysDir]));
     end;
   end;

If S.NumberOfServices >= 1000 Then
  begin
  With ListView5.Items.Add Do
    begin
    Caption := 'KeServiceDescriptorTableShadow';
    SubItems.Add('Prilis mnoho sluzeb');
    SubItems.Add(IntToStr(Int64(S.NumberOfServices)));
    SubItems.Add('Mene nez 1000');
    end;
  end
Else begin
  Size := S.NumberOfServices * SizeOf(Pointer);
  pAddresses := MemAlloc(Size);
  If Assigned(pAddresses) Then
    begin
    Ret := SSDTShadowGetAddressTable(1, pAddresses, Size);
    If Ret Then
      begin
      Size := S.NumberOfServices * SizeOf(Pointer);
      pOrigAddresses := MemAlloc(Size);
      If Assigned(pOrigAddresses) Then
        begin
        Ret := SSDTShadowGetOriginalAddresses(@S, pOrigAddresses, Size);
        If Ret Then
          begin
          For I := 0 To S.NumberOfServices - 1 Do
            begin
            If (pAddresses^[I] <> pOrigAddresses^[I]) Then
              begin
              With ListView5.Items.Add Do
                begin
                Caption := ('KeServiceDescriptorTableShadow');
                SubItems.Add(SSDTShadowGetFunctionName(I));
                SubItems.Add(AddressToModuleName(pAddresses^[I], DriverNameList, DriverBaseList, DriverSizeList));
                SubItems.Add(AddressToModuleName(pOrigAddresses^[I], DriverNameList, DriverBaseList, DriverSizeList));
                end;
              end;
            end;
          end Else Error('Nepodarilo se ziskat originalni adresy sluzeb!');

        MemFree(pOrigAddresses);
        end;
      end Else Error('Nepodarilo se ziskat adresy KeServiceDescriptorTable!');

    MemFree(pAddresses);
    end;
  end;

SubtablesCount := SSDTGetSubtablesCount;
For I := 2 To SubtablesCount - 1 Do
  begin
  S := Table^.Subtables[I];
  If Assigned(S.ServiceTable) Then
    begin
    With ListView5.Items.Add DO
      begin
      Caption := 'KeServiceDescriptorTableShadow';
      SubItems.Add(Format('Podtabulka %d: Tabulka adres', [I]));
      SubItems.Add(IntToHex(Int64(S.ServiceTable), 8));
      SubItems.Add('00000000');
      end;
    end;

  if S.NumberOfServices > 0 Then
    begin
    With ListView5.Items.Add DO
      begin
      Caption := 'KeServiceDescriptorTableShadow';
      SubItems.Add(Format('Podtabulka %d: Pocet sluzeb', [I]));
      SubItems.Add(IntToStr(Int64(S.NumberOfServices)));
      SubItems.Add('0');
      end;
    end;

  If Assigned(S.ArgumentTable) Then
    begin
    With ListView5.Items.Add DO
      begin
      Caption := 'KeServiceDescriptorTableShadow';
      SubItems.Add(Format('Podtabulka %d: Tabulka argumentu', [I]));
      SubItems.Add(IntToHex(Int64(S.ArgumentTable),8));
      SubItems.Add('00000000');
      end;
    end;
  end;
end;

Procedure TForm1.CheckMenuItemClick(Sender: TObject);
{
  Tato rutina se vykona po stisknuti volby kontroly v hlavnim menu.
  Rutina provede nekolik kontrol a nasledne zkontroluje tabulky
  systemovych volani pomoci vyse popsanych funkci.
}
Var
  Ret : Boolean;
  DriverNameList : TNameList;
  DriverBaseList : TPointerList;
  DriverSizeList : TIntegerList;

  S : SERVICE_TABLE;
  TableAddress : Pointer;
  SS : SERVICE_TABLE;
  STableAddress : Pointer;
  idx : Integer;
begin
ListView5.Clear;
Ret := GetDriverList(DriverNameList, DriverBaseList, DriverSizeList);
If Ret Then
  begin
  Ret := SSDTGetGeneralInfo(@S, TableAddress);
  If Ret Then
    begin
    idx := GetAddressOwner(DriverBaseList, DriverSizeList, TableAddress);
    if (idx = -1) Or
      (Not ((DriverNameList[idx] = GetSysDir + '\ntoskrnl.exe') Or
      (DriverNameList[idx] = GetSysDir + '\ntkrnlpa.exe'))) Then
      begin
      With ListView5.Items.Add Do
        begin
        Caption := 'KeServiceDescriptorTable';
        SubItems.Add('Chybna adresa tabulky');
        If idx <> -1 Then
          SubItems.Add(DriverNameList[idx])
        Else SubItems.Add('N/A');
        SubItems.Add(Format('%s\ntoskrnl.exe', [GetSysDir]));
        end;
      end;

    CheckSSDT(@S, DriverNameList, DriverBaseList, DriverSizeList);
    end Else Error('Nepodarilo se ziskat obecne informace o KeServiceDescriptorTable!');

  Ret := SSDTShadowGetGeneralInfo(@SS, STableAddress);
  If Ret Then
    begin
    idx := GetAddressOwner(DriverBaseList, DriverSizeList, STableAddress);
    if (idx = -1) Or
      (Not ((DriverNameList[idx] = GetSysDir + '\ntoskrnl.exe') Or
      (DriverNameList[idx] = GetSysDir + '\ntkrnlpa.exe'))) Then
      begin
      With ListView5.Items.Add Do
        begin
        Caption := 'KeServiceDescriptorTableShadow';
        SubItems.Add('Chybna adresa tabulky');
        If idx <> -1 Then
          SubItems.Add(DriverNameList[idx])
        Else SubItems.Add('N/A');
        SubItems.Add(Format('%s\ntoskrnl.ëxe', [GetSysDir]));
        end;
      end;

    CheckSSDTShadow(@SS, DriverNameList, DriverBaseList, DriverSizeList);
    end Else Error('Nepodarilo se ziskat obecne informace o KeServiceDescriptorTableShadow!');

  If Ret Then
    begin
    If (S.Subtables[0].ServiceTable <> SS.Subtables[0].ServiceTable) Then
      begin
      With ListView5.Items.Add Do
        begin
        Caption := 'Obe';
        SubItems.Add('Adresy tabulek adres nesouhlasi');
        SubItems.Add(Format('%p x %p', [S.Subtables[0].ServiceTable, SS.Subtables[0].ServiceTable]));
        SubItems.Add('=');
        end;
      end;

    If (S.Subtables[0].ArgumentTable <> SS.Subtables[0].ArgumentTable) Then
      begin
      With ListView5.Items.Add Do
        begin
        Caption := 'Obe';
        SubItems.Add('Adresy tabulek argumentu nesouhlasi');
        SubItems.Add(Format('%p, %p', [S.Subtables[0].ArgumentTable, SS.Subtables[0].ArgumentTable]));
        SubItems.Add('=');
        end;
      end;
    end;

  DriverNameList := Nil;
  DriverBaseList := Nil;
  DriverSizeList := Nil;
  end Else Error('Nepodarilo se ziskat seznam ovladacu!');
end;

Procedure TForm1.ShowSSDTInfo(Info:PSSDTInfo; DriverNameList:TNameList; DriverBaseList:TPointerList; DriverSizeList:TIntegerList);
{
  Zobrazi informace o aktualne vybrane tabulce systemovych volani
}
Var
  I, K : Integer;
  idx : Integer;
begin
Label34.Caption := AddressToModuleName(Info^.TableAddress, DriverNameList, DriverBaseList, DriverSizeList);
For I := 0 To Info^.NumberOfSubtables - 1 Do
  begin
  FAddressTables[I].Caption := AddressToModuleName(Info^.Table.Subtables[I].ServiceTable, DriverNameList, DriverBaseList, DriverSizeList);
  FCounterTables[I].Caption := AddressToModuleName(Info^.Table.Subtables[I].CounterTable, DriverNameList, DriverBaseList, DriverSizeList);
  FNumbersOfServices[I].Caption := IntToStr(Int64(Info^.Table.Subtables[I].NumberOfServices));
  FArgumentTables[I].Caption := AddressToModuleName(Info^.Table.Subtables[I].ArgumentTable, DriverNameList, DriverBaseList, DriverSizeList);
  end;

For I := 0 To Info^.NumberOfSubtables - 1 Do
  begin
  FListViews[I].Clear;
  With FListViews[I] Do
    begin
    PageControl1.Pages[I + 1].TabVisible := Info^.Table.Subtables[I].NumberOfServices > 0;
    PageControl1.Pages[I + 1].Enabled := Info^.Table.Subtables[I].NumberOfServices > 0;
    Items.BeginUpdate;
    For K := 0 To Info^.Table.Subtables[I].NumberOfServices - 1 Do
      begin
      With Items.Add Do
        begin
        Caption := IntToStr(K);
        SubItems.Add(_SSDTGetFunctionName(FTableType, I, K));
        If Assigned(Info^.Addresses[I]) Then
          begin
          If Info^.AddressesRetrieved[I] Then
            begin
            SubItems.Add(IntToHex(Int64(Info^.Addresses[I]^[K]),8))
            end Else SubItems.Add('<chyba>');
          end Else SubItems.Add('N/A');

        If Assigned(Info^.Addresses[I]) Then
          begin
          If Info^.AddressesRetrieved[I] Then
            begin
            idx := GetAddressOwner(DriverBaseList, DriverSizeList, Info^.Addresses[I]^[K]);
            If idx <> -1 Then
              SubItems.Add(DriverNameList[idx])
            Else SubItems.Add('N/A');
            end Else SubItems.Add('<chyba>');
        end Else SubItems.Add('N/A');

        If Assigned(Info^.Arguments[I]) Then
          begin
          If Info^.ArgumentsRetrieved[I] Then
            begin
            SubItems.Add(IntToStr(Info^.Arguments[I]^[K] Div SizeOf(Cardinal)))
            end Else SubItems.Add('<chyba>');;
          end Else SubItems.Add('N/A');

        If Assigned(Info^.Counters[I]) Then
          begin
          If Info^.CountersRetrieved[I] Then
            begin
            SubItems.Add(IntToStr(Int64(Info^.Counters[I]^[K])))
            end Else SubItems.Add('<chyba>');;
          end Else SubItems.Add('N/A');

        If Assigned(Info^.OriginalAddresses[I]) Then
          begin
          If Info^.OriginalAddressesRetrieved[I] Then
            begin
            SubItems.Add(IntToHex(Int64(Info^.OriginalAddresses[I]^[K]), 8))
            end Else SubItems.Add('<chyba>');
          end Else SubItems.Add('N/A');

        If Assigned(Info^.OriginalAddresses[I]) Then
          begin
          If Info^.OriginalAddressesRetrieved[I] Then
            begin
            idx := GetAddressOwner(DriverBaseList, DriverSizeList, Info^.OriginalAddresses[I]^[K]);
            If idx <> -1 Then
              SubItems.Add(DriverNameList[idx])
            Else SubItems.Add('N/A');
            end Else SubItems.Add('<chyba>');;
          end Else SubItems.Add('N/A');
        end;
      end;

    Items.EndUpdate;
    end;
  end;
end;

Procedure TForm1.RefreshMenuItemClick(Sender: TObject);
{
  Tato rutina je vykonana, kdykoliv uzivatel klepne na tlacitko
  aktualizace obsahu. Rutina znovu nacte vsechny informace
  o aktualni tabulce systemovych volani.
}
Var
  Ret : Boolean;
  DriverNameList : TNameList;
  DriverBaseList : TPointerList;
  DriverSizeList : TIntegerList;
  Info : TSSDTInfo;
begin
Ret := SSDTGetAllInfo(FTableType, @Info);
If Ret Then
  begin
  DriverNameList := Nil;
  DriverBaseList := Nil;
  DriverSizeList := Nil;
  Ret := GetDriverList(DriverNameList, DriverBaseList, DriverSizeList);
  if Ret then
    begin
    ShowSSDTInfo(@Info, DriverNameList, DriverBaseList, DriverSizeList);

    DriverNameList := Nil;
    DriverBaseList := Nil;
    DriverSizeList := Nil;
    end;

  FreeSSDTInfo(@Info);
  end
end;

Procedure TForm1.FormCreate(Sender: TObject);
{
  Tato rutina je volana tesne po vytvoreni hlavniho formulare.
  Provadi inicializaci uzivatelskeho rozhrani a zajisti nacteni
  nazvu systemovych sluzeb pro obe tabulky systemovych volani.
}
Var
  Ret : Boolean;
begin
FTableType := TABLE_TYPE_NORMAL;
KeServiceDescriptorTable1.Checked := True;
FAddressTables[0] := Label5;
FCounterTables[0] := Label6;
FNumbersOfServices[0] := Label7;
FArgumentTables[0] := Label8;

FAddressTables[1] := Label13;
FCounterTables[1] := Label14;
FNumbersOfServices[1] := Label15;
FArgumentTables[1] := Label16;

FAddressTables[2] := Label21;
FCounterTables[2] := Label22;
FNumbersOfServices[2] := Label23;
FArgumentTables[2] := Label24;

FAddressTables[3] := Label29;
FCounterTables[3] := Label30;
FNumbersOfServices[3] := Label31;
FArgumentTables[3] := Label32;

FListViews[0] := ListView1;
FListViews[1] := ListView2;
FListViews[2] := ListView3;
FListViews[3] := ListView4;

Ret := SSDTLoadFunctionNames;
If Not Ret Then
  Error('Jmena se nepodarilo nacist!');

Ret := SSDTShadowLoadFunctionNames;
If Not Ret Then
  Error('Jmena se nepodarilo nacist!');

SetMenu;
RefreshMenuItemClick(Nil);
end;

Procedure TForm1.KeServiceDescriptorTable1Click(Sender: TObject);
{
  Tato rutina zmeni aktualni tabulku na tabulku systemovych
  volani pouze pro hlavni modul jadra.
}
begin
FTableType := TABLE_TYPE_NORMAL;
KeServiceDescriptorTable1.Checked := True;
RefreshMenuItemClick(Nil);
end;

Procedure TForm1.KeServiceDescriptorTableShadow1Click(Sender: TObject);
{
  Rutina zmeni aktualni tabulku systemovych volani na stinovou
  tabulku.
}
begin
FTableType := TABLE_TYPE_SHADOW;
KeServiceDescriptorTableShadow1.Checked := True;
RefreshMenuItemClick(Nil);
end;

Procedure TForm1.ExitMenuItemClick(Sender: TObject);
{
  Zavre formular. Tato rutina je volana pri klepnuti na tlacitko
  Konec v hlavnim menu.
}
begin
Close;
end;

End.

