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

📄 hook.cpp

📁 在delphi中实现windows核心编程.原书光盘代码核心编程.原书光盘代码
💻 CPP
字号:
// hook.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "hook.h"
#include "Ring0.h"
#include "io.h"

#pragma comment(linker, "/section:.data,RWS /section:.idata,RWS /section:.bss,RWS")
#pragma comment(linker, "/base:0xBFF70000")
bool IsNT,busy=FALSE;
#define MAXFUN 4
DWORD dwProtectionFlags[MAXFUN],newproc[MAXFUN];
PROC oldproc[MAXFUN];
BYTE oldcode[MAXFUN][5];
HANDLE RecordHandle;
char RecordFile[256],ReadF[256],WriteF[256];

BOOL StartHookProc(int num);
BOOL StopHookProc(int num);
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			if(busy) return FALSE;
			busy=TRUE;
			break;
		case DLL_THREAD_ATTACH:			
			if(busy) return FALSE;
			busy=TRUE;
			break;
		case DLL_THREAD_DETACH:
			busy=FALSE;
			break;
		case DLL_PROCESS_DETACH:			
			busy=FALSE;
			break;
    }
    return TRUE;
}

__declspec(naked) void Ring0ModifyPageProtection()
{
  _asm
  {
    Mov EAX, ECX
    Shr EAX, 22
    Test DWORD PTR [0FFBFE000h + EAX * 4], 1
    Jz Fail

    Mov EAX, ECX
    Shr EAX, 12
    Mov EBX, EAX
    Mov EAX, DWORD PTR [0FF800000h + EAX * 4]
    Test EAX, 1
    Jz Fail

    Mov EAX, 1

    Cmp EDX, PAGE_READWRITE
    Je PageReadWrite

    And DWORD PTR [0FF800000h + EBX * 4], 0xFFFFFFFD
    Jmp Done

PageReadWrite:

    Or DWORD PTR [0FF800000h + EBX * 4], 2
    Jmp Done

Fail:

    Xor EAX, EAX

Done:

    Retf
  }
}


bool CallRing0(PVOID pvRing0FuncAddr, PVOID pvAddr, DWORD dwPageProtection)
{

  GDT_DESCRIPTOR *pGDTDescriptor;
  GDTR gdtr;
  bool Result;

  _asm Sgdt [gdtr]

  // Skip the null descriptor

  pGDTDescriptor = (GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);

  // Search for a free GDT descriptor

  for (WORD wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
  {
    if (pGDTDescriptor->Type == 0     &&
        pGDTDescriptor->System == 0   &&
        pGDTDescriptor->DPL == 0      &&
        pGDTDescriptor->Present == 0)
    {
      // Found one !
      // Now we need to transform this descriptor into a callgate.
      // Note that we're using selector 0x28 since it corresponds
      // to a ring 0 segment which spans the entire linear address
      // space of the processor (0-4GB).

      CALLGATE_DESCRIPTOR *pCallgate;

      pCallgate =	(CALLGATE_DESCRIPTOR *) pGDTDescriptor;
      pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
      pCallgate->Selector = 0x28;
      pCallgate->ParamCount =	0;
      pCallgate->Unused = 0;
      pCallgate->Type = 0xc;
      pCallgate->System = 0;
      pCallgate->DPL = 3;
      pCallgate->Present = 1;
      pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);

      // Prepare the far call parameters

      WORD CallgateAddr[3];

      CallgateAddr[0] = 0x0;
      CallgateAddr[1] = 0x0;
      CallgateAddr[2] = (wGDTIndex << 3) | 3;

      // Please fasten your seat belts!
      // We're about to make a hyperspace jump into RING 0.

      _asm
      {
        Mov ECX, [pvAddr]
        Mov EDX, [dwPageProtection]
        Cli
        Call FWORD PTR [CallgateAddr]
        Sti
        Mov DWORD PTR [Result], EAX
      }
      
      // Now free the GDT descriptor

      memset(pGDTDescriptor, 0, 8);

      return Result;
    }

    // Advance to the next GDT descriptor

    pGDTDescriptor++;
  }

  // Whoops, the GDT is full

  return false;
}

bool RemovePageProtection(PVOID pvAddr)
{
  return CallRing0((PVOID)Ring0ModifyPageProtection, pvAddr, PAGE_READWRITE);
}


bool SetPageProtection(PVOID pvAddr)
{
  return CallRing0((PVOID)Ring0ModifyPageProtection, pvAddr, PAGE_READONLY);
}

BOOL RemoveProtection(BOOL IsNT, PVOID pvAddress,DWORD *dwProtectionFlags)
//dwProtectionFlags 仅为NT
{
  if(!IsNT)   
	 return RemovePageProtection(pvAddress);

  else {
     MEMORY_BASIC_INFORMATION mbi;     
     DWORD dwScratch;     

     // Get page protection of API

     VirtualQuery(pvAddress, &mbi, sizeof(mbi));
     *dwProtectionFlags = mbi.Protect;     

     // Remove page protection from API

     (*dwProtectionFlags) &= ~PAGE_READONLY;
     (*dwProtectionFlags) &= ~PAGE_EXECUTE_READ;
     (*dwProtectionFlags) |= PAGE_READWRITE;

     return VirtualProtect(pvAddress, 4096, *dwProtectionFlags, &dwScratch);
  }
}

