Forum > General

Question about bit fields in bitpacked record

(1/2) > >>

440bx:
Hello,

I suspect that I am misunderstanding something about bitpacked records. 

Referring to the attached image, the DWORD value is shown is $72.  I expected the field "unknown28" (the first 28 bits of that DWORD) to be $7, not $72 (which is the entire 32bit DWORD.)  Also, I expected the field "DepDisabled" to be $1 because the second bit in the DWORD is $1.

The program that produces that output (which might be different on your system) is :
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$APPTYPE      CONSOLE} {$TYPEDADDRESS ON} {$ifdef WIN64}  {$FATAL DEP policy cannot be queried in 64bit - compile for 32bit}{$endif} program _QueryInformationProcess; uses  Windows,  sysutils  ; {$ifdef VER90}type  DWORD = longint;  PDWORD = ^DWORD;{$endif} type  NTSTATUS = DWORD;   pboolean = ^boolean; const   { 22   34 } ProcessExecuteFlags = 34;  { TPROCESS_DEP_POLICY               }   ntdll = 'ntdll';   PROCESS_ALL_ACCESS        = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $FFFF;   STATUS_SUCCESS            = 0; type  { bit types for bitfields - since Delphi 2 does not support bitfields       }  {                           these types are FPC only                        }   T1BIT      = 0 ..        $1;  T2BITS     = 0 ..        $3;  T3BITS     = 0 ..        $7;  T4BITS     = 0 ..        $F;  T5BITS     = 0 ..       $1F;  T6BITS     = 0 ..       $3F;  T7BITS     = 0 ..       $7F;  T8BITS     = 0 ..       $FF;            { byte                              }  T9BITS     = 0 ..      $1FF;   T10BITS    = 0 ..      $3FF;  T11BITS    = 0 ..      $7FF;  T12BITS    = 0 ..      $FFF;  T13BITS    = 0 ..     $1FFF;  T14BITS    = 0 ..     $3FFF;  T15BITS    = 0 ..     $7FFF;  T16BITS    = 0 ..     $FFFF;            { word                              }  T17BITS    = 0 ..    $1FFFF;  T18BITS    = 0 ..    $3FFFF;  T19BITS    = 0 ..    $7FFFF;   T20BITS    = 0 ..    $FFFFF;  T21BITS    = 0 ..   $1FFFFF;  T22BITS    = 0 ..   $3FFFFF;  T23BITS    = 0 ..   $7FFFFF;  T24BITS    = 0 ..   $FFFFFF;  T25BITS    = 0 ..  $1FFFFFF;  T26BITS    = 0 ..  $3FFFFFF;  T27BITS    = 0 ..  $7FFFFFF;  T28BITS    = 0 ..  $FFFFFFF;  T29BITS    = 0 .. $1FFFFFFF;   T30BITS    = 0 .. $3FFFFFFF;  T31BITS    = 0 .. $7FFFFFFF; {$ifdef FPC}  type    { _PROCESS_DEP_POLICY                             - 32bit only            }     PPROCESS_DEP_POLICY = ^TPROCESS_DEP_POLICY;    TPROCESS_DEP_POLICY = bitpacked record      Unknown28                       : T28BITS;      Permanent                       : T1BIT;       DepEnabledThunk                 : T1BIT;      DepDisabled                     : T1BIT;      Unknown1                        : T1BIT;    end;{$endif} {$ifdef VER90}  type    { _PROCESS_DEP_POLICY                             - 32bit only            }     PPROCESS_DEP_POLICY = ^TPROCESS_DEP_POLICY;    TPROCESS_DEP_POLICY = record      ExecuteFlags          : DWORD;    end;{$endif} function NtQueryInformationProcess(ProcessHandle            : THANDLE;                                   ProcessInformationClass  : DWORD;                                   ProcessInformation       : pointer;                                   ProcessInformationLength : DWORD;                                   ReturnLength             : PDWORD)         : NTSTATUS; stdcall; external ntdll; function IsDebuggerPresent {$ifdef FPC} () {$endif}       : BOOL; stdcall external kernel32; function _itoa             (              { _in_  } In32bitInteger  : integer;              { _out_ } OutAsciizString : pchar;              { _in_  } InRadix         : DWORD             )         : pchar; cdecl external ntdll;                            { !! CDECL } function GetProcessDEPPolicy                   (                    { _in_  } InProcessHandle : THANDLE;                    { _out_ } OutFlags        : PDWORD;                    { _out_ } OutPermanent    : pboolean      { 4th bit set   }                   )       : BOOL; stdcall external kernel32; var  ProcessHandle                   : THANDLE; var  { variable for GetProcessDEPPolicy                                          }   Flags                           : DWORD;  Permanent                       : boolean; var  { variables for NtQueryInformationProcess                                   }   ProcessExecuteFlagsData         : TPROCESS_DEP_POLICY;   BufferSize    : DWORD;   ReturnLength  : DWORD;   Status        : NTSTATUS;    itoa_buf      : packed array[0..127] of char;  begin  writeln;  writeln;   // since we are dealing with our own process we can specify PROCESS_ALL_ACCESS   ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,                               FALSE,                               GetCurrentProcessId());   if ProcessHandle = 0 then Halt(1);   { use the API to verify the results                                         }   writeln;  writeln;  if not GetProcessDEPPolicy(ProcessHandle,                            @Flags,                            @Permanent) then  begin    { this shouldn't happen                                                   }    writeln;    writeln;    writeln('  GetProcessDEPPolicy failed.');  end;   writeln;  writeln('  Flags     = ', Flags);  writeln('  Permanent = ', Permanent);    { 4th bit of DWORD                 }    { ------------------------------------------------------------------------- }  { get the same results using NtQueryInformationProcess                      }   writeln;  writeln;  writeln('  ProcessExecuteFlags : ', ord(ProcessExecuteFlags), ' (d) ',             IntToHex(ord(ProcessExecuteFlags), 0), ' (h)');   BufferSize   := sizeof(ProcessExecuteFlagsData);  ReturnLength := 0;   writeln;  writeln;  writeln('  Buffer size : ', BufferSize);   ZeroMemory(@ProcessExecuteFlagsData, sizeof(ProcessExecuteFlagsData));   if IsDebuggerPresent then DebugBreak();  Status := NtQueryInformationProcess(ProcessHandle,                                      ProcessExecuteFlags,                                     @ProcessExecuteFlagsData,                                      BufferSize,                                     @ReturnLength);   if IsDebuggerPresent then DebugBreak();  if Status <> STATUS_SUCCESS then  begin    writeln;    writeln;    writeln('  NtQueryInformationProcess failed.  NTSTATUS : ',               IntToHex(Status, 0));  end;   writeln;  writeln('  returned length : ', ReturnLength);    writeln;  writeln;   { output the result in binary for reference                                 }   writeln('  ', _itoa(DWORD(ProcessExecuteFlagsData), itoa_buf, 2));  writeln;    {$ifdef FPC}  with ProcessExecuteFlagsData do  begin    writeln('  ProcessExecuteFlagsData = $', IntToHex(DWORD(ProcessExecuteFlagsData), 0));    writeln;     writeln('  Unknown28       = $', IntToHex(Unknown28, 0));    writeln('  Permanent       = ',  Permanent);    writeln('  DepEnabledThunk = ',  DepEnabledThunk);    writeln('  DepDisabled     = ',  DepDisabled);    writeln('  Unknown1        = ',  Unknown1);  end;  {$endif}   {$ifdef VER90}    writeln;    writeln;    writeln('  Process execute flags : ',               IntToHex(ProcessExecuteFlagsData.ExecuteFlags, 0));  {$endif}     writeln;  writeln('Press <enter>/<result> to end this program.');  readln;end. 
My questions are: why isn't DepDisabled = 1 and why isn't Unknown28 = 7 ?  Any suggestion on how to get the result I want is definitely appreciated.

