|
欢迎您注册加入!这里有您将更精采!
您需要 登录 才可以下载或查看,没有账号?注册
x
标 题: 【原创】ring3下过某游戏的HS保护
作 者: fbbttfbb
时 间: 2012-03-04,12:22:58
链 接: http://bbs.pediy.com/showthread.php?t=147347
声明:本文只为研究技术,如使用本文中的源码及技术产生了侵权或违法行为,本人概不负责。如有侵犯你版权的行为,请联系我,本文将立即改正!
说明:
HS有ring0驱动保护及ring3下保护,这个方法是在不加载驱动下,就轻松过HS游戏保护,是自己这几天研究的成果,现在发表出来.游戏是韩国的名品
[C++] 纯文本查看 复制代码
<1>下载附件中的ehsvc.dll文件替换原来游戏HS目录下的文件
<2>HOOK CreateProcess, CreateFile, NtSetInformationThread
HOOK CreateProcess的目的是让HS的hsupdate.exe(HS更新进程)进程不让起来
BOOL WINAPI Mine_CreateProcessA( LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
CString strtemp= lpCommandLine;
strtemp.MakeLower();
if(strtemp.Find("hsupdate.exe") !=-1)
return FALSE;
BOOL bret = FALSE;
g_hook_CreateProcessA.UnHook();
bret = CreateProcessA( lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
g_hook_CreateProcessA.Hook();
return bret;
}
BOOL WINAPI Mine_CreateProcessW( LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
USES_CONVERSION;
CString strtemp=W2A(lpCommandLine);
strtemp.MakeLower();
if(strtemp.Find("hsupdate.exe") !=-1)
return FALSE;
BOOL bret=FALSE;
g_hook_CreateProcessW.UnHook();
bret = CreateProcessW( lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
g_hook_CreateProcessW.Hook();
return bret;
}
HOOK CreateFile的目的是让EagleXNt.sys(HS驱动)不起来
HANDLE WINAPI Mine_CreateFileA(LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
int pos = string(lpFileName).find("EagleXNt");
if(pos!=-1)
return NULL;
HANDLE hhh = NULL;
g_hook_CreateFileA.UnHook();
hhh = CreateFileA(lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile
);
g_hook_CreateFileA.Hook();
return hhh;
}
HANDLE WINAPI Mine_CreateFileW(LPCWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
int pos = wstring(lpFileName).find(L"EagleXNt");
if(pos!=-1)
return NULL;
HANDLE hhh = NULL;
g_hook_CreateFileW.UnHook();
hhh = CreateFileW(lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile
);
g_hook_CreateFileW.Hook();
return hhh;
}
HOOK NtSetInformationThread的目的是让线程可以调试
DWORD WINAPI Mine_NtSetInformationThread(
HANDLE hThread,
DWORD ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength
)
{
if (ThreadInformationClass == 17)
{
//HideFromDebugger
return 1;
}
DWORD hhh = NULL;
g_hook_NtSetInformationThread.UnHook();
hhh = NtSetInformationThread(hThread,
ThreadInformationClass,
ThreadInformation,
ThreadInformationLength);
g_hook_NtSetInformationThread.Hook();
return hhh;
}
<3>暂停HS ring3下的保护线程
暂停HS ring3下的保护线程这里需要注意,只有在游戏启动后,进入游戏画面或者登陆画面,HS ring3下的保护线程才起来然后就暂停,这里在线程里处理
unsigned WINAPI threadproc(LPVOID lpparam)
{
g_stopthread = 0;
BOOL Bretsus = FALSE;
//等待35秒, 只有在游戏启动后,进入游戏画面或者登陆画面,HS ring3下的保护线程才//起来然后就暂停
Sleep(35000);
DWORD pid = GetCurrentProcessId();
HANDLE h = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid);
THREADENTRY32 te;
te.dwSize = sizeof (te);
if(Thread32First (h, &te))
{
do
{
Bretsus = SuspendHsThread(te.th32ThreadID, pid );
}while (Thread32Next (h, &te));
};
CloseHandle(h);
_endthreadex( 0 );
return 0;
}
BOOL SuspendHsThread (DWORD tid ,DWORD dwpid)
{
THREAD_BASIC_INFORMATION tbi;
PVOID startaddr;
LONG status;
HANDLE thread, process;
thread = ::OpenThread (THREAD_ALL_ACCESS, FALSE, tid);
if (thread == NULL)
return FALSE;
status = ZwQueryInformationThread (thread,
ThreadQuerySetWin32StartAddress,
&startaddr,
sizeof (startaddr),
NULL);
if (status < 0)
{
CloseHandle (thread);
SetLastError (RtlNtStatusToDosError (status));
return FALSE;
};
// _tprintf (TEXT ("线程 %08x 的起始地址为 %p/n"),
// tid,
// startaddr);
status = ZwQueryInformationThread (thread,
ThreadBasicInformation,
&tbi,
sizeof (tbi),
NULL);
if (status < 0)
{
CloseHandle (thread);
SetLastError (RtlNtStatusToDosError (status));
return FALSE;
};
// _tprintf (TEXT ("线程 %08x 所在进程ID为 %08x/n"),
// tid,
// (DWORD)tbi.ClientId.UniqueProcess);
if(dwpid==(DWORD)tbi.ClientId.UniqueProcess)
{
process = ::OpenProcess (PROCESS_ALL_ACCESS,
FALSE,
(DWORD)tbi.ClientId.UniqueProcess);
if (process == NULL)
{
DWORD error = ::GetLastError ();
CloseHandle (thread);
SetLastError (error);
return FALSE;
};
TCHAR modname [0x100];
GetModuleFileNameEx(process, NULL, modname, 0x100);
// _tprintf (TEXT ("线程 %08x 所在进程映象为 %s/n"),
// tid,
// modname);
GetMappedFileName(process,
startaddr,
modname,
0x100);
// _tprintf (TEXT ("线程 %08x 可执行代码所在模块为 %s\n"),
// tid,
// modname);
CString strte = modname;
if(strte.Find("ehsvc.dll")!=-1)
{
//找到HS线程,暂停
SuspendThread(thread);
return TRUE;
}
CloseHandle (process);
}
CloseHandle (thread);
return FALSE;
};
<4>把以上代码封装成DLL然后注入到游戏进程
<5>DLL可能用到的其它数据结构
typedef DWORD (WINAPI *PNtSetInformationThread)(HANDLE hThread,
DWORD ThreadInformationClass,
PVOID ThreadInformation,
ULONG ThreadInformationLength
);
PNtSetInformationThread NtSetInformationThread=NULL;
typedef enum _THREADINFOCLASS {
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
MaxThreadInfoClass
} THREADINFOCLASS;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION { // Information Class 0
LONG ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
LONG AffinityMask;
LONG Priority;
LONG BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
extern "C" LONG (__stdcall *ZwQueryInformationThread) (
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
) = NULL;
extern "C" LONG (__stdcall *RtlNtStatusToDosError) (
IN ULONG status) = NULL;
<6>有错别字或者表达不清楚请见谅
|
|