Results 1 to 3 of 3

Thread: how to intercept debug events in a debugged proces

  1. #1
    Lord_Looser
    Guest

    how to intercept debug events in a debugged proces

    Compile this Dll and inject it in one debugger’s process (e.g. OllyDbg) - not debuggee. You should see in “c:\> inject.txt” an output file for each debug event e.g. "Single Stop" you make in OllyDbg.

    No warranty – demonstration program only – beta

    I found HookImportedFunction() at http://www.codeproject.com/useritems/DLL_Injection_tutorial.asp and add_log() in one nice OpenGL wrapper tutorial.


    #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
    #pragma comment(linker,"/MERGE:.data=.text /MERGE:.rdata=.text /SECTION:.text,EWR /IGNORE:4078")

    #include <windows.h>
    #include <stdio.h>

    /*
    #pragma data_seg (".InjectDll") // you must define as SHARED in .def
    HANDLE g_hModule = NULL; // one instance for all processes
    #pragma data_seg ()
    */

    #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr)+(DWORD)(addValue))

    #define CASEL( x ) &#92;
    case (##x): &#92;
    add_log(#x "&#92;n"); &#92;
    break; &#92;

    PROC HookFn( HMODULE hModule, PSTR FunctionModule, PSTR FunctionName, PROC pfnNewProc )
    {
    PROC pfnOriginalProc;
    IMAGE_DOS_HEADER *pDosHeader;
    IMAGE_NT_HEADERS *pNTHeader;
    IMAGE_IMPORT_DESCRIPTOR *pImportDesc;
    IMAGE_THUNK_DATA *pThunk;
    if ( IsBadCodePtr(pfnNewProc) ) return 0;
    pfnOriginalProc = GetProcAddress(GetModuleHandle(FunctionModule), FunctionName);
    if(!pfnOriginalProc) return 0;
    pDosHeader = (PIMAGE_DOS_HEADER)hModule;
    if ( IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) )
    return 0;
    if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
    return 0;
    pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);
    if ( IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) )
    return 0;
    if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
    return 0;
    pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDosHeader,
    pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]. VirtualAddress);
    if ( pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeader )
    return 0;
    while ( pImportDesc->Name )
    {
    PSTR pszModName = MakePtr(PSTR, pDosHeader, pImportDesc->Name);
    if ( stricmp(pszModName, FunctionModule) == 0 )
    break;
    pImportDesc++;
    }
    if ( pImportDesc->Name == 0 )
    return 0;
    pThunk = MakePtr(PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk);
    while ( pThunk->u1.Function )
    {
    if ( (DWORD)pThunk->u1.Function == (DWORD)pfnOriginalProc )
    {
    DWORD dwOldProt;
    if (VirtualProtectEx(GetCurrentProcess(),&pThunk->u1.Function,sizeof(PDWO RD),PAGE_EXECUTE_READWRITE,&dwOldProt))
    {
    pThunk->u1.Function = (PDWORD)pfnNewProc;
    DWORD dwNewProt;
    VirtualProtectEx(GetCurrentProcess(),pThunk->u1.Function,sizeof(PDWORD ),dwOldProt,&dwNewProt);
    }
    return pfnOriginalProc;
    }
    pThunk++;
    }
    return 0;
    }

    void add_log (LPCTSTR psz, ...)
    {
    char logbuf[256]="";
    va_list va;
    va_start (va,psz);
    _vsnprintf (logbuf+strlen(logbuf), sizeof(logbuf) - strlen(logbuf), psz, va);
    va_end(va);
    FILE * fp;
    if ( (fp = fopen ("c:&#92;&#92;inject.log", "a")) != NULL )
    {
    fprintf ( fp, "%s", logbuf );
    fclose (fp);
    }
    }

    BOOL
    WINAPI // your debugger filter routine - loop possible
    _WaitForDebugEvent( LPDEBUG_EVENT lpDebugEvent,
    DWORD dwMilliseconds)
    {
    BOOL bRet = WaitForDebugEvent(lpDebugEvent,dwMilliseconds);
    if (bRet == 0)
    return bRet;
    add_log("%08x ",lpDebugEvent->u.Exception.ExceptionRecord.ExceptionAddress);
    switch (lpDebugEvent->dwDebugEventCode &
    (APPLICATION_ERROR_MASK | ERROR_SEVERITY_SUCCESS | ERROR_SEVERITY_INFORMATIONAL |
    ERROR_SEVERITY_WARNING | ERROR_SEVERITY_ERROR))
    {
    case APPLICATION_ERROR_MASK:
    {
    switch (lpDebugEvent->dwDebugEventCode)
    {
    case 0:
    break;
    default:
    add_log("default 0x%08x&#92;n",lpDebugEvent->dwDebugEventCode);
    break;
    }
    }
    break;
    case ERROR_SEVERITY_SUCCESS:
    {
    switch (lpDebugEvent->dwDebugEventCode)
    {
    case EXCEPTION_DEBUG_EVENT:
    switch (lpDebugEvent->u.Exception.ExceptionRecord.ExceptionCode)
    {
    CASEL (EXCEPTION_ACCESS_VIOLATION)
    CASEL (EXCEPTION_BREAKPOINT)
    CASEL (EXCEPTION_DATATYPE_MISALIGNMENT)
    CASEL (EXCEPTION_SINGLE_STEP)
    CASEL (DBG_CONTROL_C)
    default:
    add_log("default 0x%08x&#92;n",lpDebugEvent->u.Exception.ExceptionRecord.ExceptionCode);
    break;
    }
    break;
    CASEL (CREATE_THREAD_DEBUG_EVENT)
    CASEL (CREATE_PROCESS_DEBUG_EVENT)
    CASEL (EXIT_THREAD_DEBUG_EVENT)
    CASEL (EXIT_PROCESS_DEBUG_EVENT)
    CASEL (LOAD_DLL_DEBUG_EVENT)
    CASEL (UNLOAD_DLL_DEBUG_EVENT)
    CASEL (OUTPUT_DEBUG_STRING_EVENT)
    CASEL (RIP_EVENT)
    CASEL (STATUS_WAIT_0)
    CASEL (STATUS_ABANDONED_WAIT_0)
    CASEL (STATUS_USER_APC)
    CASEL (STATUS_TIMEOUT)
    CASEL (STATUS_PENDING)
    default:
    add_log("default 0x%08x&#92;n",lpDebugEvent->dwDebugEventCode);
    break;
    }
    }
    break;
    case ERROR_SEVERITY_INFORMATIONAL:
    {
    switch (lpDebugEvent->dwDebugEventCode)
    {
    CASEL (STATUS_SEGMENT_NOTIFICATION)
    default:
    add_log("default 0x%08x&#92;n",lpDebugEvent->dwDebugEventCode);
    break;
    }
    }
    break;
    case ERROR_SEVERITY_WARNING:
    {
    switch (lpDebugEvent->dwDebugEventCode)
    {
    CASEL (STATUS_GUARD_PAGE_VIOLATION)
    CASEL (STATUS_DATATYPE_MISALIGNMENT)
    CASEL (STATUS_BREAKPOINT)
    CASEL (STATUS_SINGLE_STEP)
    default:
    add_log("default 0x%08x&#92;n",lpDebugEvent->dwDebugEventCode);
    break;
    }
    }
    break;
    case ERROR_SEVERITY_ERROR:
    {
    switch (lpDebugEvent->dwDebugEventCode)
    {
    CASEL (STATUS_ACCESS_VIOLATION)
    CASEL (STATUS_IN_PAGE_ERROR)
    CASEL ( STATUS_INVALID_HANDLE)
    CASEL ( STATUS_NO_MEMORY)
    CASEL ( STATUS_ILLEGAL_INSTRUCTION)
    CASEL ( STATUS_NONCONTINUABLE_EXCEPTION)
    CASEL ( STATUS_INVALID_DISPOSITION)
    CASEL ( STATUS_ARRAY_BOUNDS_EXCEEDED)
    CASEL ( STATUS_FLOAT_DENORMAL_OPERAND)
    CASEL ( STATUS_FLOAT_DIVIDE_BY_ZERO)
    CASEL ( STATUS_FLOAT_INEXACT_RESULT)
    CASEL ( STATUS_FLOAT_INVALID_OPERATION)
    CASEL ( STATUS_FLOAT_OVERFLOW)
    CASEL ( STATUS_FLOAT_STACK_CHECK)
    CASEL ( STATUS_FLOAT_UNDERFLOW)
    CASEL ( STATUS_INTEGER_DIVIDE_BY_ZERO)
    CASEL ( STATUS_INTEGER_OVERFLOW)
    CASEL ( STATUS_PRIVILEGED_INSTRUCTION)
    CASEL ( STATUS_STACK_OVERFLOW)
    CASEL ( STATUS_CONTROL_C_EXIT)
    CASEL ( STATUS_FLOAT_MULTIPLE_FAULTS)
    CASEL ( STATUS_FLOAT_MULTIPLE_TRAPS)
    CASEL ( STATUS_ILLEGAL_VLM_REFERENCE)
    default:
    add_log("default 0x%08x&#92;n",lpDebugEvent->dwDebugEventCode);
    break;
    }
    }
    break;
    default:
    add_log("BAD default 0x%08x&#92;n",lpDebugEvent->dwDebugEventCode);
    break;
    }
    return bRet;
    }

    BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    /* if (g_hModule == NULL)
    g_hModule = hModule;
    else
    */
    HookFn(GetModuleHandle(NULL),"kernel32.dll","WaitForDebugEvent",(PROC) _WaitForDebugEvent);
    break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    break;
    }
    return TRUE;
    }
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  2. #2
    focht
    Guest

    how to intercept debug events in a debugged proces

    Hi,

    please forgive my ignorance ... but what advantage does this method have over using ollydbg's plugin API ODBG_Pluginmainloop() callback?

    Regards,

    A. Focht
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  3. #3
    Lord_Looser
    Guest

    how to intercept debug events in a debugged proces

    If you want to debug a program that debugs itself you can yet set breakpoints or something else (without OllyDbg's aid :-( ) and catch these before the program can recognise this.
    Unfortunately OllyDbg cannot debug/open already debugged processes and on Win2k systems you cannot detach debugger.
    I promise that I have read the FAQ and tried to use the Search to answer my question.

Similar Threads

  1. Olydbg and thousands events per second
    By Morfi in forum OllyDbg Support Forums
    Replies: 5
    Last Post: April 5th, 2014, 16:37
  2. Replies: 0
    Last Post: January 12th, 2008, 00:08
  3. Is it possible to intercept the ReadFile() function of an executable
    By test in forum Advanced Reversing and Programming
    Replies: 4
    Last Post: January 2nd, 2006, 08:26
  4. How can I allocate memory in debugged program?
    By forgot in forum Plugins (General)
    Replies: 4
    Last Post: August 9th, 2005, 06:07
  5. Windows messages. How to intercept?
    By en0n in forum OllyDbg Support Forums
    Replies: 2
    Last Post: September 11th, 2003, 22:33

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •