2023腾讯游戏安全PC决赛复现

题目

2023腾讯游戏安全PC决赛复现插图

 

 

(一)解题过程

第一问让我们杀死进程,可以尝试根据windowsAPI提供的TerminateProcess函数去停止进程,写份代码测试下

 复制代码 隐藏代码
bool KillProcessByName(const char* processName) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if (Process32First(hSnapshot, &pe)) {
        do {
            if (strcmp(pe.szExeFile, processName) == 0) {
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
                if (hProcess) {
                    TerminateProcess(hProcess, 0);
                    CloseHandle(hProcess);
                    Num++;
                    printf("Kill suc:[%d]\n", Num);
                }
            }
        } while (Process32Next(hSnapshot, &pe));
    }

    CloseHandle(hSnapshot);
    return true;
}
int main()
{
    while(1)
    {
        KillProcessByName("WorkingService.exe");
    }
    return 0;
}

以管理员身份启动测试

启动前:

采集失败,请手动处理

https://attach.52pojie.cn/forum/202408/13/200155gg5qjqur5jqqjl9q.png

 

启动后

 

采集失败,请手动处理

https://attach.52pojie.cn/forum/202408/13/200157z44jqqst4vt62she.png

 

 

采集失败,请手动处理

https://attach.52pojie.cn/forum/202408/13/200159vdqd07o93qzdqtp7.png

 

 

(二)解题过程

先DIE查壳发现有VMP,只能动调入手,先观察程序功能。程序启动后会有两个进程启动,并且其中之一占用CPU性能较高;程序目录会创建十六个文件,并会做重复的删除和重新创建的操作;观察任务管理器发现进程会自动重启,手动杀死进程后就会重生一个新的进程。

拖进xdbg里观察符号,发现引入了ShellExcuteA这个函数,正好是启动进程函数,对这个函数下断点,发现确实断了下来,观察传参窗口。

采集失败,请手动处理

https://attach.52pojie.cn/forum/202408/13/200201el3khztqtcvk37l3.png

 

 

第六个参数不同,对应的是lpParameters(传入进程的参数),一个是working,一个是daemon restart

根据这个在控制台上运行加上参数working,发现只有一个工作进程,CPU占用100%,同理加上daemon restart,只有一个守护进程CPU占用不到1%。

调试参数为working的进程,观察线程发现有16个线程运行同一个函数,刚好对应16个txt日志文件的输出!!!

采集失败,请手动处理

https://attach.52pojie.cn/forum/202408/13/200059iwby5ytvhjvzhhyb.png

 

 

于是进入线程入口开始分析,对所有可能的写入文件的windowsAPI下断,发现都没有断下来,于是向CreateFile等API下断,

所有线程在CreateFileA上成功断下,观察传参确定这是对日志文件的操作函数

采集失败,请手动处理

https://attach.52pojie.cn/forum/202408/13/200101l7sayj2nuv6skyo4.png

 

 

有了这个依据,能确认的就是16个线程会循环通过CreateFileA打开文件,这可能是占用CPU的一个主要因素。但是跟之前运行的结果不同,调试发现,写入文件的API一直没有被调用,而正常运行的结果是,十六个文件会循环的做一个过程,文件被创建->文件被写入->文件被删除->新文件创建…。我通过加working参数运行,只会有一个循环过程,即不会有新文件诞生,文件内容也不会被修改。所以,十六个线程循环CreateFileA打开文件过程是无用功,只会徒增CPU负担!那么我们是不是可以HOOK CreateFileA这个函数,然后每个线程调用它的第二次的时候我们进行线程终止,是不是可以减少CPU的压力了呢?写份代码跑一下看看

 复制代码 隐藏代码
#include "pch.h"
#include <windows.h>
#include <shellapi.h>
#include <detours.h>
#include <tlhelp32.h>
#pragma comment(lib,"detours.lib")
#define _DEBUG
#define DBGMGEBOX(fmt, ...) \
    do { \
         /* 假设最大长度为1024,根据需要调整大小 */ \
        wsprintfA(out, fmt, __VA_ARGS__); \
        MessageBoxA(NULL, out, "提示", MB_OK); \
    } while(0)
