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()
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)