邪恶八进制信息安全团队技术讨论组's Archiver

EvilOctal 2005-8-21 17:55

[转载]Efilter(自动异常报告实用工具C代码)

原始连接:[url]http://pb.specialised.info/[/url]

Efilter is an automatic exception reporting utility. It is very useful and handy while doing vulnerability research on any software designed to work under Windows NT platforms. Due to that it hooks KiUserExceptionDispatcher function, it acts BEFORE any of program's active SEH frames take over the exception. In short words it reports programs exceptions even if they are handled by original program.

[code]/*

   -------------------------------------------------
    Efilter - automatic exception reporting utility
   -------------------------------------------------
      by Piotr Bania <[email]bania.piotr@gmail.com[/email]>
        [url]http://pb.specialised.info[/url]
         All rights reserved!


  Binary:
  - [url]http://pb.specialised.info/all/efilter/efilter.dll[/url]

  Source:
  - [url]http://pb.specialised.info/all/efilter/efilter.c[/url]


  Disclaimer
  ----------

  Author takes no responsibility for any actions with provided
  informations or codes. The copyright for any material created by the
  author is reserved. Any duplication of codes or texts provided here
  in electronic or printed publications is not permitted without the
  author&#39;s agreement.


  Info
  ----

  Efilter is an automatic exception reporting utility. It is very useful
  and handy while doing vulnerability research on any software designed
  to work under Windows NT platforms. Due to that it hooks
  KiUserExceptionDispatcher function, it acts BEFORE any of program&#39;s
  active SEH frames take over the exception. In short words it reports
  programs exceptions even if they are handled by original program.

  Here is some sample screenshot:
  - [url]http://pb.specialised.info/all/efilter/efilter.jpg[/url]

  Since it uses debug messages it requires DebugView utility to show
  output messages. (download from: [url]http://www.sysinternals.com[/url])


  Usage
  -----
  
  Just attach efilter.dll library to target process.
  You can obtain binary version of the library here:
  - [url]http://pb.specialised.info/all/efilter/efilter.dll[/url]


  Trick
  -----

  If you want to attach the library automaticly to all running processes
  add new registry string key at:
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
  named as "AppInit_Dlls" with value set to location of the library.



  Some more additional info
  --------------------------

  If you want to read more about advantages comming out from
  KiUserExceptionDispatcher hooking and a lot of more, check
  my PHRACK#63 article, where i have described new shellcode
  prevention techniques:

  original:
  - [url]http://www.phrack.org/phrack/63/p63-0x0f_NT_Shellcode_Prevention_Demystified.txt[/url]
  
  mirror:
  - [url]http://pb.specialised.info/all/protty/p63-0x0f_NT_Shellcode_Prevention_Demystified.txt[/url]


*/







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

#define        SHOW_R_DUMP        1        // show context dump?
#define        SIZE_OF_BUFF          2024         // size of dbgmsg buffer

#define        MY_API            extern "C" __declspec(dllexport)
#define        MY_NAKED        extern "C" _declspec(naked)
#define        MAX_BAD_SIZE          0x60
#define        calc_jump(y,x)          ((x-y)-5)



void        on_load_info(void);
void        on_unload_info(void);
void        setup_filter(void);
void        filter_exceptions(EXCEPTION_RECORD *er,CONTEXT *con);

char*        pname;
char        fn[MAX_PATH+1];
char        dbgmsg[SIZE_OF_BUFF];

DWORD        cPid;
DWORD        _KiUserExceptionDispatcher;
bool        done = false;



