Retrieve clientPID using RpcServerInqCallAttributes - c++

I need to retrieve the client process id in RPC callback which is using ncalrpc protocol. MSDN suggests to use RpcServerInqCallAttributes with RPC_CALL_ATTRIBUTES_V2 structure. The document says the process id is returned as a handle
https://msdn.microsoft.com/en-us/library/windows/desktop/aa378501(v=vs.85).aspx
I couldn't get that. Is it pointing to a DWORD which has the process id or Is it a process handle where I can get the PID using GetProcessId API?
Also in both cases, who closes the handle or delete the memory allocated for DWORD?

Given how MSDN goes out of its way several times to say that it's a PID and that the value can be re-used after the client process terminates I would say it being defined as a HANDLE is just wrong, that it is in fact a PID value. That being the case it doesn't need to be deallocated, just let the entire RPC_CALL_ATTRIBUTES_V2 structure go out of scope.

the ClientPID is process ID of the calling client as is.
Is it pointing to a DWORD ?
no
Is it a process handle ?
no
I can get the PID using GetProcessId API?
no. this is pid value itself. you can do type cast for use in OpenProcess call - (ULONG)(ULONG_PTR)RpcCallAttributes.ClientPID
who closes the handle or delete the memory allocated for DWORD?
it must not be closed (this handle never need be closed) or deallocated (this is not a pointer)
the process and thread id - is really handles in special handle table (PspCidTable.) it natively represent as handles. native (ntdll) api and kernel mode api always use process and thread id as handles. look for CLIENT_ID
typedef struct _CLIENT_ID {
   HANDLE UniqueProcess;
   HANDLE UniqueThread;
 } CLIENT_ID;
this active used in different native api, for example ZwOpenProcess
all kernel mode api use it as handle, for example - PsLookupProcessByProcessId
simply win32 layer truncating HANDLE UniqueProcess; to DWORD UniqueProcess
so if you want use ClientPID from RPC_CALL_ATTRIBUTES_V2 structure in win32 call OpenProcess - you need simply cast it to DWORD. for example:
RPC_CALL_ATTRIBUTES_V2_W RpcCallAttributes = {
RPC_CALL_ATTRIBUTES_VERSION, RPC_QUERY_CLIENT_PID
};
if (RPC_S_OK == RpcServerInqCallAttributes(0, &RpcCallAttributes))
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE,
(ULONG)(ULONG_PTR)RpcCallAttributes.ClientPID);
}
if use native api - type cast not need. for example
RPC_CALL_ATTRIBUTES_V2_W RpcCallAttributes = {
RPC_CALL_ATTRIBUTES_VERSION, RPC_QUERY_CLIENT_PID
};
if (RPC_S_OK == RpcServerInqCallAttributes(0, &RpcCallAttributes))
{
HANDLE hProcess;
static OBJECT_ATTRIBUTES zoa = { sizeof(zoa) };
CLIENT_ID cid = { RpcCallAttributes.ClientPID };
ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &zoa, &cid );
}

https://learn.microsoft.com/en-us/windows/desktop/api/rpcasync/ns-rpcasync-tagrpc_call_attributes_v2_a
ClientPID
Handle that contains the process ID of the calling client. This field
is only supported for the ncalrpc protocol sequence, and is populated
only when RPC_QUERY_CLIENT_PID is specified in the Flags parameter.
I found this working as PID, not HANDLE. That is:
HANDLE hproc = (HANDLE)ClientPID.ClientPID;
NtQueryProcessInformation ( hproc ...)
fails, but
cpid = (DWORD)(DWORD_PTR)ClientPID.ClientPID;
hcproc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, cpid);
succeeds.
So MSDN is right: it is represented as a HANDLE, but it needs to be casted to a DWORD PID to be used in subsequent calls.

Related

GetProcAddress return NULL when the hModule and lpProcName is valid

