⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 allmycode.cpp

📁 让传奇3服务端支持动态域名的插件。VS2005的工程。这个是DBSER的插件。要和LOGINSER插件一起使用。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "AllMyInclude.h"

CString	CDomainName;
BOOL		CDomainName_SaveFlag = true;//默认需要获得IP并修改
DWORD		GameGateIP_ExchangeFlag = 0;//gate1ip ga2ip 交换标志
DWORD		GameGateIP_WriteFlag = 0;//gate1ip ga2ip 交换标志
static  LPSTR lpDomainNameESI = NULL;
static	LPSTR	lpClientIP = NULL;
static	CString	CClientIP;
HANDLE	Write_Mutex = NULL;

void	GetClientIP()//没有使用
{
	__asm
	{
		mov lpClientIP, ebx;//获得客户端IP地址
	}
	TCHAR	TClientIP[16] = {0};
	CharToWchar( TClientIP, lpClientIP);
	CClientIP.Empty();
	CClientIP.Format( _T("%s"),TClientIP );
}

void GetDomainNameAddr()
{
	__asm
	{
		mov lpDomainNameESI,ebx;//获得原始地址
	}
	lpDomainNameESI -= 0x1BA28;//获得ESI基地址
	//gameser ip = esi+0x1ba28
	//gate ip 1 = esi +0x1ba48
	//gate port 1 = esi +0x1ba68
	//gate ip 2 = esi +0x1ba6c
	//gate port 2 = esi + 0x1ba8c
}


void	CallWaitMutex()//调用等待互斥对象 必须在使用全局变量前 调用高函数
{
	::WaitForSingleObject( Write_Mutex, 100 );//等待其他线程访问完成
}
void	ReleaseExMutex()//释放  必须在使用完全局变量以后调用该函数
{
  ::ReleaseMutex( Write_Mutex );//释放互斥对象以便于其他线程访问
}

void DomainToIP()//域名转IP
{
	DWORD	GameGate_One_Migration = NULL;
	DWORD	GameGate_Two_Migration = NULL;
	CString SelGateIP;
	char lpSelGateIP[32] = {0};

	CallWaitMutex();
	if( GameGateIP_ExchangeFlag % 2 )//防止无有效用户登陆情况下内外网均无法登陆
	{
		GameGate_One_Migration = 0x1ba48;
		GameGate_Two_Migration = 0x1ba6c;
		GameGateIP_WriteFlag ++;
	}
	else
	{
		GameGate_One_Migration = 0x1ba6c;
		GameGate_Two_Migration = 0x1ba48;
		GameGateIP_WriteFlag ++;
	}
  //------------------------------------
	if(lpDomainNameESI != NULL)
	{
		//CNowDomainName = _T("nuzero.xicp.net");
		TCHAR TlpDomainName[32] = {0};
		if( CDomainName_SaveFlag )
		{
			CharToWchar( TlpDomainName, lpDomainNameESI + 0x1ba48 );
			CDomainName.Empty();
			CDomainName.Format(_T("%s"), TlpDomainName);
			CDomainName_SaveFlag = false;
		}

  //------------------------------------------------------------------
		if( GameGateIP_WriteFlag%2 )
		{
			if( HostToIP(  CDomainName, &SelGateIP ) )
			{
				//-------------------------------------------------------------------
				//WcharToChar( SelGateIP.AllocSysString(), lpSelGateIP );
				//
				// 修改SELGATE IP
				TCHAR IPWChar[32];
				CharToWchar( IPWChar, (lpDomainNameESI+GameGate_One_Migration) );
				CString OldIP = IPWChar;
			
				OldIP.Trim();
				SelGateIP.Trim();
				//------------------------
				if( SelGateIP.Compare( OldIP ) != NULL )//不相同
				{
					size_t DomainName_len = strlen(lpDomainNameESI+GameGate_One_Migration);
					//目标内存清空
					ZeroMemory((LPVOID)(lpDomainNameESI+GameGate_One_Migration), IP_LEN );
					//memcpy_s( (LPVOID)(lpDomainNameESI+GameGate_One_Migration), IP_LEN ,lpSelGateIP, strlen(lpSelGateIP) );//复制内存到目标地址
					WcharToChar( SelGateIP.AllocSysString(), lpDomainNameESI+GameGate_One_Migration );
				}
			}
			SelGateIP.Empty();
			if( LocalHostToIP( &SelGateIP ))
			{
				//-------------------------------------------------------------------
				//WcharToChar( SelGateIP.AllocSysString(), lpSelGateIP );
				//
				// 修改SELGATE IP
				TCHAR IPWChar[32];
				CharToWchar( IPWChar, (lpDomainNameESI + GameGate_Two_Migration) );
				CString OldIP = IPWChar;

				OldIP.Trim();
				SelGateIP.Trim();
				//------------------------
				if( SelGateIP.Compare( OldIP ) != NULL )//不相同
				{
					size_t DomainName_len = strlen(lpDomainNameESI + GameGate_Two_Migration);
					//目标内存清空
					ZeroMemory((LPVOID)(lpDomainNameESI + GameGate_Two_Migration), IP_LEN );
					//memcpy_s( (LPVOID)(lpDomainNameESI + GameGate_Two_Migration), IP_LEN ,lpSelGateIP, strlen(lpSelGateIP) );//复制内存到目标地址
					WcharToChar( SelGateIP.AllocSysString(), lpDomainNameESI+GameGate_Two_Migration );
				}
			}
			SelGateIP.Empty();
			
			GameGateIP_ExchangeFlag++;
		}
	}
	ReleaseExMutex();
}


