首页
社区
课程
招聘
[求助]在劫持DLL过程中如何取得函数的参数
发表于: 2008-10-4 11:26 20159

[求助]在劫持DLL过程中如何取得函数的参数

2008-10-4 11:26
20159
我通过劫持ws2_32.dll可以进行相应的补丁,但我如果想支持并返回某个函数的参数,修改返回值不知如何做.
ALCDECL MemCode_accept(void)
{
IF 满足条件下
如何在这里得到accept的参数,修改返回值,不执行系统的函数,直接返回.
ELSE 执行下面系统的原函数

GetAddress("accept");
        __asm JMP EAX;
}

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (22)
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
http://bbs.pediy.com/showthread.php?t=60849

我用的是2楼的 AheadLib 2.2.150 ,可以选择最后转入真正函数是 jmp 还是 call

其实你这样写也可以,稍加修改就行。

ALCDECL MemCode_accept(void)
{
        //获取参数
        SOCKET s;
        sockaddr *addr;
        int *addrlen

        __asm
        {
                mov eax, [esp+4]
                mov s, eax
                mov eax, [esp+8]
                mov addr, eax
                mov eax, [esp+12]
                mov addrlen, eax
        }

//IF 满足条件下
//如何在这里得到accept的参数,修改返回值,不执行系统的函数,直接返回.
//ELSE 执行下面系统的原函数
//这里可以自己写,参数就是开始定义的那几个,如果不调用原函数,返回前要自己平衡堆栈

GetAddress("accept");
//        __asm JMP EAX;
//这里改成 call,以便修改返回值
        __asm CALL EAX;

//想修改什么就趁现在吧

}
2008-10-4 12:35
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
跟hook一个道理
2008-10-4 18:00
0
雪    币: 2165
活跃值: (3094)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
ALCDECL MemCode_accept(void)
{
  //获取参数
  SOCKET s;
  sockaddr *addr;
  int *addrlen

  __asm
  {
    mov eax, [esp+4]
    mov s, eax
    mov eax, [esp+8]
    mov addr, eax
    mov eax, [esp+12]
    mov addrlen, eax
  }

//IF 满足条件下
//如何在这里得到accept的参数,修改返回值,不执行系统的函数,直接返回.
//ELSE 执行下面系统的原函数
//这里可以自己写,参数就是开始定义的那几个,如果不调用原函数,返回前要自己平衡堆栈

GetAddress("accept");
//        __asm JMP EAX;
//这里改成 call,以便修改返回值
        __asm CALL EAX;

//想修改什么就趁现在吧
是不是直接在这里就可以修改s,或者其它的如int *addrlen等
}
2008-10-4 21:14
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
按2楼大侠的方法:
ALCDECL MemCode_sendto(void)
{
       
        SOCKET s;
        const char FAR * buf;
        int len;
        __asm
        {
        mov EAX, [esp+4]
        mov s, EAX
        /*
        mov eax, [esp+8]
        mov buf, eax
        mov eax, [esp+12]
        mov len, eax   //对汇编只了解一般,int类型也是esp的指针往后指4个单位么

        */
        }

        GetAddress("sendto");
        //__asm JMP EAX;

}

编译,将ws2_32.dll拷贝到应用程序目录。
启动,报错
信息:0x1001a2d4指令引用的0x00003f3a内存。该内存不能为"written"。

对汇编俺不熟悉,希望大侠们指教。
2008-10-5 12:49
0
雪    币: 293
活跃值: (10)
能力值: ( 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];
}
2008-10-6 04:51
0
雪    币: 2165
活跃值: (3094)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
__asm POP m_dwReturn[18 * TYPE long];SEND的返回地址,
__asm POP m_dwReturn[15 * TYPE long];RECV的返回地址,
两个怎么不一样.
还有,其它的例子还有吗?
2008-10-6 09:06
0
雪    币: 293
活跃值: (10)
能力值: ( 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我就没做过了。
2008-10-6 13:52
0
雪    币: 2165
活跃值: (3094)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢icersg兄,还有其它的请教,谢谢
2008-10-6 14:50
0
雪    币: 200
活跃值: (10)
能力值: ( 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的接收发送函数            /////////////
/////////////////////////////////////////////////////////////////////////////////////////////
2008-10-6 14:54
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
楼上我的这个申明在VC6编译通不过
//int (__stdcall *WSARecvFrom1)(SOCKET,WSABUF *,DWORD,LPDWORD,LPDWORD,struct sockaddr FAR *,_OVERLAPPED *,LPWSAOVERLAPPED_COMPLETION_ROUTINE );
黑体部分编译错,这个东东不知道该如何如何写,也没找到类型申明.

编译信息:
D:\源代码source\看雪下载 ws2_32\ws2_32.cpp(23) : error C2199: syntax error : found 'int (' at global scope (was a declaration intended?)
2008-10-6 15:00
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我暂时不上QQ,就在这里说吧,顺便发一下代码把,其实没有技术含量,只要读了看雪上面那个《加密解密第三版》那个样章,大家都能做。。。

VC2005的工程文件,用VC6的,重建一个,把cpp文件导进去就行了

ws2_32.zip
上传的附件:
2008-10-6 15:20
1
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
在开头加入 #include <winsock2.h> 就行了

或者自己定义
typedef
void
(CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE)(
    IN DWORD dwError,
    IN DWORD cbTransferred,
    IN LPWSAOVERLAPPED lpOverlapped,
    IN DWORD dwFlags
    );
2008-10-6 15:33
0
雪    币: 2165
活跃值: (3094)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
再次感谢ICERSG兄,有空加我吧,谢谢.
2008-10-6 16:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
谢谢icersg老大分享代码

高手写的代码和偶的就是不同,学习了
2008-10-6 17:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
[QUOTE=icersg;517302]晕,我写错了,实在是不好意思。

如果可以的话,你可以把变量定义到函数外面。我当时是在Class里面多定义了几个成员变量,用它们存的。

在函数里面定义变量会破坏堆栈,因为这样编译出来,会变成 mov dword ptr [ebp-xx],eax 的形势,而这里刚进来的时候没有 push e...[/QUOTE]

可以提供完整的代码吗?abc125318 AT hotmail.com
我刚才在按你做的在recv里搞了一下
结果抓了包程序就崩溃了
2008-10-10 17:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17

The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.


这个是提示的错误
2008-10-10 18:27
0
雪    币: 293
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
12楼的下载就是完整的代码。我测过,没问题啊。不过我当时只是做学习,只用FlashFXP等软件测过,能记录下来,不过如果你的测试软件通讯量比较大,或者有多线程(像FlashGet,Bitcomet等等),那我就没测过了,我觉得应该会很卡。至于你说的错误提示,你怎么改的recv()?最后用什么软件做的测试?
2008-10-10 19:03
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
我自己又用其他方法注入了
不用汇编啥的。。
效果还不错
这两天整理好发上来
2008-10-10 20:54
0
雪    币: 62
活跃值: (1972)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
请哪位大侠把上面的转成Delphi的.VC看不懂,我也想要一份
2008-10-10 21:38
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
icersg 在吗?有事求你帮助,我的QQ:67361048
2009-1-18 12:58
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
如果程序未加壳的话,反汇编看目标函数的返回指令的操作数就能知道参数的字节数了。
2009-1-24 17:15
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
是个好东西  希望能有人继续,不知道connect()当如何记录,这个代码生成的工具好在做补丁,而做监听记录就麻烦了点
2009-10-7 08:54
0
游客
登录 | 注册 方可回帖
返回
//