读其它进程的对象句柄和名称,代码是网上找的,只是只能看本进程的,加了个DuplicateHandle,能看名称了,只是句柄跟用process explorer看到的不一样,看到的是复制到本进程后的句柄,不是它本来的句柄,这样我不办法关闭它啊,应该怎么改一下了?
function EumKnlObjectName(var sList:TStringList;PID:DWORD):String;
type
  PObjectTypeInformation = ^TObjectTypeInformation;
  TObjectTypeInformation = packed record
    Name: UNICODE_STRING;
    ObjectCount, HandleCount: Cardinal;
    Reserved1: array[0..3] of Cardinal;
    PeakObjectCount, PeakHandleCount: Cardinal;
    Reserved2: array[0..3] of Cardinal;
    InvalidAttributes: Cardinal;
    GenericMapping: TGenericMapping;
    ValidAccess: Cardinal;
    Unknown: UCHAR;
    MaintainHandleDatabase: Boolean;
    Reserved3: array[0..1] of UCHAR;
    PoolType: Cardinal;
    PagedPoolUsage, NonPagedPoolUsage: Cardinal;
  end;  POBJECT_ALL_TYPES_INFORMATION = ^TOBJECT_ALL_TYPES_INFORMATION;
  TOBJECT_ALL_TYPES_INFORMATION = record // Information Class 3
    NumberOfTypes: DWORD;
    TypeInformation: TObjectTypeInformation;
  end;  TOBJECT_INFORMATION_CLASS = (
    ObjectBasicInformation,
    ObjectNameInformation,
    ObjectTypeInformation,
    ObjectAllTypesInformation,
    ObjectHandleInformation);  PObjectNameInformation = ^TObjectNameInformation;
  TObjectNameInformation = packed record
    Name: UNICODE_STRING;
  end;  PSystemHandleInformation = ^TSystemHandleInformation;
  TSystemHandleInformation = packed record
    ProcessId: DWORD;
    ObjectTypeNumber: Byte;
    Flags: Byte;
    Handle: Word;
    eObject: Pointer;
    GrantedAccess: ACCESS_MASK;
  end;  PSystemHandleInformation_Ex = ^TSystemHandleInformation_Ex;
  TSystemHandleInformation_Ex = packed record
    NumberOfHandles: DWORD;
    Information: TSystemHandleInformation;
  end;  PNtQuerySystemInformation = function(SystemInformationClass: DWORD; SystemInformation: Pointer; SystemInformationLength: ULONG; ReturnLength: PULONG): DWORD; stdcall;  PNtQueryObject = function(ObjectHandle: THANDLE;
    ObjectInformationClass: TOBJECT_INFORMATION_CLASS;
    ObjectInformation: Pointer;
    ObjectInformationLength: DWORD;
    ReturnLength: PDWORD): DWORD; stdcall;
var
  _ModuleHandle, _Count, i: Dword;
  _NtQueryObject: PNtQueryObject;
  _ObjTypeInfo: POBJECT_ALL_TYPES_INFORMATION;
  _P, _StrLen, _Size: DWORD;
  _ObjName: string;
  _NtQuerySystemInformation: PNtQuerySystemInformation;
  pHandleInfor: PSystemHandleInformation_Ex;
  _HandleInfor: PSystemHandleInformation;
  _Name: PObjectNameInformation;
  hProc:THandle;
  x:thandle;
begin
   Result:='';
  _Count := 0;
  _ModuleHandle := GetModuleHandle('ntdll.dll');
  _NtQueryObject := GetProcAddress(_ModuleHandle, 'NtQueryObject');
  _NtQuerySystemInformation := GetProcAddress(LoadLibrary('ntdll.dll'), 'NtQuerySystemInformation');
  _Size := $1000;
  GetMem(pHandleInfor, _Size);
  while _NtQuerySystemInformation(16, pHandleInfor, _Size, nil) <> 0 do
  begin
    _Size := _Size + _Size;
    ReallocMem(pHandleInfor, _Size);
  end;
  _Name := GetMemory($1000);
  for I := 0 to pHandleInfor^.NumberOfHandles - 1 do
  begin
    _HandleInfor := PSystemHandleInformation(dword(pHandleInfor) + 4 + (i * SizeOf(TSystemHandleInformation)));
    if (_HandleInfor^.ProcessId = PID) then   //GetCurrentProcessId
    begin
       hProc := OpenProcess(PROCESS_ALL_ACCESS,False,PID);
       DuplicateHandle(hProc,
                               _HandleInfor^.Handle,
                                GetCurrentProcess(),
                                @X,
                                0,FALSE, DUPLICATE_SAME_ACCESS);
                              
      if _NtQueryObject(_HandleInfor^.Handle, ObjectNameInformation, _Name, $1000, nil) = 0 then
      begin
        _ObjName := WideCharToString(_Name.Name.Buffer);
        sList.Add(IntToHex(Dword(_HandleInfor^.Handle), 8) + '-' + IntToStr(_HandleInfor^.ObjectTypeNumber) + ':' + _ObjName);
     end;
    end;
  end;
end;

解决方案 »

  1.   

    你可以试试用进程快照
    不过这个函数应该会返回所有的进程保存在一个Handle里面
    SYSTEM_HANDLE_INFORMATION
    最终得到对象得用到ObReferenceObjectByHandle,那个完全是驱动方面的事情了,用户态做起来很麻烦
      

  2.   

    我刚才又百度了一下,这个DuplicateHandle复制过来句柄后可以直接关闭目标进程的句柄?搞不明白了,如果不行的话是必须用远程线程的方法关了吗?
      

  3.   

    process explorer这个程序是怎么做的啊?好像它也没有DLL啊
      

  4.   

    _HandleInfor^.Handle就是那个进程的句柄号
    DUPLICATE_SAME_ACCESS换成DUPLICATE_CLOSE_SOURCE即可关闭
      

  5.   

    DUPLICATE_CLOSE_SOURCE把目标进程所有的对象都关了,我想能不能只关我指定的啊?
      

  6.   

    DuplicateHandle要放在_NtQueryObject前面才能读取对象名称啊,然后才能判断啊,怎么弄才能读取出名称然后再关句柄啊
      

  7.   

    我试了如果_NtQueryObject前面不加DuplicateHandle那读取的都是本进程的