home *** CD-ROM | disk | FTP | other *** search
/ Delphi Programming Unleashed / Delphi_Programming_Unleashed_SAMS_Publishing_1995.iso / chap17 / getgdt / getgdt.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-03-21  |  11.5 KB  |  293 lines

  1. program GetGDT;   
  2.  
  3. {Refer Undocumented Windows #356 (sgdt) and
  4.                     Windows Tech Journal #28 1/93 and
  5.                     The Processor and Coprocessor #96/99 and refer text}
  6.  
  7. {$ifdef windows}
  8. uses winprocs, win31, strings, WinCrt;
  9. {$else}
  10. uses winapi, win31, strings;
  11. {$endif}
  12.  
  13. type
  14.   AccessedStr = array[0..3] of char;      {bit 0 $01 - AccessRights}
  15.   DataWriteStr = array[0..4] of char;     {bit 1 $02 - AccessRights}
  16.   CodeReadStr = array[0..4] of char;      {bit 1 $02 - AccessRights}
  17.   ConformingStr = array[0..3] of char;    {bit 2 $04 - AccessRights}
  18.   UpDownStr = array[0..3] of char;        {bit 2 $04 - AccessRights}
  19.   CodeDataStr = array[0..3] of char;      {bit 3 $08 - AccessRights}
  20.   DescTypeStr = array[0..3] of char;      {bit 4 $10 - AccessRights}
  21.   PresentStr = array[0..3] of char;       {bit 7 $80 - AccessRights}
  22.   Bit5Str = array[0..3] of char;          {bit 5 $20 - LimitH_Flags}
  23.   DefSizeStr = array[0..4] of char;       {bit 6 $40 - LimitH_Flags}
  24.   GranStr = array[0..3] of char;          {bit 7 $80 - LimitH_Flags}
  25.   TSystemDesc = array[0..25] of Char;
  26.  
  27.   PShowDesc = ^TShowDesc;                    {---------SYSTEM DESCRIPTORS----------}
  28.   TShowDesc = record                         {INT/TRAP     CALL      TASK gate     }
  29.    LimitL,                                   {<---- offset low ----> reserved      }
  30.    BaseL: word;                              {<-- code segm. sel --> TSS segm. sel.}
  31.    BaseM,                                    {<--- bits 0/2=0 ---->, bits 0/7=res.
  32.                                               3/7=count    3/7=reserved }
  33.    AccessRights: byte;
  34.           {data/stack segm. code segment
  35.      bit 0   0=not accessed/1=accessed     bits 0/3: 0=reserved, 1=available 16b TSS
  36.      bit 1   writable       readable       2=ldt, 3=busy 16b TSS, 4=16b call gate
  37.      bit 2   expand down    conforming     5=16b task gate, 6=16b int. gate,
  38.      bit 3   always 0        always 1      7=16b trap gate, 8=reserved, 9=avail.32b TSS
  39.                                            10=reserved, 11=busy 32b TSS, 12=32b call gate
  40.                                            13=reserved, 14=32b int.gate, 15=32b task gate
  41.      bit 4   0=system desc./1=segm.descriptor  <------------ 0 ---------------->
  42.      bit 5+6 descriptor privilege level      <------------- dpl --------------->
  43.      bit 7   present                         <----------- present ------------->}
  44.    LimitH_Flags,                                 {LimitH_Flags+BaseH =            }
  45.             {80386/486 only, must be 0 on 80286} {offset (High) for Trap/Call ... }
  46.     {bit 0/4 LimitH}                             {... gate, reserved for Task gate}
  47.     {bit 5   available
  48.      bit 6   default size 16/32 bits
  49.      bit 7   granularity}
  50.    BaseH: byte;
  51.             {80386/486 only, must be 0 on 80286}
  52.   end;
  53.  
  54.   PGDTMap =^TGDTMap;
  55.   TGDTMap = array[0..65521 div Sizeof(TShowDesc)] of TShowDesc;
  56.  
  57.   LongRemap = record
  58.     case Word of
  59.       0:(Long: LongInt);
  60.       1:(LoWord, HiWord: Word);
  61.    end;
  62.  
  63. const
  64.   Accessed: array[boolean] of AccessedStr = (' Na',' Ac');
  65.   DataWrite: array[boolean] of DataWriteStr = (' R  ',' R/W');
  66.   CodeRead: array[boolean] of CodeReadStr = ('  NR','   R');
  67.   Conforming: array[boolean] of ConformingStr = (' NC','  C');
  68.   UpDown: array[boolean] of UpDownStr = (' Up',' Do');
  69.   CodeData: array[boolean] of CodeDataStr = (' Da',' Co');
  70.   DescType: array[boolean] of DescTypeStr =(' Sy',' Se');
  71.   Present: array[boolean] of PresentStr = (' Nl',' Lo');
  72.   Bit5: array[boolean] of Bit5Str = (' 5f',' 5t');
  73.   DefSize: array[boolean] of DefSizeStr = (' 16b',' 32b');
  74.                                         {default operands/adress size}
  75.   Gran: array[boolean] of Granstr = (' 1b',' 4k'); {granularity}
  76.   SystemDescType: array[0..15] of TSystemDesc =
  77.    ('Reserved - type field: ', 'Available 16b TSS', 'LDT', 'Busy 16b TSS', '16b Call Gate',
  78.     '16b Task Gate', '16b Int. Gate', '16b Trap gate', 'Reserved - type field: ',
  79.     'Available 32b TSS', 'Reserved - type field: ', 'Busy 32b TSS', '32b Call Gate',
  80.     'Reserved - type field: ', '32b Int. Gate', '32b Task Gate');
  81.  
  82.  
  83. var SGDTable, DummyStr:Array[0..79] of Char;
  84.     PGDTable: PShowDesc;
  85.     GDTable: TShowDesc;
  86.     GDTMap: PGDTMap;
  87.     Selector, _ds: Word;
  88.     Typ, DPL: byte;
  89.     DummyBase, DummyLimit,
  90.     LDTBase, LDTLimit: Longint;
  91.     Loop, LoopLimit: Integer;
  92.     OutFile: Text;
  93.  
  94. function HexB(Dest: PChar; B: Byte): PChar;
  95. const
  96.   h: array[0..15] of Char = '0123456789ABCDEF';
  97. begin
  98.   Dest[0] := h[b shr 4];
  99.   Dest[1] := h[b and $0F];
  100.   Dest[2] := #0;
  101.   HexB := Dest;
  102. end;
  103.  
  104. function HexW(Dest: PChar; I: Word): PChar;
  105. begin
  106.   HexB(Dest, Hi(I));
  107.   HexB(@Dest[2], Lo(I));
  108.   HexW := Dest;
  109. end;
  110.  
  111. function HexL(Dest: PChar; l:LongInt): PChar;
  112. var
  113.   lr: LongRemap absolute l;
  114. begin
  115.   HexW(Dest, lr.HiWord);
  116.   HexW(@Dest[4], lr.LoWord);
  117.   HexL := Dest;
  118. end;
  119.  
  120. procedure ShowGDT(var GlDescTable: TShowDesc);
  121. var DummyAccess: Word;
  122. begin
  123.   with GlDescTable do
  124.    case (AccessRights and $10) of
  125.     0: begin
  126.          StrCopy(SGDTable, SystemDescType[AccessRights and $F]);
  127.          case (AccessRights and $F) of
  128.           0, 8, 10, 13: {Reserved}
  129.             begin
  130.               HexB(DummyStr, AccessRights and $F);
  131.               StrCat(SGDTable, DummyStr);
  132.               if (LimitL=0) and (BaseL=0) and (BaseM=0) and (AccessRights=0)
  133.                  and (LimitH_Flags=0) and (BaseH=0)
  134.                then StrCat(SGDTable, ' - All zero''s ')
  135.                else StrCat(SGDTable, ' - Not all zero''s ');
  136.             end;
  137.           1, 3:  {16b Task State Segment}
  138.             begin
  139.               {no further details displayed yet - refer #319}
  140.             end;
  141.           9, 11:  {32b Task State Segment}
  142.             begin
  143.               {no further details displayed yet - refer #320}
  144.             end;
  145.           5, 15:  {Task Gate}
  146.             begin
  147.               StrCat(SGDTable, ' TSS Segment Selector: ');
  148.               HexW(DummyStr, BaseL);
  149.               StrCat(SGDTable, DummyStr);
  150.             end;
  151.           4, 6, 7, 12, 14:  {Int/Trap/Call Gate}
  152.             begin
  153.               StrCat(SGDTable, '/Segment Sel. ');
  154.               HexW(DummyStr, BaseL);
  155.               StrCat(SGDTable, DummyStr);
  156.               StrCat(SGDTable, '/Limit ');
  157.               HexL(DummyStr, Longint(LimitL) + LongInt(LimitH_Flags) shl 16
  158.                                              + LongInt(BaseH) shl 24);
  159.               StrCat(SGDTable, DummyStr);     {32 bits significant #312}
  160.               StrCat(SGDTable, '/Dpl ');
  161.               DPL:=(AccessRights shr 5) and $03;
  162.               HexB(DummyStr, DPL);
  163.               StrCat(SGDTable, @DummyStr[1]);
  164.               StrCat(SGDTable, '/');   {is TARGET code segment present?}
  165.               StrCat(SGDTable, Present[AccessRights and $80 > 0]);
  166.               StrCat(SGDTable, '/Count ');
  167.               HexB(DummyStr, BaseM and $F8); {5 bits significant #315}
  168.               StrCat(SGDTable, DummyStr);
  169.             end;
  170.           2: {LDT}
  171.             begin
  172.               LDTBase:=longint(BaseL) + longint(BaseM) shl 16 + longint(BaseH) shl 24;
  173.               LDTLimit:=longint(LimitL) + longint(LimitH_Flags and $1F) shl 16;
  174.               StrCat(SGDTable, '/Segment Sel. ');
  175.               HexW(DummyStr, BaseL);
  176.               StrCat(SGDTable, DummyStr);
  177.               StrCat(SGDTable, '/Base ');
  178.               HexL(DummyStr, LDTBase);
  179.               StrCat(SGDTable, DummyStr);
  180.               StrCat(SGDTable, '/Limit ');
  181.               HexL(DummyStr, Longint(LimitL) + LongInt(LimitH_Flags) shl 16
  182.                                              + LongInt(BaseH) shl 24);
  183.               StrCat(SGDTable, @DummyStr[3]); {only 20 bits can be significant}
  184.               StrCat(SGDTable, '/Dpl ');
  185.               DPL:=(AccessRights shr 5) and $03;
  186.               HexB(DummyStr, DPL);
  187.               StrCat(SGDTable, @DummyStr[1]);
  188.             end;
  189.          end;
  190.        end;
  191.     else
  192.        begin
  193.           DummyBase:=longint(BaseL) + longint(BaseM) shl 16 + longint(BaseH) shl 24;
  194.           DummyLimit:=longint(LimitL) + longint(LimitH_Flags and $1F) shl 16;
  195.           HexL(SGDTable, DummyBase);
  196.           Write(OutFile, 'Base ', SGDTable);
  197.           HexL(DummyStr, DummyLimit);
  198.           StrCopy(SGDTable, @DummyStr[3]); {only 20 bits can be significant}
  199.           Write(OutFile, ' Limit ');
  200.           StrCat(SGDTable, Accessed[AccessRights and $01 > 0]);
  201.           if AccessRights and $08 > 0 then      {code segment}
  202.            begin
  203.              StrCat(SGDTable, CodeRead[AccessRights and $02 > 0]);
  204.              StrCat(SGDTable, Conforming[AccessRights and $04 > 0]);
  205.              StrCat(SGDTable, CodeData[True]);
  206.            end
  207.            else begin                           {data/stack segment}
  208.                   StrCat(SGDTable, DataWrite[AccessRights and $02 > 0]);
  209.                   StrCat(SGDTable, UpDown[Typ and $04 > 0]);
  210.                   StrCat(SGDTable, CodeData[False]);
  211.                 end;
  212.           StrCat(SGDTable, DescType[AccessRights and $10 > 0]);
  213.           StrCat(SGDTable, ' ');
  214.           DPL:=(AccessRights shr 5) and $03;
  215.           HexB(DummyStr, DPL);
  216.           StrCat(SGDTable, @DummyStr[1]);
  217.           StrCat(SGDTable, Present[AccessRights and $80 > 0]);
  218.           StrCat(SGDTable, Bit5[LimitH_Flags and $20 > 0]);
  219.           StrCat(SGDTable, DefSize[LimitH_Flags and $40 > 0]);
  220.           StrCat(SGDTable, Gran[LimitH_Flags and $80 > 0]);
  221.         end;
  222.    end;
  223.   Writeln(OutFile, SGDTable);
  224. end;
  225.  
  226. function GetGDTMap(var Size: integer; Sel: Word): PGDTMap;
  227. var Result: PGDTMap;   {Thanks to Dj Murdoch for the idea of the 'sizing' method}
  228. begin
  229. {$ifdef windows}
  230.   Result:=GlobalLock(Sel);
  231. {$else}
  232.   Result:=Ptr(Sel, 0);
  233. {$endif}
  234.   Size:=(GetSelectorLimit(Sel)+1) div SizeOf(TShowDesc);
  235.   GetGDTMap:=Result;
  236. end;
  237. var
  238.   P: ^String;
  239.   D: Pointer;
  240. begin
  241.   HeapLimit := 0;
  242.   New(P);
  243.   WriteLn(Seg(P^) shr 3);
  244.   GetMem(D, 25);
  245.   WriteLn(Seg(D^) shr 3);
  246.   Assign(OutFile, 'dtable.txt');
  247.   Rewrite(OutFile);
  248.   PGDTable:=@GDTable;
  249.   asm
  250.    les bx, PGDTable
  251.    sgdt es:[bx]
  252.    mov _ds,ds
  253.   end;
  254.   Selector:=AllocSelector(_ds);
  255.   with GDTable do
  256.    begin
  257.      DummyBase:=longint(BaseL) + longint(BaseM) shl 16 + longint(AccessRights) shl 24;
  258.                       {not regular descriptor, but just limit + base !!!!}
  259.      DummyLimit:=longint(LimitL) + longint(LimitH_Flags and $1F) shl 16;
  260.      SetSelectorBase(Selector, DummyBase);
  261.      SetSelectorLimit(Selector, DummyLimit);
  262.      GDTMap:=GetGDTMap(LoopLimit, Selector);
  263.      Writeln(OutFile, ' GDT Descriptor table at: ');
  264.      HexL(SGDTable, DummyBase);
  265.      Write(OutFile, 'Base ', SGDTable);
  266.      HexL(DummyStr, DummyLimit);
  267.      StrCopy(SGDTable, @DummyStr[3]);
  268.      Writeln(OutFile,' Limit ', SGDTable);
  269.      Writeln(OutFile,'Number of entries: ');
  270.    end;
  271.   for Loop:=0 to LoopLimit-1 do
  272.     ShowGDT(GDTMap^[loop]); {walk the GDT array}
  273.   GlobalUnlock(Selector);
  274.   with GDTable do
  275.    begin
  276.      SetSelectorBase(Selector, LDTBase);
  277.      SetSelectorLimit(Selector, LDTLimit);
  278.      GDTMap:=GetGDTMap(LoopLimit, Selector);
  279.      Writeln(OutFile, ' LDT Descriptor table at: ');
  280.      HexL(SGDTable, LDTBase);
  281.      Write(OutFile, 'Base ', SGDTable);
  282.      HexL(DummyStr, LDTLimit);
  283.      StrCopy(SGDTable, @DummyStr[3]);
  284.      Writeln(OutFile,' Limit ', SGDTable);
  285.      Writeln(OutFile,'Number of entries: ');
  286.    end;
  287.   for Loop:=0 to LoopLimit-1 do ShowGDT(GDTMap^[loop]); {walk the LDT array}
  288.   GlobalUnlock(Selector);
  289.   FreeSelector(Selector);
  290.   Close(OutFile);
  291. end.
  292.  
  293.