HOOK API

一个简单的console工程,vc6,vc7在win2k pro,server上调试通过.
#include <stdio.h>
#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib,"dbghelp.lib")
#pragma comment(lib,"user32.lib")
typedef int (__stdcall *old_messagebox)( hwnd hwnd, lpctstr lptext, lpctstr lpcaption,uint utype );
old_messagebox g_procoldmessagebox = null;
int __stdcall hook_messagebox( hwnd hwnd, lpctstr lptext, lpctstr lpcaption,uint utype)
{
 printf("%s/t%d/r/n",__function__,__line__);
 if (null != g_procoldmessagebox)
  return g_procoldmessagebox(hwnd,lptext,"不好意思,hook到了!",utype); 
 else
  return messagebox(hwnd,lptext,lpcaption,utype); ;
}

int replace_iat(const char *pdllname,const char *papiname,bool breplace)
{
 handle hprocess = ::getmodulehandle (null);
 dword dwsize = 0;
 pimage_import_descriptor pimageimport = (pimage_import_descriptor)imagedirectoryentrytodata(hprocess,true,
  image_directory_entry_import,&dwsize);
 if (null == pimageimport)
  return 1;
 pimage_import_by_name pimageimportbyname = null;
 pimage_thunk_data  pimagethunkoriginal = null;
 pimage_thunk_data  pimagethunkreal  = null;
 while (pimageimport->name)
 {
  if (0 == strcmpi((char*)((pbyte)hprocess+pimageimport->name),pdllname))
  {
   break;
  }
  ++pimageimport;
 }
 if (! pimageimport->name)
  return 2;
 pimagethunkoriginal = (pimage_thunk_data)((pbyte)hprocess+pimageimport->originalfirstthunk  );
 pimagethunkreal = (pimage_thunk_data)((pbyte)hprocess+pimageimport->firstthunk   );
 while (pimagethunkoriginal->u1.function)
 {
  if ((pimagethunkoriginal->u1 .ordinal & image_ordinal_flag) != image_ordinal_flag)
  {
   pimageimportbyname = (pimage_import_by_name)((pbyte)hprocess+pimagethunkoriginal->u1 .addressofdata );
   if (0 == strcmpi(papiname,(char*)pimageimportbyname->name))
   {
    memory_basic_information mbi_thunk;
    virtualquery(pimagethunkreal, &mbi_thunk, sizeof(memory_basic_information)); 
    virtualprotect(mbi_thunk.baseaddress,mbi_thunk.regionsize, page_readwrite, &mbi_thunk.protect); 
    if (true == breplace)
    {
     g_procoldmessagebox =(old_messagebox) pimagethunkreal->u1.function; 
     pimagethunkreal->u1.function = (dword)hook_messagebox;
    }
    else
     pimagethunkreal->u1.function = (dword)g_procoldmessagebox;
    dword dwoldprotect; 
    virtualprotect(mbi_thunk.baseaddress, mbi_thunk.regionsize, mbi_thunk.protect, &dwoldprotect);
    break;
   }
  }
  ++pimagethunkoriginal;
  ++pimagethunkreal;
 }
 return 0;
}
int main()
{
 replace_iat("user32.dll","messageboxa",true);
 messagebox(null,"enumiat user32.dll messageboxa true;","",mb_ok);
 replace_iat("user32.dll","messageboxa",false);
 messagebox(null,"enumiat user32.dll messageboxa false;","",mb_ok);
 return getchar();
}

二,=======================================================
1.本地HOOK API(Inline HOOK): 
HOOK MessageBoxW 这个,让它跳到我们自己的函数处理之后再调用原来的MessageBoxW,这种本地的HOOK API应该是最简单的HOOK API而且它的作用也不是很明显,但是可以了解什么是HOOK API. 

#include <windows.h> 
#include <iostream> 
using namespace std; 

typedef int (WINAPI *pMessageBoxDef)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); 

char szOldMessageBox[5] = {0}; 
char szJmpMyMessageBox[5] = {(char)0xe9}; 
pMessageBoxDef pMessageBox = NULL; 
  
