📄 hook.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 + -