本帖最后由 592618243 于 2020-8-10 16:22 编辑
回顾一下前文提到的东西
游戏主要检测分为5大块
- 1.CALL检测 ->由TenRpcs负责
- 2.文件及内存检测 - > 由TCJ负责
- 3.客户行为游戏数据检测以及本地封包加密解密发送回传 - > 由GameRpcs负责
- 4.本地机器码查询 - > 由PolicyProbe负责
- 5.调试游戏等保护 -> 由TerSafe负责
我们需要处理的东西是1.2.3机器码解决办法是 老办法 钩住 LoadLibraryExW 让 PolicyProbe 不在载入列表里即可过掉机器码检测TerSafe 我们不做处理,没有必要
接下来我们编写一个注入到游戏大厅的DLL,然后转换成ShellCode,为了安全起见,先要把大厅的保护干掉代码如下
VOID 干游戏大厅检测() //稳妥起见还是要干掉把
{
INT 判断计次 = NULL;
BYTE 判断字节 = NULL;
DWORD 临时变量 = NULL;
DWORD 修改前的页面保护属性 = NULL;
ULONG32 模块地址 = NULL;
do
{
模块地址 = ULONG32(GetModuleHandle("TenRpcs.dll"));
} while (!模块地址);
do
{
RtlCopyMemory(&判断字节, LPVOID(模块地址 + /*此处地址屏蔽*/), sizeof(判断字节));
} while (判断字节 != 0x68);
临时变量 = /*此处地址屏蔽*/;
BYTE TenRpcs检测点1[] = { 0xE9, 0x60, 0x06, 0x00, 0x00, };
if (VirtualProtect(LPVOID(模块地址 + 临时变量), sizeof(TenRpcs检测点1), PAGE_EXECUTE_READWRITE, &修改前的页面保护属性))
{
RtlCopyMemory(LPVOID(模块地址 + 临时变量), &TenRpcs检测点1, sizeof(TenRpcs检测点1));
if (VirtualProtect(LPVOID(模块地址 + 临时变量), sizeof(TenRpcs检测点1), PAGE_EXECUTE, &修改前的页面保护属性))
{
RtlZeroMemory(TenRpcs检测点1, sizeof(TenRpcs检测点1));
}
}
CloseHandle(保护检测线程句柄);
}
干掉这个检测点之后 游戏大厅的保护系统就崩溃了,包括TerSafe,所有检测不会初始化,不知道大厅检测什么,为了安全起见还是干掉把
一定要在第一时间注入,否则保护初始化完成就没机会了
VOID 等待游戏()
{
INT 对局计次 = 1;
HWND 窗口句柄 = NULL;
DWORD 游戏进程ID = NULL;
ULONG32 模块句柄 = NULL;
INT 文字颜色[4] = { FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY };
do
{
Sleep(100);
窗口句柄 = FindWindow("RCLIENT", "League of Legends");
} while (!窗口句柄);
AllocConsole();
srand((int)time(0));
freopen("conout$", "w", stdout);
CONSOLE_CURSOR_INFO Cursor_info = { 1, 0 };
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 文字颜色[rand() % 3 + 1]);
//DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
JMP1:
std::cout << std::endl;
std::cout << "[+] 正在等待游戏对局中" << std::endl;
do
{
Sleep(10);
游戏进程ID = GetPID("League of Legends.exe");
} while (!游戏进程ID);
if (内存注入远程线程DLL(游戏进程ID, hexData1, sizeof(hexData1)))
{
if (内存注入远程线程DLL(游戏进程ID, hexData2, sizeof(hexData2)))
std::cout << "[+] 第" << 对局计次 << "场游戏对局已开始" << std::endl;
}
do
{
Sleep(100);
游戏进程ID = GetPID("League of Legends.exe");
} while (游戏进程ID);
对局计次++;
goto JMP1;
}
注入之后执行我们的循环代码,判断游戏是否启动
启动后第一时间注入我们的 ShellCode 并执行
DLL转ShellCode用010Editor即可
初步尝试1:抹掉TCJTCJ模块加载失败后,游戏正常运行5分钟后自动退出,上一篇文章说到是GameRpcs的问题然后尝试方案2
初步尝试2:抹掉GameRpcs+TCJ 正常游戏,不会掉线,大概打了3-4局之后,被服务器断开链接,封7天
初步尝试3:正常加载 GameRpcs+TCJ 在TCJ线程入口处返回Error游戏正常运行,7分钟左右掉线,打完一局掉5次线,和尝试1没有太大区别,检测处理0状态,笔者难受的打了5局,不会封7天也不会封三年,但是太难受
再次尝试4:改TCJ线程里的Sleep,Push 64 Push1470 等这些参数游戏正常运行,不会掉线,三年,说明了还是检测到了外挂,于是我把参数范围扩大到四字节,Sleep(1000000000)例如这样,笔者脑子坏掉了,开始这样做的时候想没有通讯肯定会7天,事实证明了我脑子进水了,的确是7天,没有必要做这个举动
到这里,我静下心来想,有没有一个完美的办法,既能让TCJ检测不到外挂特征,又能正常的与GameRpcs通讯呢
可行的办法1. 钩住所有TCJ调用的重要的Fun包括
笔者检查了一下,他的导入全都是外挂检测相关,如果要一个一个去处理,那我的工作量太大了,没有半个月一个月弄不完
然后又想有没有什么简单的方法,想想想了一晚上,最后想出了一个办法,详情请看第三篇。
第三篇也有坛友发出来了,有感兴趣的朋友可以借鉴一下。
再补充一下第三篇的一些问题:
GameRpcs里面的双crc是怎么个找法:需要注意的是rpcs里就一个!第二个动态CRC不要再rpcs里找第,找第二个的话 你需要在 virtualalloc 挂个钩子 接获他 virtualalloc返回的地址 然后 剩下的自由发挥吧。
特别感谢:苏苏苏苏苏苏 大神共享的方法跟提供的思路。
最后说一下,昨天发出来就被一顿狂喷,本来是看我们论坛没有的,觉得可能会有人需要或者了解所以才发的并不是为了贪图那些什么热心值 吾爱币。在论坛五年了 要水帖的话我早就发那些有的没的了没必要等到现在。
原本计划是想后续讲解一下FPS类魔术子弹等等的原理实现方法 以及 BE VAC EAC 检测的分析跟绕过思路的,不过感觉没必要了。就这样吧。 |