int WINAPI MyMessageBox(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) 
{ 
wcout<<L"hWnd:"<<(int)hWnd<<endl; 
wcout<<L"lpText:"<<lpText<<endl; 
wcout<<L"lpCaption:"<<lpCaption<<endl; 
wcout<<L"uType:"<<uType<<endl<<endl; 

WriteProcessMemory((void*)-1, pMessageBox, szOldMessageBox, 5, NULL); 

MessageBoxW(hWnd, lpText, lpCaption, uType); 

WriteProcessMemory((void*)-1, pMessageBox, szJmpMyMessageBox, 5, NULL); 
return 0; 
} 

int main() 
{ 
DWORD dwJmpAddr = 0; 
HMODULE hModule = LoadLibrary("User32.Dll"); 
pMessageBox = (pMessageBoxDef)GetProcAddress(hModule, "MessageBoxW"); 
dwJmpAddr = (DWORD)MyMessageBox - (DWORD)pMessageBox - 5; 
memcpy(szJmpMyMessageBox + 1, &dwJmpAddr, 4); 
FreeLibrary(hModule); 
ReadProcessMemory((void*)-1, pMessageBox, szOldMessageBox, 5, NULL);//读出原来的前5个字节 
WriteProcessMemory((void*)-1, pMessageBox, szJmpMyMessageBox, 5, NULL);//写入我们处理后的5个字节 

MessageBoxW(GetForegroundWindow(), L"Inline Hook:MessageBox", L"HOOK API", MB_OK);

MessageBoxW(GetForegroundWindow(), L"Hello World", L"Win32", MB_OK); 
return 0; 
}

2.Ring3 下 HOOK API(IAT HOOK)  
这种HOOK API开始有用了,它可以HOOK 别的进程的API,许多程序的进程隐藏,进程的保护,文件,端口,注册表的隐藏就是使用它.现在实现进程的隐藏(隐藏程序名开头3个字母为CIW的进程),用DLL注入(可以省去很多麻烦). 

Dll源代码: 
#include <Windows.h> 
#include <stdio.h> 
#include <ImageHlp.h> 
#include <Tlhelp32.h> 
#include <commctrl.h> 

DWORD WINAPI ThreadProc(LPVOID lpParameter); 
void ReplaceIATEntryInOneMod(PSTR pszCalleeModName,  
 PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller); 
LONG WINAPI InvalidReadExceptionFilter(PEXCEPTION_POINTERS pep); 
#define NTSTATUS DWORD 
#define NT_SUCCESS(Status) ((NTSTATUS)(Status)>=0) 

BOOL WINAPI DllMain( 
HANDLE hinstDLL,  
DWORD dwReason,  
LPVOID lpvReserved 
) 
{ 

if( DLL_PROCESS_ATTACH == dwReason ) 
{ 
CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL); 
} 
return TRUE; 
} 

typedef struct _UNICODE_STRING { 
USHORT Length; 
USHORT MaximumLength; 
PWSTR Buffer; 
} UNICODE_STRING; 
typedef UNICODE_STRING *PUNICODE_STRING; 

typedef const UNICODE_STRING *PCUNICODE_STRING; 

typedef struct _VM_COUNTERS 
{ 
ULONG PeakVirtualSize; 
ULONG VirtualSize; 
ULONG PageFaultCount; 
ULONG PeakWorkingSetSize; 
ULONG WorkingSetSize; 
ULONG QuotaPeakPagedPoolUsage; 
ULONG QuotaPagedPoolUsage; 
ULONG QuotaPeakNonPagedPoolUsage; 
ULONG QuotaNonPagedPoolUsage; 
ULONG PagefileUsage; 
ULONG PeakPagefileUsage; 
}VM_COUNTERS,*PVM_COUNTERS; 

typedef struct _IO_COUNTERS 
{ 
LARGE_INTEGER ReadOperationCount; 
LARGE_INTEGER WriteOperationCount; 
LARGE_INTEGER OtherOperationCount; 
LARGE_INTEGER ReadTransferCount; 
LARGE_INTEGER WriteTransferCount; 
LARGE_INTEGER OtherTransferCount; 
}IO_COUNTERS,*PIO_COUNTERS; 

typedef struct _CLIENT_ID 
{ 
HANDLE UniqueProcess; 
HANDLE UniqueThread; 
}CLIENT_ID; 

typedef enum _THREAD_STATE 
{ 
StateInitialized, 
StateReady, 
StateRunning, 
StateStandby, 
StateTerminated, 
StateWait, 
StateTransition, 
StateUnknown 
}THREAD_STATE; 

typedef enum _KWAIT_REASON 
{ 
Executive, 
FreePage, 
PageIn, 
PoolAllocation, 
DelayExecution, 
Suspended, 
UserRequest, 
WrExecutive, 
WrFreePage, 
WrPageIn, 
WrPoolAllocation, 
WrDelayExecution, 
WrSuspended, 
WrUserRequest, 
WrEventPair, 
WrQueue, 
WrLpcReceive, 
WrLpcReply, 
WrVertualMemory, 
WrPageOut, 
WrRendezvous, 
Spare2, 
Spare3, 
Spare4, 
Spare5, 
Spare6, 
WrKernel 
}KWAIT_REASON; 

typedef struct _SYSTEM_THREADS 
{ 
LARGE_INTEGER KernelTime; //CPU内核模式使用时间; 
LARGE_INTEGER UserTime; //CPU用户模式使用时间; 
LARGE_INTEGER CreateTime; //线程创建时间; 
ULONG WaitTime; //等待时间; 
PVOID StartAddress; //线程开始的虚拟地址; 
CLIENT_ID ClientId; //线程标识符; 
LONG Priority; //线程优先级; 
LONG BasePriority; //基本优先级; 
ULONG ContextSwitchCount; //环境切换数目; 
THREAD_STATE State; //当前状态; 
KWAIT_REASON WaitReason; //等待原因; 
}SYSTEM_THREADS,*PSYSTEM_THREADS;

struct _SYSTEM_PROCESSES 
{ 
ULONG NextEntryDelta; 
ULONG ThreadCount; 
ULONG Reserved[6]; 
LARGE_INTEGER CreateTime; 
LARGE_INTEGER UserTime; 
LARGE_INTEGER KernelTime; 
UNICODE_STRING ProcessName; 
LONG BasePriority; 
ULONG ProcessId; 
ULONG InheritedFromProcessId; 
ULONG HandleCount; 
ULONG Reserved2[2]; 
VM_COUNTERS VmCounters; 
IO_COUNTERS IoCounters; //windows 2000 only 
struct _SYSTEM_THREADS Threads[1]; 
}; 

typedef DWORD SYSTEM_INFORMATION_CLASS; 

typedef int (WINAPI *pNtQuerySystemInformationFun)( 
 SYSTEM_INFORMATION_CLASS SystemInformationClass, 
 PVOID SystemInformation, 
 ULONG SystemInformationLength, 
 PULONG ReturnLength 
 ); 

pNtQuerySystemInformationFun pNtQuerySystemInformation = 0; 

int WINAPI MyNtQuerySystemInformation( 
 SYSTEM_INFORMATION_CLASS SystemInformationClass, 
 PVOID SystemInformation, 
 ULONG SystemInformationLength, 
 OUT PULONG ReturnLength 
 ) 
{  

DWORD nState = pNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); 

_SYSTEM_PROCESSES* pProc = (_SYSTEM_PROCESSES*)SystemInformation; 

if( NT_SUCCESS(nState))  
{ 
if(SystemInformationClass == 5) 
{ 
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation; 
struct _SYSTEM_PROCESSES *prev = NULL; 
while(curr) 
{ 
if (curr->ProcessName.Length > 0) 
{ 
if(0 == memcmp(curr->ProcessName.Buffer, L"CIW", 2 * 3)) 
{ 
if(prev)  
{ 
if(curr->NextEntryDelta) 
prev->NextEntryDelta += curr->NextEntryDelta; 
else 
prev->NextEntryDelta = 0; 
} 
else 
{ 
if(curr->NextEntryDelta) 
{ 
SystemInformation =(_SYSTEM_PROCESSES*)((char *)SystemInformation + curr->NextEntryDelta); 
} 
else  
SystemInformation = NULL;  
} 
} 

} 
prev = curr; 
if(curr->NextEntryDelta) (curr = (_SYSTEM_PROCESSES*)((char *)curr + curr->NextEntryDelta)); 
else curr = NULL; 
} 
} 
return 0; 
} 
} 

