Capturing OutputDebugString

6d3419e685c17d359a9a43ec7035ba7f
0
ent 101 Nov 09, 2007 at 15:00

Using OutputDebugString for tracing your programs is probably not a good idea, at least if you have lots of traces being generated (OutputDebugString raises an exception and causes a kernel mode transition). So you will probably end up implementing your own tracing/logging system. Parts of code that are not under your control may be still using OutputDebugString(like Debugging Tools for Windows, DirectX, etc). The code listed below allows capturing OutputDebugString calls generated inside your own process (in fact, it is capturing all the OSD calls generated by all the active processes).

You will need to put this piece of code in a separate thread, but those details are omitted for better clarity.

NOTE: If the process is being debugged, the ODS calls will be intercepted by debugger.

    ////////////////////////////////////////////////////////////////////////////////////////////////
    struct DbWinBuffer
    {
        DWORD dwProcessId;
        char data[4096 - sizeof(DWORD)];
    };

    DbWinBuffer* dbBuffer;

    HANDLE hAckEvent;
    HANDLE hEvent;
    HANDLE hSharedFile;

    SECURITY_DESCRIPTOR sd;
    SECURITY_ATTRIBUTES sa;

    ////////////////////////////////////////////////////////////////////////////////////////////////

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = true;
    sa.lpSecurityDescriptor = &sd;

    if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) 
    {
        printf("ERROR: InitializeSecurityDescriptor\\n");
        return 1;
    }

    if (!SetSecurityDescriptorDacl(&sd, true, 0, false)) 
    {
        printf("ERROR: SetSecurityDescriptorDacl\n");
        return 1;
    }

    hAckEvent = CreateEvent(&sa, false, false, L"DBWIN_BUFFER_READY");
    if (!hAckEvent) 
    {
        printf("ERROR: CreateEvent(\\"DBWIN_BUFFER_READY\\")\\n");
        return 1;
    }

    hEvent = CreateEvent(&sa, false, false, L"DBWIN_DATA_READY");
    if (!hEvent) 
    {
        printf("ERROR: CreateEvent(\\"DBWIN_DATA_READY\\")\\n");
        return 1;
    }

    hSharedFile = CreateFileMapping((HANDLE)-1, &sa, PAGE_READWRITE, 0, 4096, L"DBWIN_BUFFER");
    if(!hSharedFile) 
    {
        printf("ERROR: CreateFileMapping(\\"DBWIN_BUFFER\\")\\n");
        return 1;
    }

    dbBuffer = static_cast<DbWinBuffer*>(MapViewOfFile(hSharedFile, FILE_MAP_READ, 0, 0, 4096));
    if(!dbBuffer) 
    {
        printf("ERROR: MapViewOfFile\\n");
        return 1;
    }

    SetEvent(hAckEvent);

    DWORD pid = GetCurrentProcessId();
    printf("Tracing PID: %dnn", pid);

    for(;;)
    {             
        DWORD ret = WaitForSingleObject(hEvent, INFINITE);
        if (ret == WAIT_FAILED)
        {
            printf("ERROR: WaitForSingleObject\\n");
            return 1;
        }

        if (dbBuffer->dwProcessId == pid)
        {
            printf("%s", dbBuffer->data);
        }

        SetEvent(hAckEvent);
    }

Happy coding,

http://entland.homelinux.com/blog/

2 Replies

Please log in or register to post a reply.

D077d0bf7229ce747187481ac934e8d3
0
Sascha88 101 Sep 07, 2011 at 13:51

Thanx for the advice!! mobile spy Highly appreciate your help and work in general))

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Sep 07, 2011 at 19:35

NOTE: If the process is being debugged, the ODS calls will be intercepted by debugger.

In which case OSD is *way* faster. So if you want to monitor the OSD calls from a single process, simply act as a debugger for that process.