Thank you for your help.

MathMan:
I may be off-track totally here, but shouldn't


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$ifdef FPC}  type    { _PROCESS_DEP_POLICY                             - 32bit only            }     PPROCESS_DEP_POLICY = ^TPROCESS_DEP_POLICY;    TPROCESS_DEP_POLICY = bitpacked record      Unknown28                       : T28BITS;      Permanent                       : T1BIT;       DepEnabledThunk                 : T1BIT;      DepDisabled                     : T1BIT;      Unknown1                        : T1BIT;    end;{$endif}
be defined as follows


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$ifdef FPC}  type    { _PROCESS_DEP_POLICY                             - 32bit only            }     PPROCESS_DEP_POLICY = ^TPROCESS_DEP_POLICY;    TPROCESS_DEP_POLICY = bitpacked record      Unknown1                        : T1BIT;      DepDisabled                     : T1BIT;      DepEnabledThunk                 : T1BIT;      Permanent                       : T1BIT;      Unknown28                       : T28BITS;    end;{$endif}
To me it looks like you have your definition upside down - that's why Unknown28 reflects the low 28 bit of the Flags value (when seen as DWORD).

Cheers,
MathMan

Martin_fr:
You are probably on a little endian machine (like intel)?

So $00000072 writes to mem like this

Record_addr: $72 $00 $00 $00

440bx:
@MathMan, @Martin_fr

Yes, I am on a little endian machine (intel)

I thought about what you both mentioned but, in that case, I would expect the "Unknown28" field to have the value $7200000 (28 bits) not just $72.

IOW, the only values that make sense to me is either "0000000" (which is 0) or "7200000". 

I don't see how "Unknown28" could be just "72".  In either endianness that value does not seem possible.

MathMan:

--- Quote from: 440bx on June 05, 2021, 12:38:31 pm ---@MathMan, @Martin_fr

Yes, I am on a little endian machine (intel)

I thought about what you both mentioned but, in that case, I would expect the "Unknown28" field to have the value $7200000 (28 bits) not just $72.

IOW, the only values that make sense to me is either "0000000" (which is 0) or "7200000". 

I don't see how "Unknown28" could be just "72".  In either endianness that value does not seem possible.

--- End quote ---

Huh - why would you expect that? I would expect "Unknown28" to be little endian too on an Intel machine ...

Navigation

[0] Message Index

[#] Next page

Go to full version