看流星社区

 找回密码
 注册账号
查看: 1825|回复: 0

TX游戏多开分析

[复制链接]

该用户从未签到

发表于 2017-6-1 17:20:57 | 显示全部楼层 |阅读模式
标 题: 【原创】TX游戏多开分析
作 者: 毁灭
时 间: 2013-04-08,15:06:23
链 接: http://bbs.pediy.com/showthread.php?t=167848

作者:Tiany
QQ:304400230
花了10多天研究过XX的多开研究分析出一些东西可是也被卡住了遇到瓶颈搞的郁闷了把我分析到的东西和大家分享一下吧

大家都知道一般多开检测都是一些互斥体信号量这些内核对象当然TX也不例外他也会对这些对象有检测当然还有其他的检测但是关键的代码都被VM了所以想逆的难度就相当的大(对我而言)所以我们必须要想些其他的方法



一般而言这些内核对象为了要个多个进程访问所以都有Name因为我们不好断定程序使用了1个或几个内核对象来对比判断所以这里我用的方法是InlineHookZwCreateMutexZwCreateEvent
ZwCreateSectionZwCreateSemaphore....这些函数检测一下如果Name不为空的话我们都让他的名字改变一下达到每个进程创建的内核对象都变形

这里为什么要HOOKZw开头的函数我解释一下因为CreateMutexA调用CreateMutexW然后调用ntdll.dll-ZwCreateMutex函数继续就到内核nt!ZwCreateMutexA
(ntdll.dll-ZwCreateMutex和ntdll.dll-NtCreateMutex)的导出地址是一样的


Code:

HMODULEhNTDLL=LoadLibrary("ntdll.dll");
if(!hNTDLL)
{
OutputDebugStringA("[TEN][DLL]加载ntdll.dll失败\n");
returnTRUE;
}

//NtCreateEvent
InlineHook((__pfnNtCreateEvent)(LPVOID)GetProcAddress(hNTDLL,"NtCreateEvent"),
OnNtCreateEvent,
(void**)&pfnNtCreateEvent);
[/code]

回调函数:



Code:
NTSTATUS
NTAPI
OnNtCreateEvent(
OUTPHANDLEEventHandle,
INACCESS_MASKDesiredAccess,
INPOBJECT_ATTRIBUTESObjectAttributesOPTIONAL,
INEVENT_TYPEEventType,
INBOOLEANInitialState)
{
NTSTATUSnRet;


if(ObjectAttributes&&ObjectAttributes->ObjectName&&ObjectAttributes->ObjectName->Buffer)
{
WCHARlpTemp[MAX_PATH];
ZeroMemory(lpTemp,MAX_PATH);
wsprintfW(lpTemp,L"[Ten][DLL]%lS%08X",ObjectAttributes->ObjectName->Buffer,GetCurrentProcessId());
OutputDebugStringW(ObjectAttributes->ObjectName->Buffer);
pfnRtlInitUnicodeString(ObjectAttributes->ObjectName,lpTemp);
}
nRet=pfnNtCreateEvent(
EventHandle,
DesiredAccess,
ObjectAttributes,
EventType,
InitialState
);

returnnRet;
}
[/code]



其他的函数都一样处理

我们看看效果





搞完这里只是基本工作我们运行发现还是运行不要了说明了还有其他地方检测经过我细心的观察发现一个内核对象很可疑





这个Event并未被处理他的Name也不固定反正重启过也都会变可是他为什么没有进到我们的回调函数里呢?这就是TX猥琐之处他重新加载Ntdll.dll然后执行创建对象

这个时候我们只能到更深层的ntdll.KiFastSystemCall地方去看看他是在那里调用的
(Zw函数都会调用ntdll.KiFastSystemCall来跳转到内核)




定位到这里反复跟踪后可以了解他首先打开Ntdll.dll然后读取数据到内存然后开辟内存空间来执行创建内核对象的代码

这里我用的方法就是InlineHookCreateFile函数判断如果打开的是Ntdll.dll就让他打开我实现处理好HOOK的Ntdll.dllTen文件让他继续跳到我们的回调函数去创建内核对象

上代码


Code:
//新建Ntdll.dll
BOOLCreateNtdll(LPBYTENewCode,DWORDlen)
{
PBYTEszBuffer=NULL;
BYTEszSearCode[]={0xB8,0x23,0x00,0x00,0x00,0xBA,0x00,0x03,0xFE,0x7F,0xFF,0x12,0xC2,0x14,0x00};
DWORDdwSize,lpSize;
HANDLEhFile=CreateFileA("C:\\WINDOWS\\system32\\ntdll.dll",
GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
returnFALSE;
}
dwSize=GetFileSize(hFile,NULL);
szBuffer=newBYTE[dwSize];
ReadFile(hFile,szBuffer,dwSize,&lpSize,NULL);
CloseHandle(hFile);

//特征码搜索
LPBYTEpCode=SearchFeature(szBuffer,dwSize,szSearCode,sizeof(szSearCode));
if(pCode==NULL)
{
deleteszBuffer;
returnFALSE;
}
//替换操作
memcpy(pCode,NewCode,len);

hFile=CreateFileA("C:\\WINDOWS\\system32\\ntdll.dllTen",GENERIC_WRITE,FILE_SHARE_WRITE,
NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
deleteszBuffer;
returnFALSE;
}

WriteFile(hFile,szBuffer,dwSize,&lpSize,NULL);
CloseHandle(hFile);
deleteszBuffer;
returnTRUE;
}
[/code]


CreateFile回调函数


Code:
NTSTATUS
NTAPI
OnNtCreateFile(
OUTPHANDLEFileHandle,
INACCESS_MASKDesiredAccess,
INPOBJECT_ATTRIBUTESObjectAttributes,
OUTPIO_STATUS_BLOCKIoStatusBlock,
INPLARGE_INTEGERAllocationSizeOPTIONAL,
INULONGFileAttributes,
INULONGShareAccess,
INULONGCreateDisposition,
INULONGCreateOptions,
INPVOIDEaBufferOPTIONAL,
INULONGEaLength)
{
NTSTATUSnRet;

if(ObjectAttributes&&ObjectAttributes->ObjectName&&ObjectAttributes->ObjectName->Buffer)
{
if(wcsstr(ObjectAttributes->ObjectName->Buffer,L"ntdll.dll"))
{
WCHARlpTemp[MAX_PATH];
ZeroMemory(lpTemp,MAX_PATH);
wsprintfW(lpTemp,L"%lSTen",ObjectAttributes->ObjectName->Buffer);
pfnRtlInitUnicodeString(ObjectAttributes->ObjectName,lpTemp);
OutputDebugStringW(ObjectAttributes->ObjectName->Buffer);
}
}

nRet=pfnNtCreateFile(
FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength
);

returnnRet;
}
[/code]


经过以上的处理后我们可以看到内核对象很多都已经让我们更名换姓了
当然如果不放心也可以在ZwOpen*****函数也进行HOOK让他如果用打开的时候也访问到是我们创建的内核对象处理的方法一样可惜的是程序肯定还有其他的检测我也尝试处理了CreateToolhelp32SnapshotProcess32FirstProcess32Next进程遍历的函数也没能绕过想不出解决的办法故把分析的东西都公布如果大家想一起研究或发现什么新的东西大家可以论坛PM我一起研究*转载请注明来自看雪论坛@PEdiy.com





Attached Images
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 11:31

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表