uint32 peChecksumExecSections(uint8 *peBaseAddr, void *realBase, PEPROCESS proc, PKAPC_STATE apc, PHYSICAL_ADDRESS *physArr) { uint16 numExecSections = peGetNumExecSections(peBaseAddr); uint32 checksum = 0, k, i, j, numRelocs = peGetNumberOfRelocs(peBaseAddr, realBase, proc, apc), relocDelta = peCalculateRelocDiff(peBaseAddr, realBase); uint8 *dataPtr = NULL; PHYSICAL_ADDRESS phys = {0}; SectionData *execSections = (SectionData *) MmAllocateNonCachedMemory( numExecSections * sizeof(SectionData)); peGetExecSections(peBaseAddr, execSections); //DbgPrint("Found %d relocations, delta of: %x\r\n", numRelocs, relocDelta); for (i = 0; i < numExecSections; i++) { uint32 numpages = execSections[i].Size / 0x1000, size = execSections[i].Size; if (numpages * 0x1000 < execSections[i].Size) numpages++; for (k = 0; k < numpages; k++) { KeStackAttachProcess(proc, apc); dataPtr = (uint8 *) MmMapIoSpace(MmGetPhysicalAddress((void *)(((uint32) realBase) + execSections[i].VirtualAddress + (0x1000 * k))), 0x1000, 0); phys = MmGetPhysicalAddress((void *) dataPtr); for (j = 0; j < min(size, 0x1000); j++) { checksum += dataPtr[j]; } MmUnmapIoSpace((void *) dataPtr, 0x1000); size -= 0x1000; KeUnstackDetachProcess(apc); } } // Subtract the relocations from the checksum // TODO Fix incase of lower load address checksum += numRelocs * (relocDelta & 0x000000FF); checksum += numRelocs * ((relocDelta & 0x0000FF00) >> 8); checksum += numRelocs * ((relocDelta & 0x00FF0000) >> 16); checksum += numRelocs * ((relocDelta & 0xFF000000) >> 24); MmFreeNonCachedMemory((void *) execSections, numExecSections * sizeof(SectionData)); return checksum; }
static DWORD PspThreadCutterThread(PVOID StartContext) { HANDLE ProcessHandle, ThreadHandle; PTHREAD_CONTROL_BLOCK *pt_prev_thread, *pt_cur_thread; while(1) { /* check thread cutting list */ if(!PspPopCuttingItem(&m_ThreadCuttingList, &ThreadHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); ProcessHandle = PsGetThreadPtr(ThreadHandle)->parent_process_handle; /* if requsted thread's parent process handle is same with system process handle, then do nothing!! protect system thread */ if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } /* invalid thread */ if(PsGetProcessPtr(ProcessHandle)->thread_count == 0) { goto $exit; } /* check whether there is only one thread exist in the parent process */ else if(PsGetProcessPtr(ProcessHandle)->thread_count == 1) { PsGetProcessPtr(ProcessHandle)->pt_head_thread = NULL; } /* more than 2 threads exist */ else { pt_prev_thread = pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != PsGetThreadPtr(ThreadHandle)) { /* there is no requested thread in the parent process */ if((*pt_cur_thread)->pt_next_thread == NULL) { goto $exit; } pt_prev_thread = pt_cur_thread; pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } /* change next thread pointer */ (*pt_prev_thread)->pt_next_thread = (*pt_cur_thread)->pt_next_thread; } PsGetProcessPtr(ProcessHandle)->thread_count--; /* except user mode program's stack */ if(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address >= (int *)0x00200000) MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address)); /* dealloc stack */ MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle))); /* dealloc thread */ $exit: EXIT_CRITICAL_SECTION(); } return 0; }
static DWORD PspProcessCutterThread(PVOID StartContext) { HANDLE ProcessHandle; PPROCESS_CONTROL_BLOCK *pt_prev_process, *pt_cur_process; PTHREAD_CONTROL_BLOCK *pt_cur_thread; while(1) { /* check process cutting list */ if(!PspPopCuttingItem(&m_ProcessCuttingList, &ProcessHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); /* if requsted process handle is same with system process handle, then do nothing!! protect system process */ if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } /* find requested process position in the process list */ pt_prev_process = pt_cur_process = &(m_ProcMgrBlk.pt_head_process); while(*pt_cur_process != PsGetProcessPtr(ProcessHandle)) { /* there is no requested process in the list */ if((*pt_cur_process)->pt_next_process == NULL) { goto $exit; } pt_prev_process = pt_cur_process; pt_cur_process = &((*pt_cur_process)->pt_next_process); } /* change next process pointer */ (*pt_prev_process)->pt_next_process = (*pt_cur_process)->pt_next_process; m_ProcMgrBlk.process_count--; /* dealloc all threads belonged to the requested process */ pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != NULL) { MmFreeNonCachedMemory((PVOID)((*pt_cur_thread)->pt_stack_base_address)); MmFreeNonCachedMemory((PVOID)(*pt_cur_thread)); pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } /* dealloc the requested process memory */ MmFreeNonCachedMemory((PVOID)ProcessHandle); $exit: EXIT_CRITICAL_SECTION(); } return 0; }
//종료된 쓰레드의 삭제 static DWORD PspThreadCutterThread(PVOID StartContext) { HANDLE ProcessHandle, ThreadHandle; PTHREAD_CONTROL_BLOCK *pt_prev_thread, *pt_cur_thread; while(1) { if(!PspPopCuttingItem(&m_ThreadCuttingList, &ThreadHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); ProcessHandle = PsGetThreadPtr(ThreadHandle)->parent_process_handle; if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } if(PsGetProcessPtr(ProcessHandle)->thread_count == 0) { goto $exit; } else if(PsGetProcessPtr(ProcessHandle)->thread_count == 1) { PsGetProcessPtr(ProcessHandle)->pt_head_thread = NULL; } else { pt_prev_thread = pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != PsGetThreadPtr(ThreadHandle)) { if((*pt_cur_thread)->pt_next_thread == NULL) { goto $exit; } pt_prev_thread = pt_cur_thread; pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } (*pt_prev_thread)->pt_next_thread = (*pt_cur_thread)->pt_next_thread; } PsGetProcessPtr(ProcessHandle)->thread_count--; if(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address >= (int *)0x00200000) MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle)->pt_stack_base_address)); MmFreeNonCachedMemory((PVOID)(PsGetThreadPtr(ThreadHandle))); $exit: EXIT_CRITICAL_SECTION(); } }
NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; KdPrint(("Enter HelloDDKDeviceIOControl\n")); //得到当前堆栈 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); //得到输入缓冲区大小 ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; //得到输出缓冲区大小 ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; //得到IOCTL码 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; ULONG info = 0; switch (code) { // process request case IOCTL_ENABLEDIRECTIO: { KdPrint(("IOCTL_ENABLEDIRECTIO\n")); pIOPM = (UCHAR*)MmAllocateNonCachedMemory(IOPM_SIZE); if (pIOPM) { RtlZeroMemory(pIOPM, IOPM_SIZE); Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1); Ke386SetIoAccessMap(1, pIOPM); } else pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; } case IOCTL_DISABLEDIRECTIO: { KdPrint(("IOCTL_DISABLEDIRECTIO\n")); if (pIOPM) { Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0); Ke386SetIoAccessMap(1, pIOPM); MmFreeNonCachedMemory(pIOPM, IOPM_SIZE); pIOPM = NULL; } } default: status = STATUS_INVALID_VARIANT; } // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = info; // bytes xfered IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKDeviceIOControl\n")); return status; }
//종료된 프로세스의 삭제 static DWORD PspProcessCutterThread(PVOID StartContext) { HANDLE ProcessHandle; PPROCESS_CONTROL_BLOCK *pt_prev_process, *pt_cur_process; PTHREAD_CONTROL_BLOCK *pt_cur_thread; while(1) { if(!PspPopCuttingItem(&m_ProcessCuttingList, &ProcessHandle)) { HalTaskSwitch(); continue; } ENTER_CRITICAL_SECTION(); if(ProcessHandle == PsGetThreadPtr(PsGetCurrentThread())->parent_process_handle) { goto $exit; } pt_prev_process = pt_cur_process = &(m_ProcMgrBlk.pt_head_process); while(*pt_cur_process != PsGetProcessPtr(ProcessHandle)) { if((*pt_cur_process)->pt_next_process == NULL) { goto $exit; } pt_prev_process = pt_cur_process; pt_cur_process = &((*pt_cur_process)->pt_next_process); } (*pt_prev_process)->pt_next_process = (*pt_cur_process)->pt_next_process; m_ProcMgrBlk.process_count--; pt_cur_thread = &(PsGetProcessPtr(ProcessHandle)->pt_head_thread); while(*pt_cur_thread != NULL) { MmFreeNonCachedMemory((PVOID)((*pt_cur_thread)->pt_stack_base_address)); MmFreeNonCachedMemory((PVOID)(*pt_cur_thread)); pt_cur_thread = &((*pt_cur_thread)->pt_next_thread); } MmFreeNonCachedMemory((PVOID)ProcessHandle); $exit: EXIT_CRITICAL_SECTION(); } return 0; }
/********************************************************************* Release any allocated objects. *********************************************************************/ VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject) { WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; UNICODE_STRING uniDOSString; if(IOPM_local) MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM)); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); IoDeleteSymbolicLink (&uniDOSString); IoDeleteDevice(DriverObject->DeviceObject); }
void co_os_free_pages(void *ptr, unsigned int pages) { if (ptr == 0) KeBugCheck(0x11117777 + 1); if (pages == 0) KeBugCheck(0x11117777 + 2); #ifdef DEBUG_CO_OS_ALLOC co_debug_allocations("PAGE FREE %d(%u) - %p", allocs, pages, ptr); allocs--; #endif MmFreeNonCachedMemory(ptr, pages * CO_ARCH_PAGE_SIZE); }
// Be good computer citizens and clean up after ourselves... void DriverUnload(IN PDRIVER_OBJECT driverObject) { UNICODE_STRING dosName; // free the memory we used to store our IOPM if(ioMap) { MmFreeNonCachedMemory(ioMap, sizeof(IOPM)); } RtlInitUnicodeString(&dosName, dosDevicePath); IoDeleteSymbolicLink (&dosName); IoDeleteDevice(driverObject->DeviceObject); }
NTSTATUS WinIoDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack; ULONG dwInputBufferLength; ULONG dwOutputBufferLength; ULONG dwIoControlCode; PVOID pvIOBuffer; NTSTATUS ntStatus; struct tagPhys32Struct Phys32Struct; OutputDebugString ("Entering WinIoDispatch"); // Init to default settings Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IrpStack = IoGetCurrentIrpStackLocation(Irp); // Get the pointer to the input/output buffer and it's length pvIOBuffer = Irp->AssociatedIrp.SystemBuffer; dwInputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (IrpStack->MajorFunction) { case IRP_MJ_CREATE: OutputDebugString("IRP_MJ_CREATE"); break; case IRP_MJ_CLOSE: OutputDebugString("IRP_MJ_CLOSE"); break; case IRP_MJ_DEVICE_CONTROL: OutputDebugString("IRP_MJ_DEVICE_CONTROL"); dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (dwIoControlCode) { case IOCTL_WINIO_ENABLEDIRECTIO: OutputDebugString("IOCTL_WINIO_ENABLEDIRECTIO"); pIOPM = MmAllocateNonCachedMemory(sizeof(IOPM)); if (pIOPM) { RtlZeroMemory(pIOPM, sizeof(IOPM)); Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1); Ke386SetIoAccessMap(1, pIOPM); } else Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; break; case IOCTL_WINIO_DISABLEDIRECTIO: OutputDebugString("IOCTL_WINIO_DISABLEDIRECTIO"); if (pIOPM) { Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0); Ke386SetIoAccessMap(1, pIOPM); MmFreeNonCachedMemory(pIOPM, sizeof(IOPM)); pIOPM = NULL; } break; case IOCTL_WINIO_MAPPHYSTOLIN: OutputDebugString("IOCTL_WINIO_MAPPHYSTOLIN"); if (dwInputBufferLength) { memcpy (&Phys32Struct, pvIOBuffer, dwInputBufferLength); ntStatus = MapPhysicalMemoryToLinearSpace(Phys32Struct.pvPhysAddress, Phys32Struct.dwPhysMemSizeInBytes, &Phys32Struct.pvPhysMemLin, &Phys32Struct.PhysicalMemoryHandle); if (NT_SUCCESS(ntStatus)) { memcpy (pvIOBuffer, &Phys32Struct, dwInputBufferLength); Irp->IoStatus.Information = dwInputBufferLength; } Irp->IoStatus.Status = ntStatus; } else Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; case IOCTL_WINIO_UNMAPPHYSADDR: OutputDebugString("IOCTL_WINIO_UNMAPPHYSADDR"); if (dwInputBufferLength) { memcpy (&Phys32Struct, pvIOBuffer, dwInputBufferLength); ntStatus = UnmapPhysicalMemory(Phys32Struct.PhysicalMemoryHandle, Phys32Struct.pvPhysMemLin); Irp->IoStatus.Status = ntStatus; } else Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; default: OutputDebugString("ERROR: Unknown IRP_MJ_DEVICE_CONTROL"); Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; } break; } // DON'T get cute and try to use the status field of the irp in the // return status. That IRP IS GONE as soon as you call IoCompleteRequest. ntStatus = Irp->IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); // We never have pending operation so always return the status code. OutputDebugString("Leaving WinIoDispatch"); return ntStatus; }
static STDCALL NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,ULONG PhysMemSizeInBytes,PVOID *PhysMemLin){ alloc_priv* alloclisttmp; PMDL Mdl=NULL; PVOID SystemVirtualAddress=NULL; PVOID UserVirtualAddress=NULL; PHYSICAL_ADDRESS pStartPhysAddress; OutputDebugString ("dhahelper: entering MapPhysicalMemoryToLinearSpace"); #ifdef _WIN64 pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress; #else pStartPhysAddress.QuadPart = (ULONGLONG)(ULONG)pPhysAddress; #endif #ifndef NO_SEH __try { #endif SystemVirtualAddress=MmMapIoSpace(pStartPhysAddress,PhysMemSizeInBytes, /*MmWriteCombined*/MmNonCached); if(!SystemVirtualAddress){ OutputDebugString("dhahelper: MmMapIoSpace failed"); return STATUS_INVALID_PARAMETER; } OutputDebugString("dhahelper: SystemVirtualAddress 0x%x",SystemVirtualAddress); Mdl=IoAllocateMdl(SystemVirtualAddress, PhysMemSizeInBytes, FALSE, FALSE,NULL); if(!Mdl){ OutputDebugString("dhahelper: IoAllocateMdl failed"); return STATUS_INSUFFICIENT_RESOURCES; } OutputDebugString("dhahelper: Mdl 0x%x",Mdl); MmBuildMdlForNonPagedPool(Mdl); #ifdef _WIN64 UserVirtualAddress = (PVOID)(((ULONGLONG)PAGE_ALIGN(MmMapLockedPages(Mdl,UserMode))) + MmGetMdlByteOffset(Mdl)); #else UserVirtualAddress = (PVOID)(((ULONG)PAGE_ALIGN(MmMapLockedPages(Mdl,UserMode))) + MmGetMdlByteOffset(Mdl)); #endif if(!UserVirtualAddress){ OutputDebugString("dhahelper: MmMapLockedPages failed"); return STATUS_INSUFFICIENT_RESOURCES; } OutputDebugString("dhahelper: UserVirtualAddress 0x%x",UserVirtualAddress); #ifndef NO_SEH }__except(EXCEPTION_EXECUTE_HANDLER){ NTSTATUS ntStatus; ntStatus = GetExceptionCode(); OutputDebugString("dhahelper: MapPhysicalMemoryToLinearSpace failed due to exception 0x%0x\n", ntStatus); return ntStatus; } #endif OutputDebugString("dhahelper: adding data to internal allocation list"); alloclisttmp=MmAllocateNonCachedMemory((alloccount+1)*sizeof(alloc_priv)); if(!alloclisttmp){ OutputDebugString("dhahelper: not enough memory to create temporary allocation list"); MmUnmapLockedPages(UserVirtualAddress, Mdl); IoFreeMdl(Mdl); return STATUS_INSUFFICIENT_RESOURCES; } if(alloccount){ memcpy(alloclisttmp,alloclist,alloccount * sizeof(alloc_priv)); MmFreeNonCachedMemory(alloclist,alloccount*sizeof(alloc_priv)); } alloclist=alloclisttmp; alloclist[alloccount].Mdl=Mdl; alloclist[alloccount].SystemVirtualAddress=SystemVirtualAddress; alloclist[alloccount].UserVirtualAddress=UserVirtualAddress; alloclist[alloccount].PhysMemSizeInBytes=PhysMemSizeInBytes; ++alloccount; *PhysMemLin=UserVirtualAddress; OutputDebugString("dhahelper: leaving MapPhysicalMemoryToLinearSpace"); return STATUS_SUCCESS; }