DWORD WINAPI ThreadProc(LPVOID lpParameter) 
{  
char szDllName[] = "NTDLL.dll"; 

pNtQuerySystemInformation = (pNtQuerySystemInformationFun)GetProcAddress(LoadLibrary("NTDLL.DLL"), "NtQuerySystemInformation"); 

if(!pNtQuerySystemInformation) 
ExitProcess(0); 

bool bMore = true; 
MODULEENTRY32 stMod; 
stMod.dwSize = sizeof(MODULEENTRY32); 

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());

bMore = Module32First(hSnap, &stMod); 
do 
{ 
ReplaceIATEntryInOneMod(szDllName, (PROC)pNtQuerySystemInformation, (PROC)MyNtQuerySystemInformation, stMod.hModule); 
bMore = Module32Next(hSnap, &stMod); 
}while(bMore); 

CloseHandle(hSnap); 
return 0; 
}

LONGWINAPIInvalidReadExceptionFilter(PEXCEPTION_POINTERSpep){ 
LONGlDisposition=EXCEPTION_EXECUTE_HANDLER; 
return(lDisposition); 
} 

voidWideToString(LPCWSTRwcChar,char*lpDesStr) 
{ 
WideCharToMultiByte(0,0,wcChar,wcslen(wcChar),lpDesStr,wcslen(wcChar),NULL,NULL); 
} 

voidStringToWide(constchar*lpStr,WCHAR*wcChar) 
{ 
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpStr,-1,wcChar,strlen(lpStr)); 
} 


char*Change(char*szText) 
{ 
char*szOrg=szText; 
for(;szText;szText++) 
{ 
if(*szText>='A'&&*szText<='Z') 
{ 
*szText=*szText-'A'+'a'; 
} 
} 

returnszOrg; 
}


EXE 代码: 

#include <Windows.h> 
#include <tlhelp32.h> 
#include <vector> 

char szDLLFileName[MAX_PATH] = "E:\\MyProject\\VC\\VC 6.0\\DLL 编程\\REMOTE_HOOK\\Debug\\REMOTE_HOOK.dll"; //要注入的DLL路径 

void InfectEXE(int nID) 
{ 
HANDLE hHookProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nID); 
if( hHookProcess == NULL ) 
{ 
return ; 
} 
PVOID pRemoteAddr = VirtualAllocEx(hHookProcess, NULL, strlen(szDLLFileName) + 1, MEM_COMMIT, PAGE_READWRITE); 

LPTHREAD_START_ROUTINE dwLoadLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("Kernel32.Dll"), "LoadLibraryA"); 
if( dwLoadLibAddr == NULL ) 
{ 
return ; 
} 

DWORD dwSize = 0; 
if( WriteProcessMemory(hHookProcess, pRemoteAddr, szDLLFileName, strlen(szDLLFileName), &dwSize) == 0 ) 
{ 
return ; 
} 

DWORD dwThreadID; 
HANDLE hThread = CreateRemoteThread(hHookProcess, NULL, NULL, dwLoadLibAddr, pRemoteAddr, NULL, &dwThreadID); 
CloseHandle(hThread); 

} 
char* Change(char* szText) 
{ 
char *szOrg = szText;  
for(; *szText; szText++) 
{ 
if( *szText >= 'A' && *szText <= 'Z' ) 
{ 
*szText = *szText - 'A' + 'a'; 
} 
} 

return szOrg; 
} 
DWORD GetProcessIdFromName(LPTSTR name) //通过执行文件名获得进程ID的方法 
{ 
char szExeName[MAX_PATH]; 
PROCESSENTRY32 pe; 
DWORD id = 0; 
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 
pe.dwSize = sizeof(PROCESSENTRY32); 
if( !Process32First(hSnapshot,&pe) ) 
return 0; 
do 
{ 
strcpy(szExeName, pe.szExeFile); 
if(strcmp(Change(szExeName), name) == 0) 
{ 
id = pe.th32ProcessID; 
break; 
} 

pe.dwSize = sizeof(PROCESSENTRY32); 
if( Process32Next(hSnapshot,&pe)==FALSE ) 
break; 

} while(1); 

CloseHandle(hSnapshot); 
return id; 
} 