//在宿主程序中的任意代码处插入调用我们DLL中函数的代码
DWORD DetourGameEbx( DWORD targetCodeAddress, DWORD targetCodeLength, DWORD ourFunctionAddress )//,int Flag = false)//需要自动还原代码为FALSE,否则为true
{
    // 目标处代码长度小于 5 则太短不足以填充跳转代码
    if ( targetCodeLength < 5 )
        return 0x01;//代码太小

    //
    // 修改权限, 分配相关资源
    //
    DWORD oldAttr = 0, tmpAttr = 0, tmpIdx = 0;

    // 修改目标代码区权限为可执行可读写
    if ( !VirtualProtect( (void *)(DWORD_PTR)targetCodeAddress, targetCodeLength, PAGE_EXECUTE_READWRITE, &oldAttr ) )
	{
		MessageBox(NULL, _T("内存权限设置失败!"),_T("提示"),NULL);
        return 0x02;
	}

	BYTE *backupCode;
		// 在堆上分配内存用以备份原目标代码
		backupCode = new BYTE[ targetCodeLength ];
		if ( backupCode == NULL )
			return 0x03;

    // 在堆上分配内存用以存放构造的跳转代码
    BYTE *jumpCode = new BYTE[ targetCodeLength ];
    if ( jumpCode == NULL )
    {
        delete[] backupCode;
        return 0x04;
    }

    // 在堆上分配内存用以存放构造的"门"代码, 并修改其权限为可执行可读写
    BYTE *gatewayCode = new BYTE[ (targetCodeLength*2) + 12 +2 ];
    if ( gatewayCode == NULL )
    {
        delete[] backupCode;
        delete[] jumpCode;

        return 0x05;
    }
    if ( !VirtualProtect( (void *)gatewayCode, targetCodeLength + 12, PAGE_EXECUTE_READWRITE, &tmpAttr ) )
    {
        delete[] backupCode;
        delete[] jumpCode;
        delete[] gatewayCode;

        return 0x06;
    }

		//
		// 备份原目标代码
		//   
		memcpy( (void *)backupCode, (const void *)(DWORD_PTR)targetCodeAddress, targetCodeLength );
    //
    // 构造跳转代码, 覆盖到目标处代码处, 使其转到我们构造的"门"代码处
    //
    jumpCode[0] = 0xE9;//E8 CALL E9 JMP,原始E8
    *(PDWORD)( jumpCode + 1 ) = \
		(DWORD)(DWORD_PTR)(&(*gatewayCode)) - targetCodeAddress - 5;

    // 将多余字节填充为 nop
    DWORD tmp = 5;
    while ( tmp < targetCodeLength )
        jumpCode[ tmp++ ] = 0x90;

    memcpy( (void *)(DWORD_PTR)targetCodeAddress, (const void *)jumpCode, targetCodeLength );

    //
    // 构造"门"代码, 维护宿主程序现场并调用 ourFuncitonAddr
    //
		gatewayCode[0] = 0x60;
		memcpy( (void *)(gatewayCode+1), backupCode, targetCodeLength );
		gatewayCode[1+targetCodeLength] = 0x8B;
		gatewayCode[2+targetCodeLength] = 0xD8;
		gatewayCode[3+targetCodeLength] = 0xE8;
		*(PDWORD)(gatewayCode+4+targetCodeLength) = ourFunctionAddress - (DWORD)(DWORD_PTR)(&(*gatewayCode)) - 1 - 1 - 4 - targetCodeLength - 2;
		gatewayCode[8+targetCodeLength] = 0x61;
	
		memcpy( (void *)(gatewayCode+9+targetCodeLength), backupCode, targetCodeLength );
	    gatewayCode[ 9 + (targetCodeLength*2) ] = 0xE9;
		*(PDWORD)( gatewayCode + 9 + (targetCodeLength*2) + 1 )
			= targetCodeAddress + targetCodeLength - (DWORD)(DWORD_PTR)(&(*gatewayCode)) - 7 - (targetCodeLength*2) - 1 - 4 -2;
      
    //
    // 恢复权限, 释放相关资源
    //
    // 注意, 这里释放 backupCode, jumpCode, 不释放 gatewayCode
    // gatewayCode 在我们的目的上生命期相当于静态变量, 所以不用删除, 程
    // 序退出时操作系统会将其释放
    //
    VirtualProtect( (void *)(DWORD_PTR)targetCodeAddress, targetCodeLength, oldAttr, &tmpAttr );
   
	delete[] backupCode;
    delete[] jumpCode;

    return 0xff;
}