void filter_exceptions(EXCEPTION_RECORD *er,CONTEXT *con)
{
    DWORD aSEH;
    DWORD req = (DWORD)er->ExceptionInformation+4;
    DWORD method = (DWORD)er->ExceptionInformation;
   

    /*
        well, following functions generate exceptions that are "safe",
        so we will filter them here because they generate a lot of unusable
        traffic, calculation is based on the fact that exceptions always
        occurs from &Api to &Api+0x60 (i have put here 0x60 - it could be lower
        but i don&#39;t know how those functions look on different Windows versions,
        so i have made some up-rounded value)
    */

    if (((DWORD)(er->ExceptionAddress) >= (DWORD)&IsBadReadPtr) && \
        ((DWORD)(er->ExceptionAddress) <= (DWORD)(&IsBadReadPtr) + MAX_BAD_SIZE))
        goto nono;

    if (((DWORD)(er->ExceptionAddress) >= (DWORD)&IsBadWritePtr) && \
        ((DWORD)(er->ExceptionAddress) <= (DWORD)(&IsBadWritePtr) + MAX_BAD_SIZE))
        goto nono;

    if (((DWORD)(er->ExceptionAddress) >= (DWORD)&IsBadStringPtr) && \
        ((DWORD)(er->ExceptionAddress) <= (DWORD)(&IsBadStringPtr) + MAX_BAD_SIZE))
        goto nono;


    _asm {
        mov eax,dword ptr fs:[0]
        mov eax,[eax+4]
        mov aSEH,eax
    }

    pname=strrchr(fn,&#39;\\&#39;); pname++;
    _snprintf(dbgmsg, sizeof(dbgmsg),"[+] Efilter: Exception occured in %s (pid: %x) at: 0x%X - requested addr: 0x%X \r\n[+] Efilter: Process %s (pid: %X) has active SEH pointed to 0x%X \r\n",pname,cPid,er->ExceptionAddress,*(DWORD*)req,pname,cPid,aSEH);
    OutputDebugString(dbgmsg);

    if (*(DWORD*)method == 0)
    {
        _snprintf(dbgmsg,sizeof(dbgmsg),"[+] Efilter: Process attempted to *READ* the inaccessible data \r\n");
        if (*(DWORD*)req == (DWORD)er->ExceptionAddress)
            _snprintf(dbgmsg,sizeof(dbgmsg),"[+] Efilter: Process attempted to *EXECUTE* the inaccessible data \r\n");
    }

    if (*(DWORD*)method == 1)
        _snprintf(dbgmsg,sizeof(dbgmsg),"[+] Efilter: Process attempted to *WRITE* the inaccessible data \r\n");
   
    OutputDebugString(dbgmsg);

    #if SHOW_R_DUMP == 1
        _snprintf(dbgmsg,sizeof(dbgmsg),"***\n[+] Efilter: Begin context dump:\n[+] Efilter: EAX=%.08x * ECX=%.08x * EDX=%.08x * EBX=%.08x\n",con->Eax,con->Ecx,con->Edx,con->Ebx);
        OutputDebugString(dbgmsg);
        _snprintf(dbgmsg,sizeof(dbgmsg),"[+] Efilter: ESI=%.08x * EDI=%.08x * EBP=%.08x * ESP=%.08x\n[+] Efilter: End of context dump.\n***\n",con->Esi,con->Edi,con->Ebp,con->Esp);
        OutputDebugString(dbgmsg);
    #endif

    Beep(0xFF,50);

nono:;
}


MY_NAKED void filter_handler() {
    __asm {
                mov ecx,[esp+4]               
                mov ebx,[esp]               
                pushad
                cmp dword ptr [ebx],0xc0000005
                jne _leave_it
                mov ebp,esp
                push ecx
                push ebx
                call filter_exceptions
                mov esp,ebp

    _leave_it:  popad
                push _KiUserExceptionDispatcher
                add [esp],7
                ret
    }
}


BOOL APIENTRY DllMain( HANDLE hModule,
                DWORD  ul_reason_for_call,
                LPVOID lpReserved
                     )
{
   switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            on_load_info();
            break;

        case DLL_PROCESS_DETACH:
            on_unload_info();
            break;
   }
   return TRUE;
}


void on_load_info(void) {
    cPid=GetCurrentProcessId();

    if (GetModuleFileName(NULL,fn,MAX_PATH) != NULL)
    {
        pname=strrchr(fn,&#39;\\&#39;); pname++;
        OutputDebugString("[*] Efilter by Piotr Bania <[url]http://pb.specialised.info>[/url] is now loading\n");
        _snprintf(dbgmsg, sizeof(dbgmsg),"[*] Efilter: Attached to %s - pid: 0x%X \r\n",pname,cPid);
        OutputDebugString(dbgmsg);
        OutputDebugString("---------------------------------------------------------------------\n");
        setup_filter();
    }


}

void on_unload_info(void) {
    if (done == false)
    {
        pname=strrchr(fn,&#39;\\&#39;); pname++;
        _snprintf(dbgmsg, sizeof(dbgmsg),"[*] Efilter: Unloaded from %s - pid: 0x%X \r\n",pname,cPid);
        OutputDebugString(dbgmsg);
        done = true;
    }
}


void setup_filter(void)
{
    DWORD oldp;
    _KiUserExceptionDispatcher=(DWORD)GetProcAddress(LoadLibrary("ntdll.dll"),"KiUserExceptionDispatcher");
    if (_KiUserExceptionDispatcher != NULL)
    {
        if (*(BYTE *)_KiUserExceptionDispatcher != 0xE9)
        {
            if (VirtualProtect((LPVOID)_KiUserExceptionDispatcher,5,PAGE_READWRITE,&oldp))
            {
                *(BYTE *)_KiUserExceptionDispatcher = 0xE9;
                *(DWORD *)(_KiUserExceptionDispatcher+1) = calc_jump(_KiUserExceptionDispatcher,(unsigned long)filter_handler);
                VirtualProtect((LPVOID)_KiUserExceptionDispatcher,5,oldp,&oldp);
                Sleep(1000);
            }
        }
    }
}[/code]

页: [1]
© 1999-2008 EvilOctal Security Team