Process Handles Objname empty in Win XP

delphi package - easy access to kernel objects etc.

Process Handles Objname empty in Win XP

Postby brian » Sun Jan 13, 2013 7:33 pm

Not sure when this happened, but probably during the added support for Unicode/XE, with the latest madKernel, Process.Handles.Items.KernelObj.Objname are now empty when running in Windows XP.
brian
 
Posts: 36
Joined: Fri Feb 29, 2008 11:12 am

Re: Process Handles Objname empty in Win XP

Postby madshi » Mon Jan 14, 2013 8:57 am

Can you post some sample code with which I can reproduce the problem, please?
madshi
Site Admin
 
Posts: 9414
Joined: Sun Mar 21, 2004 5:25 pm

Re: Process Handles Objname empty in Win XP

Postby madshi » Mon Jan 14, 2013 9:02 am

P.S: Just tried the following code and it worked just fine on my XPSP3 PC. Tested with both Delphi 7 and XE2:

Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
var s1, s2 : AnsiString;
    i1     : integer;
begin
  s1 := '';
  with Process('calc.exe').Handles do
    for i1 := 0 to ItemCount - 1 do begin
      s2 := Items[i1].KernelObj.ObjName;
      if s2 <> '' then
        s1 := s1 + s2 + #$D#$A;
    end;
  MessageBoxA(0, PAnsiChar(s1), 'info', 0);
end;
madshi
Site Admin
 
Posts: 9414
Joined: Sun Mar 21, 2004 5:25 pm

Re: Process Handles Objname empty in Win XP

Postby brian » Mon Jan 14, 2013 9:41 am

Using this code:

Code: Select all
procedure TForm1.Button2Click(Sender: TObject);
Var a: integer;
    b: string;
begin
  Memo1.Clear;
  Memo1.Lines.BeginUpdate;
  with Process('vlc.exe').Handles do
  for a := 0 to ItemCount - 1 do
  with Items[a] do
  begin
    if not IsValid then Continue;
    if not (ObjType in [otFile]) then Continue;
    b := KernelObj.ObjName;
    if b = '' then Continue;
    Memo1.Lines.Add(b);
  end;
  Memo1.Lines.EndUpdate;
end;


Run on win7 works, run on a XP results in empty names:

Image

I just noticed something really odd though:

I tried other code to retrieve the names, which does work in both XP and W7, and.. if I run that code, then madKernel's without closing the program, it works from then on while the app is running oO

Image
brian
 
Posts: 36
Joined: Fri Feb 29, 2008 11:12 am

Re: Process Handles Objname empty in Win XP

Postby madshi » Mon Jan 14, 2013 10:22 am

Then it's probably a privilege problem. Just try enabling all privileges first:

Code: Select all
var PrivilegesEnabled : boolean = false;
procedure EnableAllPrivileges;
type TTokenPrivileges = record
       PrivilegeCount : dword;
       Privileges     : array [0..maxInt shr 4 - 1] of TLUIDAndAttributes;
     end;
var token : THandle;
    c2    : dword;
    i1    : integer;
    ptp   : ^TTokenPrivileges;
begin
  if PrivilegesEnabled then
    exit;
  if OpenProcessToken(windows.GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token) then
    try
      c2 := 0;
      GetTokenInformation(token, TokenPrivileges, nil, 0, c2);
      if c2 <> 0 then begin
        ptp := pointer(LocalAlloc(LPTR, c2 * 2));
        if GetTokenInformation(token, TokenPrivileges, ptp, c2 * 2, c2) then begin
          for i1 := 0 to integer(ptp^.PrivilegeCount) - 1 do
            ptp^.Privileges[i1].Attributes := ptp^.Privileges[i1].Attributes or SE_PRIVILEGE_ENABLED;
          AdjustTokenPrivileges(token, false, PTokenPrivileges(ptp)^, c2, PTokenPrivileges(nil)^, dword(pointer(nil)^));
        end;
        LocalFree(HLOCAL(ptp));
      end;
    finally CloseHandle(token) end;
  PrivilegesEnabled := true;
end;
madshi
Site Admin
 
Posts: 9414
Joined: Sun Mar 21, 2004 5:25 pm

Re: Process Handles Objname empty in Win XP

Postby brian » Mon Jan 14, 2013 10:40 am

Nice, it works now! I had actually a proc in the other code to enable privs. but didn't think of that, since the other code was working without enabling them first.

Anyway while we are on this, do you mind a couple related things to this:

1) It might be good to modify the code at GetHandleTableNt to loop the call until it succeeds, as per info from http://forum.sysinternals.com/howto-enumerate-handles_topic18892.html

An unusual aspect of calling NtQuerySystemInformation with SystemHandleInformation is that if you supply a buffer which is too small, it returns STATUS_INFO_LENGTH_MISMATCH (0xc0000004) instead of giving you the correct buffer size in ReturnLength. This means you will have to guess the buffer size. A common technique is to call NtQuerySystemInformation in a loop until it succeeds with STATUS_SUCCESS (0), reallocating and doubling the buffer size each time it fails with STATUS_INFO_LENGTH_MISMATCH.