DWORD DetourGame( DWORD targetCodeAddress, DWORD targetCodeLength, DWORD ourFunctionAddress )//,int Flag = false)//需要自动还原代码为FALSE,否则为true
{
    // 目标处代码长度小于 5 则太短不足以填充跳转代码
    if ( targetCodeLength < 5 )
        return 0x01;//代码太小

    //
    // 修改权限, 分配相关资源
    //
    DWORD oldAttr = 0, tmpAttr = 0, tmpIdx = 0;

    // 修改目标代码区权限为可执行可读写
    if ( !VirtualProtect( (void *)(DWORD_PTR)targetCodeAddress, targetCodeLength, PAGE_EXECUTE_READWRITE, &oldAttr ) )
	{
		MessageBox(NULL, _T("内存权限设置失败!"),_T("提示"),NULL);
        return 0x02;
	}

	BYTE *backupCode;
		// 在堆上分配内存用以备份原目标代码
		backupCode = new BYTE[ targetCodeLength ];
		if ( backupCode == NULL )
			return 0x03;

    // 在堆上分配内存用以存放构造的跳转代码
    BYTE *jumpCode = new BYTE[ targetCodeLength ];
    if ( jumpCode == NULL )
    {
        delete[] backupCode;
        return 0x04;
    }

    // 在堆上分配内存用以存放构造的"门"代码, 并修改其权限为可执行可读写
    BYTE *gatewayCode = new BYTE[ targetCodeLength + 12 ];
    if ( gatewayCode == NULL )
    {
        delete[] backupCode;
        delete[] jumpCode;

        return 0x05;
    }
    if ( !VirtualProtect( (void *)gatewayCode, targetCodeLength + 12, PAGE_EXECUTE_READWRITE, &tmpAttr ) )
    {
        delete[] backupCode;
        delete[] jumpCode;
        delete[] gatewayCode;

        return 0x06;
    }

		//
		// 备份原目标代码
		//   
		memcpy( (void *)backupCode, (const void *)(DWORD_PTR)targetCodeAddress, targetCodeLength );
    //
    // 构造跳转代码, 覆盖到目标处代码处, 使其转到我们构造的"门"代码处
    //
    jumpCode[0] = 0xE9;//E8 CALL E9 JMP,原始E8
    *(PDWORD)( jumpCode + 1 ) = \
		(DWORD)(DWORD_PTR)(&(*gatewayCode)) - targetCodeAddress - 5;

    // 将多余字节填充为 nop
    DWORD tmp = 5;
    while ( tmp < targetCodeLength )
        jumpCode[ tmp++ ] = 0x90;

    memcpy( (void *)(DWORD_PTR)targetCodeAddress, (const void *)jumpCode, targetCodeLength );

    //
    // 构造"门"代码, 维护宿主程序现场并调用 ourFuncitonAddr
    //
		gatewayCode[0] = 0x60;
		gatewayCode[1] = 0xE8;
		*(PDWORD)(gatewayCode+2) = ourFunctionAddress - (DWORD)(DWORD_PTR)(&(*gatewayCode)) - 1 - 1 - 4;
		gatewayCode[6] = 0x61;
	
		memcpy( (void *)(gatewayCode+7), backupCode, targetCodeLength );
	    gatewayCode[ 7 + targetCodeLength ] = 0xE9;
		*(PDWORD)( gatewayCode + 7 + targetCodeLength + 1 )
			= targetCodeAddress + targetCodeLength - (DWORD)(DWORD_PTR)(&(*gatewayCode)) - 7 - targetCodeLength - 1 - 4;
      
    //
    // 恢复权限, 释放相关资源
    //
    // 注意, 这里释放 backupCode, jumpCode, 不释放 gatewayCode
    // gatewayCode 在我们的目的上生命期相当于静态变量, 所以不用删除, 程
    // 序退出时操作系统会将其释放
    //
    VirtualProtect( (void *)(DWORD_PTR)targetCodeAddress, targetCodeLength, oldAttr, &tmpAttr );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -