BYTE *temp = (BYTE*)date;
for (int i = 0; i < length; i )
{
astemp1.cat_sprintf("%0.2x ", temp);
}
astemp1.cat_sprintf("][");
for(int i=0;i<length;i )
if(temp>=0x20)
astemp1.cat_sprintf("%c",temp);
else
astemp1.cat_sprintf(".");
astemp1.cat_sprintf("]");
Memo1->Lines->Add(astemp1);
break;
}
}
上面就是全部了,对于发送的命令拦截,和接收的类似,可以自己分析。在前几节教程中我已经将打补丁的注意点说了一遍,这里就不再说了。对于9.16之后的程序,我只做了很少的研究,主要是因为没有大量的时间和心情来做这些事情,这里仅仅给一点初步的提示:
1、 对于发送的数据,有些部分可能会采用二次加密的办法。
2、 对于接收的数据,程序为了增加调试的难度,将数据转换成浮点数之后不断的进行地址的变换和数据的转移。
3、 程序将接收和发送放入了一个线程中(这个可能,因为9.16之后比9.16之前多了一个线程)。
4、 数据采用浮点数存储,加密过程中有可能转换成浮点数,但加密完之后又会转换成浮点数,直到最后的时候才会转换成整数发送。
由于大话程序内部进行了非常大量的浮点和整数的转换,因此现在的大话程序是非常的耗费CPU资源的。以下面的代码来说:
Int I;
Float k=(float)I;//利用浮点数寄存器,这个用的时间很短
I=(int)k;//在编译器编译的时候,会用自己的浮点整型转换,而不是数学协处理器进行转换,这个转换大概比使用浮点寄存器转换慢12—60倍左右或者更多。使用ida4.7可以看到反编译之后调用了库函数_ftol。慢的原因是因为库函数是为数学计算进行的,而不是为了游戏中的效率而设计的。这是9.16之后大话变得卡的主要原因。
对于9.16之后的程序,也可以进行相同的处理,只是在调试的时侯对于代码地址的查找比较麻烦。如果不喜欢自己来写代码数组的话,可以自己根据PE文件来写个代码补丁工具。这个我就不讲了,事实上,我自己也没有写,时间不足是一方面,人懒是没办法的。
在前面APIHOOK一节(教程三)中,我的API类有点错误,这里更正一下:
在APIHOOK.h中
private:
pfnOrig,PROC pfnHook,BOOL fExcludeAPIHookMod);
void WINAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,PROC pfnOrig,PROC pfnHook,HMODULE hmodcaller,HANDLE handle);
void WINAPI FixupNewlyLoadedModule(HMODULE hmod,DWORD dwFlags);
应该改为:
private:
//pfnOrig,PROC pfnHook,BOOL fExcludeAPIHookMod);这个是没有删除干净的注释
void WINAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,PROC pfnOrig,PROC pfnHook,HMODULE hmodcaller,HANDLE handle);
void WINAPI FixupNewlyLoadedModule(HMODULE hmod,DWORD dwFlags);
APIHOOK.cpp中:
m_module = GetModuleHandle(pszCalleeModName);
ReplaceIATEntryInOneMod(m_pszCalleeModName, m_pfnOrig, m_pfnHook, m_module,prochandle);
应该修改为:
m_module = hmod;
ReplaceIATEntryInOneMod(m_pszCalleeModName, m_pfnOrig, m_pfnHook, m_module,prochandle);