#pragma once
#include "KByS.h"
#include "Erika.h"
using namespace std;
DWORD __stdcall packbuff(unsigned char *inBuffer,DWORD inSize);
//----------------------------------------------
//全局变量开始
//----------------------------------------------
//原始无壳PE头
PIMAGE_DOS_HEADER pOldDosHeader;
PIMAGE_NT_HEADERS pOldNtHeader;
//加壳后的PE头
PIMAGE_DOS_HEADER imDos_Headers;
PIMAGE_NT_HEADERS imNT_Headers;
#define isdll ((imNT_Headers->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0)
pe_header_t ih, oh;
//三个区段头
PIMAGE_SECTION_HEADER pISHUpx0;
PIMAGE_SECTION_HEADER pISHUpx1;
PIMAGE_SECTION_HEADER pISHUpxRes;
upx_byte *oexport;
unsigned soexport;
upx_byte* obuf;
upx_byte* ibuf;
int icondir_count;
//映射的文件内存
LPVOID lpFileMap;
unsigned soxrelocs;
upx_byte *oxrelocs;
#define rvamin (pISHUpx0->VirtualAddress)
// for use with qsort()
extern "C" {
int __cdecl le32_compare(const void *, const void *);
} // extern "C"
int __cdecl le32_compare(const void *e1, const void *e2)
{
const unsigned d1 = get_le32(e1);
const unsigned d2 = get_le32(e2);
return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0);
}
//----------------------------------------------
//全局变量结束
//----------------------------------------------
///////////////////////////////////////////////////////////////
void BackupSrcFile(const char* szSrcFileName)
{
char szDstFileName[MAX_PATH];
strcpy(szDstFileName, szSrcFileName);
strcat(szDstFileName, ".bak");
CopyFile(szSrcFileName, szDstFileName, FALSE);
}
///////////////////////////////////////////////////////////////
BOOL IsPE(HANDLE hFile)
{
WORD temp;
DWORD dwEntryPoint;
DWORD dwRead;
DWORD dwOffset;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
ReadFile(hFile, &temp, 2, &dwRead, NULL);
if (temp != 'ZM')
return FALSE;
SetFilePointer(hFile, 0x3C, NULL, FILE_BEGIN);
ReadFile(hFile, &dwOffset, 4, &dwRead, NULL);
SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
ReadFile(hFile, &temp, 2, &dwRead, NULL);
if (temp != 'EP')
return FALSE;
SetFilePointer(hFile, dwOffset+0x16, NULL, FILE_BEGIN);
ReadFile(hFile, &temp, 2, &dwRead, NULL);
SetFilePointer(hFile, dwOffset+0x28, NULL, FILE_BEGIN);
ReadFile(hFile, &dwEntryPoint, 4, &dwRead, NULL);
if (dwEntryPoint == 0)
return FALSE;
if ((temp & 0x2000) != 0)
bDLL = TRUE;
else
bDLL = FALSE;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
return TRUE;
}
/*
///////////////////////////////////////////////////////////////
void MapFile(HANDLE hFile)
{
DWORD dwRead;
DWORD dwOffset;
DWORD dwImageSize;
DWORD dwHeadSize;
DWORD i;
SetFilePointer(hFile, 0x3C, NULL, FILE_BEGIN);
ReadFile(hFile, &dwOffset, 4, &dwRead, NULL);
SetFilePointer(hFile, dwOffset+0x50, NULL, FILE_BEGIN);
ReadFile(hFile, &dwImageSize, 4, &dwRead, NULL);
SetFilePointer(hFile, dwOffset+0x54, NULL, FILE_BEGIN);
ReadFile(hFile, &dwHeadSize, 4, &dwRead, NULL);
MapOfFile = (LPBYTE)VirtualAlloc(0, dwImageSize, MEM_COMMIT, PAGE_READWRITE);
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
ReadFile(hFile, MapOfFile, dwHeadSize, &dwRead, NULL);
PE = (IMAGE_NT_HEADERS32 *)(MapOfFile+dwOffset);
SH = IMAGE_FIRST_SECTION32(PE);
for (i=0; i<PE->FileHeader.NumberOfSections; i++)
{
SetFilePointer(hFile, (SH+i)->PointerToRawData, NULL, FILE_BEGIN);
ReadFile(hFile, (SH+i)->VirtualAddress+MapOfFile, (SH+i)->SizeOfRawData, &dwRead, NULL);
}
}*/
///////////////////////////////////////////////////////////////
void OverlayFile(HANDLE hFile)
{
DWORD dwFileSize;
DWORD dwRead;
//文件实际大小
dwFileSize = GetFileSize(hFile, NULL);
//减去内存中最后一个区段需要映射的大小
dwFileSize -= pISHUpxRes->SizeOfRawData + pISHUpxRes->PointerToRawData;
SizeOfOverlay = dwFileSize;
if (SizeOfOverlay != 0)
{
MapOfOverlay = (unsigned char *)VirtualAlloc(NULL, SizeOfOverlay, MEM_COMMIT, PAGE_READWRITE);
ReadFile(hFile, MapOfOverlay, SizeOfOverlay, &dwRead, NULL);
}
else
{
MapOfOverlay = NULL;
SizeOfOverlay = 0;
}
return ;
}
struct import_desc
{
LE32 oft; // orig first thunk
char _[8];
LE32 dllname;
LE32 iat; // import address table
}
__attribute_packed;
Interval::Interval(void *b) : capacity(0),base(b),ivarr(NULL),ivnum(0)
{}
Interval::~Interval()
{
free(ivarr);
}
void Interval::add(const void *start,unsigned len)
{
add(ptr_diff(start,base),len);
}
void Interval::add(const void *start,const void *end)
{
add(ptr_diff(start,base),ptr_diff(end,start));
}
int __cdecl Interval::compare(const void *p1,const void *p2)
{
const interval *i1 = (const interval*) p1;
const interval *i2 = (const interval*) p2;
if (i1->start < i2->start) return -1;
if (i1->start > i2->start) return 1;
if (i1->len < i2->len) return 1;
if (i1->len > i2->len) return -1;
return 0;
}
void Interval::add(unsigned start,unsigned len)
{
if (ivnum == capacity)
ivarr = (interval*) realloc(ivarr,(capacity += 15) * sizeof (interval));
ivarr[ivnum].start = start;
ivarr[ivnum++].len = len;
}
void Interval::add(const Interval *iv)
{
for (unsigned ic = 0; ic < iv->ivnum; ic++)
add(iv->ivarr[ic].start,iv->ivarr[ic].len);
}
void Interval::flatten()
{
if (!ivnum)
return;
qsort(ivarr,ivnum,sizeof (interval),Interval::compare);
for (unsigned ic = 0; ic < ivnum - 1; ic++)
{
unsigned jc;
for (jc = ic + 1; jc < ivnum && ivarr[ic].start + ivarr[ic].len >= ivarr[jc].start; jc++)
if (ivarr[ic].start + ivarr[ic].len < ivarr[jc].start + ivarr[jc].len)
ivarr[ic].len = ivarr[jc].start + ivarr[jc].len - ivarr[ic].start;
if (jc > ic + 1)
{
memmove(ivarr + ic + 1, ivarr + jc,sizeof(interval) * (ivnum - jc));
ivnum -= jc - ic - 1;
}
}
}
void Interval::clear()
{
for (unsigned ic = 0; ic < ivnum; ic++)
memset((char*) base + ivarr[ic].start,0,ivarr[ic].len);
}
void Interval::dump() const
{
printf("%d intervals:\n",ivnum);
for (unsigned ic = 0; ic < ivnum; ic++)
printf("%x %x\n",ivarr[ic].start,ivarr[ic].len);
}
void rebuildTls()
{
// this is an easy one : just do nothing ;-)
}
struct Reloc::reloc
{
LE32 pagestart;
LE32 size;
};
void Reloc::newRelocPos(void *p)
{
rel = (reloc*) p;
rel1 = (LE16*) ((char*) p + sizeof (reloc));
}
Reloc::Reloc(upx_byte *s,unsigned si) :
start(s), size(si), rel(NULL), rel1(NULL)
{
assert(sizeof(reloc) == 8);
memset(counts,0,sizeof(counts));
unsigned pos,type;
while (next(pos,type))
counts[type]++;
}
Reloc::Reloc(unsigned rnum) :
start(NULL), size(0), rel(NULL), rel1(NULL)
{
start = new upx_byte[rnum * 4 + 8192];
counts[0] = 0;
}
bool Reloc::next(unsigned &pos,unsigned &type)
{
if (!rel)
newRelocPos(start);
if (ptr_diff(rel, start) >= (int) size || rel->pagestart == 0)
return rel = 0,false; // rewind
pos = rel->pagestart + (*rel1 & 0xfff);
type = *rel1++ >> 12;
//printf("%x %d\n",pos,type);
if (ptr_diff(rel1,rel) >= (int) rel->size)
newRelocPos(rel1);
return type == 0 ? next(pos,type) : true;
}
void Reloc::add(unsigned pos,unsigned type)
{
set_le32(start + 1024 + 4 * counts[0]++,(pos << 4) + type);
}
void Reloc::finish(upx_byte *&p,unsigned &siz)
{
unsigned prev = 0xffffffff;
set_le32(start + 1024 + 4 * counts[0]++,0xf0000000);
qsort(start + 1024,counts[0], 4, le32_compare);
rel = (reloc*) start;
rel1 = (LE16*) rel;
for (unsigned ic = 0; ic < counts[0]; ic++)
{
unsigned pos = get_le32(start + 1024 + 4 * ic);
if ((pos ^ prev) >= 0x10000)
{