2014-09-04 5 views
0

텍스트 파일 인 mydesktop parent.lock에 파일이 있습니다. 이 파일을 잠그고있는 PID를 원합니다. 그래서 나는 사용중인 모든 핸들을 나열 할 수있었습니다. 아래 코드가 치솟았습니다.잠긴 파일 경로의 핸들을 얻는 방법

은 내가이 열려 내가 DuplicateHandle를 사용할 수있는 방법을 알고하지 않는 한, 그 핸들을 얻기 위해 내 바탕 화면에 parent.lock을 열 CreateFile를 사용하고 싶습니다. 이것이 가능한가?

GetFullPathFinal 몇 가지 이유로 나를위한 옵션이 아닙니다. 하나는 유일한 비스타 +.

나는 NtQuerySystemInformation(SystemHandleInformation.... 모든 핸들을 나열하며 (이 번호를 잘 들린다?)

하는 텍스트 파일입니다 mydesktop을 parent.lock에있는 파일이 있습니다 54000 개 핸들을 돌려 보냈다. 이 파일을 잠그고있는 PID를 원합니다. 하지만 바탕 화면에서 parent.lock 파일의 파일 핸들을 알아낼 수 없습니다.

Cu.import("resource://gre/modules/ctypes.jsm"); 
var lib_ntdll = ctypes.open("ntdll.dll"); 
var lib_kernel32 = ctypes.open("kernel32.dll"); 

var STATUS_BUFFER_TOO_SMALL = 0xC0000023>>0; 
var STATUS_INFO_LENGTH_MISMATCH = 0xC0000004>>0; 
var SystemHandleInformation = 16; 

var UNICODE_STRING = new ctypes.StructType("UNICODE_STRING", [ 
{'Length': ctypes.unsigned_short}, //USHORT 
{'MaximumLength': ctypes.unsigned_short}, //USHORT 
{'Buffer': ctypes.jschar.ptr} ]); //PWSTR 

//https://github.com/tjguk/winsys/blob/5f11b308171382046ff0f67ef3129e47e9fee06c/random/file_handles.py#L100 
var SYSTEM_HANDLE_TABLE_ENTRY_INFO = new ctypes.StructType('SYSTEM_HANDLE_TABLE_ENTRY_INFO', [ //typedef struct _TagHANDLEINFO 
{'UniqueProcessId': ctypes.unsigned_short}, //USHORT dwPid; //UniqueProcessId 
{'CreatorBackTraceIndex': ctypes.unsigned_short}, //USHORT CreatorBackTraceIndex; //CreatorBackTraceIndex 
{'ObjectTypeIndex': ctypes.unsigned_long}, //BYTE ObjType; //ObjectTypeIndex UCHAR 
{'HandleAttributes': ctypes.unsigned_long}, //BYTE HandleAttributes; //im not sure if byte should be unsigned_long, maybe unsigned_char //HandleAttributes UCHAR 
{'HandleValue': ctypes.unsigned_short}, //USHORT HndlOffset; //HandleValue USHORT 
{'Object': ctypes.void_t.ptr}, //DWORD dwKeObject; //Object PVOID 
{'GrantedAccess': ctypes.unsigned_long} //ULONG GrantedAccess; //GrantedAccess ULONG 
]); //HANDLEINFO, PHANDLEINFO; 


var SYSTEM_HANDLE_INFORMATION = new ctypes.StructType('SYSTEM_HANDLE_INFORMATION', [ 
{'NumberOfHandles': ctypes.unsigned_long}, 
{'Handles': ctypes.ArrayType(SYSTEM_HANDLE_TABLE_ENTRY_INFO, 5)} 
]); 

var NtQuerySystemInformation = lib_ntdll.declare("NtQuerySystemInformation", 
ctypes.winapi_abi, 
ctypes.long, // return //NTSTATUS 
ctypes.int, // SystemInformationClass //SYSTEM_INFORMATION_CLASS 
ctypes.void_t.ptr, // SystemInformation //PVOID 
ctypes.unsigned_long, // SystemInformationLength //ULONG 
ctypes.unsigned_long.ptr); // ReturnLength //PULONG 

/* http://msdn.microsoft.com/en-us/library/ms633499%28v=vs.85%29.aspx 
* HWND WINAPI FindWindow(
* __in_opt LPCTSTR lpClassName, 
* __in_opt LPCTSTR lpWindowName 
*); 
*/ 
// NOT SUPPORTED BY WINXP so just doing this to test and then later will figure out how to get handle to path name then look in here 
var GetFinalPathNameByHandle = lib_kernel32.declare('GetFinalPathNameByHandleW', ctypes.winapi_abi, ctypes.uint32_t, //DWORD 
ctypes.unsigned_short, // HANDLE 
ctypes.void_t.ptr, // LPTSTR 
ctypes.uint32_t, // DWORD 
ctypes.uint32_t // DWORD 
); 



function enumHandles() { 
    var res = {}; 
    var _enumBufSize = new ctypes.unsigned_long(0x4000); 
    var buffer = ctypes.char.array(_enumBufSize.value)(); 

    while (true) { 
     var status = NtQuerySystemInformation(SystemHandleInformation, buffer, 
      _enumBufSize, _enumBufSize.address()); 
     if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) { 
      buffer = ctypes.char.array(_enumBufSize.value)(); 
     } else break; 
    } 

    if (status < 0) return null; 
    var proc = ctypes.cast(buffer.addressOfElement(0), SYSTEM_HANDLE_INFORMATION.ptr).contents; 

    for (var i=0; i<proc.Handles.length; i++) { 
     //console.log('i:', proc.Handles[i].HandleValue); 
     //var nbuff = ctypes.jschar.array()(32); //nbuff.length == 32 
     //var ret = GetFinalPathNameByHandle(proc.Handles[i].HandleValue, nbuff.address(), nbuff.length, 0); 
     //console.log(nbuff.readString()); //always blank i have no idea why 
     if (res[proc.Handles[i].HandleValue]) { 
     res[proc.Handles[i].HandleValue].push(proc.Handles[i]); 
     //console.error('multiple handlevalue occourance for handle value of ', res[proc.Handles[i].HandleValue]) 
     } else { 
     res[proc.Handles[i].HandleValue] = [proc.Handles[i]] 
     } 
    } 
    return res; 
} 

