The parent process file handle is occupied by the process, and the process handle is occupied by the Process Handle.
Parent process file handle used by quilt Process
Scenario Description:
1.parent path a uses javasfopento open (create a file named file.exe. tmp)
2. The parent process downloads and writes data for a long time.
3. Use fclose to close the file handle after downloading and writing.
4.rename file.exe.tmpas file.exe
The above is an ideal code execution process.
Problem:
In step 4, renaming a file may fail. You can use the GetLastError function to find that the file is occupied by another process.
Solution:
1.use handle.exe developed by Microsoft to find out which process occupies the file
(Handle.exe https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx)
Usage: After the file is downloaded and the rename function is executed, run the Handle.exe file.exe. tmp/accepteula command (obtain and print the direct result using the MPs Queue)
2. The printed results show that the file is occupied by sub-process B of parent process.
During file.exe. tmp download, parent process A creates child process B using the createprocess function. Let's take A look at the function prototype:
Bool winapi CreateProcess (
_ In_opt _ LPCTSTR lpApplicationName,
_ Inout_opt _ LPTSTR lpCommandLine,
_ In_opt _ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_ In_opt _ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_ In _ BOOL bInheritHandles,
_ In _ DWORD dwCreationFlags,
_ In_opt _ LPVOID lpEnvironment,
_ In_opt _ maid directory,
_ In _ LPSTARTUPINFO lpStartupInfo,
_ Out _ LPPROCESS_INFORMATION lpProcessInformation
);
The bInheritHandles parameter is described as follows:
If this parameter TRUE, each inheritable handle in the calling process is inherited by the new process. if the parameter is FALSE, the handles are not inherited. note that inherited handles have the same value and access rights as the original handles.
Simply put, a child process is allowed to inherit the handle of the parent process.
3. A simple solution: Set the bInheritHandles parameter to flase, so that sub-process B will not occupy this file.
But I cannot use this method here, because this sub-process B is a third-party program, and he must inherit some handles to play, so I will solve it in another way.
4. Check the fopen function to implement the Code in the CRT. The CRT code is open source and the path is Microsoft Visual Studio 10.0 \ VC \ crt \ src.
Layer by layer, it is found that fopen is actually the _ topenfile function, __topenfile function has a detailed file open mode processing process.
There is a piece of code in the mode processing process:
Case _ T ('n '):
Modeflag | = _ O_NOINHERIT;
Break;
_ O_NOINHERIT is defined:
/* Open handle inherit bit */
# Define _ O_NOINHERIT 0x0080/* child process doesn't inherit file */
This is to control whether the handle allows the quilt process to occupy.
You only need to set the fopen Mode to "AB + N.
Continue with the source code and find that the final call function at the CRT layer is _ tsopen_nolock (file \ Microsoft Visual Studio 10.0 \ VC \ crt \ src \ open. c)
And finally calling the CreateFile function to create and open the file, and there are a lot of CreateFile function exception handling code.
The CreateFile function is a system API and is not open-source. If you want to continue tracking, You have to reverse the function.
5. A total of 3rd solutions are available: directly use the system API CreateFile to create and open files,
6. solution 4: refer to the unlock method: First openprocess, then copy the handle through DuplicateHandle, and then end the handle to solve the occupation of sub-process B. This method can easily find the source code on the Internet, so I will not talk nonsense.
7. Summary
The above four methods are proposed to solve the problem of occupying the parent Process Handle quilt process. The following four methods are compared:
1. CreateProcess: it is convenient to set parameters, but it is not applicable if the sub-process requires special inheritance handles.
2. fopen parameter setting: it is convenient and cross-platform compatible. You only need to add one byte to modify the code to solve the problem.
3. using CreateFile to create and open Files Replaces fopen: CreateFile with powerful functions. However, it is not easy to use this function in commercial software, A large number of exceptions need to be processed (refer to the implementation source code of the _ tsopen_nolock function)
4. duplicateHandle: the most powerful way to close handles in other processes. It is mainly used in ring3 to remove the simple trojan virus file occupation technology (it cannot be applied to the file trap technology ), however, there are some use risks. Real applications also need to write a lot of exception handling code.