有些情况下需要让注入的库所在的低权限进程和外部进程或驱动通信,由于权限太低,很多资源是无法访问的,需要通过其他的方式赋予。
为了让注入的动态库和外部进程和驱动安全通信,Sandboxie在服务进程中打开设设备,并复制句柄,将句柄赋权给注入进程。这样其他的进程就可以访问设备了。
打开设备:
RtlInitUnicodeString(&uni, API_DEVICE_NAME);
InitializeObjectAttributes(
&objattrs, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtOpenFile(
&HandleLocal, FILE_GENERIC_READ, &objattrs, &MyIoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0);
复制句柄
if (NT_SUCCESS(status)) {
//
// duplicate opened handle into new process
//
BOOL ok = DuplicateHandle(NtCurrentProcess(), HandleLocal,
hProcess, &HandleRemote, 0, FALSE,
DUPLICATE_SAME_ACCESS);
CloseHandle(HandleLocal);
if (ok) {
return HandleRemote;
}
}
同样可以打开文件做filemapping,提供只读句柄
HANDLE GuiServer::GetClipboardDataSlave2(
ULONG pid, void *mem_ptr, SIZE_T mem_len)
{
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid);
if (! hProcess)
return 0;
#ifdef _WIN64
ULONG size_high = (ULONG)(mem_len >> 32);
ULONG size_low = (ULONG)(mem_len & 0xFFFFFFFF);
#else
ULONG size_high = 0;
ULONG size_low = mem_len;
#endif _WIN64
HANDLE hSectionRemote = NULL;
HANDLE hSectionLocal = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE | SEC_COMMIT,
size_high, size_low, NULL);
if (hSectionLocal) {
void *data =
MapViewOfFile(hSectionLocal, FILE_MAP_WRITE, 0, 0, mem_len);
if (data) {
memcpy(data, mem_ptr, mem_len);
UnmapViewOfFile(data);
if (! DuplicateHandle(NtCurrentProcess(), hSectionLocal,
hProcess, &hSectionRemote,
SECTION_QUERY | SECTION_MAP_READ,
FALSE, 0)) {
hSectionRemote = NULL;
}
}
}
ULONG LastError = GetLastError();
if (hSectionLocal)
CloseHandle(hSectionLocal);
CloseHandle(hProcess);
SetLastError(LastError);
return hSectionRemote;
}