var allHandles = enumHandles(); 
console.log('enumHandles:', Object.keys(allHandles).length, allHandles); 

lib_ntdll.close(); 
lib_kernel32.close(); 

+1

"파일 경로의 핸들"이란 무엇입니까? "디렉토리"를 의미합니까? 아니면 "파일 핸들"입니까? 또는 핸들에서 파일 경로를 검색하려고합니까? 네가 여기서 묻고 있는게 뭔지 잘 모르겠다. 귀하의 번호가 올바른지 아닌지는 귀하의 특정 시스템과 그 당시에 어떤 프로세스가 실행되고 있는지에 달려 있습니다. 쉽게 옳을 수도 있고 쉽게 잘못 될 수도 있습니다. a) 사용중인 코드없이 b) 시스템에 대한 자세한 정보를 여기에서 액세스 할 수있는 것보다 많이 전달하는 것은 어렵습니다. 작업 관리자와 프로세스 모니터는 귀하에게 무엇을 말합니까? –

+0

감사합니다. @KenWhite 코드 및 설명을 추가했습니다. 제발 손잡이가 필요해. 바탕 화면의 텍스트 파일로. – Blagoh

+0

@Blagoh : 귀하의 편집은 Ken의 질문에 전혀 대답하지 않습니다. –

답변

4

NtQuerySystemInformation(SystemHandleInformation, ...)SYSTEM_HANDLE_INFORMATION 항목이 아닌 SYSTEM_HANDLE_TABLE_ENTRY_INFO 항목의 배열을 반환 내가 핸들을 열거하는 방법을

이입니다. Enumerating the processes referencing an objectHOWTO: Enumerate handles을 참조하십시오.

CreateFile()과 같이 파일/디렉토리 경로에 이미 HANDLE이 열려 있다면 HANDLE을 여는 데 사용 된 원래 경로가 이미 있어야합니다. 동일한 경로에 다른 핸들을 찾으려면, 당신은 할 수 있습니다 누구의 Handle 필드의 모든 항목을 찾고 배열을 통해

  1. 루프는 일치하는 HANDLE 하나가 있다면 당신은 이미 있습니다.

  2. ObjectTypeNumber 필드가 HANDLE_TYPE_FILE 인 항목을 찾고 배열을 반복합니다. 각 Handle에 대해 DuplicateHandle()을 사용하여 앱의 프로세스 공간에 액세스 할 수있게 한 다음 NtQueryInformationFile(..., FileNameInformation) 또는 GetFinalPathNameByHandle()을 사용하여 경로를 쿼리하면 찾고자하는 경로와 비교할 수 있습니다 (File handle operations demo 참조).

+0

Thanks Remy. 나는 그것을 다시 편집했다. 54k 핸들을 통과하고 각각 GetFinalPathNameByHandle을 호출하는 것은 생각 이었지만 너무 집중적이었습니다. 나는 그 파일을 열고 그 파일에 대한 핸들을 얻으려고 노력하고, 54k 핸들에서 그 핸들을 찾는다. 그러나 파일을 잠그기 때문에 파일을 여는 데 어려움을 겪고있었습니다. – Blagoh

+0

핸들을 얻기 위해 읽기 전용 모드로 파일을 열 수없는 경우 경로 문자열을 비교하는 것이 유일한 옵션입니다. 고마워요. 레미, –

+0

. 읽기 전용 모드로 어떻게 열 수 있습니까?이 플래그를'CreateFile'에 전달해야합니까? – Blagoh

관련 문제