我爱萨其马虞co 发表于 2024-3-6 09:24:24

过QQ游戏大厅的SX保护附源代码

早些时间看的教程,写过qq游戏练练看的挂,那时候CE附加QQ游戏大厅的时候貌似是没有任何保护的,昨天舍友让做个斗地主的记牌器,但是,我用CE附加的时候,被检测到了,其实不附加也会被检测,所以猜测可能只是检测窗口进程或是模块名称啥的吧,被检测到的时候主程序会退出,但是那个对话框还在,就是那个SX什么什么的,所以如果是QQgame启动了某个线程来检测非法的话,在主程序退出其他线程对象都释放掉的时候,那个检测的线程对象还是存在的(提示SX非法的对话框别关掉!)。借助pt很容易就找到了这个线程。


#include "stdafx.h"   
#include "windows.h"   
#include "TlHelp32.h"   
const TCHAR QQ_GAME[] = _T("QQGame.exe");
const TCHAR QQ_THREAD_DLL[] = _T("TenSLX.dll");

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 LONG (__stdcall *_pfnZwQueryInformationThread) (
    IN   HANDLE   ThreadHandle,   
    IN   THREADINFOCLASS   ThreadInformationClass,   
    OUT   PVOID   ThreadInformation,   
    IN   ULONG   ThreadInformationLength,   
    OUT   PULONG   ReturnLength   OPTIONAL   
    );

HANDLE m_GameProcessHandle;
//记录QQ_THREAD_DLL信息   
BYTE* m_pmodBaseAddr;   
DWORD   m_dwmodBaseSize;
_pfnZwQueryInformationThread m_pfnZwQueryInformationThread;

BOOL StartPatch();//PATCHQQ主函数   
DWORD EnablePrivilege (LPCTSTR name);//提权函数   
BOOL ListProcessModules(DWORD dwPID);//枚举指定进程的模块   
BOOL ListProcessThreads( DWORD dwOwnerPID);//枚举指定进程创建的线程,并结束掉QQ保护线程   
PVOID ShowThreadInfo(DWORD tid);//获取线程的起始地址   

int _tmain(int argc, _TCHAR* argv[])
{
    m_pfnZwQueryInformationThread =(_pfnZwQueryInformationThread)\
      GetProcAddress   (LoadLibrary(_T("ntdll.dll")),"ZwQueryInformationThread");

    if (StartPatch())
    {
      printf("可以CE附加QQ游戏大厅了\n");
    }
    else
      printf("失败!\n");
    return 0;
}

BOOL StartPatch()
{
    if(0!=EnablePrivilege (SE_DEBUG_NAME))   
    {
      return FALSE;   
    }
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;

    hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if( hProcessSnap == INVALID_HANDLE_VALUE )
    {
      return FALSE;
    }

    pe32.dwSize = sizeof( PROCESSENTRY32 );

    if( !Process32First( hProcessSnap, &pe32 ) )
    {
      CloseHandle( hProcessSnap );
      return FALSE;
    }

    BOOL bStartGame = FALSE;
    do
    {
      if (_tcscmp(pe32.szExeFile, QQ_GAME) == 0)
      {
            bStartGame = TRUE;
            m_GameProcessHandle = OpenProcess(PROCESS_VM_WRITE|PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION,\
                FALSE, pe32.th32ProcessID);
            if (m_GameProcessHandle == NULL)
            {
                return FALSE;
            }
            for (int i=0; i<5;i++)
            {
                if (!ListProcessModules(pe32.th32ProcessID))
                {
                  return FALSE;
                }

            }
            if (!ListProcessThreads(pe32.th32ProcessID))
            {
                return FALSE;
            }
      }

    } while( Process32Next( hProcessSnap, &pe32 ) );

    if (!bStartGame)
    {
      MessageBox(NULL,_T("运行QQ大厅后才能使用"),_T("提示"),MB_OK);
      return FALSE;
    }
    CloseHandle( hProcessSnap );
    return TRUE;
}

DWORD EnablePrivilege (LPCTSTR name)   
{   
    HANDLE hToken;   
    BOOL rv;   
    //设置结构      
    TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };   
    // 查找权限值      
    LookupPrivilegeValue (   
      0,   
      name,   
      &priv.Privileges.Luid   
      );   
    // 打开本进程Token      
    OpenProcessToken(   
      GetCurrentProcess (),   
      TOKEN_ADJUST_PRIVILEGES,   
      &hToken   
      );   
    // 提权      
    AdjustTokenPrivileges (   
      hToken,   
      FALSE,   
      &priv,   
      sizeof priv,   
      0,   
      0   
      );   
    // 返回值,错误信息,如果操作成功,则应为ERROR_SUCCESS,为O      
    rv = GetLastError();   
    // 关闭Token      
    CloseHandle (hToken);   
    return rv;   
}   

BOOL ListProcessModules(DWORD dwPID)
{
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32 me32;

    hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
    if( hModuleSnap == INVALID_HANDLE_VALUE )
    {
      return( FALSE );
    }

    me32.dwSize = sizeof( MODULEENTRY32 );
    if( !Module32First( hModuleSnap, &me32 ) )
    {
      CloseHandle( hModuleSnap );
      return( FALSE );
    }
    do
    {
      if (_tcscmp(me32.szModule, QQ_THREAD_DLL) == 0)
      {
            m_pmodBaseAddr = me32.modBaseAddr;
            m_dwmodBaseSize = me32.modBaseSize;

      }

    }while( Module32Next( hModuleSnap, &me32 ));

    CloseHandle( hModuleSnap );
    return( TRUE );

}

BOOL ListProcessThreads( DWORD dwOwnerPID)   
{   
    HANDLE hThreadSnap = INVALID_HANDLE_VALUE;   
    THREADENTRY32 te32;   
    PVOID addr;

    hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );   
    if( hThreadSnap == INVALID_HANDLE_VALUE )   
      return( FALSE );   

    te32.dwSize = sizeof(THREADENTRY32 );   


    if( !Thread32First( hThreadSnap, &te32 ) )   
    {
      CloseHandle( hThreadSnap );   
      return( FALSE );
    }

    do   
    {   
      if( te32.th32OwnerProcessID == dwOwnerPID )
      {
            addr = ShowThreadInfo(te32.th32ThreadID);
            if(((DWORD)addr>(DWORD)m_pmodBaseAddr)&&((DWORD)addr<\
                ((DWORD)m_pmodBaseAddr+(DWORD)m_dwmodBaseSize)))
            {

                HANDLE oth=OpenThread(THREAD_ALL_ACCESS,FALSE,te32.th32ThreadID);
                //关闭这个线程   
                TerminateThread(oth, 0);
            }
      }
    } while( Thread32Next(hThreadSnap, &te32 ) );   

    CloseHandle( hThreadSnap );
    return( TRUE );
}

PVOID ShowThreadInfo(DWORD tid)   
{   

    PVOID                  startaddr;   
    HANDLE                   thread;      
    //thread = m_pfnOpenThread_ex(THREAD_ALL_ACCESS,FALSE,tid);   
    thread=OpenThread(THREAD_ALL_ACCESS,FALSE,tid);
    if   (thread   ==   NULL)   
      return   FALSE;

    m_pfnZwQueryInformationThread(thread,
      ThreadQuerySetWin32StartAddress,   
      &startaddr,   
      sizeof(startaddr),   
      NULL);   

    CloseHandle   (thread);   
    return   startaddr;   
}

页: [1]
查看完整版本: 过QQ游戏大厅的SX保护附源代码