Example #1
0
// Creats Post breakpoint object, adds it to the list and enables it
_Use_decl_annotations_ void SbpCreateAndEnablePostBreakpoint(
    void* address, const PatchInformation& info,
    const CapturedParameters& parameters, EptData* ept_data) {
  auto duplicated_info =
      SbppFindDuplicatedPostPatchInfo(address, PsGetCurrentThreadId());
  if (duplicated_info) {
    duplicated_info->parameters = parameters;
    return;
  }
  auto info_for_post = SbppCreatePostBreakpoint(
      address, info, PsGetCurrentThreadId(), parameters);
  auto ptr = info_for_post.get();
  SbppAddBreakpointToList(std::move(info_for_post));
  SbppEnablePageShadowingForExec(*ptr, ept_data);
}
Example #2
0
void TlsRemoveCurrentThread(THREAD_LOCAL_STORAGE* InTls)
{
/*
Description:

    Removes the caller from the local storage. If the caller
    is already removed, the method will do nothing.

Parameters:

    - InTls

        The storage from which the caller should be removed.
*/
#ifndef DRIVER
	ULONG		    CurrentId = (ULONG)GetCurrentThreadId();
#else
	ULONG		    CurrentId = (ULONG)PsGetCurrentThreadId();
#endif
    ULONG           Index;

    RtlAcquireLock(&InTls->ThreadSafe);

	for(Index = 0; Index < MAX_THREAD_COUNT; Index++)
	{
		if(InTls->IdList[Index] == CurrentId)
		{
			InTls->IdList[Index] = 0;

			RtlZeroMemory(&InTls->Entries[Index], sizeof(THREAD_RUNTIME_INFO));
		}
	}

	RtlReleaseLock(&InTls->ThreadSafe);
}
Example #3
0
VOID ThreadStart(PVOID lpStartContext)
{
	PKEVENT pEvent = (PKEVENT)lpStartContext;
	DbgPrint("Hello! I am kernel thread. My ID is %u. Regards..", (ULONG)PsGetCurrentThreadId());
	KeSetEvent(pEvent, 0, 0);
	PsTerminateSystemThread(STATUS_SUCCESS);
}
Example #4
0
VOID __stdcall Filter(ULONG ServiceId, ULONG TableBase, ULONG Argc, ULONG StackAddr) {
	ULONG pid = (ULONG)PsGetCurrentProcessId();
	if (pid == g_nPid) {
		ULONG i;
		PXBoxData pData=(PXBoxData)ExAllocateFromNPagedLookasideList(&g_nPageList);
		if(!pData)
			return;
		
		if (StackAddr < MmUserProbeAddress)
			pData->bFromUser = 1;
		else
			pData->bFromUser = 0;
		
		if (TableBase == (ULONG)KeServiceDescriptorTable.ServiceTableBase)
			pData->bFromSSDT = 1;
		else
			pData->bFromSSDT = 0;

		if (Argc > 16)
			Argc = 16;
		pData->argc = (UCHAR)Argc;
		for (i = 0; i < Argc; ++i)
			pData->args[i] = ((PULONG)StackAddr)[i];

		pData->pid = (ULONG)pid;
		pData->tid = (ULONG)PsGetCurrentThreadId();
		pData->sid = ServiceId;
		KeQuerySystemTime(&pData->time);
		ExInterlockedInsertTailList(&g_linkListHead, &pData->ListEntry, &g_lock);
		KeReleaseSemaphore( &g_keySemaphore, 0, 1, FALSE );
	}
}
Example #5
0
NTSTATUS
	IoCompletionRoutine(
	IN PDEVICE_OBJECT  DeviceObject,
	IN PIRP  Irp,
	IN PVOID  Context
	)
{
	UNREFERENCED_PARAMETER(DeviceObject);
	UNREFERENCED_PARAMETER(Context);

	PAGED_CODE();

	KdPrint(("SYS(%d:%d):IoCompletionRoutine!\n", PsGetCurrentProcessId(), PsGetCurrentThreadId()));
	*Irp->UserIosb = Irp->IoStatus;

	if (Irp->UserEvent)
		KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);

	if (Irp->MdlAddress)
	{
		IoFreeMdl(Irp->MdlAddress);
		Irp->MdlAddress = NULL;
	}

	IoFreeIrp(Irp);

	return STATUS_MORE_PROCESSING_REQUIRED;
}
Example #6
0
void
AFSProcessNotify( IN HANDLE  ParentId,
                  IN HANDLE  ProcessId,
                  IN BOOLEAN  Create)
{

    //
    // If this is a create notification then update our tree, otherwise remove the
    // entry
    //

    if( Create)
    {

        AFSProcessCreate( ParentId,
                          ProcessId,
                          PsGetCurrentProcessId(),
                          PsGetCurrentThreadId());
    }
    else
    {

        AFSProcessDestroy( ProcessId);
    }

    return;
}
Example #7
0
VOID
NDISLWF_ReceiveNetBufferListsHandler (
    NDIS_HANDLE         FilterModuleContext,
    PNET_BUFFER_LIST    NetBufferLists,
    NDIS_PORT_NUMBER    PortNumber,
    ULONG               NumberOfNetBufferLists,
    ULONG               ReceiveFlags )
{
    PNDISLWF_CONTEXT FilterContext = (PNDISLWF_CONTEXT)FilterModuleContext;

    // process the NBL chain to determine if should be allowed or rejected
    if ( ProcessNblChain ( NetBufferLists ) ) {
        DPF(("%s!%s [%x.%x] NBL=%p BLOCKED\n", __MODULE__, __FUNCTION__, 
            PsGetCurrentProcessId(), PsGetCurrentThreadId(), NetBufferLists ));

        // Step #1 : Return the NBL chain to the caller instead of indicating it up to 
        // the driver above (NdisFReturnNetBufferLists())
        // ensure that the ReceiveFlags are properly translated to ReturnFlags
        NdisFReturnNetBufferLists(FilterContext->FilterHandle, NetBufferLists, ReceiveFlags & NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL);

    } else {
        // Step #2 : Indicate the NBL chain to the driver above (NdisFIndicateReceiveNetBufferLists())
        NdisFIndicateReceiveNetBufferLists(FilterContext->FilterHandle, NetBufferLists, PortNumber, NumberOfNetBufferLists, ReceiveFlags);

    }
} // NDISLWF_ReceiveNetBufferListsHandler()
Example #8
0
void WmipWaitForCollectionEnabled(
    PBGUIDENTRY GuidEntry
    )
{
    PAGED_CODE();
    
    WmipAssert((GuidEntry->Flags & GE_FLAG_COLLECTION_IN_PROGRESS) ==
                   GE_FLAG_COLLECTION_IN_PROGRESS);
    
    //
    // Collection Enable/Disable is in progress so
    // we cannot return just yet. Right now there could be a 
    // disable request being processed and if we didn't wait, we
    // might get back to this caller before that disable request
    // got around to realizing that it needs to send and enable 
    // request (needed by this thread's caller). So we'd have a 
    // situation where a thread though that collection was enabled
    // but in reality it wasn't yet enabled.
    if ((GuidEntry->Flags & GE_FLAG_WAIT_ENABLED) == 0)
    {
        KeInitializeEvent(GuidEntry->CollectInProgress, 
                          NotificationEvent,
                          FALSE);
        GuidEntry->Flags |= GE_FLAG_WAIT_ENABLED;
        WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL,"WMI: %p.%p for %p %x created event\n",
                                 PsGetCurrentProcessId(), PsGetCurrentThreadId(),
                                 GuidEntry,
                                 GuidEntry->Flags));
    }
            
    WmipLeaveSMCritSection();
    WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL,"WMI: %p.%p waiting for %p %x on event\n",
                                 PsGetCurrentProcessId(), PsGetCurrentThreadId(),
                                     GuidEntry,
                                     GuidEntry->Flags));
    KeWaitForSingleObject(GuidEntry->CollectInProgress, 
                          Executive,
                          KernelMode,
                          FALSE,
                          NULL);
    WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL,"WMI: %p.%p done %p %x waiting on event\n",
                                 PsGetCurrentProcessId(), PsGetCurrentThreadId(),
                                     GuidEntry,
                                     GuidEntry->Flags));
    WmipEnterSMCritSection();
    
}
Example #9
0
BOOL TlsAddCurrentThread(THREAD_LOCAL_STORAGE* InTls)
{
/*
Description:

    Tries to reserve a THREAD_RUNTIME_INFO entry for the calling thread.
    On success it may call TlsGetCurrentValue() to query a pointer to
    its private entry.

    This is a replacement for the Windows Thread Local Storage which seems
    to cause trouble when using it in Explorer.EXE for example.

    No parameter validation (for performance reasons).

    This method will raise an assertion if the thread was already added
    to the storage!

Parameters:
    - InTls

        The thread local storage to allocate from.

Returns:

    TRUE on success, FALSE otherwise.
*/
#ifndef DRIVER
	ULONG		CurrentId = (ULONG)GetCurrentThreadId();
#else
	ULONG		CurrentId = (ULONG)PsGetCurrentThreadId();
#endif
	LONG		Index = -1;
    LONG		i;

    RtlAcquireLock(&InTls->ThreadSafe);

    // select Index AND check whether thread is already registered.
	for(i = 0; i < MAX_THREAD_COUNT; i++)
	{
		if((InTls->IdList[i] == 0) && (Index == -1))
			Index = i;
		
		ASSERT(InTls->IdList[i] != CurrentId);
	}

	if(Index == -1)
	{
		RtlReleaseLock(&InTls->ThreadSafe);

		return FALSE;
	}

	InTls->IdList[Index] = CurrentId;
	RtlZeroMemory(&InTls->Entries[Index], sizeof(THREAD_RUNTIME_INFO));
	
	RtlReleaseLock(&InTls->ThreadSafe);

	return TRUE;
}
Example #10
0
// Enumerate all big pages and calls a callback routine when it matched with
// a criteria specified by filters parameters. It stops to enumerate when the
// callback returned false.
template <typename TableType> static
void WinXpEnumBigPages(
    __in EnumBigPagesCallbackType Callback,
    __in_opt void* Context,
    __in_opt ULONG KeyFilter,
    __in_opt SIZE_T MinSizeFilter,
    __in TableType* BigPageTable,
    __in SIZE_T NumberOfBigPageTable)
{
    DBG_PRINT("[%5Iu:%5Iu] Initialize : PoolBigPageTable = %p\n",
        reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
        reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
        BigPageTable);
    DBG_PRINT("[%5Iu:%5Iu] Initialize : PoolBigPageTableSize = %p\n",
        reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
        reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
        NumberOfBigPageTable);

    for (SIZE_T i = 0; i < NumberOfBigPageTable; ++i)
    {
        auto entry = &BigPageTable[i];
        auto startAddr = reinterpret_cast<ULONG_PTR>(entry->Va);

        // Ignore unused entries
        if (!startAddr || (startAddr & 1))
        {
            continue;
        }

        // Get the size in bytes
        const auto sizeInBytes = entry->Size * Multiplier<TableType>::value;

        // Filter if it is needed
        if ((KeyFilter && entry->Key != KeyFilter)
         || (sizeInBytes < MinSizeFilter))
        {
            continue;
        }

        // Call a callback function
        if (!Callback(startAddr, sizeInBytes, entry->Key, Context))
        {
            break;
        }
    }
}
Example #11
0
VCOS_STATUS_T vcos_platform_init(void)
{
   VCOS_STATUS_T st;
   uint32_t flags = 0;

   st = _vcos_named_semaphore_init();
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_NAMED_SEM;

   st = vcos_once(&current_thread_key_once, current_thread_key_init);
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   /* Initialise a VCOS wrapper for the thread which called vcos_init. */
   st = vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0);
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_MAIN_SEM;

