NTSTATUS UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PVOID pPhysMemLin) { NTSTATUS ntStatus; ntStatus = ZwUnmapViewOfSection((HANDLE)-1, pPhysMemLin); ZwClose(PhysicalMemoryHandle); return ntStatus; }
NTSTATUS UnmapViewOfModule(IN HANDLE hProcess, IN PVOID lpBaseAddr ) { NTSTATUS status = STATUS_UNSUCCESSFUL; status = ZwUnmapViewOfSection(hProcess, lpBaseAddr); return status; }
PVOID NTAPI EngMapSectionView( _In_ HANDLE hSection, _In_ SIZE_T cjSize, _In_ ULONG cjOffset, _Out_ PHANDLE phSecure) { LARGE_INTEGER liSectionOffset; PVOID pvBaseAddress; NTSTATUS Status; /* Check if the size is ok (for 64 bit) */ if (cjSize > ULONG_MAX) { DPRINT1("chSize out of range: 0x%Id\n", cjSize); return NULL; } /* Align the offset at allocation granularity and compensate for the size */ liSectionOffset.QuadPart = cjOffset & ~(MM_ALLOCATION_GRANULARITY - 1); cjSize += cjOffset & (MM_ALLOCATION_GRANULARITY - 1); /* Map the section */ Status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &pvBaseAddress, 0, cjSize, &liSectionOffset, &cjSize, ViewShare, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status); return NULL; } /* Secure the section memory */ *phSecure = EngSecureMem(pvBaseAddress, (ULONG)cjSize); if (!*phSecure) { ZwUnmapViewOfSection(NtCurrentProcess(), pvBaseAddress); return NULL; } /* Return the address where the requested data starts */ return (PUCHAR)pvBaseAddress + (cjOffset & (MM_ALLOCATION_GRANULARITY - 1)); }
// 卸载原外壳占用内存 BOOL CExeMemory::UnloadShell(HANDLE ProcHnd, unsigned long BaseAddr) { typedef unsigned long (__stdcall *pfZwUnmapViewOfSection)(unsigned long, unsigned long); pfZwUnmapViewOfSection ZwUnmapViewOfSection = NULL; BOOL res = FALSE; HMODULE m = LoadLibrary(TEXT("ntdll.dll")); if(m){ ZwUnmapViewOfSection = (pfZwUnmapViewOfSection)GetProcAddress(m, "ZwUnmapViewOfSection"); if(ZwUnmapViewOfSection) res = (ZwUnmapViewOfSection((unsigned long)ProcHnd, BaseAddr) == 0); FreeLibrary(m); } return res; }
void ShareMemKImp::UninitializeShareMem() { m_LockObject.UninitializeShareLock(); if (m_hMapView) { ZwUnmapViewOfSection(PsGetCurrentProcessId(), m_hMapView); m_hMapView = NULL; } if (m_hMapSect) { ZwClose(m_hMapSect); m_hMapSect = NULL; } m_hMapSize = 0; }
NTSTATUS UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PVOID pPhysMemLin) { NTSTATUS ntStatus; OutputDebugString ("Entering UnmapPhysicalMemory"); ntStatus = ZwUnmapViewOfSection((HANDLE)-1, pPhysMemLin); if (!NT_SUCCESS(ntStatus)) OutputDebugString ("ERROR: UnmapViewOfSection failed"); ZwClose(PhysicalMemoryHandle); OutputDebugString ("Leaving UnmapPhysicalMemory"); return ntStatus; }
void ShareLockKImp::UninitializeShareLock() { switch(m_LockType) { case LockTypeMutex: RtlZeroMemory(&m_LockObject.m_Mutex.m_Mutex, sizeof(KMUTEX)); break; case LockTypeEvent: RtlZeroMemory(&m_LockObject.m_Event.m_Event, sizeof(KEVENT)); break; case LockTypeSemaphore: RtlZeroMemory(&m_LockObject.m_Semaphore.m_Semaphore, sizeof(KSEMAPHORE)); break; case LockTypeSpinlock: break; case LockTypeNamedSpinlock: { if (m_LockObject.m_NamedSpinlock.m_hMapView) { ZwUnmapViewOfSection(ZwCurrentProcess(), m_LockObject.m_NamedSpinlock.m_hMapView); m_LockObject.m_NamedSpinlock.m_hMapView = NULL; } if (m_LockObject.m_NamedSpinlock.m_hMapFile) { ZwClose(m_LockObject.m_NamedSpinlock.m_hMapFile); m_LockObject.m_NamedSpinlock.m_hMapFile = NULL; } m_LockObject.m_NamedSpinlock.m_lpHeader = NULL; } break; default: break; } m_LockType = LockTypeNone; }
static VOID TestPhysicalMemorySection(VOID) { NTSTATUS Status; UNICODE_STRING SectionName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); OBJECT_ATTRIBUTES ObjectAttributes; HANDLE SectionHandle; PVOID SectionObject; PUCHAR MyPage; PHYSICAL_ADDRESS MyPagePhysical; PUCHAR ZeroPageContents; PHYSICAL_ADDRESS ZeroPagePhysical; PVOID Mapping; PUCHAR MappingBytes; SIZE_T ViewSize; SIZE_T EqualBytes; MyPage = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'MPmK'); if (skip(MyPage != NULL, "Out of memory\n")) return; MyPagePhysical = MmGetPhysicalAddress(MyPage); RtlFillMemory(MyPage + 0 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x23); RtlFillMemory(MyPage + 1 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x67); RtlFillMemory(MyPage + 2 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xab); RtlFillMemory(MyPage + 3 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xef); ZeroPageContents = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'ZPmK'); if (skip(ZeroPageContents != NULL, "Out of memory\n")) { ExFreePoolWithTag(MyPage, 'MPmK'); return; } ZeroPagePhysical.QuadPart = 0; Mapping = MmMapIoSpace(ZeroPagePhysical, PAGE_SIZE, MmCached); if (skip(Mapping != NULL, "Failed to map zero page\n")) { ExFreePoolWithTag(ZeroPageContents, 'ZPmK'); ExFreePoolWithTag(MyPage, 'MPmK'); return; } RtlCopyMemory(ZeroPageContents, Mapping, PAGE_SIZE); MmUnmapIoSpace(Mapping, PAGE_SIZE); InitializeObjectAttributes(&ObjectAttributes, &SectionName, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "No section\n")) { /* Map zero page and compare */ Mapping = NULL; ViewSize = PAGE_SIZE; Status = ZwMapViewOfSection(SectionHandle, ZwCurrentProcess(), &Mapping, 0, 0, &ZeroPagePhysical, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "No view\n")) { ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); EqualBytes = RtlCompareMemory(Mapping, ZeroPageContents, PAGE_SIZE); ok_eq_size(EqualBytes, PAGE_SIZE); Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); ok_eq_hex(Status, STATUS_SUCCESS); } /* Map the zero page non-cached */ Mapping = NULL; ViewSize = PAGE_SIZE; Status = ZwMapViewOfSection(SectionHandle, ZwCurrentProcess(), &Mapping, 0, 0, &ZeroPagePhysical, &ViewSize, ViewUnmap, 0, PAGE_READWRITE | PAGE_NOCACHE); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "No view\n")) { ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); EqualBytes = RtlCompareMemory(Mapping, ZeroPageContents, PAGE_SIZE); ok_eq_size(EqualBytes, PAGE_SIZE); Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); ok_eq_hex(Status, STATUS_SUCCESS); } /* Map our NP page, compare, and check that modifications are reflected */ Mapping = NULL; ViewSize = PAGE_SIZE; Status = ZwMapViewOfSection(SectionHandle, ZwCurrentProcess(), &Mapping, 0, 0, &MyPagePhysical, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "No view\n")) { ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping); EqualBytes = RtlCompareMemory(Mapping, MyPage, PAGE_SIZE); ok_eq_size(EqualBytes, PAGE_SIZE); MappingBytes = Mapping; ok(MappingBytes[5] == 0x23, "Mapping[5] = 0x%x\n", MappingBytes[5]); ok(MyPage[5] == 0x23, "MyPage[5] = 0x%x\n", MyPage[5]); MyPage[5] = 0x44; ok(MappingBytes[5] == 0x44, "Mapping[5] = 0x%x\n", MappingBytes[5]); ok(MyPage[5] == 0x44, "MyPage[5] = 0x%x\n", MyPage[5]); MappingBytes[5] = 0x88; ok(MappingBytes[5] == 0x88, "Mapping[5] = 0x%x\n", MappingBytes[5]); ok(MyPage[5] == 0x88, "MyPage[5] = 0x%x\n", MyPage[5]); Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping); ok_eq_hex(Status, STATUS_SUCCESS); } Status = ZwClose(SectionHandle); ok_eq_hex(Status, STATUS_SUCCESS); } /* Try flag 0x80000000, which ROS calls SEC_PHYSICALMEMORY */ InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwCreateSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes, NULL, PAGE_READWRITE, 0x80000000, NULL); ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); if (NT_SUCCESS(Status)) ZwClose(SectionHandle); /* Assertion failure: AllocationAttributes & SEC_IMAGE | SEC_RESERVE | SEC_COMMIT */ if (!KmtIsCheckedBuild) { InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); Status = MmCreateSection(&SectionObject, SECTION_ALL_ACCESS, &ObjectAttributes, NULL, PAGE_READWRITE, 0x80000000, NULL, NULL); ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); if (NT_SUCCESS(Status)) ObDereferenceObject(SectionObject); } InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); Status = MmCreateSection(&SectionObject, SECTION_ALL_ACCESS, &ObjectAttributes, NULL, PAGE_READWRITE, SEC_RESERVE | 0x80000000, NULL, NULL); ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6); if (NT_SUCCESS(Status)) ObDereferenceObject(SectionObject); ExFreePoolWithTag(ZeroPageContents, 'ZPmK'); ExFreePoolWithTag(MyPage, 'MPmK'); }
NTSTATUS NTAPI INIT_FUNCTION VdmpInitialize(PVOID ControlData) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); NTSTATUS Status; HANDLE PhysMemHandle; PVOID BaseAddress; volatile PVOID NullAddress = NULL; LARGE_INTEGER Offset; ULONG ViewSize; /* Open the physical memory section */ InitializeObjectAttributes(&ObjectAttributes, &PhysMemName, 0, NULL, NULL); Status = ZwOpenSection(&PhysMemHandle, SECTION_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("Couldn't open \\Device\\PhysicalMemory\n"); return Status; } /* Map the BIOS and device registers into the address space */ Offset.QuadPart = 0; ViewSize = PAGE_SIZE; BaseAddress = 0; Status = ZwMapViewOfSection(PhysMemHandle, NtCurrentProcess(), &BaseAddress, 0, ViewSize, &Offset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Couldn't map physical memory (%x)\n", Status); ZwClose(PhysMemHandle); return Status; } /* Enter SEH */ _SEH2_TRY { /* Copy the first physical page into the first virtual page */ RtlMoveMemory(NullAddress, BaseAddress, ViewSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Fail */ DPRINT1("Couldn't copy first page (%x)\n", Status); ZwClose(PhysMemHandle); ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; /* Close physical memory section handle */ ZwClose(PhysMemHandle); /* Unmap the section */ Status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress); if (!NT_SUCCESS(Status)) { DPRINT1("Couldn't unmap the section (%x)\n", Status); return Status; } return STATUS_SUCCESS; }
NTSTATUS VdmpInitialize( PVDMICAUSERDATA pIcaUserData ) /*++ Routine Description: Initialize the address space of a VDM. Arguments: None, Return Value: NTSTATUS. --*/ { NTSTATUS Status, StatusCopy; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SectionName; UNICODE_STRING WorkString; ULONG ViewSize; LARGE_INTEGER ViewBase; PVOID BaseAddress; PVOID destination; HANDLE SectionHandle, RegistryHandle; PEPROCESS Process; ULONG ResultLength; ULONG Index; PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor; PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor; PKEY_VALUE_FULL_INFORMATION KeyValueBuffer; PCM_ROM_BLOCK BiosBlock; ULONG LastMappedAddress; PVDM_PROCESS_OBJECTS pVdmObjects = NULL; USHORT PagedQuotaCharged = 0; USHORT NonPagedQuotaCharged = 0; HANDLE hThread; PVDM_TIB VdmTib; PAGED_CODE(); Status = VdmpGetVdmTib(&VdmTib, VDMTIB_PROBE); // take from user mode and probe if (!NT_SUCCESS(Status)) { return Status; } if ((KeI386MachineType & MACHINE_TYPE_PC_9800_COMPATIBLE) == 0) { // // This is PC/AT (and FMR in Japan) VDM. // RtlInitUnicodeString( &SectionName, L"\\Device\\PhysicalMemory" ); InitializeObjectAttributes( &ObjectAttributes, &SectionName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = ZwOpenSection( &SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { return Status; } // // Copy the first page of memory into the VDM's address space // BaseAddress = 0; destination = 0; ViewSize = 0x1000; ViewBase.LowPart = 0; ViewBase.HighPart = 0; Status = ZwMapViewOfSection( SectionHandle, NtCurrentProcess(), &BaseAddress, 0, ViewSize, &ViewBase, &ViewSize, ViewUnmap, 0, PAGE_READWRITE ); if (!NT_SUCCESS(Status)) { ZwClose(SectionHandle); return Status; } // problem with this statement below -- // it could be a non-vdm process and copying memory to address 0 // should be guarded against StatusCopy = STATUS_SUCCESS; try { RtlMoveMemory( destination, BaseAddress, ViewSize ); } except(ExSystemExceptionFilter()) { StatusCopy = GetExceptionCode(); } Status = ZwUnmapViewOfSection( NtCurrentProcess(), BaseAddress ); if (!NT_SUCCESS(Status) || !NT_SUCCESS(StatusCopy)) { ZwClose(SectionHandle); return (NT_SUCCESS(Status) ? StatusCopy : Status); } // // Map Rom into address space // BaseAddress = (PVOID) 0x000C0000; ViewSize = 0x40000; ViewBase.LowPart = 0x000C0000; ViewBase.HighPart = 0; // // First unmap the reserved memory. This must be done here to prevent // the virtual memory in question from being consumed by some other // alloc vm call. // Status = ZwFreeVirtualMemory( NtCurrentProcess(), &BaseAddress, &ViewSize, MEM_RELEASE ); // N.B. This should probably take into account the fact that there are // a handfull of error conditions that are ok. (such as no memory to // release.) if (!NT_SUCCESS(Status)) { ZwClose(SectionHandle); return Status; } // // Set up and open KeyPath // InitializeObjectAttributes( &ObjectAttributes, &CmRegistryMachineHardwareDescriptionSystemName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, (HANDLE)NULL, NULL ); Status = ZwOpenKey( &RegistryHandle, KEY_READ, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { ZwClose(SectionHandle); return Status; } // // Allocate space for the data // KeyValueBuffer = ExAllocatePoolWithTag( PagedPool, KEY_VALUE_BUFFER_SIZE, ' MDV' ); if (KeyValueBuffer == NULL) { ZwClose(RegistryHandle); ZwClose(SectionHandle); return STATUS_NO_MEMORY; } // // Get the data for the rom information // RtlInitUnicodeString( &WorkString, L"Configuration Data" ); Status = ZwQueryValueKey( RegistryHandle, &WorkString, KeyValueFullInformation, KeyValueBuffer, KEY_VALUE_BUFFER_SIZE, &ResultLength ); if (!NT_SUCCESS(Status)) { ZwClose(RegistryHandle); ExFreePool(KeyValueBuffer); ZwClose(SectionHandle); return Status; } ResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) ((PUCHAR) KeyValueBuffer + KeyValueBuffer->DataOffset); if ((KeyValueBuffer->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) || (ResourceDescriptor->PartialResourceList.Count < 2) ) { ZwClose(RegistryHandle); ExFreePool(KeyValueBuffer); ZwClose(SectionHandle); // No rom blocks. return STATUS_SUCCESS; } PartialResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)ResourceDescriptor + sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + ResourceDescriptor->PartialResourceList.PartialDescriptors[0] .u.DeviceSpecificData.DataSize); if (KeyValueBuffer->DataLength < ((PUCHAR)PartialResourceDescriptor - (PUCHAR)ResourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + sizeof(CM_ROM_BLOCK)) ) { ZwClose(RegistryHandle); ExFreePool(KeyValueBuffer); ZwClose(SectionHandle); return STATUS_ILL_FORMED_SERVICE_ENTRY; } BiosBlock = (PCM_ROM_BLOCK)((PUCHAR)PartialResourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); Index = PartialResourceDescriptor->u.DeviceSpecificData.DataSize / sizeof(CM_ROM_BLOCK); // // N.B. Rom blocks begin on 2K (not necessarily page) boundaries // They end on 512 byte boundaries. This means that we have // to keep track of the last page mapped, and round the next // Rom block up to the next page boundary if necessary. // LastMappedAddress = 0xC0000; while (Index) { #if 0 DbgPrint( "Bios Block, PhysAddr = %lx, size = %lx\n", BiosBlock->Address, BiosBlock->Size ); #endif if ((Index > 1) && ((BiosBlock->Address + BiosBlock->Size) == BiosBlock[1].Address) ) { // // Coalesce adjacent blocks // BiosBlock[1].Address = BiosBlock[0].Address; BiosBlock[1].Size += BiosBlock[0].Size; Index--; BiosBlock++; continue; } BaseAddress = (PVOID)(BiosBlock->Address); ViewSize = BiosBlock->Size; if ((ULONG)BaseAddress < LastMappedAddress) { if (ViewSize > (LastMappedAddress - (ULONG)BaseAddress)) { ViewSize = ViewSize - (LastMappedAddress - (ULONG)BaseAddress); BaseAddress = (PVOID)LastMappedAddress; } else { ViewSize = 0; } } ViewBase.LowPart = (ULONG)BaseAddress; if (ViewSize > 0) { Status = ZwMapViewOfSection( SectionHandle, NtCurrentProcess(), &BaseAddress, 0, ViewSize, &ViewBase, &ViewSize, ViewUnmap, MEM_DOS_LIM, PAGE_READWRITE ); if (!NT_SUCCESS(Status)) { break; } LastMappedAddress = (ULONG)BaseAddress + ViewSize; } Index--; BiosBlock++; } // // Free up the handles // ZwClose(SectionHandle); ZwClose(RegistryHandle); ExFreePool(KeyValueBuffer); } else {
int main() { unsigned long long segmnt; LARGE_INTEGER viewbase; size_t vaddress,maplen; WCHAR ppath[PATH_MAX]; NTSTATUS status; char tmp[64]; int fd; if (OpenPhysMem()) { fprintf(stderr,"Unable to open physical memory device\n"); return 1; } memset(&viewbase,0,sizeof(viewbase)); viewbase.QuadPart = (ULONGLONG)ROM_offset; maplen = ROM_size-1; vaddress = 0; status = ZwMapViewOfSection(mem_fd,(HANDLE)-1,(PVOID*)(&vaddress),0UL, ROM_size-1,&viewbase,(PDWORD)(&maplen),ViewShare,0,PAGE_READONLY); if (!NT_SUCCESS(status)) { fprintf(stderr,"Failed to map view of section for %08llx status=0x%08lx\n",viewbase.QuadPart,(unsigned long)status); return 1; } ROM = (unsigned char*)((size_t)vaddress); printf(HELLO); printf("Press ENTER to start\n"); waitforenter(); /* write it out */ for (segmnt=ROM_offset; segmnt < (ROM_offset+(unsigned long long)ROM_size); segmnt += (unsigned long long)ROM_blocksize) { while (freespace() < (66UL << 10UL)) { if (GetCurrentDirectoryW(sizeof(ppath),ppath) == 0) { fprintf(stderr,"Unable to get current directory\n"); return 1; } /* chdir() off the drive so that it is safe for the user to remove the * pen drive, floppy, etc. */ if (SetCurrentDirectoryW(L"C:\\"/*FIXME*/) == 0) { fprintf(stderr,"Unable to bail out to root\n"); return 1; } printf("Unmount and remove disk, move files off on another computer,\n"); printf("re-mount and re-insert and hit ENTER\n"); waitforenter(); /* assuming the user has reloaded the disk/flash drive/whatever and remounted * at the same point, jump back into the directory and try to resume our work */ if (SetCurrentDirectoryW(ppath) == 0) { fprintf(stderr,"Unable to reenter capture dir\n"); return 1; } } sprintf(tmp,CAPTURE_SPRINTF,segmnt); printf("Writing ... %s\n",tmp); fd = open(tmp,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0644); if (fd < 0) { fprintf(stderr,"Unable to open file, %s\n",strerror(errno)); return 1; } if ((size_t)write(fd,ROM+segmnt-ROM_offset,ROM_blocksize) != ROM_blocksize) { fprintf(stderr,"Unable to write ROM block\n"); return 1; } close(fd); } ZwUnmapViewOfSection((HANDLE)-1,(PVOID)vaddress); ClosePhysMem(); return 0; }
VOID LpcpDeletePort( IN PVOID Object ) { PLPCP_PORT_OBJECT Port = Object; PLPCP_PORT_OBJECT ConnectionPort; LPC_CLIENT_DIED_MSG ClientPortClosedDatagram; PLPCP_MESSAGE Msg; PLIST_ENTRY Head, Next; HANDLE CurrentProcessId; PAGED_CODE(); // // Send an LPC_PORT_CLOSED datagram to whoever is connected // to this port so they know they are no longer connected. // if ((Port->Flags & PORT_TYPE) == CLIENT_COMMUNICATION_PORT) { ClientPortClosedDatagram.PortMsg.u1.s1.TotalLength = sizeof( ClientPortClosedDatagram ); ClientPortClosedDatagram.PortMsg.u1.s1.DataLength = sizeof( ClientPortClosedDatagram.CreateTime ); ClientPortClosedDatagram.PortMsg.u2.s2.Type = LPC_PORT_CLOSED; ClientPortClosedDatagram.PortMsg.u2.s2.DataInfoOffset = 0; ClientPortClosedDatagram.CreateTime = PsGetCurrentProcess()->CreateTime; LpcRequestPort( Port, (PPORT_MESSAGE)&ClientPortClosedDatagram ); } // // If connected, disconnect the port, and then scan the message queue // for this port and dereference any messages in the queue. // LpcpDestroyPortQueue( Port, TRUE ); // // If the client has a port memory view, then unmap it // if (Port->ClientSectionBase != NULL) { ZwUnmapViewOfSection( NtCurrentProcess(), Port->ClientSectionBase ); } // // If the server has a port memory view, then unmap it // if (Port->ServerSectionBase != NULL) { ZwUnmapViewOfSection( NtCurrentProcess(), Port->ServerSectionBase ); } // // Dereference the pointer to the connection port if it is not // this port. // if (ConnectionPort = Port->ConnectionPort) { CurrentProcessId = PsGetCurrentThread()->Cid.UniqueProcess; ExAcquireFastMutex( &LpcpLock ); Head = &ConnectionPort->LpcDataInfoChainHead; Next = Head->Flink; while (Next != Head) { Msg = CONTAINING_RECORD( Next, LPCP_MESSAGE, Entry ); Next = Next->Flink; if (Msg->Request.ClientId.UniqueProcess == CurrentProcessId) { LpcpTrace(( "%s Freeing DataInfo Message %lx (%u.%u) Port: %lx\n", PsGetCurrentProcess()->ImageFileName, Msg, Msg->Request.MessageId, Msg->Request.CallbackId, ConnectionPort )); RemoveEntryList( &Msg->Entry ); LpcpFreeToPortZone( Msg, TRUE ); } } ExReleaseFastMutex( &LpcpLock ); if (ConnectionPort != Port) { ObDereferenceObject( ConnectionPort ); } } // // Free any static client security context // LpcpFreePortClientSecurity( Port ); }
VOID tgwinkEvtIoDeviceControl( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode ) { WDFMEMORY mem; NTSTATUS status; WDFDEVICE dev; PDEVICE_CONTEXT context; void *uBase = NULL; LARGE_INTEGER offset; size_t size; dev = WdfIoQueueGetDevice(Queue); context = DeviceGetContext(dev); switch (IoControlCode) { case IOCTL_TGWINK_SAY_HELLO: if (OutputBufferLength != 4) { WdfRequestComplete(Request, STATUS_BAD_DATA); break; } status = WdfRequestRetrieveOutputMemory(Request, &mem); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status); WdfVerifierDbgBreakPoint(); WdfRequestComplete(Request, status); break; } *((DWORD32 *)(WdfMemoryGetBuffer(mem, NULL))) = 0x5a5aa5a5; WdfRequestComplete(Request, STATUS_SUCCESS); break; case IOCTL_TGWINK_MAP_BAR_0: if (sizeof(void *) > OutputBufferLength) { KdPrint("tgwinkEvtIoDeviceControl needs a larger buffer (%d > %d)!\n", sizeof(void *), OutputBufferLength); WdfRequestComplete(Request, STATUS_BUFFER_TOO_SMALL); break; } offset = context->bar[0].phyAddr; size = context->bar[0].length; status = ZwMapViewOfSection(context->hMemory, ZwCurrentProcess(), &uBase, 0, 0, &offset, &size, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl could not map view of section, status "); switch (status) { case STATUS_CONFLICTING_ADDRESSES: KdPrint("STATUS_CONFLICTING_ADDRESSES\n"); break; case STATUS_INVALID_PAGE_PROTECTION: KdPrint("STATUS_INVALID_PAGE_PROTECTION\n"); break; case STATUS_SECTION_PROTECTION: KdPrint("STATUS_SECTION_PROTECTION\n"); break; default: KdPrint("0x % x\n", status); break; } WdfRequestComplete(Request, status); break; } status = WdfRequestRetrieveOutputMemory(Request, &mem); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status); WdfVerifierDbgBreakPoint(); WdfRequestComplete(Request, status); break; } *((void **)(WdfMemoryGetBuffer(mem, NULL))) = uBase; WdfRequestComplete(Request, STATUS_SUCCESS); break; case IOCTL_TGWINK_READ_PHYS: { PVOID buf; ULONG_PTR page, ofs, vtgt = 0; SIZE_T vsz = 0; if (InputBufferLength != sizeof(PVOID)) { KdPrint("tgwinkEvtIoDeviceControl requires a %d-byte buffer for this ioctl (got %d)\n", sizeof(PVOID), OutputBufferLength); WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES); break; } status = WdfRequestRetrieveInputBuffer(Request, sizeof(PVOID), &buf, NULL); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status); WdfRequestComplete(Request, status); break; } ofs = *((ULONG_PTR *)buf); page = ofs & ~0xfff; vsz = OutputBufferLength + (page ^ ofs); buf = NULL; status = WdfRequestRetrieveOutputMemory(Request, &mem); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl could not get request memory buffer, status 0x%x\n", status); WdfRequestComplete(Request, status); break; } status = ZwMapViewOfSection(context->hMemory, (HANDLE)-1, (PVOID *)&vtgt, 0, 0, (PLARGE_INTEGER)&page, &vsz, ViewUnmap, 0, PAGE_READONLY); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl could not map view of physical memory section, status 0x%x\n", status); WdfRequestComplete(Request, status); break; } ofs -= page; status = WdfMemoryCopyFromBuffer(mem, 0, (PVOID)(vtgt + ofs), OutputBufferLength); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl failed to copy data from memory to buffer, status 0x%x\n", status); WdfRequestComplete(Request, status); break; } status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)vtgt); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl failed to unmap view of physical memory section, status 0x%x\n", status); WdfRequestComplete(Request, status); break; } WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, OutputBufferLength); } break; case IOCTL_TGWINK_PEND_INTR: { WdfWaitLockAcquire(context->nnLock, NULL); if (context->notifyNext) { PINTERRUPT_CONTEXT pCtx = InterruptGetContext(context->hIrq); status = WdfRequestRetrieveOutputMemory(Request, &mem); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl failed to retrieve output memory, status 0x%x\n", status); WdfRequestComplete(Request, status); } status = WdfMemoryCopyFromBuffer(mem, 0, &pCtx->serial, 8); if (!NT_SUCCESS(status)) { KdPrint("tgwinkEvtIoDeviceControl failed to copy interrupt number to buffer, status 0x%x\n", status); WdfRequestComplete(Request, status); } WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 8); context->notifyNext = 0; KdPrint("tgwinkEvtIoDeviceControl satisfied interrupt notification request synchronously.\n"); //WdfInterruptEnable(context->hIrq); } else { KdPrint("tgwinkEvtIoDeviceControl forwarding PEND_INTR request to notification queue\n"); WdfRequestForwardToIoQueue(Request, context->NotificationQueue); } WdfWaitLockRelease(context->nnLock); } break; default: WdfRequestComplete(Request, STATUS_UNSUCCESSFUL); } }