Ejemplo n.º 1
0
static int nsis_headers(struct nsis_st *n, cli_ctx *ctx) {
  char buf[28];
  struct stat st;
  uint32_t pos;
  int i;
  uint8_t comps[] = {0, 0, 0, 0}, trunc = 0;
  
  if (fstat(n->ifd, &st)==-1 ||
      lseek(n->ifd, n->off, SEEK_SET)==-1 ||
      cli_readn(n->ifd, buf, 28) != 28)
    return CL_EIO;

  n->hsz = (uint32_t)cli_readint32(buf+0x14);
  n->asz = (uint32_t)cli_readint32(buf+0x18);

  cli_dbgmsg("NSIS: Header info - Flags=%x, Header size=%x, Archive size=%x\n", cli_readint32(buf), n->hsz, n->asz);

  if (st.st_size - n->off < (off_t) n->asz) {
    cli_dbgmsg("NSIS: Possibly truncated file\n");
    n->asz = st.st_size - n->off;
    trunc++;
  } else if (st.st_size - n->off != (off_t) n->asz) {
    cli_dbgmsg("NSIS: Overlays found\n");
  }

  n->asz -= 0x1c;

  /* Guess if solid */
  for (i=0, pos=0;pos < n->asz-4;i++) {
    int32_t nextsz;
    if (cli_readn(n->ifd, buf+4, 4)!=4) return CL_EIO;
    nextsz=cli_readint32(buf+4);
    if (!i) n->comp = nsis_detcomp(buf+4);
    if (nextsz&0x80000000) {
      nextsz&=~0x80000000;
      if (cli_readn(n->ifd, buf+4, 4)!=4) return CL_EIO;
      comps[nsis_detcomp(buf+4)]++;
      nextsz-=4;
      pos+=4;
    }
    if ((pos+=4+nextsz) > n->asz) {
      n->solid = 1;
      break;
    }

    if (lseek(n->ifd, nextsz, SEEK_CUR)==-1) return CL_EIO;
  }
  
  if (trunc && i>=2) n->solid=0;

  cli_dbgmsg("NSIS: solid compression%s detected\n", (n->solid)?"":" not");

  /* Guess the compression method */
  if (!n->solid) {
    cli_dbgmsg("NSIS: bzip2 %u - lzma %u - zlib %u\n", comps[1], comps[2], comps[3]);
    n->comp = (comps[1]<comps[2]) ? (comps[2]<comps[3] ? COMP_ZLIB : COMP_LZMA) : (comps[1]<comps[3] ? COMP_ZLIB : COMP_BZIP2);
  }

  if (lseek(n->ifd, n->off+0x1c, SEEK_SET)==-1) return CL_EIO;

  return nsis_unpack_next(n, ctx);
}
Ejemplo n.º 2
0
static int cli_nsis_unpack(struct nsis_st *n, cli_ctx *ctx) {
  return (n->fno) ? nsis_unpack_next(n, ctx) : nsis_headers(n, ctx);
}
Ejemplo n.º 3
0
static int nsis_headers(struct nsis_st *n, cli_ctx *ctx) {
  const char *buf;
  uint32_t pos;
  int i;
  uint8_t comps[] = {0, 0, 0, 0}, trunc = 0;
  
  if (!(buf = fmap_need_off_once(n->map, n->off, 0x1c)))
    return CL_EREAD;

  n->hsz = (uint32_t)cli_readint32(buf+0x14);
  n->asz = (uint32_t)cli_readint32(buf+0x18);
  n->fullsz = n->map->len;

  cli_dbgmsg("NSIS: Header info - Flags=%x, Header size=%x, Archive size=%x\n", cli_readint32(buf), n->hsz, n->asz);

  if (n->fullsz - n->off < (off_t) n->asz) {
    cli_dbgmsg("NSIS: Possibly truncated file\n");
    n->asz = n->fullsz - n->off;
    trunc++;
  } else if (n->fullsz - n->off != (off_t) n->asz) {
    cli_dbgmsg("NSIS: Overlays found\n");
  }

  n->asz -= 0x1c;
  buf += 0x1c;

  /* Guess if solid */
  for (i=0, pos=0;pos < n->asz-4;i++) {
    int32_t nextsz;
    if (!(buf = fmap_need_ptr_once(n->map, (void *)buf, 4))) return CL_EREAD;
    nextsz=cli_readint32(buf);
    if (!i) n->comp = nsis_detcomp(buf);
    buf += 4;
    if (nextsz&0x80000000) {
      nextsz&=~0x80000000;
      if (!(buf = fmap_need_ptr_once(n->map, (void *)buf, 4))) return CL_EREAD;
      comps[nsis_detcomp(buf)]++;
      nextsz-=4;
      pos+=4;
      buf+=4;
    }
    if ((pos+=4+nextsz) > n->asz) {
      n->solid = 1;
      break;
    }

    buf += nextsz;
  }
  
  if (trunc && i>=2) n->solid=0;

  cli_dbgmsg("NSIS: solid compression%s detected\n", (n->solid)?"":" not");

  /* Guess the compression method */
  if (!n->solid) {
    cli_dbgmsg("NSIS: bzip2 %u - lzma %u - zlib %u\n", comps[1], comps[2], comps[3]);
    n->comp = (comps[1]<comps[2]) ? (comps[2]<comps[3] ? COMP_ZLIB : COMP_LZMA) : (comps[1]<comps[3] ? COMP_ZLIB : COMP_BZIP2);
  }

  n->curpos = n->off+0x1c;
  return nsis_unpack_next(n, ctx);
}