int main() 
{ 
char szHookProcName[521] = "taskmgr.exe"; 
WinExec(szHookProcName, SW_SHOW); 
Sleep(500); 
InfectEXE(GetProcessIdFromName(szHookProcName)); 

return 0; 
}

3.Ring0 下 HOOK API(SSDT HOOK),用处多大就不说了,下面是一个进程保护的HOOK. 

#include "ntddk.h" 

PMDL g_pmdlSystemCall; 

PVOID *MappedSystemCallTable; 

NTSYSAPI 
NTSTATUS 
NTAPI ZwOpenProcess ( 
 OUT PHANDLE ProcessHandle, 
 IN ACCESS_MASK DesiredAccess, 
 IN POBJECT_ATTRIBUTES ObjectAttributes, 
 IN PCLIENT_ID ClientId 
 ); 

typedef NTSTATUS (*ZwFunDef) ( 
 OUT PHANDLE ProcessHandle, 
 IN ACCESS_MASK DesiredAccess, 
 IN POBJECT_ATTRIBUTES ObjectAttributes, 
 IN PCLIENT_ID ClientId 
 ); 



ZwFunDef pOldFun= NULL;

VOID OnUnload(IN PDRIVER_OBJECT DriverObject) 
{ 
 DbgPrint("ROOTKIT: OnUnload called\n"); 
 UNHOOK_SYSCALL( ZwOpenProcess, pOldFun, NewFun ); 
 // Unlock and Free MDL 
 if(g_pmdlSystemCall) 
 { 
 MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall); 
 IoFreeMdl(g_pmdlSystemCall); 
 } 
} 

NTSTATUS NewFun( 
 OUT PHANDLE ProcessHandle, 
 IN ACCESS_MASK DesiredAccess, 
 IN POBJECT_ATTRIBUTES ObjectAttributes, 
 IN PCLIENT_ID ClientId 
 ) 
{ 
  
if( ClientId->UniqueProcess == (HANDLE)1472) 
 return STATUS_SUCCESS; 
 return pOldFun(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); 
} 



NTSTATUS SetSSDTWrite() 
{ 
 g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); 
 if(!g_pmdlSystemCall) 
 return STATUS_UNSUCCESSFUL; 

 MmBuildMdlForNonPagedPool(g_pmdlSystemCall); 

 // Change the flags of the MDL 
 g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; 

 MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); 

 return STATUS_SUCCESS; 
} 


NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,  
 IN PUNICODE_STRING theRegistryPath) 
{ 
 theDriverObject->DriverUnload = OnUnload;  

 SetSSDTWrite(); 
  
 pOldFun =(ZwFunDef)(SYSTEMSERVICE(ZwOpenProcess)); 
  
  
 HOOK_SYSCALL( ZwOpenProcess,NewFun , pOldFun ); 
  
 return STATUS_SUCCESS; 
}

#include <windows.h> 
#include <iostream> 
using namespace std; 

char cOldIst = 85;  

LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo) 
{ 
CONTEXT stCT = *(ExceptionInfo->ContextRecord); 

cout<<"SEH Hook"<<endl; 

DWORD dwSize = 0; 
WriteProcessMemory((HANDLE)-1, (LPVOID)stCT.Eip, &cOldIst, 1, &dwSize); 
SetThreadContext(GetCurrentThread(), &stCT); 
return EXCEPTION_EXECUTE_HANDLER; 
} 

int MyFunc() 
{ 
cout<<"My Func"<<endl; 
return 0; 
} 

int main() 
{ 
DWORD dwHookAddress = (DWORD)&MyFunc; 

SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); 

DWORD dwSize = 0, dwOldProtect = 0; 
char cInt3 = 204; 

ReadProcessMemory((HANDLE)-1, (LPVOID)dwHookAddress, &cOldIst, 1, &dwSize); 
WriteProcessMemory((HANDLE)-1, (LPVOID)dwHookAddress, &cInt3, 1, &dwSize); 

MyFunc(); 

return 0; 
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值