When I try to CloseHandle() a handle in a remote process, it fails. If I have debugging rights will it work then?
Printable View
When I try to CloseHandle() a handle in a remote process, it fails. If I have debugging rights will it work then?
SeDebugPrivilege will work for you.
No, it won't. All HANDLEs are process-specific. Obtaining the value of a HANDLE from another process is of no use because it has no meaning within the context of your process. You have to use DuplicateHandle to transfer the handle to your own process first.
Of course, calling CloseHandle will then only affect the copy. You need a remote thread within the other process to actually affect the handle there.
I stand corrected. I was thinking along the lines of terminating a process.
How does that work? I have never seen any function/code that would assign a thread to a process.Quote:
Originally Posted by CornedBee
CreateRemoteThread(). It doesn't assign, it creates.
I can't think of many valid reasons for corrupting a remote process, but:
CloseRemoteHandle
.Quote:
You have to use DuplicateHandle to transfer the handle to your own process first
I'll have to stand UNcorrected on this. I initially thought there was something unique about DuplicateHandles making it easy to close handles on remote processes. Well, it seems to me that this is just misinformation. The only way to use DuplicateHandle with a remote process is to establish an IPC transport mechanism such as name pipes, WM_COPYDATA etc. between the two processes. This will allow the handle to be passed back and forth. Thus, it is limited to user processes not system processes. That is, it's nothing more than a very basic client/server model. The following code is an example of the ONLY way DuplicateHandle can be used to close a handle in a LOCAL process. It is for illustrative purposes. It's fully functional but executing the code will probably put your OS in an unstable state. To finish it off, you'll have to add an ExitProcess function and to be really fancy add a DeleteFile function to delete the executable making it a self deleting executable
Code:#include <windows.h>
#include <stdio.h>
typedef UINT (WINAPI *WAITFORSINGLEOBJECT)(HANDLE, DWORD);
typedef BOOL (WINAPI *CLOSEHANDLE)(HANDLE);
typedef BOOL (WINAPI *DELETEFILE)(LPCTSTR);
typedef VOID (WINAPI *EXITPROCESS)(DWORD);
typedef DWORD (WINAPI *REMOTETHREAD)(LPVOID);
typedef struct
{
WAITFORSINGLEOBJECT WaitForSingleObject;
CLOSEHANDLE CloseHandle;
HANDLE hProcess;
TCHAR szFileName[MAX_PATH];
} FUNCTIONINJECT;
#pragma check_stack(off)
DWORD WINAPI RemoteThread(FUNCTIONINJECT *injectremote)
{
injectremote->WaitForSingleObject(injectremote->hProcess, INFINITE);
injectremote->CloseHandle(injectremote->hProcess);
return 0;
}
#pragma check_stack
BOOL CloseHandle()
{
HANDLE hRemoteProcess = NULL;
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
if(CreateProcess(0, "explorer.exe", 0, 0, FALSE, (CREATE_SUSPENDED | CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS), 0, 0, &si, &pi)){
CloseHandle(pi.hThread);
hRemoteProcess = pi.hProcess;
}
if(hRemoteProcess == NULL) return FALSE;
BYTE *code = (BYTE *)VirtualAllocEx(hRemoteProcess, 0, sizeof(FUNCTIONINJECT) + 128, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(code == NULL){ CloseHandle(hRemoteProcess); return FALSE; };
FUNCTIONINJECT *remotestruct = (FUNCTIONINJECT *)(code + 128);
HMODULE hKernel32 = GetModuleHandle("kernel32.dll");
FUNCTIONINJECT injectlocal;
injectlocal.WaitForSingleObject = (WAITFORSINGLEOBJECT)GetProcAddress(hKernel32, "WaitForSingleObject");
injectlocal.CloseHandle = (CLOSEHANDLE)GetProcAddress(hKernel32, "CloseHandle");
// Duplicate our own process handle for remotestruct process to wait on
HANDLE hCurrentProcess = GetCurrentProcess();
DuplicateHandle(hCurrentProcess, hCurrentProcess, hRemoteProcess, &injectlocal.hProcess, 0, FALSE, DUPLICATE_SAME_ACCESS);
GetModuleFileName(NULL, injectlocal.szFileName, MAX_PATH);
WriteProcessMemory(hRemoteProcess, code, RemoteThread, 128, 0);
WriteProcessMemory(hRemoteProcess, remotestruct, &injectlocal, sizeof(injectlocal), 0);
DWORD dwThreadId = 0;
HANDLE hThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (REMOTETHREAD)code, remotestruct, 0, &dwThreadId);
if(hThread != 0) CloseHandle(hThread);
return TRUE;
}
int main(void)
{
CloseHandle();
return 0;
}
Uh, I explicitly said that DuplicateHandle won't help you with closing handles, because you'd only be closing the copy. I didn't spread any misinformation.Quote:
Originally Posted by BobS0327
Well, the OP poster was concerned about the inability to budge handles outside his process as in remote process. The DuplicateHandle function creates a CLONE of the original handle. They are exactly the same right down to the same security and access rights. Neither handle can be used to manipulate anything outside the local process unless SeDebugPrivilege is established. But you said that this debug level will NOT work. So, unless SeDugPrivilege is set, DuplicateHandle function is worthless if there is a requirement to access a remote process.
BTW, I have test case code that uses the DuplicateHandle function to terminate a remote user processes with/without SeDebugPrivilege to support my claim and will post it if you like.