首页
社区
课程
招聘
[旧帖] mistfall里面汇编用到的重定位,代码有些疑惑,请求大家帮助 0.00雪花
发表于: 2010-10-25 20:28 3035

[旧帖] mistfall里面汇编用到的重定位,代码有些疑惑,请求大家帮助 0.00雪花

2010-10-25 20:28
3035
int CMistfall::Asm()
{
#ifdef DUMP_MSG
  printf("+ asm()\n");
#endif // DUMP_MSG

  fasthooy = (HOOY**)xrealloc( fasthooy, (pe->pe_imagesize+1)*4 );(为什么*4)
  if (fasthooy == NULL) return MF_ERR_NOMEMORY;

  // find entry that describes whole fixup structure
  HOOY* fxrva  = hooybyoldrva(pe->pe_fixuprva, FL_DATA);
  if (fxrva==NULL) return MF_ERR_INTERNAL1;
  HOOY* fxsize = hooybyoldrva(mz->mz_neptr+0xA4, FL_DELTA);   //A4=fixupsize
  if (fxsize==NULL) return MF_ERR_INTERNAL2;

re:
#ifdef DUMP_MSG
  printf("+ recalculating addresses\n");
#endif // DUMP_MSG

  // recalculate addresses

  memset(fasthooy, 0x00, (pe->pe_imagesize+1)*4);

  DWORD v = 0, p = 0;
  for (HOOY* h = root; h; h=h->next)
  {
    if (h->flags & FL_LABEL)
      fasthooy[h->oldrva] = h;

    h->newrva = v;
    h->newofs = p;

    if (h->flags & FL_SECTALIGN)
    {
      v = ALIGN(v, pe->pe_objectalign);
      p = ALIGN(p, pe->pe_filealign);
    }
    else
    {
      if (h->flags & FL_VPRESENT) v += h->datalen;
      if (h->flags & FL_PRESENT)  p += h->datalen;
    }
  }

#ifdef DUMP_MSG
  printf("+ rebuilding fixup table\n");
#endif // DUMP_MSG

  // rebuild fixup table(详细过程不太理解)

  DWORD xptr = 0, o = 0, xbase;
  for (HOOY* h=root; h; h=h->next)
  {
    if (h->flags & FL_FIXUP)
    {
      if (o == 0)
      {
c7:     xbase = h->newrva & 0xFFFFF000;
        *(DWORD*)&(fxrva->dataptr[xptr+0]) = xbase;
        o = 8;
      }
      if (h->newrva - xbase > 0xFFF)
      {
        *(DWORD*)&(fxrva->dataptr[xptr+4]) = o;
        xptr += o;
        goto c7;
      }
      if (xptr+o+2 > fxrva->datalen)
      {
        fxrva->datalen += 65536;
        fxrva->dataptr = (BYTE*) xrealloc( fxrva->dataptr, fxrva->datalen );
        if (fxrva->dataptr == NULL) return MF_ERR_NOMEMORY;
        goto re;
      }
      *(WORD*)&(fxrva->dataptr[xptr+o]) = (h->newrva - xbase) | 0x3000;
      o += 2;
    }
  }
  if (o != 0)
  {
    *(DWORD*)&(fxrva->dataptr[xptr+4]) = o;
    xptr += o;
  }

  if (xptr==0)
    return MF_ERR_NOFIXUPS;         // new fixup table size == 0

  fxrva->datalen = xptr;

  if (*(DWORD*)fxsize->dataptr != xptr)
  {
    *(DWORD*)fxsize->dataptr = xptr;
    goto re;
  }

#ifdef DUMP_MSG
  printf("+ recalculating pointers\n");
#endif // DUMP_MSG

  // recalc pointers

  int expanded = 0;

#define SETHOOY(x,y)  HOOY* x = (y) <= pe->pe_imagesize ? fasthooy[ y ] : NULL;

  for (HOOY* h = root; h; h=h->next)
  {
    if (h->flags & FL_RVA)
    {
      SETHOOY(h1, h->arg1);
      if (h1)
      if (h->flags & FL_PHYS)
        *(DWORD*)h->dataptr = h1->newofs;
      else
        *(DWORD*)h->dataptr = h1->newrva;
    }
    if (h->flags & FL_FIXUP)
    {
      SETHOOY(h1, h->arg1);
      if (h1)
      *(DWORD*)h->dataptr = h1->newrva + pe->pe_imagebase;
    }
    if (h->flags & FL_DELTA)
    {
      SETHOOY(h1, h->arg1);
      SETHOOY(h2, h->arg2);
      if (h1)
      if (h2)
      if (h->flags & FL_PHYS)
        *(DWORD*)h->dataptr = h2->newofs - h1->newofs;
      else
        *(DWORD*)h->dataptr = h2->newrva - h1->newrva;
    }
    if (h->flags & FL_RES8)
    {
      *(DWORD*)h->dataptr |= 0x80000000;
    }
    if (h->flags & FL_FORCEOBJALIGN)
    {
      *(DWORD*)h->dataptr = ALIGN(*(DWORD*)h->dataptr, pe->pe_objectalign);
    }
    if (h->flags & FL_FORCEFILEALIGN)
    {
      *(DWORD*)h->dataptr = ALIGN(*(DWORD*)h->dataptr, pe->pe_filealign);
    }
    if (h->flags & FL_HAVEREL)
    {
      SETHOOY(h1, h->arg1);
      if (h1)
      {
        DWORD t = h1->newrva - (h->newrva + h->datalen);

        if (h->arg2 == 1)
        {
          if ((long)t != (char)t)
          {
            if (h->dataptr[0] == 0xEB)
            {
              h->dataptr[0]=0xE9;
              h->datalen=5;
            }
            else
            if ((h->dataptr[0] & 0xF0) == 0x70)
            {
              h->dataptr[1]=h->dataptr[0]^0x70^0x80;
              h->dataptr[0]=0x0F;
              h->datalen=6;
            }
            else
            if (h->dataptr[0]==0xE3)
            {
              h->dataptr[0]=0x09;     // or ecx, ecx
              h->dataptr[1]=0xC9;
              h->dataptr[2]=0x0F;     // jz
              h->dataptr[3]=0x84;
              h->datalen=2+6;
            }
            else
            if (h->dataptr[0]==0xE2)
            {
              h->dataptr[0]=0x49;     // dec ecx
              h->dataptr[1]=0x0F;     // jnz
              h->dataptr[2]=0x85;
              h->datalen=1+6;
            }
            else
            {
              return MF_ERR_CANTEXPAND;
            }
            h->arg2 = 4;
            expanded++;
          }
          else
            h->dataptr[h->datalen-1] = t;
        }

        if (h->arg2 == 4)
        {
          *(DWORD*)&(h->dataptr[h->datalen-4]) = t;
        }
      }
    }
  } // for h

  if (expanded)
  {
    // +pass
    goto re;
  }

#ifdef DUMP_MSG
  printf("+ assembling\n");
#endif // DUMP_MSG

  // assembling

  for (HOOY* h=root; h; h=h->next)
    p = h->newofs;
  p = ALIGN(p, pe->pe_filealign);

  o_phys_len = p + ovr_size;
  o_phys_mem = (BYTE*)xrealloc(o_phys_mem, o_phys_len);
  if (o_phys_mem == NULL) return MF_ERR_NOMEMORY;

  for (HOOY* h = root; h; h=h->next)
  if (h->flags & FL_PRESENT)
    memcpy(
    &o_phys_mem[h->newofs], h->dataptr, h->datalen);

  if (ovr_size > 0)
    memcpy(&o_phys_mem

, &i_phys_mem[ovr_offs], ovr_size);

  // recalc csum

  MZ_HEADER* tmz = (MZ_HEADER*) &o_phys_mem[0];
  PE_HEADER* tpe = (PE_HEADER*) &o_phys_mem[ tmz->mz_neptr ];
  if (tpe->pe_checksum != 0)
  {
    tpe->pe_checksum = 0;
    tpe->pe_checksum = calc_pe_csum(o_phys_mem, o_phys_len);
  }

  xfree((void**)&fasthooy);

  return MF_ERR_SUCCESS;
} // CMistfall::Asm()

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 162
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
全部源代码见附件
上传的附件:
2010-10-25 20:29
0
游客
登录 | 注册 方可回帖
返回
//