char out[100];
DWORD tlsIndex;//tls索引
typedef BOOL(WINAPI* ShellExecuteExA_t)(SHELLEXECUTEINFOA*);
typedef HANDLE (WINAPI* CreateFileA_t)(
    LPCSTR                lpFileName,
    DWORD                 dwDesiredAccess,
    DWORD                 dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD                 dwCreationDisposition,
    DWORD                 dwFlagsAndAttributes,
    HANDLE                hTemplateFile
);

ShellExecuteExA_t TrueShellExecuteExA = NULL;
CreateFileA_t TrueCreateFileA = NULL;

BOOL WINAPI HookedShellExecuteExA(SHELLEXECUTEINFOA* pExecInfo) {
#if 1
    //执行第一个ShellExecuteExA守护进程
    static int Num = 0;
    DBGMGEBOX("ShellExecuteExA 被调用:Num = %d\nhProcess = %p", Num, pExecInfo->hProcess);
    if (Num == 0)
    {
        Num++;
        return TrueShellExecuteExA(pExecInfo);
    }
    else
    {
        return TrueShellExecuteExA(pExecInfo);
    }
#else
    //执行第二个ShellExecuteExA病毒进程
    static int Num = 0;
    DBGMGEBOX("ShellExecuteExA 被调用:Num = %d \n调用者窗口句柄 = 0x%p\n", Num, pExecInfo->hwnd);
    if (Num == 0)
    {
        Num++;
        DBGMGEBOX("[2]:当前线程ID:%d", GetCurrentThreadId());
        pExecInfo->lpFile = "C:\\Users\\Administrator\\Desktop\\自动F8直到call.txt";//修改参数导致重启失败;
        return TrueShellExecuteExA(pExecInfo);

    }
    else
    {

        DBGMGEBOX("[1]:当前线程ID:%d", GetCurrentThreadId());
        return TrueShellExecuteExA(pExecInfo);
    }
#endif
}
HANDLE WINAPI HookCreateFileA(
    LPCSTR                lpFileName,
    DWORD                 dwDesiredAccess,
    DWORD                 dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD                 dwCreationDisposition,
    DWORD                 dwFlagsAndAttributes,
    HANDLE                hTemplateFile
)
{

    //判断线程是否是第一次运行CreateFileA,是的话就放行,不是第一次运行就终止线程
    // 获取当前线程的TLS值
    LPVOID tlsValue = TlsGetValue(tlsIndex);

    if (tlsValue == NULL)
    {
        // 第一次运行,设置TLS值
#ifdef _DEBUG
        DBGMGEBOX("放行\nlpFileName:%s\n", lpFileName);
#endif 
        TlsSetValue(tlsIndex, (LPVOID)1);
    }
    else
    {
        // 不是第一次运行,终止线程
#ifdef _DEBUG
        DBGMGEBOX("终止\nlpFileName:%s\n", lpFileName);
#endif 
        ExitThread(0);
    }
    return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        /*TrueShellExecuteExA = (ShellExecuteExA_t)DetourFindFunction("shell32.dll", "ShellExecuteExA");
        DetourAttach(&(PVOID&)TrueShellExecuteExA, HookedShellExecuteExA);*/

        tlsIndex = TlsAlloc();//初始化TLS
        TrueCreateFileA = (CreateFileA_t)DetourFindFunction("kernelbase.dll", "CreateFileA");
        DetourAttach(&(PVOID&)TrueCreateFileA, HookCreateFileA);

        DetourTransactionCommit();
        break;
    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)TrueShellExecuteExA, HookedShellExecuteExA);
        DetourDetach(&(PVOID&)TrueCreateFileA, HookCreateFileA);
        TlsFree(tlsIndex);//清理TLS
        DetourTransactionCommit();
        break;
    }
    return TRUE;
}

注入进去查看CPU,与不注入的CPU情况对比如图,进程CPU占比显著下降

本站资源来自互联网收集,仅提供信息发布
一旦您浏览本站,即表示您已接受以下条约:
1.使用辅助可能会违反游戏协议,甚至违法,用户有权决定使用,并自行承担风险;
2.本站辅助严禁用于任何形式的商业用途,若被恶意贩卖,利益与本站无关;
3.本站为非营利性网站,但为了分担服务器等运营费用,收费均为赞助,没有任何利益收益。
死神科技 » 2023腾讯游戏安全PC决赛复现

死神科技,因为专业,所以领先。

网站首页 24小时自动发卡
在线客服
24小时在线客服
阿里云自动发卡,购卡进群售后
12:01
您好,有任何疑问请与我们联系!

选择聊天工具: