void ultimap_flushBuffers_all(UINT_PTR param) { DbgPrint("Calling perfmon_interrupt_centry() manually\n"); if (DS_AREA[cpunr()]) //don't call if ultimap has been disabled { perfmon_interrupt_centry(); enableInterrupts(); //the handler disables it on exit so re-enable it } }
int inthook_UnhookInterrupt(unsigned char intnr) { if (InterruptHook[intnr].hooked) { //it's hooked, try to unhook DbgPrint("cpu %d : interrupt %d is hooked\n",cpunr(),intnr); if (InterruptHook[intnr].dbvmInterruptEmulation) { if (intnr==1) vmx_redirect_interrupt1(virt_differentInterrupt, 1, 0, 0); else if (intnr==3) vmx_redirect_interrupt3(virt_differentInterrupt, 3, 0, 0); else vmx_redirect_interrupt14(virt_differentInterrupt, 14, 0, 0); return TRUE; //that's all we need } //still here so not a dbvm hook, unhook the old way and hope nothing has interfered { INT_VECTOR newVector; //newVector.bUnused=0; /* newVector.gatetype=6; //interrupt gate newVector.gatesize=1; //32-bit newVector.zero=0; newVector.DPL=0; newVector.P=1; */ newVector.wHighOffset=(WORD)((DWORD)(InterruptHook[intnr].originalEIP >> 16)); newVector.wLowOffset=(WORD)InterruptHook[intnr].originalEIP; newVector.wSelector=(WORD)InterruptHook[intnr].originalCS; #ifdef AMD64 newVector.TopOffset=(InterruptHook[intnr].originalEIP >> 32); newVector.Reserved=0; #endif { IDT idt; GetIDT(&idt); newVector.bAccessFlags=idt.vector[intnr].bAccessFlags; disableInterrupts(); idt.vector[intnr]=newVector; enableInterrupts(); } DbgPrint("Restored\n"); } }
int perfmon_interrupt_centry(void) { KIRQL old; void *temp; int causedbyme=(DS_AREA[cpunr()]->BTS_IndexBaseAddress>=DS_AREA[cpunr()]->BTS_InterruptThresholdAddress); UINT_PTR blocksize; DbgPrint("perfmon_interrupt_centry\n", cpunr()); if (causedbyme) ultimap_cleanstate(); blocksize=DS_AREA[cpunr()]->BTS_IndexBaseAddress-DS_AREA[cpunr()]->BTS_BufferBaseAddress; { if (KeGetCurrentIrql() < DISPATCH_LEVEL) { //When called by the pre-emptive caller old = KeRaiseIrqlToDpcLevel(); } DbgPrint("Entry cpunr=%d\n", cpunr()); DbgPrint("Entry threadid=%d\n", PsGetCurrentThreadId()); temp=ExAllocatePool(NonPagedPool, blocksize); if (temp) { RtlCopyMemory(temp, (PVOID *)DS_AREA[cpunr()]->BTS_BufferBaseAddress, blocksize); DbgPrint("temp=%p\n", temp); DS_AREA[cpunr()]->BTS_IndexBaseAddress=DS_AREA[cpunr()]->BTS_BufferBaseAddress; //don't reset on alloc error } else { DbgPrint("ExAllocatePool has failed\n"); KeLowerIrql(old); disableInterrupts(); return causedbyme; } KeLowerIrql(old); //should be passive mode, taskswitches and cpu switches will happen now (When this returns, I may not be on the same interrupt as I was when I started) if (SaveToFile) { IO_STATUS_BLOCK iosb; NTSTATUS r; //Instead of sending the data to a usermode app it was chosen to store the data to a file for later usage DbgPrint("Writing buffer to disk\n"); r=ZwWriteFile(FileHandle, NULL, NULL, NULL, &iosb, temp, (ULONG)blocksize, NULL, NULL); DbgPrint("Done Writing. Result=%x\n", r); } else { DbgPrint("Waiting till there is a block free\n"); //When all workers are busy do not continue if ((DataBlock) && (KeWaitForSingleObject(&DataBlockSemaphore, Executive, KernelMode, FALSE, NULL) == STATUS_SUCCESS)) { int currentblock; int i; //Enter a critical section and choose a block DbgPrint("Acquired semaphore. Now picking a usable datablock\n"); ExAcquireFastMutex(&DataBlockMutex); DbgPrint("Acquired mutex. Looking for a Datablock that can be used\n"); if (DataBlock) { currentblock=-1; for (i=0; i< MaxDataBlocks; i++) { if (DataBlock[i].Available) //look for a block that is set as available { currentblock=i; DataBlock[currentblock].Available=FALSE; //not available anymore break; } } } else currentblock=-1; if (currentblock>=0) { DbgPrint("Using datablock %d\n", currentblock); DataBlock[currentblock].Data=temp; DataBlock[currentblock].DataSize=(int)blocksize; DataBlock[currentblock].CpuID=cpunr(); DbgPrint("Calling KeSetEvent/KeWaitForSingleObject\n"); KeSetEvent(&DataBlock[currentblock].DataReady, 1, FALSE); //Trigger a worker thread to start working } ExReleaseFastMutex(&DataBlockMutex); //DbgPrint("Released mutex\n"); } else { DbgPrint("if ((DataBlock) && (KeWaitForSingleObject(&DataBlockSemaphore, Executive, KernelMode, FALSE, NULL) == STATUS_SUCCESS)) failed\n"); } } //and return to the caller process disableInterrupts(); return causedbyme; } DbgPrint("Returning from perfmon_interrupt_centry\n"); return causedbyme; }