#ifdef WIN32_KERN 
   vcos_thread_main.thread = PsGetCurrentThreadId();

   // TODO Implement thread context for kernel mode
#else
   int pst;

   vcos_thread_main.thread = GetCurrentThread();

   // For windows zero return value is failure
   pst = TlsSetValue(_vcos_thread_current_key, &vcos_thread_main);
   if (!vcos_verify(pst != 0))
   {
       st = VCOS_EINVAL;
       goto end;
   }
#endif

   st = vcos_msgq_init();
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_MSGQ;

   vcos_logging_init();

end:
   if (st != VCOS_SUCCESS)
      vcos_term(flags);

   return st;
}
Example #12
0
EXTERN_C
ULONG_PTR Win8HandleKeDelayExecutionThread(
    __in ULONG_PTR* AddressOfReturnAddress)
{
    PAGED_CODE();
    const auto pg_SelfEncryptWaitAndDecrypt = g_Symbols.KiScbQueueScanWorker
        + WIN8_OFFSET_TO_Pg_SelfEncryptWaitAndDecrypt;

    auto returnAddr = *AddressOfReturnAddress;

    // Check if the thread is going to return to Pg_SelfEncryptWaitAndDecrypt
    if (returnAddr == pg_SelfEncryptWaitAndDecrypt)
    {
        DBG_PRINT("[%5Iu:%5Iu] PatchGuard ???????????????? :"
                  " KeDelayExecutionThread is returning to"
                  " Pg_SelfEncryptWaitAndDecrypt (%016llX).\n",
            reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
            reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
            returnAddr);
        //DBG_BREAK();
        return 1;
    }

    // Check if the thread is going to return to FsRtlMdlReadCompleteDevEx
    if (*reinterpret_cast<ULONG64*>(returnAddr)
        == WIN8_KeDelayExecutionThread_RETURN_CODE_PATTERN)
    {
        DBG_PRINT("[%5Iu:%5Iu] PatchGuard ???????????????? :"
                  " KeDelayExecutionThread is returning to"
                  " FsRtlMdlReadCompleteDevEx (%016llX).\n",
            reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
            reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
            returnAddr);
        //DBG_BREAK();
        return 2;
    }

    // It is not a PatchGuard
    return 0;
}
Example #13
0
/*!
 *  \see http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
 */
