|

提醒:若下载的软件是收费的"请不要付款",可能是骗子,请立即联系本站举报,执意要付款被骗后本站概不负责。(任何交易请走第三方中介,请勿直接付款交易以免被骗!切记).
该反 系统是某游戏公司的,只是好奇如有得罪,请谅解及联系版主删除!
1,首先是初始化数据,服务器返回第一包,里面包含即将要调用的dll数据和函数名称,目的是让后面的要调用的
代码作前期初始化工作。每个特殊含义的数据,都有自己的ID,后面根据ID进行解析出正确的fuc。
贴上解析数据,并进行数据解析的函数:复制内容到剪贴板代码:
DWORD _CallRetEax(LPBYTE pData)
{
DWORD dwRetEax = 0xFFFFFFFF;
INT nPox = 0;
CHAR* pRecvBuffer = NULL ;
INT nLen;
RetPoxLen pRetPoxLen;
INT n1stType = 0;
INT n;
INT n1stLen = 0;
INT nLastType = 0;
INT nTypeID = 0;
INT n1stTypeLen = 0;
INT n2scTypeLen = 0;
INT n2sc = 0;
INT nLastSum = 0;
INT nLast = 0;
INT nLastLen = 0;
WORD wInsertId = 0;
CHAR* pCallBuffer= NULL;
DWORD CallAddr;
WORD wFixPox = 0;
WORD wFixId = 0;
WORD wFindFixId = 0;
GS_CHECKPTR(pData);
pRecvBuffer = (CHAR*)(pData);
nPox = 0;
nLen = *(WORD*)(pRecvBuffer + nPox);
nPox += 8;
pRetPoxLen = _RetLen(pRecvBuffer + nPox);
nPox += pRetPoxLen.nPox;
//大类个数
n1stType = pRetPoxLen.nLen;
for (n = 0; n < n1stType ; n++)
{
nLastLen = 0;
pRetPoxLen = _RetLen(pRecvBuffer + nPox);
nPox += pRetPoxLen.nPox;
//大类长度
n1stLen = pRetPoxLen.nLen;
//大类长度
n1stTypeLen = *(WORD*)(pRecvBuffer + nPox);
nLastLen +=2;
n1stTypeLen -= 2;
//ID
nTypeID = *(WORD*)(pRecvBuffer + nPox + nLastLen);
nLastLen +=2;
wInsertId = _FidUseId(nTypeID);
if(wInsertId == 0xFFFF)
{
wInsertId = _FidNoUseId();
}
m_szRetCall[wInsertId].wId = nTypeID;
n1stTypeLen -= 2;
//读法类型
nLastType = *(WORD*)(pRecvBuffer + nPox + nLastLen);
nLastLen +=2;
n1stTypeLen -= 2;
switch(nLastType)
{
case 0://读STRING 初始化API名称+数据
nPox += nLastLen;
memcpy(m_szRetCall[wInsertId].szRetBuffer ,pRecvBuffer + nPox, n1stTypeLen);
m_szRetCall[wInsertId].pRetBuffer = m_szRetCall[wInsertId].szRetBuffer;
nPox += n1stTypeLen;
break;
case 1://DWORD+DWORD 初始化API对应关系
nPox += nLastLen;
m_szRetCall[wInsertId].w1stId = *(WORD*)(pRecvBuffer + nPox);
nPox +=2;
m_szRetCall[wInsertId].w2secId = *(WORD*)(pRecvBuffer + nPox);
nPox +=2;
break;
case 2://开始执行CALL
//nPox += nLastLen;
//dwRetEax = _CallBufferId(nTypeID);
__logger.Trace("RetEax = %p \n", m_pHook->_dwRetvalue);
__logger.Trace("-------------------------------------\n");
__logger.Trace("END\n\n");
__logger.Fflush();
break;
default://对CALL开始修正
//初始化传过来的API
_InitApIDAte();
//开始修正CALL BUFFER
if(nLastLen < nLastType )
{
//读出要修正地方的个数
nLastSum = *(WORD*)(pRecvBuffer + nPox + nLastLen);
nLastLen += 2;
n1stTypeLen -= 2;
//循环读出修改的内容
for(nLast = 0; nLast < nLastSum; nLast++)
{
wFixPox = *(WORD*)(pRecvBuffer + nPox + nLastLen);
nLastLen +=2;
wFixId = *(WORD*)(pRecvBuffer + nPox + nLastLen);
nLastLen +=2;
n1stTypeLen -= 4;
//修改CALL BUFFER的API地址
wFindFixId = _FidUseId(wFixId);
if(wFindFixId != 0xFFFF)
{
//修改为0的地方
if(m_szRetCall[wFindFixId].dwApiAddr != 0)
{
if( *(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0E8)
{
//CALL XXXXX
CallAddr = (DWORD)m_szCallBuffer;
*(DWORD*)(pRecvBuffer + nPox + wFixPox) = (DWORD)(m_szRetCall[wFindFixId].dwApiAddr - CallAddr -(wFixPox - nLastSum*4 - 8) - 4);
__logger.Trace(" ox:%p CALL %s \n",wFixPox - nLastSum*4 - 8, m_szRetCall[_FidUseId(m_szRetCall[wFindFixId].w2secId)].szRetBuffer);
__logger.Fflush();
}else if( *(WORD*)(pRecvBuffer + nPox + wFixPox - 2 ) == 0x15FF)
{
//CALL [XXXXX]
*(DWORD*)(pRecvBuffer + nPox + wFixPox) = (DWORD)&(m_szRetCall[wFindFixId].dwApiAddr);
__logger.Trace(" ox:%p CALL %s \n",wFixPox - nLastSum*4 - 8, m_szRetCall[_FidUseId(m_szRetCall[wFindFixId].w2secId)].szRetBuffer);
__logger.Fflush();
}else if( *(BYTE*)(pRecvBuffer + nPox + wFixPox - 2 ) == 0x8B ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0xA1 )
{
//MOV RB32 , [XXXXX]
*(DWORD*)(pRecvBuffer + nPox + wFixPox) = (DWORD)&(m_szRetCall[wFindFixId].dwApiAddr);
__logger.Trace(" ox:%p MOV RB32, %s \n",wFixPox - nLastSum*4 - 8, m_szRetCall[_FidUseId(m_szRetCall[wFindFixId].w2secId)].szRetBuffer);
__logger.Fflush();
}else if( *(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0B8 ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0B9 ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0BA ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0BB ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0BC ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0BD ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0BE ||
*(BYTE*)(pRecvBuffer + nPox + wFixPox - 1 ) == 0x0BF
)
{
//MOV RB32 , XXXXX
*(DWORD*)(pRecvBuffer + nPox + wFixPox) = (DWORD)&(m_szRetCall[wFindFixId].dwApiAddr);
__logger.Trace(" ox:%p MOV RB32, %p = %p \n",wFixPox - nLastSum*4 - 8, m_szRetCall[_FidUseId(m_szRetCall[wFindFixId].w2secId)].szRetBuffer);
__logger.Fflush();
}
}else
{
//此为读常量,非API地址的情况 (地址的地址)
*(DWORD*)(pRecvBuffer + nPox + wFixPox) = (DWORD)&(m_szRetCall[wFindFixId].pRetBuffer);
__logger.Trace(" ox:%p [%p] = %p \n",wFixPox - nLastSum*4 - 8,m_szRetCall[wFindFixId].szRetBuffer,*(DWORD*)m_szRetCall[wFindFixId].szRetBuffer);
__logger.Fflush();
}
}else
{
__logger.Trace(" ox:%p CALL [addr] = %p \n", wFixPox - nLastSum*4 - 8, wFixId);
__logger.Fflush();
dwRetEax = 0;
return dwRetEax;
}
}
}
//余下为CALL BUFFER
nPox += nLastLen;
ZeroMemory(m_szCallBuffer,sizeof(m_szCallBuffer));
__logger.Trace("\nCallBufferAddr: %p CallBufferLen: %p \n\n", &m_szCallBuffer, n1stTypeLen);
memcpy(m_szCallBuffer ,pRecvBuffer + nPox, n1stTypeLen);
m_szRetCall[wInsertId].pCallBufferAddr = (CHAR*)m_szCallBuffer;
nPox += n1stTypeLen;
break;
}
}
GS_EXIT:;
return dwRetEax;
}2,经过上面的解析后,根据数据进行函数初始化复制内容到剪贴板代码:
void _InitApiDate()
{
HINSTANCE hInstLibrary;
CHAR* cDllName;
CHAR* cApiName;
INT nFindId;
for(INT i = 0;i <= CALL_BUFFER_NO; i++)
{
if( m_szRetCall.wId != 0 &&
m_szRetCall.w1stId != 0 &&
m_szRetCall.dwApiAddr == 0 &&
m_szRetCall.w2secId != 0
)
{
nFindId = _FidUseId(m_szRetCall.w1stId);
cDllName = m_szRetCall[nFindId].szRetBuffer;
hInstLibrary = LoadLibrary(cDllName);
nFindId = _FidUseId(m_szRetCall.w2secId);
cApiName = m_szRetCall[nFindId].szRetBuffer;
m_szRetCall.dwApiAddr = (DWORD)GetProcAddress(hInstLibrary,cApiName);
FreeLibrary(hInstLibrary);
}
}
return;
}3,根据
case 2://开始执行CALL
去调用要执行的函数代码复制内容到剪贴板代码:
INT _CallBufferId(DWORD dwId)
{
CHAR* pCallBuffer;
INT nRet;
DWORD dwFindUseId;
BOOL bRetPortect;
DWORD dwOldType;
pCallBuffer = (CHAR*)m_szCallBuffer;
dwFindUseId = (DWORD)_FidUseId(dwId);
bRetPortect = VirtualProtect(m_szCallBuffer, 8190, PAGE_EXECUTE_READWRITE, &dwOldType);
if(m_szRetCall[dwFindUseId].pCallBufferAddr != 0)
{
__asm
{
pushad
pushfd
mov eax, pCallBuffer
call eax
mov nRet, eax
popfd
popad
}
}
bRetPortect = VirtualProtect(m_szCallBuffer, 8190, dwOldType, &dwOldType);
return nRet;
}这里返回的eax就是反 需要的数据,服务器根据此数据来判断你是否作弊。到此,这反 系统简单流程就是如此了。
专门看了下送来执行的几个函数,发现它们在检查这些数据:
1)代码crc
2)窗体判断
3)hookdll判断
这些都是反 的小功能fuc,当然官方想加什么就加什么,应该非常好diy的,故该游戏的 比较少,也是该系统的功能,
浅析到此为止,如有深入的分析和见解,请发到论坛上来吧 |
联系我时,请说是在 挂海论坛 上看到的,谢谢! |
上一篇: 基础知识入门教学下一篇: 出售审判踢腿REZ源码
免责声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关。一切关于该内容及资源商业行为与www.52ghai.com无关。
2、本站提供的一切资源内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。
3、本站信息来自第三方用户,非本站自制,版权归原作者享有,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
4、如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵犯你版权的,请邮件与我们联系删除(邮箱:xhzlw@foxmail.com),本站将立即改正。
|