天天看點

DLL劫持三:inline hook JMP執行個體 (UDP recvfrom)

核心代碼從網上找的,但原始函數調用一直有問,經過分析 整理并測試成功。

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

#pragma comment( lib, "Ws2_32.lib" )

DWORD OldProtect2;
byte pData[10];    //保留原始函數的調用
FARPROC FunAddr;   //生成新的函數調用

typedef int ( WINAPI RecvFromFN)( SOCKET s, char *buf, int len, int flags, sockaddr *from, int *fromlen);
RecvFromFN* pfnOrigRecvFrom ;

void inhook(char* path,char* FunctionName,DWORD NewAddr)
{
	if(FunAddr!=0)
	 return ;
	HMODULE ModuleHandle= LoadLibraryA(path);
	FunAddr = GetProcAddress(ModuleHandle,FunctionName);

	VirtualProtect(FunAddr,5,PAGE_EXECUTE_READWRITE,&OldProtect);
	ZeroMemory(pData,10);
	RtlMoveMemory(pData,FunAddr,5);
	long b;
	b=NewAddr-((long)FunAddr+5);
	byte a[5];
	a[0]=0xE9;
	RtlMoveMemory(&a[1],&b,4);
	WriteProcessMemory(GetCurrentProcess(),FunAddr,a,5,NULL);
	pData[5]=0xE9;
	pData[6]=0;
	pData[7]=0;
	pData[8]=0;
	pData[9]=0;
	b=(long)FunAddr+5-(long)(pData+10);
	WriteProcessMemory(GetCurrentProcess(),pData+6,&b,4,NULL);
	FreeLibrary(ModuleHandle);

        //下面這兩行用于調用原始函數
	pfnOrigRecvFrom = (RecvFromFN*) (DWORD) (pData);
	VirtualProtect(pfnOrigRecvFrom,10,PAGE_EXECUTE_READWRITE,&OldProtect2);
 
}
void unhook(void)
{
	if(FunAddr==0)
	 return ;
	WriteProcessMemory(GetCurrentProcess(),FunAddr,pData,5,NULL);
	VirtualProtect(FunAddr,5,OldProtect,NULL);
	FunAddr=0;
	ZeroMemory(pData,10);
	VirtualProtect(pfnOrigRecvFrom,10,OldProtect2,NULL);  //恢複原始函數指針
}

int WINAPI Mine_RecvFrom(SOCKET s, char *buf, int len, int flags, sockaddr *from, int *fromlen)
{		
    int tmpRet = pfnOrigRecvFrom(s,buf,len,flags,from,fromlen);	
    sockaddr_in * pSin = (sockaddr_in *) from;
        
    //顯示接收資料長度,來源IP和端口
    fprintf(stdout,"Recv Data Size:%d From:%s:%d.\n",tmpRet, inet_ntoa(pSin->sin_addr),ntohs(pSin->sin_port));
	
    return tmpRet;
}
           

以上代碼在程序内調用有效,也支援程序内DLL方式,實際調用時使用代碼

inhook("Ws2_32.dll","recvfrom",(DWORD) Mine_RecvFrom); 

就可以了,DLL的話在DllMain中直接加載。

繼續閱讀