⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spyserver.c

📁 一文件过滤与加密,系统监视以及控制的东东,自己看
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************/
/*                                                                */
/*  Winpooch : Windows Watchdog                                   */
/*  Copyright (C) 2004-2006  Benoit Blanchon                      */
/*                                                                */
/*  This program is free software; you can redistribute it        */
/*  and/or modify it under the terms of the GNU General Public    */
/*  License as published by the Free Software Foundation; either  */
/*  version 2 of the License, or (at your option) any later       */
/*  version.                                                      */
/*                                                                */
/*  This program is distributed in the hope that it will be       */
/*  useful, but WITHOUT ANY WARRANTY; without even the implied    */
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       */
/*  PURPOSE.  See the GNU General Public License for more         */
/*  details.                                                      */
/*                                                                */
/*  You should have received a copy of the GNU General Public     */
/*  License along with this program; if not, write to the Free    */
/*  Software Foundation, Inc.,                                    */
/*  675 Mass Ave, Cambridge, MA 02139, USA.                       */
/*                                                                */
/******************************************************************/


/******************************************************************/
/* Build configuration                                            */
/******************************************************************/

#define TRACE_LEVEL	2	// warning level


/******************************************************************/
/* Includes                                                       */
/******************************************************************/

// module's interface
#include "SpyServer.h"

// Windows headers
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <winioctl.h>

// project's headers
#include "AskDlg.h"
#include "Assert.h"
#include "Config.h"
#include "DrvInterface.h"
#include "EventLog.h"
#include "Filter.h"
#include "FilterDefault.h"
#include "FilterFile.h"
#include "FilterSet.h"
#include "Language.h"
#include "Link.h"
#include "Malloc.h"
#include "ProcList.h"
#include "ProcListWnd.h"
#include "ProjectInfo.h"
#include "Reason.h"
#include "Resources.h"
#include "FiltRule.h"
#include "RuleDlg.h"
#include "Scanner.h"
#include "Sounds.h"
#include "Strlcpy.h"
#include "TrayIcon.h"
#include "Trace.h"
#include "VirusDlg.h"


/******************************************************************/
/* Internal macros                                                */
/******************************************************************/

#define arraysize(A) (sizeof(A)/sizeof((A)[0]))


/******************************************************************/
/* Internal constants                                             */
/******************************************************************/

TCHAR szFilterFilename[] = TEXT("Current.wpf") ;

TCHAR g_szServiceName[] = TEXT("Winpooch") ;

TCHAR g_szDriverFileName[] = TEXT("Winpooch.sys") ;

TCHAR szNoFiltersAlert[] = 
  TEXT("No filter file has been found, default filters will be used.\n"
       "You can ignore this alert if you are running Winpooch for the first time.") ;

TCHAR szFiltersErrorAlert[] =
  TEXT("Error reading file %s :\n%s\nDefault filters will be used.") ;

TCHAR szOldFiltersCleared[] =
  TEXT("Filters from a previous version have been found but can't be used.\n"
       "The file has been backed up but filters have been cleared.") ;


/******************************************************************/
/* Internal data types                                            */
/******************************************************************/

typedef LPTHREAD_START_ROUTINE THREADPROC ;


/******************************************************************/
/* Internal data                                                  */
/******************************************************************/

static HINSTANCE	g_hInstance = NULL ;
static HWND		g_hwndMain = NULL ;
static HFILTERSET	g_hFilterSet = NULL ;
static HANDLE		g_hFilterMutex = NULL ;
static HANDLE		g_hDriver = NULL ;


/******************************************************************/
/* Internal functions                                             */
/******************************************************************/

// Notification function called by spy DLL
DWORD _SpySrv_RequestFromDriver (LPVOID, DWORD) ;

// initialize spy dll
BOOL _SpySrv_InitDriver () ;

// destroy filters
BOOL _SpySrv_UninitFilters () ;

// uninitialize spy dll
VOID _SpySrv_UninitDriver () ;

BOOL _SpySrv_RefreshProcList () ;



/******************************************************************/
/* Internal function                                              */
/******************************************************************/

BOOL _SpySrv_Log (PROCADDR nProcessAddr, PCFILTCOND pCond,
		  DWORD nReaction, BOOL bAlert)
{
  UINT		nProcessId ;
  DWORD		dwEventId ;
  TCHAR		szProcess[MAX_PATH] = TEXT("???") ;
  
  TRACE ; 

  // get process name
  {
    PROCSTRUCT * pProc ;

    ProcList_Lock () ;
    pProc = ProcList_Get (nProcessAddr) ;

    nProcessId = pProc->nProcessId ;

    if( pProc ) {
      wcslcpy (szProcess, pProc->szPath, MAX_PATH) ;
    } else {
      wsprintf (szProcess, TEXT("Process %d"), nProcessId) ;
      TRACE_WARNING (TEXT("Process %d not in list (addr=0x08X)\n"), 
		     nProcessId, nProcessAddr) ;
    }

    ProcList_Unlock () ;
  }
    
  dwEventId = EventLog_Add (nProcessId, szProcess, nReaction,
			    bAlert ? RULE_ALERT : RULE_LOG,
			    pCond) ;
  
  if( bAlert ) 
    {
      Sounds_Play (SOUND_ALERT) ;
      PostMessage (g_hwndMain, WM_SPYNOTIFY, SN_ALERT, dwEventId) ;
    }
  
  PostMessage (g_hwndMain, WM_SPYNOTIFY, SN_EVENTLOGGED, dwEventId) ;

  return TRUE ;
}


