SendSpyer是一个控制台程序。其接受2个输入参数:pid recordfile。其中pid是想要拦截网络发送数据的目标进程ID,recordfile是记录拦截下来的网络数据的文件路径。
对于不使用winsock函数send来发送网络数据的程序无法拦截其发生数据。处于效率和稳定性的考虑,没有对send函数的指令恢复做同步限制,可能会导致部分提交数据的遗漏。
void HookSend(LPVOID lParam)
{
RemoteParam* pRP = (RemoteParam*)lParam;
HMODULE hUser32 = NULL;
HMODULE hKernel32 = NULL;
PFN_LOADLIBRARY pfnLoadlibrary = (PFN_LOADLIBRARY)pRP->dwLoadLibrary;
PFN_FREELIBRARY pfnFreeLibrary = (PFN_FREELIBRARY)pRP->dwFreeLibrary;
hUser32 = pfnLoadlibrary(pRP->szModuleName1);
hKernel32 = pfnLoadlibrary(pRP->szModuleName2);
#ifndef NDEBUG
char szMsgContent[256];
PFN_GETMODULEFILENAME pfnGetModuleName = (PFN_GETMODULEFILENAME)pRP->dwGetModuleFileName;
pfnGetModuleName(NULL, szMsgContent, sizeof(szMsgContent));
#endif
PFN_CREATEFILE pfnCreateFile = (PFN_CREATEFILE)pRP->dwCreatefile;
PFN_SETFILEPOINTER pfnSetFilePointer = (PFN_SETFILEPOINTER)pRP->dwSetFilePointer;
PFN_WRITEFILE pfnWriteFile = (PFN_WRITEFILE)pRP->dwWriteFile;
PFN_CLOSEHANDLE pfnCloseHandle = (PFN_CLOSEHANDLE)pRP->dwCloseHandle;
DWORD NextIpAddr = 0;
DWORD dwParamaAddr = 0;
SOCKET s;
char * buf;
int len;
int flags;
PFN_SEND pfnSend = (PFN_SEND)pRP->dwSend;
int RetValue = 0;
__asm
{
MOV EAX,[EBP+8]
MOV [dwParamaAddr], EAX
MOV EAX,[EBP+12]
MOV [NextIpAddr], EAX
MOV EAX,[EBP+16]
MOV [s], EAX
MOV EAX,[EBP+20]
MOV [buf],EAX
MOV EAX,[EBP+24]
MOV [len],EAX
MOV EAX,[EBP+28]
MOV [flags],EAX
}
unsigned char szNewCode[10];
int PramaAddr = (int)dwParamaAddr;
szNewCode[4] = PramaAddr>>24;
szNewCode[3] = (PramaAddr<<8)>>24;
szNewCode[2] = (PramaAddr<<16)>>24;
szNewCode[1] = (PramaAddr<<24)>>24;
szNewCode[0] = 0x68;
int funaddr = (int)pRP->FunAddr - (int)pfnSend - 10 ;
szNewCode[9] = funaddr>>24;
szNewCode[8] = (funaddr<<8)>>24;
szNewCode[7] = (funaddr<<16)>>24;
szNewCode[6] = (funaddr<<24)>>24;
szNewCode[5] = 0xE8;
PFN_GETCURRENTPROCESS pfnGetCurrentProcess = (PFN_GETCURRENTPROCESS)pRP->dwGetCurrentProcess;
PFN_WRITEPROCESSMEMORY pfnWriteProcessMemory = (PFN_WRITEPROCESSMEMORY)pRP->dwWriteProcessMemory;
if (!pfnWriteProcessMemory(pfnGetCurrentProcess(),
(LPVOID)pfnSend,
(LPCVOID)pRP->szOldCode,
10,
NULL))
{
#ifndef NDEBUG
char szMsgCaption[8] = {'R', 'e', 's', 'u', 'm', '!', '\0'};
PFN_MESSAGEBOX pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, szMsgContent, szMsgCaption, MB_ICONINFORMATION | MB_OK);
#endif
}
RetValue = pfnSend(s, buf, len, flags);
if (!pfnWriteProcessMemory(pfnGetCurrentProcess(),
(LPVOID)pfnSend,
(LPCVOID)szNewCode,
10,
NULL))
{
#ifndef NDEBUG
char szMsgCaption[8] = {'H', 'o', 'o', 'k', '!', '\0'};
PFN_MESSAGEBOX pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, szMsgContent, szMsgCaption, MB_ICONINFORMATION | MB_OK);
#endif
}
HANDLE fp = pfnCreateFile(pRP->szFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fp == INVALID_HANDLE_VALUE)
{
#ifndef NDEBUG
char szMsgCaption[8] = {'C', 'r', 'e', 'a', 't', 'e', '!', '\0'};
PFN_MESSAGEBOX pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, szMsgContent, szMsgCaption, MB_ICONINFORMATION | MB_OK);
#endif
__asm
{
MOV EDX, [NextIpAddr]
MOV EAX, [RetValue]
MOV ESP, EBP
POP EBP
ADD ESP, 1CH //恢复堆栈
PUSH EDX
RET
}
}
DWORD i = 0;
DWORD nWritten = 0;
while (buf[i] != 0)
i++;
pfnSetFilePointer(fp, 0, NULL, FILE_END);
if (!pfnWriteFile(fp, (LPCVOID)buf, i, &nWritten, NULL))
{
#ifndef NDEBUG
char szMsgCaption[8] = {'W', 'r', 'i', 't', 'e', '!', '\0'};
PFN_MESSAGEBOX pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, szMsgContent, szMsgCaption, MB_ICONINFORMATION | MB_OK);
#endif
pfnCloseHandle(fp);
__asm
{
MOV EDX, [NextIpAddr]
MOV EAX, [RetValue]
MOV ESP, EBP
POP EBP
ADD ESP, 1CH //恢复堆栈
PUSH EDX
RET
}
}
pfnCloseHandle(fp);
pfnFreeLibrary(hKernel32);
pfnFreeLibrary(hUser32);
__asm
{
POP EDI
POP ESI
POP EBX
MOV EDX, [NextIpAddr]
MOV EAX, [RetValue]
MOV ESP, EBP
POP EBP
ADD ESP, 1CH //恢复堆栈
PUSH EDX
RET
}
}