安装包逆向1

1.找到程序的入口点

在IDA中我们看到函数非常多,但是一般都是有主要的入口的,所以找一下有没有主函数
可以直接
Ctr+F直接查找
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CNsInstaller::CNsInstaller

这里搞半天在获取文件路径
在这里插入图片描述

CNsInstaller::StartInstall

在这里插入图片描述
在这里插入图片描述

CNsInstaller::InstallFunc
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;
  }
}

在这里插入图片描述

NsResGetBuff

在这里插入图片描述

CNsInstaller::InstallComponent‘

看名字安装原件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CNsInstaller::GetSetupInfo

在这里插入图片描述
下一步:通过自己的代码,把内嵌文件名,大小,文件内容还原出来就行
后续继续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Back~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值