Maybe rather than re-sizing the buffer once we could do something like

Code: Select all
function GetHandleTableNt : TNtHandleTable;
var c1 : cardinal;
    p1 : pointer;
    r: Cardinal;
begin
  result.ItemCount := 0;
  result.Items := nil;
  if @NtQuerySystemInformation = nil then
    NtQuerySystemInformation := GetProcAddress(GetModuleHandle(ntdll), 'NtQuerySystemInformation');
  dword(p1) := LocalAlloc(LPTR, 20);
  try
    c1 := 0;
    r := NtQuerySystemInformation(16, p1, 20, @c1);
    LocalFree(dword(p1));
    //dword(p1) := LocalAlloc(LPTR, c1 * 2);
    while r = $C0000004 do begin
      dword(p1) := LocalAlloc(LPTR, c1 * 2);
      r := NtQuerySystemInformation(16, p1, c1 * 2, @c1)
    end;
    //if NtQuerySystemInformation(16, p1, c1 * 2, nil) = 0 then begin
    if r = 0 then begin
      result.ItemCount := TPInteger(p1)^;
      SetLength(result.Items, result.ItemCount);
      Move(pointer(integer(p1) + 4)^, pointer(result.Items)^, result.ItemCount * sizeOf(TNtHandleItem));
    end;
  finally LocalFree(dword(p1)) end;
end;


($C0000004 = STATUS_INFO_LENGTH_MISMATCH)

2) Filenames with Unicode return with garbage, for example "123★456" comes up as "123?456". Any way to fix that?

Thanks.
brian
 
Posts: 36
Joined: Fri Feb 29, 2008 11:12 am

Re: Process Handles Objname empty in Win XP

Postby madshi » Mon Jan 14, 2013 10:47 am

I'm already looping NtQuerySystemInformation if it doesn't return the needed buffer size.

The current madKernel version is still not converted to Unicode and/or x64. I will probably do the conversion at some point in the future, but it's currently not very high on my priority list.
madshi
Site Admin
 
Posts: 9414
Joined: Sun Mar 21, 2004 5:25 pm

Re: Process Handles Objname empty in Win XP

Postby brian » Mon Jan 14, 2013 10:55 am

There's only 1 extra call in the original code

Code: Select all
function GetHandleTableNt : TNtHandleTable;
var c1 : cardinal;
    p1 : pointer;
begin
  result.ItemCount := 0;
  result.Items := nil;
  if @NtQuerySystemInformation = nil then
    NtQuerySystemInformation := GetProcAddress(GetModuleHandle(ntdll), 'NtQuerySystemInformation');
  dword(p1) := LocalAlloc(LPTR, 20);
  try
    c1 := 0;
    NtQuerySystemInformation(16, p1, 20, @c1);
    LocalFree(dword(p1));
    dword(p1) := LocalAlloc(LPTR, c1 * 2);
    if NtQuerySystemInformation(16, p1, c1 * 2, nil) = 0 then begin
      result.ItemCount := TPInteger(p1)^;
      SetLength(result.Items, result.ItemCount);
      Move(pointer(integer(p1) + 4)^, pointer(result.Items)^, result.ItemCount * sizeOf(TNtHandleItem));
    end;
  finally LocalFree(dword(p1)) end;
end;
brian
 
Posts: 36
Joined: Fri Feb 29, 2008 11:12 am

Re: Process Handles Objname empty in Win XP

Postby madshi » Mon Jan 14, 2013 11:07 am

Ah sorry, I looked in the wrong unit... :shock:

Anyway, the code works, doesn't it? I've not had any reports that it would fail on any OS. My solution is different to that suggested by your link, but what does it matter if it works? There are often multiple solutions to one problem.
madshi
Site Admin
 
Posts: 9414
Joined: Sun Mar 21, 2004 5:25 pm

Re: Process Handles Objname empty in Win XP

Postby brian » Mon Jan 14, 2013 1:22 pm

Yeah never had it fail besides this XP issue earlier, but just out of safety.. idk. In other tests with different code the call fails randomly, sometimes once, sometimes up to 3 times, although incrementing the size only 1kb each iteration. I guess 2x is never gonna have an issue. Pretty lame that microsoft never documented this.
brian
 
Posts: 36
Joined: Fri Feb 29, 2008 11:12 am

Re: Process Handles Objname empty in Win XP

Postby madshi » Mon Jan 14, 2013 2:30 pm

Well, if that quote "An unusual aspect of calling NtQuerySystemInformation with SystemHandleInformation is that if you supply a buffer which is too small, it returns STATUS_INFO_LENGTH_MISMATCH (0xc0000004) instead of giving you the correct buffer size in ReturnLength" were true, my code would fail, every time, on every OS. That is not the case, so obviously that quote is totally incorrect.

Anyway, if you can reproduce a situation where my code fails, please let me know and I will look into it.
madshi
Site Admin
 
Posts: 9414
Joined: Sun Mar 21, 2004 5:25 pm


Return to madKernel

Who is online

Users browsing this forum: No registered users and 3 guests

cron