예제 #1
0
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
	}
}
예제 #2
0
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");
		}
	}
예제 #3
0
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;

	
}