ACCESS班门弄斧一涂鸦~~VC++.NET 2008描写的HOOK RECV代码

当真是班门弄斧,因为自己是效仿VB的,虽然VB6和.NET都算入门吧,可真以VC++写程序还是率先软。学B/C/D的就从来不看了。

是因为是用上点滴首写的远线程调用,所以多参数等等都是流传的,而未是一直拿走的。

 

下就一个就此VB的人数能明白吧目标召开简单说明跟注释:

1、VC里面声明变量和VB不等同:类型在前方,名称在继,例如:

BYTE B ;

等同于:

dim B as byte

VC用分号来识别行结束,而VB用回车;VB用圆括号表示数组,VC用方括号……不多说了,我啊未是充分知,总之习惯就是吓

2、VC里面的函数、变量等等区分轻重缓急写,VB不分,这个一定要小心!

3、类型转换:VB有显式或隐式的,而VC必须用显式的——即经常内存里面存的就是生东东君吧无可知直接将来为此,够严厉,不过指针够灵活也足够太灵敏……转换时利用的措施就是是当圆括号内写副你如之类型,后面就你的参数就可。例如:

(DWORD)LEN;就是管LEN转换成DWORD类型,据自己理解还是是UINTEGER,要么是INTEGER,可能两样API要求不同,我直接还是依照INTEGER处理的,也就是说,前面那句相当给CTYPE(LEN,INTEGER)了。

4、&将会见吧后面的变量变为指针,*以见面把指针变成相应的多少……说的不确切,应该是易吧

5、其他省就清楚了,VC用API、常数等向不声明……而是导入.H文件吧(头文件,而且其中可以用宏来改变API书写的称号,就比如VB声明API时那个别名吧),反正这工程里没因此到。

 

以上言论而产生误导,请及早指出………………以免造孽更要命…………谢谢………………

 

 

//自定义APIHOOK结构
typedef struct
{
    FARPROC funcaddr;  //RECV函数所在地方
 BYTE    olddata[8];      //RECV函数开头的8单字节原始数据
 BYTE    newdata[8];   
//我们若描绘副的数量,汇编代码在脚,利用了EAX存储要跳转的地点,并且FF
E0这个操作是绝地址的
}HOOKSTRUCT;
//0-4 : move eax 0x00000000
//绝对地方,避免了一个折算,其实这换算为大概,ADDRESS-MFUNADDRESS-5即是
//5-7 : jmp eax

HWND  _fHandle ;  //接收信息窗口句柄
DWORD _dwIdNew ;  //PID
HANDLE hProc; 
//进程内核句柄,就是OPENPROCESS打开PID得到的可怜东东——读写内存用到
////////////////////////////////////////
DWORD _ws2_RecvIndex = 1 ;  //ws2_32.dll
RECVHOOK标志,实际和HOOK没关系,但是当你HOOK的函数多起来,你得区分是何许人也函数发来的音信啊!
HOOKSTRUCT _ws2_RecvHook; //ws2_32.dll HOOK结构
////////////////////////////////////////

//这下的这些家伙,就是一个定义,和脚写的函数实体一样声明即可,VB里不用这样干编译器也克鉴别都产生怎样函数,可VC不成为

int WINAPI m_ws2_recv(SOCKET s, char FAR *buf, int len, int flags);

void SendMsg(char *buf,DWORD len,DWORD Index);
void HookOnOne(HOOKSTRUCT *hookfunc);
void HookOffOne(HOOKSTRUCT *hookfunc);
bool HOOKAPI(DWORD Address,HOOKSTRUCT *hookfunc,DWORD mFncAddress);

//下面传入了有参数:被注入进程PID,要收下返回信息窗口的句柄

extern “C” _declspec(dllexport) void __stdcall Init(DWORD PID ,HWND
FormHandle)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());  
//这个……VC里被宏吧,哎……说来讲话长,这句去丢为无所谓的

 _dwIdNew = PID ;           
//备份PID,其实背后代码没下,主要是为鉴别注入了大多单程序的话语,是哪个程序发回的信为
 _fHandle = FormHandle ;  //接收信息之窗口句柄,SendMsg函数用到
 hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, _dwIdNew);  
//打开进程,进一步操作他
}

//下面这个用来:记录为HOOK函数前8字节原数据、构建新的8许节代码、将新代码替换RECV函数原来代码的

//说明全部都是以RECV函数为例,其实是函数是一个通用函数

bool HOOKAPI(DWORD Address,HOOKSTRUCT *hookfunc,DWORD mFncAddress)
{
 hookfunc->funcaddr = (FARPROC)Address; 
//这个地方用了一个转移,把染入值转换成何结构中声明的均等
    memcpy(hookfunc->olddata, hookfunc->funcaddr, 8);
//记录RECV函数前8字节原本数据
 //下面开始构建汇编代码{0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00
}
 hookfunc->newdata[0]=0xB8;   //MOVE EAX
(EAX后面的一再就是脚4字节了)
 hookfunc->newdata[1]=0x00;
 hookfunc->newdata[2]=0x00;
 hookfunc->newdata[3]=0x00;
 hookfunc->newdata[4]=0x00; //到这里是 MOVE EAX 00000000
,这里的地点,将会晤以底下被替换(注意是绝地址)
 hookfunc->newdata[5]=0xFF; 

 hookfunc->newdata[6]=0xE0;//到这里是 JMP EAX
 hookfunc->newdata[7]=0xCC;//填充一个INT3
,其实NOP(&h90)啥的吧尽,换句话说这个不改、不理他都可,不过翻看帖子时看部分人口说CPU识别错代码,谁知道真假,还是扩个家喻户晓的可比保险……
 memcpy(&hookfunc->newdata[1], &mFncAddress, 4); 
//这里替换了端提到的 00000000 为我们之所以来代表RECV的函数的地址
 HookOnOne(hookfunc);  //将RECV函数前8字节交替为咱构建的代码——开始HOOK
RECV
 return true;
}

 

 

////////////////////////////////////////////////////////////////////////////////////
//recv,这个函数将实现RECV函数的轮换:只待执行同一蹩脚即可
////////////////////////////////////////////////////////////////////////////////////
extern “C” _declspec(dllexport) bool __stdcall Hook_ws2_Recv(DWORD
RecvAddress)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 HOOKAPI(RecvAddress,&_ws2_RecvHook,(DWORD)m_ws2_recv);
//这里,(DWORD)m_ws2_recv的归值就是m_ws2_recv函数的地方!你看人家VC多方便……
    return true;
}

//显然了,这个事解除RECV HOOK的
extern “C” _declspec(dllexport) bool __stdcall UnHook_ws2_Recv()
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 HookOffOne(&_ws2_RecvHook);
    return true;
}
//—————————————————————————

//这个函数,就是我们所以来替换RECV函数的火器了,必须叫这家伙和RECV函数声明相同,这么相同呢,很简单,VC++.NET也发生像样VB的代码提示(虽然少点),找一个方便的地方打及recv(小写)然后由圆括号……看到了?
int WINAPI m_ws2_recv(SOCKET s, char FAR *buf, int len, int flags)
{
    int nReturn = 0; 
//这个铁记录了RECV的回到值,-1啊不当,我们不处理,0为断开,其他嘛,就是实际于SOCKET缓冲区复制了有点字节到RECV缓冲区。简单的说,-1,0还未处理,其他价值就是是咱而于BUF里面读小字节了!

 HookOffOne(&_ws2_RecvHook); //先关闭HOOK,因为既入我们的函数了
    nReturn = recv(s, buf, len, flags); 
//先运行原来的RECV,否则我们无可知取或未可知取所有为复制的内容
 HookOnOne(&_ws2_RecvHook); //继续HOOK

 //sndmsg((DWORD)len,(DWORD)nReturn);

 if ( nReturn == SOCKET_ERROR )
 return -1 ;
 
 SendMsg(buf ,nReturn,_ws2_RecvIndex);
//发送BUF里面NRETURN个字节到接窗体
  
    return(nReturn);
}
/////////////////////////////////////////////////////////////////////////////
//WSARECV

 

/////////////////////////////////////////////////////////////////////////////////

//将原的函数内容写回——关闭HOOK
void HookOffOne(HOOKSTRUCT *hookfunc)
{
 WriteProcessMemory(hProc, hookfunc->funcaddr, hookfunc->olddata,
8, 0);
}
//—————————————————————————

//将我们构建的代码写副——打开HOOK
void HookOnOne(HOOKSTRUCT *hookfunc)
{
 WriteProcessMemory(hProc, hookfunc->funcaddr, hookfunc->newdata,
8, 0);
}

//发送WM_COPYDATA消息及指定窗口
void SendMsg(char *buf,DWORD len,DWORD Index)
{
          COPYDATASTRUCT cds;  
          cds.dwData = 0;//sizeof(COPYDATASTRUCT);   
//有的说之参数影响发送,还尚未利用,本来是存PID的,个人觉得该无会见潜移默化
          cds.cbData = len;    //LPDATA里面的字节数
          cds.lpData = buf;   //实际数据
         
SendMessage(_fHandle,WM_COPYDATA,(WPARAM)Index,(LPARAM)&cds); 
//发到INIT里面指定的雅窗口
}

 

 

今日来编排一下帖子,因为用VB.NET完成了HOOK工作。

实际用VB.NET
HOOK本进程API早就来好了,并且因此了一段时间,感觉要称心如意的。但是注入其他进程一直以就此VC,写起代码真的不如VB.NET顺手,于是想到注入VB.NET的DLL到其它进程,其实就宗事不行已经有人在做,主要是给对方进程加载CLR的题目,其实这项工作且是出于mscoree.dll完成的,本纪念用VB.NET写一段子汇编代码注入及对方进程然后远线程,可圈了羁押工作量确实无略,于是要用了一个VC写的DLL,导出了一个函数,然后远线程调之所以它们用来加载CLR和VB.NET的DLL,这个VC的DLL很简短,只是调用CorBindToRuntimeEx函数来加载CLR,并由的调用VB.NET写的DLL(就是一个正常化的类库,无需另处理)中的办法。这样既可以调用VB.NET的DLL中的点子了,那么接下只有待以VB.NET的DLL中展开拍卖就执行了。总结起来,主要是3片:

1、VC的DLL:导出一个函数,用来加载CLR而后加载VB.NET的DLL并调用其指定方法,十来行代码而已。

2、注入器:远线程运行API的力(这个代码很悠久之前为发过了),当然,根据需要还可能得装有些过程看权限或者再次底层的事物。

3、VB.NET的DLL:公开一个办法,使得CLR能够找到并直调用它。接下来的作业还在这个DLL里面处理便行了,爱启动线程启动线程,想读什么就读什么,想写吗就形容什么吧。结合以前完成的HOOK本进程API的局部艺术,完全好为此托管代码来HOOK和拍卖了。

切切实实实现即无贴了,毕竟非该归为原创,网上就有无数近似代码了,只是直调用CorBindToRuntimeEx,使用远线程的连无是诸多,之所以采取远线程是盖可以在VC的DLL的导出函数那里传来一些参数。例如:加载的CLR版本,标志,要调用的托管DLL,类,方法,参数等还好由注入器传递,从而提高了通用性和操纵的油滑。毕竟我们还尚未到纠结到底几个DLL的境界,当CLR加载完成并运行托管DLL时对方进程还免知情多出去多少DLL呢。

相关文章