BOOL RestoreProtection(BOOL IsNT, PVOID pvAddress, DWORD dwProtectionFlags)
{
   if(!IsNT) return SetPageProtection(pvAddress);
   else {
	  DWORD dwScratch;
      return VirtualProtect(pvAddress, 4096, dwProtectionFlags, &dwScratch);
   }
}

HANDLE _stdcall MyCreateFileA(LPCTSTR lpFileName,DWORD dwDesiredAccess,
  DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,
  HANDLE hTemplateFile)
{   
	StopHookProc(0);	
    HANDLE r=CreateFileA(lpFileName,dwDesiredAccess,
		dwShareMode,lpSecurityAttributes,
		dwCreationDisposition,dwFlagsAndAttributes,
		hTemplateFile);
	if( (stricmp(lpFileName,RecordFile)==0) ||    // COM2
	    ((*((DWORD*)lpFileName)==0x5c2e5c5c)&&(stricmp(&lpFileName[4],RecordFile)==0)) || // \\.\COM2
	    ((*((WORD*)&lpFileName[4])==0x002e)&&(strnicmp(lpFileName,RecordFile,4)==0)) ) // COM2.
	   RecordHandle=r;
	StartHookProc(0);
	return r;
}
BOOL _stdcall MyCloseHandle(HANDLE hObject)
{
	StopHookProc(3);	
    BOOL r=CloseHandle(hObject);
	if((r)&&(hObject==RecordHandle)) RecordHandle=INVALID_HANDLE_VALUE;
	StartHookProc(3);
	return r;
}
void SaveToFile(LPCTSTR Files,LPCVOID lpBuffer,DWORD Bytes)
{  HANDLE h;
   DWORD i;
   if(Bytes==0) return;
   if((h=CreateFile(Files,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL))==INVALID_HANDLE_VALUE) return;
   SetFilePointer(h,0,0,FILE_END);
   WriteFile(h,lpBuffer,Bytes,&i,NULL);
   CloseHandle(h);
}

BOOL _stdcall MyWriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,
  LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped)
{
    StopHookProc(1);
	BOOL r=WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,
        lpNumberOfBytesWritten,lpOverlapped);
    if((hFile!=INVALID_HANDLE_VALUE)&&(hFile==RecordHandle)) {
		SaveToFile(WriteF,lpBuffer,nNumberOfBytesToWrite);
	}
	StartHookProc(1);
	return r;
}

BOOL _stdcall MyReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,
  LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
{
    StopHookProc(2);
	BOOL r=ReadFile(hFile,lpBuffer,nNumberOfBytesToRead,
        lpNumberOfBytesRead,lpOverlapped);
    if((hFile!=INVALID_HANDLE_VALUE)&&(hFile==RecordHandle)) {
        SaveToFile(ReadF,lpBuffer,*lpNumberOfBytesRead); 
	}
	StartHookProc(2);
	return r;
}
 
BOOL StartHookProc(int num)
{       		    
	((PBYTE) oldproc[num])[0]=0xE9;
    *((DWORD *)((PBYTE)oldproc[num]+1))=newproc[num] - (DWORD)oldproc[num] - 5;
	//if (!RestoreProtection(IsNT,oldproc[num],dwProtectionFlags[num])) return FALSE;
	return TRUE;
}

BOOL StopHookProc(int num)
{   
    //if (!RemoveProtection(IsNT,oldproc[num],&dwProtectionFlags[num])) return FALSE;
	memcpy(oldproc[num],oldcode[num],5);	
	return TRUE;
}

extern "C" BOOL _stdcall StopHookAll(void)
{      	
	for(int i=MAXFUN-1;i>=0;i--) {
	   if(oldproc[i]!=NULL) {
          StopHookProc(i);	
	      RestoreProtection(IsNT,oldproc[i],dwProtectionFlags[i]);
	   }
	}    	
	return TRUE;
}

BOOL StartHookAll(void)
{	
	IsNT=false;	//在Windows9x下运行
	RecordHandle=INVALID_HANDLE_VALUE;	
	oldproc[0]=(PROC)CreateFileA; //GetProcAddress(GetModuleHandle("kernel32.dll"),"CreateFileA");
	newproc[0]=(DWORD)MyCreateFileA;
	oldproc[1]=(PROC)WriteFile;
	newproc[1]=(DWORD)MyWriteFile;
	oldproc[2]=(PROC)ReadFile;
	newproc[2]=(DWORD)MyReadFile;
	oldproc[3]=(PROC)CloseHandle;
	newproc[3]=(DWORD)MyCloseHandle;

    for(int i=0;i<MAXFUN;i++)
		if(oldproc[i]==NULL) return FALSE;
    for(i=0;i<MAXFUN;i++){				   
   	    if((((PBYTE)oldproc[i])[0]==0x68)&&(((PBYTE)oldproc[i])[5]==0xe9))
		   oldproc[i]=*((PROC*)((PBYTE)oldproc[i]+1));
	    memcpy(oldcode[i],oldproc[i],5);
		if( (!RemoveProtection(IsNT,oldproc[i],&dwProtectionFlags[i]))|| 
			(!StartHookProc(i)) ) {		
		   StopHookAll();
           return FALSE;
		}
	}  
	return TRUE;
}

extern "C" BOOL _stdcall StartHookAllWithFiles(LPCTSTR RecordFiles,LPCTSTR ReadFiles,LPCTSTR WriteFiles)
{	
	strcpy(RecordFile,RecordFiles);
	strcpy(ReadF,ReadFiles);
	strcpy(WriteF,WriteFiles);
	return StartHookAll();
}

⌨️ 快捷键说明

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