NTSTATUS
NTAPI
KsecGatherEntropyData(
    PKSEC_ENTROPY_DATA EntropyData)
{
    MD4_CTX Md4Context;
    PTEB Teb;
    PPEB Peb;
    PWSTR String;
    SIZE_T ReturnLength;
    NTSTATUS Status;

    /* Query some generic values */
    EntropyData->CurrentProcessId = PsGetCurrentProcessId();
    EntropyData->CurrentThreadId = PsGetCurrentThreadId();
    KeQueryTickCount(&EntropyData->TickCount);
    KeQuerySystemTime(&EntropyData->SystemTime);
    EntropyData->PerformanceCounter = KeQueryPerformanceCounter(
                                            &EntropyData->PerformanceFrequency);

    /* Check if we have a TEB/PEB for the process environment */
    Teb = PsGetCurrentThread()->Tcb.Teb;
    if (Teb != NULL)
    {
        Peb = Teb->ProcessEnvironmentBlock;

        /* Initialize the MD4 context */
        MD4Init(&Md4Context);
        _SEH2_TRY
        {
            /* Get the end of the environment */
            String = Peb->ProcessParameters->Environment;
            while (*String)
            {
                String += wcslen(String) + 1;
            }

            /* Update the MD4 context from the environment data */
            MD4Update(&Md4Context,
                      (PUCHAR)Peb->ProcessParameters->Environment,
                      (ULONG)((PUCHAR)String - (PUCHAR)Peb->ProcessParameters->Environment));
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Simply ignore the exception */
        }
        _SEH2_END;

        /* Finalize and copy the MD4 hash */
        MD4Final(&Md4Context);
        RtlCopyMemory(&EntropyData->EnvironmentHash, Md4Context.digest, 16);
    }
Example #14
0
void WmipReleaseCollectionEnabled(
    PBGUIDENTRY GuidEntry
    )
{
    PAGED_CODE();
    
    if (GuidEntry->Flags & GE_FLAG_WAIT_ENABLED)
    {
        WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL,"WMI: %p.%p enable releasning %p.%p %x event %p\n",
                                 PsGetCurrentProcessId(), PsGetCurrentThreadId(),
                                     GuidEntry,
                                     GuidEntry->Flags));
                                 
        KeSetEvent(GuidEntry->CollectInProgress, 0, FALSE);
        WmipDebugPrintEx((DPFLTR_WMICORE_ID, DPFLTR_INFO_LEVEL,"WMI: %p.%p enable did release %p %x event %p\n",
                                 PsGetCurrentProcessId(), PsGetCurrentThreadId(),
                                     GuidEntry,
                                     GuidEntry->Flags));
                                 
        GuidEntry->Flags &= ~GE_FLAG_WAIT_ENABLED;
    }
}
Example #15
0
NDIS_STATUS
NDISLWF_RestartHandler (
    NDIS_HANDLE                     FilterModuleContext,
    PNDIS_FILTER_RESTART_PARAMETERS RestartParameters )
{
    PNDISLWF_CONTEXT FilterContext = (PNDISLWF_CONTEXT)FilterModuleContext;

    DPF(("%s!%s [%x.%x] (Context=%p RestartParameters=%p)\n", __MODULE__, __FUNCTION__, 
        PsGetCurrentProcessId(), PsGetCurrentThreadId(), 
        FilterContext, RestartParameters )); 

    return NDIS_STATUS_SUCCESS;
} //NDISLWF_RestartHandler()
Example #16
0
VOID
NDISLWF_StatusHandler (
    NDIS_HANDLE FilterModuleContext,
    PNDIS_STATUS_INDICATION StatusIndication )
{
    PNDISLWF_CONTEXT FilterContext = (PNDISLWF_CONTEXT)FilterModuleContext;

    DPF(("%s!%s [%x.%x] (Context=%p StatusIndication=%p)\n", __MODULE__, __FUNCTION__, 
        PsGetCurrentProcessId(), PsGetCurrentThreadId(), 
        FilterModuleContext, 
        StatusIndication )); 

    NdisFIndicateStatus(FilterContext->FilterHandle, StatusIndication);
} //NDISLWF_StatusHandler()
Example #17
0
EXTERN_C static
bool WinXpCollectPatchGuardContexts(
    __in ULONG_PTR StartAddress,
    __in SIZE_T SizeInBytes,
    __in ULONG Key,
    __inout_opt void* Context)
{
    // Ignore this if the address is not in the NonPaged pool
    if (StartAddress < *g_WinXSymbols.MmNonPagedPoolStart)
    {
        return true;
    }

    if (!Context)
    {
        return false;
    }

    auto storage = static_cast<PatchGuardContexts*>(Context);
    PatchGuardContextInfo result = {};
    for (SIZE_T searchedBytes = 0; searchedBytes < SizeInBytes; /**/)
    {
        // Search a context
        const auto remainingBytes = SizeInBytes - searchedBytes;
        const auto searchPosition = StartAddress + searchedBytes;
        const auto checkedBytes = WinXpSearchPatchGuardContext(
            searchPosition, remainingBytes, result);
        searchedBytes += checkedBytes;

        // Check if a context was found
        if (result.PgContext)
        {
            // save it to the storage
            storage->PgContexts[storage->NumberOfPgContexts] = result;
            storage->NumberOfPgContexts++;

            DBG_PRINT("[%5Iu:%5Iu] PatchGuard %016llX : XorKey %016llX\n",
                reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
                reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
                result.PgContext, result.XorKey);
            break;
        }
    }

    // Tell WinXpEnumBigPages to stop enumerating pages when the storage is full
    return (storage->NumberOfPgContexts <
            storage->MAX_SUPPORTED_NUMBER_OF_PG_CONTEXTS);
}
Example #18
0
BOOL TlsGetCurrentValue(
            THREAD_LOCAL_STORAGE* InTls,                
            THREAD_RUNTIME_INFO** OutValue)
{
/*
Description:

    Queries the THREAD_RUNTIME_INFO for the calling thread.
    The caller shall previously be added to the storage by
    using TlsAddCurrentThread().

Parameters:

    - InTls

        The storage where the caller is registered.

    - OutValue

        Is filled with a pointer to the caller's private storage entry.

Returns:

    FALSE if the caller was not registered in the storage, TRUE otherwise.
*/
#ifndef DRIVER
	ULONG		CurrentId = (ULONG)GetCurrentThreadId();
#else
	ULONG		CurrentId = (ULONG)PsGetCurrentThreadId();
#endif
    LONG        Index;

	for(Index = 0; Index < MAX_THREAD_COUNT; Index++)
	{
		if(InTls->IdList[Index] == CurrentId)
		{
			*OutValue = &InTls->Entries[Index];

			return TRUE;
		}
	}

	return FALSE;
}
Example #19
0
VOID
NTAPI
DbgLogEvent(PSLIST_HEADER pslh, LOG_EVENT_TYPE nEventType, LPARAM lParam)
{
    PLOGENTRY pLogEntry;

    /* Log a maximum of 100 events */
    if (QueryDepthSList(pslh) >= 1000) return;

    /* Allocate a logentry */
    pLogEntry = EngAllocMem(0, sizeof(LOGENTRY), 'golG');
    if (!pLogEntry) return;

    /* Set type */
    pLogEntry->nEventType = nEventType;
    pLogEntry->ulUnique = InterlockedIncrement((LONG*)&gulLogUnique);
    pLogEntry->dwProcessId = HandleToUlong(PsGetCurrentProcessId());
    pLogEntry->dwThreadId = HandleToUlong(PsGetCurrentThreadId());
    pLogEntry->lParam = lParam;

    /* Capture a backtrace */
    DbgCaptureStackBackTace(pLogEntry->apvBackTrace, 20);

    switch (nEventType)
    {
        case EVENT_ALLOCATE:
        case EVENT_CREATE_HANDLE:
        case EVENT_REFERENCE:
        case EVENT_DEREFERENCE:
        case EVENT_LOCK:
        case EVENT_UNLOCK:
        case EVENT_DELETE:
        case EVENT_FREE:
        case EVENT_SET_OWNER:
        default:
            break;
    }

    /* Push it on the list */
    InterlockedPushEntrySList(pslh, &pLogEntry->sleLink);
}
Example #20
0
// runs in kernel mode as KAPC.KernelRoutine
VOID
KernelApcKernelRoutine (
    PKAPC Apc,
    PKNORMAL_ROUTINE *NormalRoutine,
    PVOID *NormalContext,
    PVOID *SystemArgument1,
    PVOID *SystemArgument2 )
{
    UNREFERENCED_PARAMETER(NormalContext);
    UNREFERENCED_PARAMETER(SystemArgument1);
    UNREFERENCED_PARAMETER(SystemArgument2);

    DPF(("%s!%s CID=%x.%x Irql=%u Apc=%p NormalRoutine=%p\n", __MODULE__, __FUNCTION__, 
        PsGetCurrentProcessId(),
        PsGetCurrentThreadId(),
        KeGetCurrentIrql(),
        Apc,
        *NormalRoutine ));

    ExFreePool ( Apc );
}
Example #21
0
// A thread runs as long as info.buffer_flush_thread_should_be_alive is true and
// flushes a log buffer to a log file every kLogpLogFlushIntervalMsec msec.
_Use_decl_annotations_ static VOID LogpBufferFlushThreadRoutine(
    void *start_context) {
  PAGED_CODE();
  auto status = STATUS_SUCCESS;
  auto info = reinterpret_cast<LogBufferInfo *>(start_context);
  info->buffer_flush_thread_started = true;
  HYPERPLATFORM_LOG_DEBUG("Log thread started (TID= %p).",
                          PsGetCurrentThreadId());

  while (info->buffer_flush_thread_should_be_alive) {
    NT_ASSERT(LogpIsLogFileActivated(*info));
    if (info->log_buffer_head[0]) {
      NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
      NT_ASSERT(!KeAreAllApcsDisabled());
      status = LogpFlushLogBuffer(info);
      // Do not flush the file for overall performance. Even a case of
      // bug check, we should be able to recover logs by looking at both
      // log buffers.
    }
    LogpSleep(kLogpLogFlushIntervalMsec);
  }
  PsTerminateSystemThread(status);
}
Example #22
0
void SendRegistryOperationToUserland (ULONG _opType, PUNICODE_STRING _pTarget )
{
	PRECORD_LIST recordList = SpyNewRecord();
	if (!recordList)
		return;

	//Set the operation type.
	recordList->LogRecord.Data.RecordType = _opType;
	//Fill the basic stuff (PID-TID).
	recordList->LogRecord.Data.ProcessId = (FILE_ID)PsGetCurrentProcessId();
	recordList->LogRecord.Data.ThreadId = (FILE_ID)PsGetCurrentThreadId();
	//Fill the SystemTypeStuff.
	KeQuerySystemTime(&recordList->LogRecord.Data.OriginatingTime);
	KeQuerySystemTime(&recordList->LogRecord.Data.CompletionTime);
	////Set the name to ""
	UNICODE_STRING emptySTR;
	RtlInitUnicodeString(&emptySTR, L"");
	DbgPrint("SendRegistryOperationToUserland : %wZ", _pTarget);
	SpySetRecordNameAndEcpData(&recordList->LogRecord, _pTarget, NULL);
	////Send to the userland!
	SpyLog(recordList);

}
Example #23
0
// Gets called by AsmKeWaitForSingleObject, and returns one of following codes:
//  1. returning to FsRtlMdlReadCompleteDevEx (PatchGuard)
//  0. returning to anywhere else (Not PatchGuard)
// AsmKeWaitForSingleObject returns the thread till ExpWorkerThead if the
// returned code is 1 rather than manipulating them. This is because the
// PatchGuard context may be encrypted on the fly and cannot be manipulated at
// that moment.
EXTERN_C
ULONG_PTR Win8HandleKeWaitForSingleObject(
    __in ULONG_PTR* AddressOfReturnAddress)
{
    auto returnAddr = *AddressOfReturnAddress;

    // Check if the thread is going to return to FsRtlMdlReadCompleteDevEx
    if (*reinterpret_cast<ULONG_PTR*>(returnAddr)
        == WIN8_KeWaitForSingleObject_RETURN_CODE_PATTERN)
    {
        DBG_PRINT("[%5Iu:%5Iu] PatchGuard ???????????????? :"
                  " KeWaitForSingleObject is returning to"
                  " FsRtlMdlReadCompleteDevEx (%016llX).\n",
            reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
            reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
            returnAddr);
        //DBG_BREAK();
        return 1;
    }

    // It is not a PatchGuard
    return 0;
}
Example #24
0
void rnd_reseed_now()
{
	seed_data seed;

	KeQuerySystemTime(&seed.seed20);
	
	seed.seed1  = PsGetCurrentProcess();
	seed.seed2  = PsGetCurrentProcessId();
	seed.seed3  = KeGetCurrentThread();
	seed.seed4  = PsGetCurrentThreadId();
	seed.seed5  = KeGetCurrentProcessorNumber();
	seed.seed6  = KeQueryInterruptTime();
	seed.seed10 = KeQueryPerformanceCounter(NULL);
	seed.seed11 = __rdtsc();
	seed.seed12 = ExGetPreviousMode();	
	seed.seed14 = IoGetTopLevelIrp();
	seed.seed15 = MmQuerySystemSize();
	seed.seed24 = KeGetCurrentIrql();
	
	if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
		seed.seed7  = KeQueryPriorityThread(seed.seed3);
		seed.seed17 = ExUuidCreate(&seed.seed18);
		seed.seed19 = RtlRandom(&seed.seed8);
	}
	if (KeGetCurrentIrql() <= APC_LEVEL) {
		seed.seed13 = IoGetInitialStack();
		seed.seed16 = PsGetProcessExitTime();
		IoGetStackLimits(&seed.seed22, &seed.seed23);
	}	
	KeQueryTickCount(&seed.seed21);
	
	rnd_add_buff(&seed, sizeof(seed));
	
	/* Prevent leaks */	
	zeroauto(&seed, sizeof(seed));
}
Example #25
0
// Gets called from AsmPg_IndependentContextWorkItemRoutine
EXTERN_C
void Win8HandlePg_IndependentContextWorkItemRoutine(
    __in Pg_IndependentContextWorkItemContext* Context)
{
    DBG_PRINT("[%5Iu:%5Iu] PatchGuard %016llX :"
              " Pg_IndependentContextWorkItemRoutine was called.\n",
        reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
        reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
        Context->PgContext);

    if (Win8pIsMonitoringModeEnabled())
    {
        // Now, we have got a decrypted PatchGuard context that is about to
        // execute Pg_IndependentContextWorkItemRoutine
        auto pgContext = reinterpret_cast<PgContext_8_1*>(Context->PgContext);
        Win8pPatchPgContext(pgContext);
    }
    else
    {
        // You can replace the routine with a harmless empty function instead of
        // modifying the PatchGuard context.
        Context->FsUninitializeSmallMcb = [](void*) {};
    }
}
Example #26
0
// Concatenates meta information such as the current time and a process ID to
// user given log message.
EXTERN_C static NTSTATUS LogpMakePrefix(_In_ ULONG Level,
                                        _In_ const char *FunctionName,
                                        _In_ const char *LogMessage,
                                        _Out_ char *LogBuffer,
                                        _In_ size_t LogBufferLength) {
  char const *levelString = nullptr;
  switch (Level) {
    case LOGP_LEVEL_DEBUG:
      levelString = "DBG";
      break;
    case LOGP_LEVEL_INFO:
      levelString = "INF";
      break;
    case LOGP_LEVEL_WARN:
      levelString = "WRN";
      break;
    case LOGP_LEVEL_ERROR:
      levelString = "ERR";
      break;
    default:
      return STATUS_INVALID_PARAMETER;
  }

  auto status = STATUS_SUCCESS;

  char timeBuffer[20] = {};
  if ((g_LogpDebugFlag & LOG_OPT_DISABLE_TIME) == 0) {
    // Want the current time.
    TIME_FIELDS timeFields;
    LARGE_INTEGER systemTime, localTime;
    KeQuerySystemTime(&systemTime);
    ExSystemTimeToLocalTime(&systemTime, &localTime);
    RtlTimeToTimeFields(&localTime, &timeFields);

    status = RtlStringCchPrintfA(timeBuffer, RTL_NUMBER_OF(timeBuffer),
                                 "%02u:%02u:%02u.%03u\t", timeFields.Hour,
                                 timeFields.Minute, timeFields.Second,
                                 timeFields.Milliseconds);
    if (!NT_SUCCESS(status)) {
      return status;
    }
  }

  char functionNameBuffer[50] = {};
  if ((g_LogpDebugFlag & LOG_OPT_DISABLE_FUNCTION_NAME) == 0) {
    // Want the function name
    const auto baseFunctionName = LogpFindBaseFunctionName(FunctionName);
    status = RtlStringCchPrintfA(functionNameBuffer,
                                 RTL_NUMBER_OF(functionNameBuffer), "%-40s\t",
                                 baseFunctionName);
    if (!NT_SUCCESS(status)) {
      return status;
    }
  }

  //
  // It uses PsGetProcessId(PsGetCurrentProcess()) instead of
  // PsGetCurrentThreadProcessId() because the later sometimes returns
  // unwanted value, for example:
  //  PID == 4 but its image name != ntoskrnl.exe
  // The author is guessing that it is related to attaching processes but
  // not quite sure. The former way works as expected.
  //
  status = RtlStringCchPrintfA(
      LogBuffer, LogBufferLength, "%s%s\t%5lu\t%5lu\t%-15s\t%s%s\r\n", timeBuffer,
      levelString,
      reinterpret_cast<ULONG_PTR>(PsGetProcessId(PsGetCurrentProcess())),
      reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
      PsGetProcessImageFileName(PsGetCurrentProcess()), functionNameBuffer,
      LogMessage);
  return status;
}
Example #27
0
BOOL 
ShareMemKImp::InitializeShareMem(HANDLE hFile,
	LPSECURITY_ATTRIBUTES lpAttributes,
	DWORD flProtect,
	DWORD dwMaximumSize,
	LPCWSTR lpName, 
	DWORD dwDesiredAccess,
	ShareMemClassInit* lpInitialization,
	void* lpUserContext) {

	UninitializeShareMem();

	DWORD size;
	size = dwMaximumSize + sizeof(ShareMemHeader);
	if (size < dwMaximumSize)
		return FALSE;

	UNICODE_STRING us;
	RtlInitUnicodeString(&us,
		lpName);

	OBJECT_ATTRIBUTES attr;
	InitializeObjectAttributes(&attr,
		&us,
		OBJ_OPENIF,
		NULL,
		NULL);

	LARGE_INTEGER li;
	li.QuadPart = size;

	NTSTATUS status;
	status = ZwCreateSection(&m_hMapSect,
		READ_CONTROL|WRITE_DAC|dwDesiredAccess,
		&attr,
		&li,
		flProtect,
		SEC_COMMIT,
		hFile);

	BOOLEAN init;
	init = status != STATUS_SUCCESS ? FALSE : TRUE;
	
	if (m_hMapSect) {
		SIZE_T v_size;
		v_size = 0;
		status = ZwMapViewOfSection(m_hMapSect,
			ZwCurrentProcess(),
			&m_hMapView,
			0,
			size,
			NULL,
			&v_size,			
			ViewUnmap,
			0,
			PAGE_READWRITE);
		if (m_hMapView) {
			m_hMapSize = dwMaximumSize;

			ShareMemHeader* smh;
			smh = (ShareMemHeader*)m_hMapView;			
			if (init) {
				LARGE_INTEGER tick;
				KeQueryTickCount(&tick);

				RtlStringCchPrintfW(smh->m_LockName, 
					sizeof(smh->m_LockName), 
					L"K-%08x-%08x-%08x",
					PsGetCurrentProcessId(),
					PsGetCurrentThreadId(),
					tick.LowPart);
								
				if (lpInitialization)
					smh->m_bResult = lpInitialization(this,
						lpUserContext);
				else
					smh->m_bResult = TRUE;

				smh->m_bInitialized = TRUE;
			}
			else
				while(1)
					if (smh->m_bInitialized)
						break;

			return smh->m_bResult;
		}
	}
	return FALSE;
}
Example #28
0
NTSTATUS
ioctlDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	PIO_STACK_LOCATION  irpSp;
	NTSTATUS            NtStatus = STATUS_SUCCESS;
	int ret = 0;
	union {
		struct nm_ifreq ifr;
		struct nmreq nmr;
	} arg;


	size_t	argsize = 0;
	PVOID	data;
	struct sockopt	*sopt;
	int	space, len = 0;

	(void)DeviceObject; // XXX

	irpSp = IoGetCurrentIrpStackLocation(Irp);
	argsize = irpSp->Parameters.DeviceIoControl.InputBufferLength;
	data = Irp->AssociatedIrp.SystemBuffer;

	switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
	case NIOCGINFO:
		DbgPrint("Netmap.sys: NIOCGINFO");
		argsize = sizeof(arg.nmr);
		break;

	case NIOCREGIF:
		DbgPrint("Netmap.sys: NIOCREGIF");
		argsize = sizeof(arg.nmr);
#if 0
		struct nmreq* test = (struct nmreq*) Irp->AssociatedIrp.SystemBuffer;
		DbgPrint("IFNAMSIZ: %i , sizeof(nmreq): %i\n", IFNAMSIZ, sizeof(struct nmreq));
		DbgPrint("nr_version: %i , nr_ringid: %i\n", test->nr_version, test->nr_ringid);
		DbgPrint("nr_cmd: %i , nr_name: %s\n", test->nr_cmd, test->nr_name);
		DbgPrint("nr_tx_rings: %i , nr_tx_slots: %i\n", test->nr_tx_rings, test->nr_tx_slots);
		DbgPrint("nr_offset: %i , nr_flags: %s\n", test->nr_offset, test->nr_flags);
#endif
		break;

	case NIOCTXSYNC:
		//DbgPrint("Netmap.sys: NIOCTXSYNC");
		break;

	case NIOCRXSYNC:
		//DbgPrint("Netmap.sys: NIOCRXSYNC");
		break;

	case NIOCCONFIG:
		DbgPrint("Netmap.sys: NIOCCONFIG");
		argsize = sizeof(arg.ifr);
		break;

	case NETMAP_MMAP:
		DbgPrint("Netmap.sys: NETMAP_MMAP");
		NtStatus = windows_netmap_mmap(Irp);
		Irp->IoStatus.Status = NtStatus;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return NtStatus;

	case NETMAP_GETSOCKOPT:
	case NETMAP_SETSOCKOPT:
		DbgPrint("Netmap.sys: NETMAP_SET/GET-SOCKOPT (Common code)");
		if (argsize < sizeof(struct sockopt)) {
			NtStatus = STATUS_BAD_DATA;
			Irp->IoStatus.Status = NtStatus;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return NtStatus;
		}
		sopt = Irp->AssociatedIrp.SystemBuffer;
		len = sopt->sopt_valsize;
		if (irpSp->Parameters.DeviceIoControl.IoControlCode == NETMAP_SETSOCKOPT) {
			DbgPrint("Netmap.sys: NETMAP_SETSOCKOPT");
			NtStatus = do_netmap_set_ctl(NULL, sopt->sopt_name, sopt + 1, len);
			Irp->IoStatus.Information = 0;
		} else {
			DbgPrint("Netmap.sys: NETMAP_GETSOCKOPT");
			NtStatus = do_netmap_get_ctl(NULL, sopt->sopt_name, sopt + 1, &len);
			sopt->sopt_valsize = len;
			// XXX should we use OutputBufferLength ?
			space = irpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (len + sizeof(struct sockopt) <= space) {
				Irp->IoStatus.Information = len + sizeof(struct sockopt);
			} else {
				Irp->IoStatus.Information = space;
			}
		}
		Irp->IoStatus.Status = NtStatus;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return NtStatus;

	case NETMAP_POLL:
		{
			//DbgPrint("%i: Requested call to POLL \n", PsGetCurrentThreadId());
			POLL_REQUEST_DATA *pollData = data;
			LARGE_INTEGER tout;
			tout.QuadPart = -(int)(pollData->timeout) * 1000 * 10;
			struct netmap_priv_d *priv = irpSp->FileObject->FsContext;

			if (priv == NULL) {
				NtStatus = STATUS_DEVICE_DATA_ERROR;
				goto done;
			}

			irpSp->FileObject->FsContext2 = NULL;
			pollData->revents = netmap_poll(priv, pollData->events, irpSp);
			while ((irpSp->FileObject->FsContext2 != NULL) && (pollData->revents == 0)) {
				NTSTATUS waitResult = KeWaitForSingleObject(&((win_SELINFO*)irpSp->FileObject->FsContext2)->queue,
								UserRequest, KernelMode, 
								FALSE, &tout);
				if (waitResult == STATUS_TIMEOUT) {
					DbgPrint("%i: Timeout on 0x%p \n", PsGetCurrentThreadId(), irpSp->FileObject->FsContext2);
					pollData->revents = STATUS_TIMEOUT;
					NtStatus = STATUS_TIMEOUT;
					break;
				}
				pollData->revents = netmap_poll(priv, pollData->events, irpSp);
			}	
			irpSp->FileObject->FsContext2 = NULL;
			copy_to_user((void*)data, &arg, sizeof(POLL_REQUEST_DATA), Irp);
		}
		Irp->IoStatus.Status = NtStatus;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return NtStatus;

	default:
		//bail out if unknown request issued
		DbgPrint("Netmap.sys: wrong request issued! (%i)", irpSp->Parameters.DeviceIoControl.IoControlCode);
		NtStatus = STATUS_INVALID_DEVICE_REQUEST;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return NtStatus;
	}

	if (argsize) {
		if (!data) {
			NtStatus = STATUS_DATA_ERROR;
		} else {
			bzero(&arg, argsize);
			if (!NT_SUCCESS(copy_from_user(&arg, (void *)data, argsize, Irp))) {
				NtStatus = STATUS_DATA_ERROR;
			}	
		}	
	}

	if (NT_SUCCESS(NtStatus)) {
		struct netmap_priv_d *priv = irpSp->FileObject->FsContext;

		if (priv == NULL) {
			NtStatus = STATUS_DEVICE_DATA_ERROR;
			goto done;
		}

		ret = netmap_ioctl(priv, irpSp->Parameters.DeviceIoControl.IoControlCode,
			(caddr_t)&arg, NULL);
		if (NT_SUCCESS(ret)) {
			if (data && !NT_SUCCESS(copy_to_user((void*)data, &arg, argsize, Irp))) {
				DbgPrint("Netmap.sys: ioctl failure/cannot copy data to user");
				NtStatus = STATUS_DATA_ERROR;
			}
		} else {
			DbgPrint("Netmap.sys: ioctl failure (%i)", ret);
			NtStatus = STATUS_BAD_DATA;
		}
	}

