安装包逆向1

时间:2024-03-14 22:49:31
char __thiscall CNsInstaller::InstallFunc(CNsInstaller *this) { const wchar_t *v2; // eax CNsInstaller *v3; // ecx const WCHAR *v4; // eax __int64 v5; // rax const wchar_t *v6; // eax CNsInstaller *v7; // edx const WCHAR *v8; // eax struct CNsApp *v9; // eax CNsApp *v10; // eax const WCHAR *v11; // eax char *v12; // [esp-24h] [ebp-A58h] char *v13; // [esp-20h] [ebp-A54h] int Offset; // [esp+28h] [ebp-A0Ch] BYREF int v15; // [esp+2Ch] [ebp-A08h] BYREF int v16; // [esp+30h] [ebp-A04h] BYREF int Buff; // [esp+34h] [ebp-A00h] int v18; // [esp+38h] [ebp-9FCh] BYREF char v19[4]; // [esp+3Ch] [ebp-9F8h] BYREF char v20[5]; // [esp+40h] [ebp-9F4h] BYREF char v21; // [esp+45h] [ebp-9EFh] char v22; // [esp+46h] [ebp-9EEh] char v23; // [esp+47h] [ebp-9EDh] FILE *Stream; // [esp+48h] [ebp-9ECh] CNsInstaller *v25; // [esp+4Ch] [ebp-9E8h] LONG dwNewLong[297]; // [esp+50h] [ebp-9E4h] BYREF WCHAR Buffer[202]; // [esp+4F4h] [ebp-540h] BYREF WCHAR String1[202]; // [esp+688h] [ebp-3ACh] BYREF WCHAR Filename[260]; // [esp+81Ch] [ebp-218h] BYREF int v30; // [esp+A30h] [ebp-4h] v25 = this; memset(Filename, 0, sizeof(Filename)); GetModuleFileNameW(0, Filename, 0x104u); 用于获取当前进程已加载模块的文件路径 *((_QWORD *)v25 + 2) = FileSize(Filename); Buff = NsResGetBuff(0x1F41u, L"BIN", &Offset);这里也很重要,从获取buff点进去看 尝试从资源中检索包含安装数据的缓冲区,该资源由 "BIN" 和 ID 0x1F41 标识 if ( !Buff ) { memset((char *)v25 + 36, 0, 0x15C8u); return 0; } Stream = _wfopen(Filename, L"rb"); if ( !Stream ) return 0; fseek(Stream, Offset, 0); memset((char *)v25 + 36, 0, 0x15C8u); fread((char *)v25 + 36, 0x15C8u, 1u, Stream);将文件的前 4096 字节 (0x15C8) 读入 CNsInstaller 对象中的缓冲区 CNsInstaller::InitPath(v25, (CNsInstaller *)((char *)v25 + 36)); DoReport(L"http://hofosoft.cn/api/report.asp", L"install", (LPCWSTR)v25 + 18);这里看到火凤一个网站 CNsInstaller::CheckValid(v25); CNsInstaller::InstallComponent(v25); v2 = (const wchar_t *)Json::StaticString::c_str((CNsInstaller *)((char *)v25 + 5808)); 使用 Json::StaticString::c_str 从安装数据缓冲区中提取文件路径。 CNsInstaller::CheckDir(v25, v2, &word_11FBED4);使用 CNsInstaller::CheckDir 检查目录是否存在 v15 = 0; Buff = NsResGetBuff(0x1F5Bu, L"BIN", &v15);检索包含安装数据的另一个缓冲区 (ID 0x1F5B)if ( Buff && v15 ) { v3 = v25; *((_DWORD *)v25 + 4) = 0; *((_DWORD *)v3 + 5) = 0; memset(String1, 0, sizeof(String1)); fread(String1, 0x194u, 1u, Stream); CNsInstaller::ExtractFile(v25, String1, Stream); 使用 CNsInstaller::ExtractFile 从可执行文件中提取文件 memset(String1, 0, sizeof(String1)); fread(String1, 0x194u, 1u, Stream); if ( lstrcmpW(String1, L"SPLIT") || *(_DWORD *)&String1[200] ) 检查文件名是否为 "SPLIT" 以及偏移量 200 处是否存在特定值 return 0; fclose(Stream); sub_11396A0(Filename); v30 = 0; sub_113D410(v20); sub_113D470((wchar_t *)L".exe", L".hf"); v4 = (const WCHAR *)Json::StaticString::c_str((Json::StaticString *)v20); 获取新文件的大小并将其存储在 CNsInstaller 对象中 v5 = FileSize(v4); *((_QWORD *)v25 + 2) = v5; *((_QWORD *)v25 + 3) = 0i64; 计算可执行文件的剩余大小以进行进一步处理 v6 = (const wchar_t *)Json::StaticString::c_str((Json::StaticString *)v20); Stream = _wfopen(v6, L"rb");//这里对文件进行读写的操作 if ( !Stream ) { v23 = 0; v30 = -1; sub_1139680(v20); return v23; } v30 = -1; sub_1139680(v20); } else { *((_QWORD *)v25 + 2) -= Offset; v7 = v25; *((_DWORD *)v25 + 6) = 5576; *((_DWORD *)v7 + 7) = 0; } if ( *((__int64 *)v25 + 2) >= 419430400 ) { if ( *((__int64 *)v25 + 2) >= 0x100000000i64 ) *((_DWORD *)v25 + 8) = 2; else *((_DWORD *)v25 + 8) = 1; } else { *((_DWORD *)v25 + 8) = 0; } while ( !feof(Stream) ) { if ( *((_BYTE *)v25 + 8) ) return 0; memset(Buffer, 0, sizeof(Buffer)); fread(Buffer, 0x194u, 1u, Stream); if ( !lstrcmpW(Buffer, &off_11FBF4C) && !*(_DWORD *)&Buffer[200] )检查缓冲区内容是否指示安装数据部分的结尾 break; if ( *(_DWORD *)&Buffer[200] == -1 ) { CNsInstaller::CheckDir(v25, Buffer, 0); } else { *((_QWORD *)v25 + 3) += 404i64; if ( !CNsInstaller::ExtractFile(v25, Buffer, Stream) ) break; } } fclose(Stream); sub_11397C0(&v18); v30 = 1; sub_1139D70((int)&v18, (wchar_t *)L"%s\\%s", *((_DWORD *)v25 + 1452)); v8 = (const WCHAR *)Json::StaticString::c_str((Json::StaticString *)&v18); if ( PathFileExistsW(v8) ) { if ( *((_BYTE *)v25 + 5816) ) { sub_11397C0(&v16); LOBYTE(v30) = 4; sub_1139D70((int)&v16, (wchar_t *)L"%s\\%s", *((_DWORD *)v25 + 1452)); v11 = (const WCHAR *)Json::StaticString::c_str((Json::StaticString *)&v16); DeleteFileW(v11); LOBYTE(v30) = 1; sub_1139680(&v16); } else { CNsInstaller::WriteReg(v25, (CNsInstaller *)((char *)v25 + 36)); CNsInstaller::CreateShortcuts(v25, (CNsInstaller *)((char *)v25 + 36)); CNsInstaller::CreateUninstallCfg(v25, (CNsInstaller *)((char *)v25 + 36)); } CNsInstaller::ExecScript(v25, (const wchar_t *)v25 + 1868); CNsInstaller::ImportReg(v25); SendMessageW(*(HWND *)v25, 0x7E9u, 0x2710u, 0); v21 = 1; v30 = -1; sub_1139680(&v18); return v21; } else { sub_11397C0(v19); LOBYTE(v30) = 2; if ( isEnglish() ) sub_11395C0(v19, L"Installation failed, does not have write permission!"); else sub_11395C0(v19, &unk_11FBFD8); sub_113DBE0(); LOBYTE(v30) = 3; v13 = (char *)CNsApp::Instance() + 530; v12 = (char *)Json::StaticString::c_str((Json::StaticString *)v19); v9 = CNsApp::Instance(); sub_113E350((LONG)dwNewLong, *((_DWORD *)v9 + 1), v12, v13, 0, 6, 300, 160, 8, 9, 1); v10 = CNsApp::Instance(); CNsApp::ExitApp(v10); v22 = 0; LOBYTE(v30) = 2; sub_113DE10(dwNewLong); LOBYTE(v30) = 1; sub_1139680(v19); v30 = -1; sub_1139680(&v18); return v22; } }