/******************************************************************/
/* Internal function                                              */
/******************************************************************/

DWORD _SpySrv_Ask (PROCADDR nProcessAddress, UINT nDefReaction, PFILTCOND pCond)
{
  TCHAR		szProcess[MAX_PATH] = TEXT("???") ;
  UINT		nProcessId ;
  int		nResult ;  
  
  TRACE ; 
  
  // get process name
  {
    PROCSTRUCT * pProc ;
    
    ProcList_Lock () ;
    pProc = ProcList_Get (nProcessAddress) ;

    nProcessId = pProc->nProcessId ;
    
    if( pProc ) {
      wcslcpy (szProcess, pProc->szPath, MAX_PATH) ;
    } else {
      wsprintf (szProcess, TEXT("Process %d"), nProcessId) ;
      TRACE_WARNING (TEXT("Process %d not in list (addr=0x%08X\n"), 
		     nProcessId, nProcessAddress) ;
    }
    
    ProcList_Unlock () ;
  }
  
  Sounds_Play (SOUND_ASK) ;
  
  TRACE_INFO (TEXT("  /----ASK----\\\n")) ;

 askdlg:

  nResult = AskDlg_DialogBox (g_hInstance, g_hwndMain, szProcess, nProcessId, nDefReaction, pCond) ;

  if( nResult==ASKDLG_CREATEFILTER )
    {
      FILTRULE	* pRule ;
	  
      // alloc new rule
      pRule = (FILTRULE*) calloc (1, sizeof(FILTRULE)) ;

      // fill params as they appear in the ask dialog
      pRule->nReaction	= nDefReaction ;
      pRule->nVerbosity	= RULE_LOG ;
      pRule->nOptions	= 0 ;
      FiltCond_Dup (&pRule->condition, pCond) ;
      
      // show rule dialog
      if( IDOK!=RuleDlg_DialogBox (g_hInstance, g_hwndMain, szProcess, pRule, FALSE) )
	{
	  free (pRule) ;
	  goto askdlg ;
	}

      // verify that this rule matches the current event
      if( ! FiltCond_Check(&pRule->condition,pCond) )
	{
	  MessageBox (g_hwndMain, 
		      STR_DEF(_RULE_DOESNT_MATCH,
			      TEXT("The rule you defined doesn't match current event")), 
		      TEXT(APPLICATION_NAME), MB_ICONERROR) ;
	  free (pRule) ;
	  goto askdlg ;	      
	}

      SpySrv_AddRuleForProgram (pRule, szProcess) ;
      
      nResult = pRule->nReaction ;
    }

  if( nResult==ASKDLG_UNHOOK )
    {
      SpySrv_IgnoreProcess (nProcessAddress, TRUE) ;    
      nResult = RULE_ACCEPT ;
    }

  TRACE_INFO (TEXT("  \\----ASK-%d--/\n"), nResult) ;

  return nResult ;
}

/******************************************************************/
/*                                                                */
/* Return true if file open is allowed                            */
/******************************************************************/

SCANRESULT SpySrv_ScanFile (LPCTSTR szFilePath, BOOL bBackground)
{
  TCHAR	szOutput[1024] ;
  UINT	nResult ;  
  VIRUSDLGPARAMS dlgparams = {
    szFilePath,
    szOutput
  } ;

  TRACE_INFO (TEXT("Will scan file %ls\n"), szFilePath) ;
  
  if( ! Scanner_IsConfigured() )
    return SCAN_NOT_SCANNED ;
  
  nResult = Scanner_ScanFile (szFilePath,szOutput,1024,bBackground) ; 

  TRACE_INFO (TEXT("Scan result = %d\n"), nResult) ;
  
  if( nResult != SCAN_NO_VIRUS )
    {
      UINT nReaction ;

      Sounds_Play (SOUND_VIRUS) ;
      
      nReaction = DialogBoxParam (g_hInstance, MAKEINTRESOURCE(DLG_VIRUS), g_hwndMain, 
				  VirusDlg_DlgProc, (LPARAM)&dlgparams) ;     

      if( nReaction == RULE_ACCEPT )
	nResult++ ;	
    } 
    
  return nResult ;
}


/******************************************************************/
/* Internal function : SpyDllNotify                               */
/******************************************************************/

DWORD _SpySrv_RequestFromDriver (LPVOID pBuffer, DWORD nSize) 
{
  SDNMHDR	*p = pBuffer ;
  VOID		*pSerial ;
  UINT		nSerialSize ;
  DWORD		nResponseSize = 0 ;

  TRACE ; 

  ASSERT (pBuffer) ;
  ASSERT (nSize>0) ;
  ASSERT (nSize>=sizeof(SDNMHDR)) ;
  
  TRACE_INFO (TEXT(" /----REQ-%d----\\ (size=%d\n"), p->dwCode, nSize) ;

  switch( p->dwCode )
    {
    case SDN_ASK:
      {
	DWORD		nReaction ;
	FILTCOND	cond ;

	pSerial = ((SDNASK*)p)->data ;
	nSerialSize = nSize - sizeof(SDNASK) ;
	
	ASSERT (nSerialSize>0) ;

	if( ! FiltCond_Unserialize (&cond, pSerial, nSerialSize) )
	  {
	    TRACE_ERROR (TEXT("FiltCond_Unserialize failed\n")) ;
	    nReaction = RULE_ACCEPT ;	    
	  }
	else
	  {   
	    nReaction = _SpySrv_Ask (((SDNASK*)p)->nProcessAddress, 
				     ((SDNASK*)p)->nDefReaction, 
				     &cond) ;
	  }
	
	*((DWORD*)pBuffer) = nReaction ;
	nResponseSize = sizeof(DWORD) ;
      }
      break ;

    case SDN_LOG:
    case SDN_ALERT:
      {
	DWORD		nReaction ;
	FILTCOND	cond ;

	nReaction = ((SDNLOG*)p)->dwReaction ;

	pSerial = ((SDNLOG*)p)->data ;
	nSerialSize = nSize - sizeof(SDNLOG) ;

	if( ! FiltCond_Unserialize (&cond, pSerial, nSerialSize) )
	  {
	    TRACE_ERROR (TEXT("FiltCond_Unserialize failed\n")) ;
	    nReaction = RULE_ACCEPT ;	    
	  }
	else
	  {
	    _SpySrv_Log (((SDNLOG*)p)->nProcessAddress, &cond, nReaction, p->dwCode==SDN_ALERT) ;
	  }
      }
      break ;

    case SDN_SCANFILE:
      {
	DWORD		nScanResult ;

	nScanResult = SpySrv_ScanFile (((SDNSCANFILE*)pBuffer)->wszFilePath, FALSE) ;

	*((DWORD*)pBuffer) = nScanResult ;
	nResponseSize = sizeof(DWORD) ;
      }
      break ;

    case SDN_PROCESSCREATED:
      {
	SDNPROCESSCREATED * pSdnpc = pBuffer ;
	PROCSTRUCT	proc ;
	
	proc.nProcessAddress	= pSdnpc->nProcessAddress ;
	proc.nProcessId		= pSdnpc->nProcessId ;
	proc.nState		= PS_HOOKED_SINCE_BIRTH ;
	wcslcpy (proc.szName, PathFindFileName(pSdnpc->wszFilePath), 32) ;
	wcslcpy (proc.szPath, pSdnpc->wszFilePath, MAX_PATH) ;
	
	ProcList_Lock () ;
	ProcList_Add (&proc) ;
	ProcList_Unlock () ;
	  
	PostMessage (g_hwndMain, WM_SPYNOTIFY, SN_PROCESSCREATED, pSdnpc->nProcessAddress) ;
      }
      break ;

    case SDN_PIDCHANGED:
      {
  	SDNPIDCHANGED	*pSdnpc = pBuffer ;
  	PROCSTRUCT	*pProc ;

	ProcList_Lock () ;	
	pProc = ProcList_Get (pSdnpc->nProcessAddress) ;
	if( pProc ) 
	  {
	    TRACE_ALWAYS (TEXT("PID changed %d -> %d\n"), pProc->nProcessId, pSdnpc->nNewProcessId) ; 
	    pProc->nProcessId = pSdnpc->nNewProcessId ;  
	  }
	ProcList_Unlock () ;

	// This notification has been disabled because it caused a dead-lock.
	// PostMessage (g_hwndMain, WM_SPYNOTIFY, SN_PIDCHANGED, pSdnpc->nProcessAddress) ;
      }
      break ;

    case SDN_PROCESSTERMINATED:
      {
	SDNPROCESSTERMINATED * pSdnpt = pBuffer ;

	TRACE_INFO (TEXT("Process terminated 0x%08X\n"),pSdnpt->nProcessAddress) ; 
	
	ProcList_Lock () ;
	ProcList_Remove (pSdnpt->nProcessAddress) ;
	ProcList_Unlock () ;
	  
	PostMessage (g_hwndMain, WM_SPYNOTIFY, SN_PROCESSTERMINATED, pSdnpt->nProcessAddress) ;
      }
      break ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -