能力值:
( LV2,RANK:10 )
6 楼
晕,我写错了,实在是不好意思。
如果可以的话,你可以把变量定义到函数外面。我当时是在Class里面多定义了几个成员变量,用它们存的。
在函数里面定义变量会破坏堆栈,因为这样编译出来,会变成 mov dword ptr [ebp-xx],eax 的形势,而这里刚进来的时候没有 push ebp 和 mov ebp, esp。
这个是我以前用 AheadLib 改的一个例子,拿send() 和 recv() 举个例子吧,调用原函数前后的操作。红色是我自己加的,其他的是自动生成就有的。这个我以前测试过,没问题。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AheadLib 命名空间
namespace AheadLib
{
HMODULE m_hModule = NULL; // 原始模块句柄
DWORD m_dwReturn[500] = {0}; // 原始函数返回地址
[COLOR="Red"]LPVOID m_ptrBuffer = 0;
DWORD m_size = 0;
HANDLE m_hFile = NULL;
DWORD m_byteCount = 0;[/COLOR]
// 加载原始模块
inline BOOL WINAPI Load()
{
TCHAR tzPath[MAX_PATH];
TCHAR tzTemp[MAX_PATH * 2];
GetSystemDirectory(tzPath, MAX_PATH);
lstrcat(tzPath, TEXT("\\ws2_32"));
m_hModule = LoadLibrary(tzPath);
if (m_hModule == NULL)
{
wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);
MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
}
[COLOR="red"]m_hFile = CreateFile("MyLog.log", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0);
if (m_hFile == INVALID_HANDLE_VALUE)
MessageBox(NULL, "Can not open log file!", "ws2_32.dll", MB_ICONSTOP);
else
{
SetFilePointer(m_hFile, 0, 0, FILE_END);
WriteFile(m_hFile, TEXT("========== START ===========\r\n"), 30, &m_byteCount, 0);
FlushFileBuffers(m_hFile);
}[/COLOR]
return (m_hModule != NULL);
}
// 释放原始模块
inline VOID WINAPI Free()
{
if (m_hModule)
{
FreeLibrary(m_hModule);
}
[COLOR="red"]if (m_hFile)
{
WriteFile(m_hFile, "=========== END ============\r\n", 30, &m_byteCount, 0);
WriteFile(m_hFile, m_ptrBuffer, m_size, &m_byteCount, 0);
FlushFileBuffers(m_hFile);
CloseHandle(m_hFile);
}[/COLOR]
}
// 获取原始函数地址
FARPROC WINAPI GetAddress(PCSTR pszProcName)
{
FARPROC fpAddress;
CHAR szProcName[16];
TCHAR tzTemp[MAX_PATH];
fpAddress = GetProcAddress(m_hModule, pszProcName);
if (fpAddress == NULL)
{
if (HIWORD(pszProcName) == 0)
{
wsprintf(szProcName, "%d", pszProcName);
pszProcName = szProcName;
}
wsprintf(tzTemp, TEXT("无法找到函数 %hs,程序无法正常运行。"), pszProcName);
MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
ExitProcess(-2);
}
return fpAddress;
}
}
using namespace AheadLib;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_send(void)
{
// 保存返回地址
__asm POP m_dwReturn[18 * TYPE long];
[COLOR="red"]__asm
{
push eax
mov eax, [esp+8]
mov m_ptrBuffer, eax
mov eax, [esp+12]
mov m_size, eax
}
if (m_hFile != INVALID_HANDLE_VALUE)
{
WriteFile(m_hFile, TEXT("---------- send() ----------\r\n"), 30, &m_byteCount, 0);
WriteFile(m_hFile, m_ptrBuffer, m_size, &m_byteCount, 0);
FlushFileBuffers(m_hFile);
}
__asm pop eax[/COLOR]
// 调用原始函数
GetAddress("send")();
// 转跳到返回地址
__asm JMP m_dwReturn[18 * TYPE long];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_recv(void)
{
// 保存返回地址
__asm POP m_dwReturn[15 * TYPE long];
[COLOR="red"]__asm
{
push eax;
mov eax, [esp+8]
mov m_ptrBuffer, eax
mov eax, [esp+12]
mov m_size, eax
pop eax
}[/COLOR]
// 调用原始函数
GetAddress("recv")();
[COLOR="red"]__asm push eax
if (m_hFile != INVALID_HANDLE_VALUE)
{
WriteFile(m_hFile, "---------- recv() ----------\r\n", 30, &m_byteCount, 0);
WriteFile(m_hFile, m_ptrBuffer, m_size, &m_byteCount, 0);
FlushFileBuffers(m_hFile);
}
__asm pop eax[/COLOR]
// 转跳到返回地址
__asm JMP m_dwReturn[15 * TYPE long];
}
能力值:
( LV2,RANK:10 )
8 楼
// 导出函数
#pragma comment(linker, "/EXPORT:accept=_AheadLib_accept,@1")
#pragma comment(linker, "/EXPORT:bind=_AheadLib_bind,@2")
#pragma comment(linker, "/EXPORT:closesocket=_AheadLib_closesocket,@3")
#pragma comment(linker, "/EXPORT:connect=_AheadLib_connect,@4")
#pragma comment(linker, "/EXPORT:getpeername=_AheadLib_getpeername,@5")
#pragma comment(linker, "/EXPORT:getsockname=_AheadLib_getsockname,@6")
#pragma comment(linker, "/EXPORT:getsockopt=_AheadLib_getsockopt,@7")
#pragma comment(linker, "/EXPORT:htonl=_AheadLib_htonl,@8")
#pragma comment(linker, "/EXPORT:htons=_AheadLib_htons,@9")
#pragma comment(linker, "/EXPORT:ioctlsocket=_AheadLib_ioctlsocket,@10")
#pragma comment(linker, "/EXPORT:inet_addr=_AheadLib_inet_addr,@11")
#pragma comment(linker, "/EXPORT:inet_ntoa=_AheadLib_inet_ntoa,@12")
#pragma comment(linker, "/EXPORT:listen=_AheadLib_listen,@13")
#pragma comment(linker, "/EXPORT:ntohl=_AheadLib_ntohl,@14")
#pragma comment(linker, "/EXPORT:ntohs=_AheadLib_ntohs,@15")
#pragma comment(linker, "/EXPORT:recv=_AheadLib_recv,@16")
#pragma comment(linker, "/EXPORT:recvfrom=_AheadLib_recvfrom,@17")
#pragma comment(linker, "/EXPORT:select=_AheadLib_select,@18")
#pragma comment(linker, "/EXPORT:send=_AheadLib_send,@19")
#pragma comment(linker, "/EXPORT:sendto=_AheadLib_sendto,@20")
#pragma comment(linker, "/EXPORT:setsockopt=_AheadLib_setsockopt,@21")
#pragma comment(linker, "/EXPORT:shutdown=_AheadLib_shutdown,@22")
...
程序开始声明了
DWORD m_dwReturn[500] = {0}; // 原始函数返回地址
用来存放返回地址,按照导出列表 recv() 排16,send()排19,因为数组是0开始的,所以各减了1,就成了15和18。
我当时做这个的时候只是记录发送和接受的数据,所以只修改了send(), sendto(), recv(), recvfrom(), WSASend(), WSASendTo(), WSARecv(), WSARecvFrom(),内容基本都差不多。我也是照着上面那个地址里的例子做的,他讲得挺详细的。其他的dll我就没做过了。
能力值:
( LV2,RANK:10 )
10 楼
因为不太懂汇编,所以我把接收发送数据的函数单独搞出来
希望各位大哥指教.
同样是调用相同写包的函数,在send函数中调用包写文件函数的时候容易出错,比如测试时候导致IE经常出错.
不知道icersg 老大能否也把你的代码贴上来,以供我等新手学习参考下.
CPP源文件我增加的部分代码
另外我增加处理的几个函数用def文件导出函数名,同时需要把源文件下面的#pragma comment相应的函数申明注释掉.
int (__stdcall *sendto1)(SOCKET,const char FAR *,int,int,const struct sockaddr FAR *,int);
//int (__stdcall *recvfrom1)(SOCKET,char FAR*,int,int,struct sockaddr FAR*,int FAR*);
int (__stdcall *recvfrom1)(SOCKET,char FAR*,int,int,struct sockaddr FAR*,int FAR*);
int (__stdcall *recv1)(SOCKET ,char FAR * ,int ,int );
int (__stdcall *send1)(SOCKET ,const char FAR * ,int ,int);
//int (__stdcall *WSARecvFrom1)(SOCKET,WSABUF *,DWORD,LPDWORD,LPDWORD,struct sockaddr FAR *,_OVERLAPPED *,LPWSAOVERLAPPED_COMPLETION_ROUTINE *); void wbs_openfile_b(void)
{
//if (g_wbs_fp!=NULL) fclose(g_wbs_fp);
//g_wbs_fp=NULL;
if (g_wbs_fp==NULL) g_wbs_fp=fopen(wbs_DataFile,"at");
if (g_wbs_fp==NULL)
{
MessageBox(NULL,"打开文件失败","wbs_openfile_b",0);
}
}
void PrintData_header(FILE *pf, BYTE FAR *pdata,int len,char * header)
{
int i,i_16;
int size;
char * temp_buf[16]={" "};
i_16=0;
size = len;
g_packet_number=g_packet_number+1;
//判断是否目标程序,将目标程序特征码g_Targetcode写入文件
isTarget(GetCurrentProcess());
fprintf(pf,"p:=%6d %s 特征码:%08xh\n",g_packet_number,header,g_Targetcode);
if(size>Max_Data_Len) size=Max_Data_Len;
for(i=0;i<size;i++)
{
//16进制的格式化
switch (i_16)
{
case 0:
{
fprintf(pf,"%08xh ",g_position); //写行数
fprintf(pf,"%02x ",pdata[i]);
//memcpy(&temp_buf[i_16],"0",1);
memcpy(temp_buf,&pdata[i],16);
g_position=g_position+1;
i_16=i_16+1; //放在CASE最后,
break;
}
case 15:
{
fprintf(pf,"%02x ",pdata[i]); //最后一个字节给出4个空格
//写TEXT部分
//memcpy(&temp_buf[i_16],"q",1);
//memcpy(&temp_buf[i_16],&pdata[i],1);
fprintf(pf,"%s",temp_buf);
fprintf(pf,"\n"); //写满16个字节换行
i_16=0; //放在CASE最后,写满16个字节,初始化
break;
}
default :
{
fprintf(pf,"%02x ",pdata[i]);
//memcpy(&temp_buf[i_16],&pdata[i],1);
//memcpy(temp_buf[i_16],"d",1);
i_16=i_16+1; //放在CASE最后
break;
}
}//switch结束
}//for语句结束
if (i_16!=15) fprintf(pf," %s",temp_buf);
fprintf(pf,"\n");
} int wbs_SaveSendData(int socket, char *p, int size,char * header)
{
if(size<=0) return size;
wbs_openfile_b();
if(g_wbs_fp!=NULL) {
//fprintf(g_wbs_fp,"call recv, used socket=%d,len:%d\n",socket,size);
PrintData_header(g_wbs_fp,(BYTE *)p,size,header);
}
return size;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
HINSTANCE h_dll;
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
for (INT i = 0; i < sizeof(m_dwReturn) / sizeof(DWORD); i++)
{
m_dwReturn[i] = TlsAlloc();
}
}
else if (dwReason == DLL_PROCESS_DETACH)
{
for (INT i = 0; i < sizeof(m_dwReturn) / sizeof(DWORD); i++)
{
TlsFree(m_dwReturn[i]);
}
Free();
}
h_dll=LoadLibrary("c:\\winnt\\system32\\ws2_32.dll");
//h_dll=LoadLibrary("ws2_32_1.dll");
proc=GetProcAddress(h_dll,"sendto");
sendto1=(int (__stdcall *)(SOCKET,const char FAR *,int,int,const struct sockaddr FAR *,int))proc;
proc=GetProcAddress(h_dll,"recvfrom");
recvfrom1=(int (__stdcall *)(SOCKET,char FAR*,int,int,struct sockaddr FAR*,int FAR*))proc;
proc=GetProcAddress(h_dll,"recv");
recv1=(int (_stdcall *)(SOCKET ,char FAR * ,int ,int ))proc;
proc=GetProcAddress(h_dll,"send");
send1=(int (_stdcall *)(SOCKET ,const char FAR * ,int ,int ))proc; //proc=GetProcAddress(h_dll,"WSARecv");
//WSARecv1=(int (_stdcall *)(SOCKET,LPWSABUF,DWORD,DWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE))proc; return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
/////////////// wbs开始处理ws2_32.dll的接收发送函数 /////////////
int PASCAL FAR sendto(SOCKET s,const char FAR * buf,int len,int flags,const struct sockaddr FAR * to,int tolen)
{
int rc;
char * s_len[6];
rc=sendto1(s,buf,len,flags,to,tolen);
{
wsprintf((char *)s_len,"function sendto size:=%d",len);
wbs_SaveSendData((int)s, (char *)buf, len,(char *)s_len);
}
return rc;
}
int PASCAL FAR recvfrom (SOCKET s,char FAR* buf,int len,int flags,struct sockaddr FAR* from,int FAR* fromlen)
{
int rc;
char * s_len[6];
rc=recvfrom1(s,buf,len,flags,from,fromlen);
{
wsprintf((char *)s_len,"function recvfrom size:=%d",len);
wbs_SaveSendData((int)s, (char *)buf, len,(char *)s_len);
}
return rc;
}
int PASCAL FAR recv(SOCKET s, char FAR * buf, int len, int flags)
{
int rc;
char * s_len[6];
rc=recv1(s, buf, len, flags);
{
wsprintf((char *)s_len,"function recv size:=%d",len);
wbs_SaveSendData((int)s, (char *)buf, len,(char *)s_len);
}
return rc;
}
int PASCAL FAR send(SOCKET s,const char FAR * buf,int len,int flags)
{
int rc;
char * s_len[6];
rc = send1(s,buf,len,flags);
//容易出错的代码
/*
{
wsprintf((char *)s_len,"function send size:=%d",len);
wbs_SaveSendData((int)s, (char *)buf, len,(char *)s_len);
}
*/
return rc;
} /*
int PASCAL FAR WSARecv (SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE)
{
int rc;
char * s_len[6];
rc=WSARecv1(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd,lpFlags,lpOverlapped,lpCompletionROUTINE);
//if (g_VK_F9==TRUE)
{
wsprintf((char *)s_len,"function recv size:=%d",dwBufferCount);
//wbs_SaveSendData((int)s, (char *)buf, rc,(char *)s_len);
wbs_SaveSendData((int)s, (char *)lpBuffers, dwBufferCount,(char *)s_len);
}
return rc;
}
*/
/////////////// wbs结束处理ws2_32.dll的接收发送函数 /////////////
/////////////////////////////////////////////////////////////////////////////////////////////