代码更新:全C版,自动脱掉自己写的MessageBox,解压算法使用了徐大力大牛逆向的解压算法,主要代码如下,这个头文件就是解压算法

代码:
#include <windows.h>
#include <stdlib.h>

#include "upx.h"

#ifndef _IMAGEHLP_H 
#include "imagehlp.h"
#pragma comment ( lib, "imagehlp.lib" )
#endif

IMAGE_DOS_HEADER *DosHeader        = NULL;      //DOS头
IMAGE_NT_HEADERS *NtHeader         = NULL;      //NT头
IMAGE_FILE_HEADER *FileHeader      = NULL;    //文件头
IMAGE_OPTIONAL_HEADER32 *OptHeader = NULL;  //可选头
IMAGE_SECTION_HEADER  *SecHeader   =NULL;
IMAGE_IMPORT_DESCRIPTOR *pIID      = NULL;    //数据目录
DWORD dwImportBase;
PIMAGE_DOS_HEADER  GetDosHeader(LPVOID ImageBase)
{
//////////////////////////////结构声明
  PIMAGE_DOS_HEADER  pDosHeader = NULL;
/////////////////////////////获得DosHeader结构
  pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
  return pDosHeader;
}
PIMAGE_NT_HEADERS  GetNtHeader(LPVOID  ImageBase) 
{
//////////////////////////////结构声明
  PIMAGE_DOS_HEADER  pDosHeader = NULL;
  PIMAGE_NT_HEADERS  pNtHeader  = NULL;
/////////////////////////////获得NtHeader结构
  pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
  pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
  return    pNtHeader;
}