I started a new project recently and my objectives is to inject bytecode into another process, and then start a remote thread executing my bytecode, however i have run into a very strange problem.
What it does is that it allocates and write to memory of a arbitrary process, it writes a struct containing pointers to functions in user32.dll and kernel32.dll for the remote process, it also writes a calling operation for the function pointers from the struct, it then creates a remotethread with a lpStartAddress of the "calling operation"
You can find the source code here :
http://pastie.org/9298306
GetPrivileges is being called on line 55 (method on line 185), it returns true meaning that OpenProcessToken, LookupPrivilegeValue and AdjustTokenPrivileges returned true.
Soon after that the following will be callled:
param->pMessageBox = (DWORD)GetProcAddress(user32, "MessageBoxA");
param->pSleep = (DWORD)GetProcAddress(kernel32, "Sleep");
Both user32 and kernel32 are valid handles, but param->pMessageBox will be set to NULL, whilst param->pSleep will get the actual pointer for the Sleep.
And the strange thing about this is when i replace the GetPrivileges with this snippet that i copied online it works fine and the param->pMessageBox will be set with the correct pointer address.
BOOL GetPrivileges()
{
HANDLE tokenHandle;
TOKEN_PRIVILEGES tokenPriv;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &tokenHandle) != 0)
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPriv.Privileges[0].Luid);
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(tokenHandle, 0, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
}
else
{
TCHAR buffer[256];
wsprintf(buffer, TEXT("0x%x"), GetLastError());
MessageBox(NULL, buffer, TEXT("OpenProcessTokenError"), MB_ICONERROR);
return FALSE;
}
return true;
}
Continuing on with my debugging take note that the else statement in the copied GetPrivileges will not be called due to OpenProcessToken returning true as expected, and by removing:
TCHAR buffer[256];
wsprintf(buffer, TEXT("0x%x"), GetLastError());
param->pMessageBox will set to NULL, how can that be?
Regards a frustrated ogelami.
The module handles are in fact not valid. They are module handles for a remote process. Module handles are in fact implement as base addresses and so only have meaning with respect to the virtual address space of the executing process.
It looks like, by chance, the base address of the kernel32 module of the injecting process is the same as the base address of the kernel32 module in the remote process.
Realistically, your goals are going to be hard to achieve if you put so much code in the injecting process. You would be better off if you injected a DLL into the other process. Create a remote thread whose first act is to load this DLL. Then you will have code running in the other process, inside its address space, and so able to call directly functions like GetModuleHandle, GetProcAddress etc.

What is the easiest way to send text from a child GUI process to a console parent?

I've coded two processes using C++. One is the GUI process that is called by my console app using CreateProcess API. I need to pass text from the GUI app (child) to the console app (parent.) The amount of text could be arbitrary -- from a few lines to KBs of text.
What is the easiest way to do it?
PS. I have access to the source code of both processes.
Console application can create a WinAPI window (non-visible), such that it can receive messages (idea taken from AllocateHWND function in Delphi).
Another solution is to use named pipes.
Another solution is to send data locally via TCP/IP.
If these strings are only a debug ones, consider using OutputDebugString function from WinAPI and capturing them with a program like SysInternals' DbgView.
If the GUI application is truly graphical only, you don't really use the standard output stream (i.e. std::cout). This can the be reused for output to your console application.
First you need to create an anonymous pipe using CreatePipe:
HANDLE hPipeRead;
HANDLE hPipeWrite;
CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0);
Now you have to handles that can be used as a normal file handle; One to read from and the other to write to. The write-handle should be set as the standard output for the new process you create:
STARTUPINFO startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags = STARTF_USESTDHANDLES;
startupInfo.hStdOutput = hPipeWrite; // Standard output of the new process
// is set to the write end of the pipe
CreateProcess(
lpApplicationName,
lpCommandLine,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startupInfo, // Use our startup information
&processInfo);
Now whenever the child process needs to write to the parent, it only have to use standard output:
std::cout << "In child process, are you getting this parent?";
The parent uses ReadFile to read from the read-end of the pipe:
char buffer[256];
DWORD bytesRead = 0;
ReadFile(hPipeRead, buffer, sizeof(buffer), &bytesRead, NULL);
Note: I haven't done WIN32 programming in some time, so might be wrong on some details. But should hopefully be enough to get you started.
There are of course many other ways if Inter Process Communications (IPC), including (but not limited to) sockets, files, shared memory, etc.
The easy way is probably to make the child actually a console application, even though it also creates windows.
In that case, you can have your parent spawn the child using _popen, and the child can just write the output to its normal stdout/std::cout. _popen returns a FILE *, so the parent can read the child's output about like it'd normally read a file (well, normally for C anyway).
Various methods can be used, some of them were given above. Which one is simplest depends on you task.
I can also suggest you filemapping technics which is widely used in IPC, and for ex. dll are implemented using filemapping.
It allows mutliply processes to share the same resources simultaniously, access is random not consequntial.
Here are main steps of implementation:
1. Process A creates a file;
2. Process A creates a named system object mappedfile to the file (mappedfile allocates memory);
3. Process A creates a system object a viewOfMapped file(this allows to map some area of the process A to the pages in the main memory which were allocated by mappedFile);
4. Process B creates the named system object mappedfile(name should be similar to the one of process A used), viewOfMapped file;
5. By pointers returned by viewOfMapped processes can share the same memory.
Example:
Process A:
/* 1. file creation */
hFile = CreateFile(0, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL);
/* 2. Create file mapping */
wchar_t lpName[] = L"fileMappingObject0";
HANDLE hfileMappingObject;
hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName);
/* 3. Create MappedFileViewOfFile */
void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
Process B:
/* 2. Create file mapping */
wchar_t lpName[] = L"fileMappingObject0";
HANDLE hfileMappingObject;
hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName);
/* 3. Create MappedFileViewOfFile */
void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
This method is rather simple and also powerfull.