done:
	Irp->IoStatus.Status = NtStatus;
	IoCompleteRequest( Irp, IO_NO_INCREMENT );
	return NtStatus;
}
Example #29
0
/**	-----------------------------------------------------------------------
	\brief	debug message output routine

	\param	
		IN  Level
				Debug Level (DBG_ERR, DBG_INFO, etc..)
				
		IN  Format
				Debug Message Format

	\return			
		NONE
	\code	
	\endcode		
-------------------------------------------------------------------------*/
VOID DrvDebugPrint(IN DWORD Level, IN const char* Function,IN const char* Format, IN ...)
{
	CHAR ProcName[NT_PROCNAMELEN]={0};
    ULONG i=0;
    va_list vaList;
    va_start(vaList, Format);

    // check mask for debug area and debug level
	//
    if (Level <= g_DebugLevel)
    {
        // find a free buffer
		//
        for (i = 0; i < NUMBER_DEBUG_BUFFERS; ++i)
        {
            if (InterlockedCompareExchange((LONG*)&g_DebugBufferBusy[i], 1, 0) == 0)
            {
                __try
				{
					if (TRUE != NT_SUCCESS( RtlStringCbVPrintfA(
										            g_DebugBuffer[i], 
										            sizeof(g_DebugBuffer[i]),
										            Format,
										            vaList
										            )))
					{
						return;
					}
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
                    return;
				}


				get_process_name(PsGetCurrentProcess(), ProcName);
								
                if (DPFLTR_ERROR_LEVEL == Level)
                {
                    DbgPrintEx(
						DPFLTR_IHVDRIVER_ID, 
						DPFLTR_ERROR_LEVEL, 
						DRIVERNAME"(IRQL %2.2d): %-16s(%04u:%04u) : [ERR ] %s(), %s\n", 
						KeGetCurrentIrql(), 
						ProcName, 
						PsGetCurrentProcessId(), PsGetCurrentThreadId(),
						Function, 
                        g_DebugBuffer[i]
                        ); 
                }
                else if (DPFLTR_WARNING_LEVEL == Level)
                {
                    DbgPrintEx(
						DPFLTR_IHVDRIVER_ID, 
						DPFLTR_WARNING_LEVEL | DPFLTR_MASK,
						DRIVERNAME"(IRQL %2.2d): %-16s(%04u:%04u) : [WARN] %s(), %s\n", 
						KeGetCurrentIrql(), 
						ProcName, 
						PsGetCurrentProcessId(), PsGetCurrentThreadId(),
						Function,                         
                        g_DebugBuffer[i]
                    );
                }
				//else if (DPFLTR_TRACE_LEVEL == Level)
				//{
				//	DbgPrintEx(
				//		DPFLTR_IHVDRIVER_ID, 
				//		DPFLTR_TRACE_LEVEL | DPFLTR_MASK,
				//		DRIVERNAME"(IRQL %2.2d): [TRCE] %s(), %s\n", 
				//		KeGetCurrentIrql(), 
				//		Function,                         
				//		g_DebugBuffer[i]
				//	);					
				//}
                else
                {
                    DbgPrintEx(
						DPFLTR_IHVDRIVER_ID, 
						DPFLTR_INFO_LEVEL |  DPFLTR_MASK, 
						DRIVERNAME"(IRQL %2.2d): %-16s(%04u:%04u) : [INFO] %s(), %s\n", 
                        KeGetCurrentIrql(), 
						ProcName,
						PsGetCurrentProcessId(), PsGetCurrentThreadId(),
						Function,                         
                        g_DebugBuffer[i]
                        );
                }

                InterlockedExchange((LONG*)&g_DebugBufferBusy[i], 0);
                break;
            }
        }
    }
Example #30
0
EXTERN_C
NTSTATUS WinXDisablePatchGuard(
    __in const WinXSymbols& Symbols)
{
    // Based on the size of FsRtlMdlReadCompleteDevEx on each platform
    static const SIZE_T MIN_SIZE_FILTER_XP = 0x2000;
    static const SIZE_T MIN_SIZE_FILTER = 0x4000;

    g_WinXSymbols = Symbols;

    auto exclusivity = std::experimental::unique_resource(
        ExclGainExclusivity(), ExclReleaseExclusivity);
    if (!exclusivity)
    {
        return STATUS_UNSUCCESSFUL;
    }

    // Collects all PatchGuard contexts
    PatchGuardContexts contexts = {};
    if (Symbols.PoolBigPageTableXp)
    {
        // For XP
        WinXpEnumBigPages(WinXpCollectPatchGuardContexts, &contexts, 0,
            MIN_SIZE_FILTER_XP,
            *g_WinXSymbols.PoolBigPageTableXp,
            *g_WinXSymbols.PoolBigPageTableSize);
    }
    else
    {
        // For 7 and Vista
        WinXpEnumBigPages(WinXpCollectPatchGuardContexts, &contexts, 0,
            MIN_SIZE_FILTER,
            *g_WinXSymbols.PoolBigPageTable,
            *g_WinXSymbols.PoolBigPageTableSize);
    }

    //DBG_BREAK();
    DBG_PRINT("[%5Iu:%5Iu] Initialize : %Iu contexts found.\n",
        reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()),
        reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()),
        contexts.NumberOfPgContexts);

    auto status = STATUS_SUCCESS;
    if (!contexts.NumberOfPgContexts ||
        contexts.NumberOfPgContexts
        == contexts.MAX_SUPPORTED_NUMBER_OF_PG_CONTEXTS)
    {
        // If a lot of PatchGuard contexts were found, it is likely an error
        status = STATUS_UNSUCCESSFUL;
    }
    else
    {
        // Install patches for all contexts
        for (SIZE_T i = 0; i < contexts.NumberOfPgContexts; ++i)
        {
            WinXpInstallPatchOnPatchGuardContext(contexts.PgContexts[i]);
        }
    }

    return status;
}