PIMAGE_FILE_HEADER GetFileHeader(LPVOID  ImageBase)
{
//////////////////////////////结构声明
  PIMAGE_DOS_HEADER  pDosHeader     = NULL;
  PIMAGE_NT_HEADERS  pNtHeader      = NULL;
  PIMAGE_FILE_HEADER  pFileHeader   = NULL;
/////////////////////////////获得FileHeader结构
  pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
  pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
  pFileHeader =(PIMAGE_FILE_HEADER)&pNtHeader->FileHeader;
  return  pFileHeader;
}
PIMAGE_OPTIONAL_HEADER  GetOptionalHeader(LPVOID  ImageBase)
{
//////////////////////////////结构声明
  PIMAGE_DOS_HEADER  pDosHeader         = NULL;
  PIMAGE_NT_HEADERS  pNtHeader          = NULL;
  PIMAGE_OPTIONAL_HEADER  pOptionHeader = NULL;
/////////////////////////////获得OptionalHeader结构
  pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
  pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
  pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)&pNtHeader->OptionalHeader;
  return  pOptionHeader;
}
PIMAGE_SECTION_HEADER GetSectionHeader(LPVOID ImageBase)
{
//////////////////////////////结构声明
  PIMAGE_DOS_HEADER  pDosHeader         = NULL;
  PIMAGE_NT_HEADERS  pNtHeader          = NULL;
  PIMAGE_OPTIONAL_HEADER  pOptionHeader = NULL;
  PIMAGE_FILE_HEADER  pFileHeader       = NULL;
  PIMAGE_SECTION_HEADER pSecHeader      = NULL;
/////////////////////////////获得SectionHeader结构
  pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
  pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
  pFileHeader =(PIMAGE_FILE_HEADER)&pNtHeader->FileHeader; 
  pOptionHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;
  pSecHeader =(PIMAGE_SECTION_HEADER)((LPBYTE)pOptionHeader + pFileHeader->SizeOfOptionalHeader);
  return pSecHeader;
}
PIMAGE_IMPORT_DESCRIPTOR  GetFirstImportDesc(LPVOID  ImageBase)
{
//////////////////////////////结构声明
  PIMAGE_DOS_HEADER  pDosHeader         = NULL;
  PIMAGE_NT_HEADERS  pNtHeader          = NULL;
  PIMAGE_OPTIONAL_HEADER  pOptionHeader = NULL;
  PIMAGE_FILE_HEADER  pFileHeader       = NULL;
  PIMAGE_SECTION_HEADER pSecHeader      = NULL;
/////////////////////////////获得OptionalHeader结构
  pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
  pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
  pFileHeader =(PIMAGE_FILE_HEADER)&pNtHeader->FileHeader; 
  pOptionHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;  
  pSecHeader =(PIMAGE_SECTION_HEADER)((LPBYTE)pOptionHeader + pFileHeader->SizeOfOptionalHeader);
  DWORD pImportOffset = (pOptionHeader->DataDirectory[1]).VirtualAddress ;
  
  PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
  ImageRvaToVa (pNtHeader,ImageBase,pImportOffset,&pSecHeader ) ; 
  return  pImportDesc;
}
////////////////////比较是否为PE文件
BOOL MemCmpPe(LPVOID ImageBase)
{
  PIMAGE_DOS_HEADER  pDosHeader =(PIMAGE_DOS_HEADER)ImageBase;
    PIMAGE_NT_HEADERS  pNtHeader  =(PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
  while(!ImageBase)
    return FALSE;
  while(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
    return FALSE;
  while(pNtHeader->Signature!=IMAGE_NT_SIGNATURE)
      return FALSE;
  return TRUE;
}
///////////////////////////读取文件到内存
LPVOID MapFileToMemory(char *szFileName)
{
  HANDLE hFile = CreateFile(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile==INVALID_HANDLE_VALUE)
  {
    MessageBox(NULL,"不能打开文件","提示",MB_OK);
    return NULL;
  }
  HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
  LPVOID pMap = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
  return pMap;
}
///////////////////////////获得对齐值
DWORD Alignment(DWORD Size,DWORD Align)
{
  if(Size%Align!=0)
    return  (Size/Align+1)*Align;
  return Size;
}
/////////////////////修复区段名字
void ModifySecName(PIMAGE_SECTION_HEADER SecHeader,DWORD SecNum)
{
  int i=0;
  while(i<SecNum)
  {
    strcpy((char*)SecHeader[i].Name,"UnPack");
    i++;
  }
}
///////////////////修复输入表
void ModifyImport(DWORD SecOffset,DWORD SecOffsetA,DWORD SecOffsetB)
{
  DWORD SecOffsetC=SecOffset+SecOffsetA;
  DWORD ImPort    =*(DWORD*)SecOffsetC;
  while(ImPort)
  {
    DWORD FuncAddr  =*(DWORD*)(SecOffsetC+4);
    HMODULE hMod=LoadLibraryA((char*)SecOffsetB+ImPort);
    FuncAddr+=SecOffset;
    SecOffsetC+=8;
    while(*(BYTE*)SecOffsetC!=0)
    {
        ++SecOffsetC;
        *(DWORD*)FuncAddr=(DWORD)GetProcAddress(hMod,(char*)SecOffsetC);
        FuncAddr+=4;
      SecOffsetC+=strlen((char*)SecOffsetC)+1;
    }
    ++SecOffsetC;
    ImPort=*(DWORD*)SecOffsetC;
  }
}
////////////用于处理0xE8,0xE9//////////////C语言表示///////////////有点问题
void ModifyCall(BYTE *Start,int Size)
{
  BYTE DB;
  DWORD DDb;
  DWORD FixAddr=(DWORD)Start;
  WORD DWA;
  BYTE Hi8;
  WORD Lo8;
  while(Size)
  {
    DB=*(BYTE*)Start-0xE8;
    ++Start;
    if(DB>1||*Start!=3)
    {
      continue;
    }
    DDb=*(DWORD*)Start;
    DWA=DDb&0x0ffff;
    DWA>>=8;
    DDb&=0xffff0000;
    DDb|=DWA;
    DDb=((DDb<<0x10)|(DDb>>0x10));
    DWA=DDb&0x0ffff;
    Lo8=((WORD)DWA<<8);
    Hi8=(BYTE)(DWA>>8);
    DWA=(Lo8+Hi8);
    DDb&=0xffff0000;
    DDb|=DWA;
    DDb-=(DWORD)Start;
    *(DWORD*)Start=DDb+FixAddr;
    Start+=4;
    --Size;
  }
}
///////////////////设置区段对齐
void SetSectionAlignment(IMAGE_SECTION_HEADER  *TempSecHeader,int SectionNum,DWORD SecValue)
{
  int AlignValue=0;
    for(int i=0;i<SectionNum;i++)
    {
    AlignValue=Alignment(TempSecHeader->Misc.VirtualSize, SecValue);
    TempSecHeader->SizeOfRawData   =AlignValue;
        TempSecHeader->Misc.VirtualSize=AlignValue;    
    TempSecHeader->PointerToRawData=TempSecHeader->VirtualAddress;
    TempSecHeader++;
    } 
}
BYTE PCode;                                                         //压缩后的代码的文件指针
BYTE *pImage;                                                       //新的映像空间
DWORD ImageSize;                                                    //加壳后的映像大小
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
  DWORD dwWrite;
  LPBYTE lpFile=(LPBYTE)MapFileToMemory("Test.exe");
  if(MemCmpPe(lpFile)==FALSE)
  {
    MessageBoxA(NULL,"PE签名无效","提示",MB_OK);
  }
  DosHeader    =GetDosHeader(lpFile);
  NtHeader     =GetNtHeader(lpFile);
  FileHeader   =GetFileHeader(lpFile);
  OptHeader    =GetOptionalHeader(lpFile);
  SecHeader    =GetSectionHeader(lpFile);
  pIID         =GetFirstImportDesc(lpFile);
/////////////////////处理第一个区段,并复制到内存中
  ImageSize=Alignment(OptHeader->SizeOfImage,OptHeader->SectionAlignment);//获得加壳后的映像大小,也就是虚拟空间大小
  pImage =VirtualAlloc(NULL,ImageSize,MEM_COMMIT,PAGE_READWRITE);         //分配新的PE映像空间
  memcpy(pImage,lpFile,OptHeader->SizeOfHeaders);                         //复制PE头到新分配的映像控件里面
  IMAGE_SECTION_HEADER  *TempSecHeader   =SecHeader;                      //临时区段结构
////////////////////依次复制区段到新的PE的区段里面去
  for(int i=0;i<FileHeader->NumberOfSections;i++)                         //依次复制代码到新的映像空间里面
  {
    memcpy(pImage+TempSecHeader->VirtualAddress,                        //接收代码的映像地址
      lpFile+TempSecHeader->PointerToRawData,                         //复制代码的文件偏移地址
      Alignment(TempSecHeader->SizeOfRawData,OptHeader->FileAlignment)//复制代码大小以文件大小和对齐计算
      );                                         
    ++TempSecHeader;
  }
////////////////////修正Image里面的PE头
    IMAGE_NT_HEADERS *NewNtHeader         = GetNtHeader(pImage);  //NT头
    IMAGE_SECTION_HEADER  *NewSecHeader   = GetSectionHeader(pImage);
  IMAGE_OPTIONAL_HEADER *NewOptHeader    =GetOptionalHeader(pImage);
////////////////////设置入口点
    NewNtHeader->OptionalHeader.AddressOfEntryPoint=0x1020;
////////////////////文件对齐方式
    NewNtHeader->OptionalHeader.SizeOfImage   =Alignment(NewOptHeader->SizeOfImage,NewOptHeader->SectionAlignment);
    NewNtHeader->OptionalHeader.FileAlignment =NewOptHeader->FileAlignment;
    NewNtHeader->OptionalHeader.SizeOfHeaders =NewSecHeader->VirtualAddress; 
////////////////////修正区段位置和大小 
  SetSectionAlignment(NewSecHeader,NewNtHeader->FileHeader.NumberOfSections,0x1000);       //修复区段对齐
////////////////////开始解压代码
  UnCompress(pImage+SecHeader->VirtualAddress,(BYTE*)lpFile+SecHeader->PointerToRawData);      //从只读内存中得压缩代码解压回映像空间
   //DisposureE8(pImage+SecHeader->VirtualAddress,0x84);                                      //现在处理E8
  ModifyCall(pImage+SecHeader->VirtualAddress,0x84);
////////////////////修复输入表
    ModifyImport((DWORD)pImage+0x1000,0x9000,(DWORD)pImage+0xC000); 
////////////////////修改区段名字
    ModifySecName(GetSectionHeader(pImage),3);                                                              
///////////////////写入文件
  HANDLE Handle=CreateFile("UnpackMe.exe", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
  SetFilePointer(Handle,0,0,FILE_BEGIN);
  WriteFile(Handle,pImage,ImageSize,&dwWrite,NULL);
  MessageBox(NULL,"脱壳成功","UnpackMe",MB_OK);
  return TRUE;
}
上传的附件 UnPackMe.zip