GetThreadContext via DuplicateHandle?

I am trying to open process duplicate handles and query information from thread handles using GetThreadContext but i get error ERROR_INVALID_HANDLE or ERROR_GEN_FAILURE. Information about this seems very limited....
processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)
DuplicateHandle(processHandle,handle.Handle,GetCurrentProcess(),&dupHandle,0,FALSE,DUPLICATE_SAME_ACCESS);
memset(&ctx,0x00,sizeof(ctx));
GetThreadContext(dupHandle,&ctx);
printf("Error:%x", GetLastError());
Anyone ?
First of all, as suggested above you should be passing thread handle as the argument, and not process handle.
Then, what part of CONTEXT structure you request to be filled by GetThreadContext API? You leave zero there and there should be 1+ flags to indicate data of interest:
CONTEXT ThreadContext = { CONTEXT_CONTROL };
if(GetThreadContext(ThreadHandle, &ThreadContext)) {
// ...
See also code snippet at https://stackoverflow.com/a/199809/868014
GetThreadContext takes a thread handle not a process handle.

How to check if a HANDLE is valid or not?

In C++, I have opened a serial port that has a HANDLE. Since the port may close by an external application, how can I verify that the HANDLE is still valid before reading data?
I think it can be done by checking the HANDLE against a suitable API function, but which?
Thank you.
Checking to see whether a handle is "valid" is a mistake. You need to have a better way of dealing with this.
The problem is that once a handle has been closed, the same handle value can be generated by a new open of something different, and your test might say the handle is valid, but you are not operating on the file you think you are.
For example, consider this sequence:
Handle is opened, actual value is 0x1234
Handle is used and the value is passed around
Handle is closed.
Some other part of the program opens a file, gets handle value 0x1234
The original handle value is "checked for validity", and passes.
The handle is used, operating on the wrong file.
So, if it is your process, you need to keep track of which handles are valid and which ones are not. If you got the handle from some other process, it will have been put into your process using DuplicateHandle(). In that case, you should manage the lifetime of the handle and the source process shouldn't do that for you. If your handles are being closed from another process, I assume that you are the one doing that, and you need to deal with the book keeping.
Some WinAPI functions return meaningless ERROR_INVALID_PARAMETER even if valid handles are passed to them, so there is a real use case to check handles for validity.
GetHandleInformation function does the job:
http://msdn.microsoft.com/en-us/library/ms724329%28v=vs.85%29.aspx
as the port may close by a external application
This is not possible, an external application cannot obtain the proper handle value to pass to CloseHandle(). Once you have the port opened, any other process trying to get a handle to the port will get AccessDenied.
That said, there's crapware out there that hacks around this restriction by having secret knowledge of the undocumented kernel structures that stores handles for a process. You are powerless against them, don't make the mistake of taking on this battle by doing the same. You will lose. If a customer complains about this then give them my doctor's advice: "if it hurts then don't do it".
If you are given a HANDLE and simply want to find out whether it is indeed an open file handle, there is the Windows API function GetFileInformationByHandle for that.
Depending on the permissions your handle grants you for the file, you can also try to move the file pointer using SetFilePointer, read some data from it using ReadFile, or perform a null write operation using WriteFile with nNumberOfBytesToWrite set to 0.
Probably you are under windows and using ReadFile to read the data. The only way to check it is trying to read. If the HANDLE is invalid it'll return an error code (use GetLastEror() to see which one it is) which will probably be ERROR_HANDLE_INVALID.
I know that it's a little bit late but I had a similar question to you, how to check if a pipe (a pipe I created using CreateFile) is still open (maybe the other end shut down the connection) and can read, and if it is not, to open it again. I did what #Felix Dombek suggested, and I used the WriteFile to check the connection. If it returned 1 it means the pipe is open, else I opened it using the CreateFile again. This implies that your pipe is duplex. Here's the CreateFile:
hPipe2 = CreateFile(lpszPipename2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
and here is how I checked for the connection:
while(1)
{
bool MessageSent = WriteFile(hPipe2, "Test", 0, &cbWritten, NULL);
if (!(MessageSent))
{
LogsOut("Read pipe has been disconnected");
//Call method to start the pipe again
break;
}
Sleep(200); // I need this because it is a thread
}
This is working just fine for me :)
You can use DuplicateHandle to test handle validity.
First method: You can try to duplicate the handle you want to check on validity. Basically, invalid handles can not be duplicated.
Second method: The DuplicateHandle function does search the Win32 handle descriptor table from beginning for an empty record to reuse it and so assign into it a duplicated handle. You can just test the duplicated handle address value on value greater than yours handle address and if it is greater, then the handle is not treated as invalid and so is not reused. But this method is very specific and limited, and it does only work, when there is no more empty or invalid handle records above the handle value address you want to test.
But all this just said above is valid only if you track all handles creation and duplication on your side.
Examples for Windows 7:
Method #1
// check stdin on validity
HANDLE stdin_handle_dup = INVALID_HANDLE_VALUE;
const bool is_stdin_handle_dup = !!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &stdin_handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (is_stdin_handle_dup && stdin_handle_dup != INVALID_HANDLE_VALUE) {
CloseHandle(stdin_handle_dup);
stdin_handle_dup = INVALID_HANDLE_VALUE;
}
Method #2
// Assume `0x03` address has a valid stdin handle, then the `0x07` address can be tested on validity (in Windows 7 basically stdin=0x03, stdout=0x07, stderr=0x0b).
// So you can duplicate `0x03` to test `0x07`.
bool is_stdout_handle_default_address_valid = false;
HANDLE stdin_handle_dup = INVALID_HANDLE_VALUE;
const bool is_stdin_handle_dup = !!DuplicateHandle(GetCurrentProcess(), (HANDLE)0x03, GetCurrentProcess(), &stdin_handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (is_stdin_handle_dup && stdin_handle_dup != INVALID_HANDLE_VALUE) {
if (stdin_handle_dup > (HANDLE)0x07) {
is_stdout_handle_default_address_valid = true; // duplicated into address higher than 0x07, so 0x07 contains a valid handle
}
CloseHandle(stdin_handle_dup);
stdin_handle_dup = INVALID_HANDLE_VALUE;
}
In order to check the handle , first we need to know what is our HANDLE for, (for a File/Port/Window, ...), Then find an appropriate function to check it (thanks #janm for help). Note that the function's duty may be specially for this destination or not. In my case that iv'e opened a Serial port by CreateFile() , i can check the COM status by GetCommState() API function that fills our COM info struct. If the port is not open anymore or inaccessible the function returns 0 and if you call GetLastError() immediately, you`ll get the ERROR_INVALID_HANDLE value. Thanks everyone for helps.

How to Compare Two variable of HANDLE type

I have a variable of HANDLE type.
First HANDLE variable is a process HANDLE (with name hProcess) that does not have PROCESS_QUERY_INFORMATION access right.
Second variable is a process HANDLE (with name hwndProcess) too that I have opened via OpenProcess function and have PROCESS_QUERY_INFORMATION access right. I am sure both processes should have same handle.
But when i compare them as below, it returns false;
if (hProcess==hwndProcess) {do something}
How shall I do it?
There is not an explicit way to check whether two handles refer to the same process. The only way would be to query the process information and check that, e.g. using GetProcessId on each handle to check the process IDs.
If you don't have the necessary access rights to call the desired query functions then you can try calling DuplicateHandle to get a new handle with more access rights. However, if this fails then you have no way of telling whether the handles are to the same process or not.
hProcess must not hold the ProcessHandle of the Process that will be closed. It can and will most times be NULL. I'm doing something similar to get the PIDs of terminated processes.
if((hProcess == NULL) || (hProcess == GetCurrentProcess())){
pid = GetCurrentProcessId();
} else {
pid = ProcessHandleToId(hProcess);
}
Are your sure, that it's an access rights problem and your function doesn't fail, because the handle is NULL?
The Windows 10 SDK has CompareObjectHandles(HANDLE, HANDLE) which returns TRUE if the handles refer to the same underlying kernel object.
And you don't have to worry about access rights.