//ShellDlg.cpp
void CShellDlg::OnButtonBuild()
{
// TODO: Add your control notification handler code here
char * szFilePath;
szFilePath = (char *)malloc(MAX_PATH * sizeof(char));
GetDlgItemText(IDC_EDIT_FILEPATH , szFilePath , MAX_PATH);
StatusCode = STATUS_OK;
MyFile mFile;
if(CheckFileExists(szFilePath)) //文件存在
{
mFile.m_szPath = szFilePath;
if(mFile.GetPEInfo() && mFile.Unpacked()) //是PE文件且未加壳
{
mFile.AddSection(); //添加新节区
mFile.EnCode(); //xor加密
mFile.WriteDeCode(); //添加解密代码
}
else
{
StatusCode = ERROR_FILE_NOT_PE;
goto _PROCESS;
}
}else
{
StatusCode = ERROR_FILE_NOT_EXIST;
goto _PROCESS;
}
free(szFilePath);
_PROCESS:
mFile.Close();
Process(StatusCode);
}
BOOL CShellDlg::CheckFileExists(char* szFilePath)
{
HANDLE hFile;
BOOL bRet=TRUE;
hFile = (HANDLE)CreateFile(szFilePath ,
NULL ,
NULL ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
bRet=FALSE;
return bRet;
}
CloseHandle(hFile);
return bRet;
}
void CShellDlg::Process(int StatusCode)
{
int MaxErrMsgLen = 30;
char* szErrMsg;
szErrMsg = (char *)calloc(MaxErrMsgLen , sizeof(char)); //用calloc初始化元素
switch(StatusCode)
{
case STATUS_OK :
break;
case ERROR_FILE_NOT_EXIST : szErrMsg = MSG_FILE_NOT_EXIST;
break;
case ERROR_FILE_NOT_PE : szErrMsg = MSG_FILE_NOT_PE;
break;
default:
break;
}
if(strcmp(szErrMsg,"")) MessageBox(szErrMsg);
}
MyFile::MyFile() //初始化MyFile类
{
m_szPath = (char *)calloc(MAX_PATH , sizeof(char)); //calloc初始化path
m_pDosHdr = NULL;
m_pNtHdr = NULL;
m_pSecHdr = NULL;
m_hFile = NULL;
m_hMap = NULL;
m_lpBase = NULL;
m_dwImageBase = 0;
m_dwEntryPoint = 0;
m_nXorValue = 0xFF;
}
int MyFile::FileMapViewCreate()
{
m_hFile=CreateFile(m_szPath ,
GENERIC_READ | GENERIC_WRITE ,
FILE_SHARE_READ ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
{
return ERROR_CREATE_FILE;
}
m_hMap = CreateFileMapping(m_hFile , NULL , PAGE_READWRITE , NULL , NULL , NULL);
if(m_hMap == NULL)
{
CloseHandle(m_hFile);
return ERROR_CREATE_FILE_MAPPING;
}
m_lpBase = MapViewOfFile(m_hMap , FILE_MAP_READ | FILE_MAP_WRITE , NULL , NULL , NULL);
if( m_lpBase == NULL)
{
CloseHandle(m_hMap);
CloseHandle(m_hFile);
return ERROR_MAP_VIEW_OF_FILE;
}
return STATUS_OK;
}
BOOL MyFile::GetPEInfo()
{
BOOL bRet=FALSE;
int Status;
Status=FileMapViewCreate();
if(Status == STATUS_OK)
{
m_pDosHdr = (PIMAGE_DOS_HEADER)m_lpBase;
if(m_pDosHdr ->e_magic != IMAGE_DOS_SIGNATURE)
{
return bRet;
}
m_pNtHdr = (PIMAGE_NT_HEADERS)((DWORD)m_lpBase + m_pDosHdr -> e_lfanew);
if(m_pNtHdr ->Signature != IMAGE_NT_SIGNATURE)
{
return bRet;
}
m_pSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)&(m_pNtHdr -> OptionalHeader) +
m_pNtHdr ->FileHeader.SizeOfOptionalHeader);
m_dwImageBase = m_pNtHdr ->OptionalHeader.ImageBase;
m_dwEntryPoint = m_pNtHdr ->OptionalHeader.AddressOfEntryPoint;
m_SecTextHdr = *m_pSecHdr;
bRet=TRUE;
return bRet;
}
return bRet;
}
BOOL MyFile::Unpacked()
{
BOOL bRet = TRUE;
/*
检测是否已加壳
*/
return bRet;
}
void MyFile::AddSection()
{
int nSecNum = m_pNtHdr ->FileHeader.NumberOfSections; //节区数量
int nSecSize = SHELL_SECTION_SIZE;
char szSecName[IMAGE_SIZEOF_SHORT_NAME]=SHELL_SECTION_NAME;
PIMAGE_SECTION_HEADER pTmpSec = m_pSecHdr + nSecNum;
strncpy((char *)pTmpSec ->Name , szSecName , IMAGE_SIZEOF_SHORT_NAME);
DWORD dwFileAlignment = m_pNtHdr ->OptionalHeader.FileAlignment; //文件对齐值
DWORD dwSecAlignment = m_pNtHdr ->OptionalHeader.SectionAlignment; //内存对齐值
/*
CString tmp;
tmp.Format("%ld",dwFileAlignment); //0x200
MessageBox(tmp);
tmp.Format("%ld",dwSecAlignment); //0x1000
MessageBox(tmp);
*/
pTmpSec ->Misc.VirtualSize = AlignSize(nSecSize , dwSecAlignment); //节的内存大小
pTmpSec ->VirtualAddress = m_pSecHdr[nSecNum - 1].VirtualAddress + //节的内存起始位置
AlignSize(m_pSecHdr[nSecNum - 1].Misc.VirtualSize,dwSecAlignment);
pTmpSec ->SizeOfRawData = AlignSize(nSecSize , dwFileAlignment); //节的文件大小
pTmpSec ->PointerToRawData = m_pSecHdr[nSecNum -1].PointerToRawData + //节的文件起始位置
AlignSize(m_pSecHdr[nSecNum -1].SizeOfRawData,dwSecAlignment);
pTmpSec ->Characteristics |= IMAGE_SCN_MEM_WRITE;
m_pNtHdr ->FileHeader.NumberOfSections ++; //修正节数量
m_pNtHdr ->OptionalHeader.SizeOfImage += pTmpSec ->Misc.VirtualSize; //修正镜像大小
PIMAGE_SECTION_HEADER pSecTextHdr = m_pSecHdr;
pSecTextHdr->Characteristics |= IMAGE_SCN_MEM_WRITE; //.text节设为可写
FlushViewOfFile(m_lpBase , NULL); //更新文件映像
AddSecData(pTmpSec ->SizeOfRawData); //添加节的数据
m_SecNewHdr = *pTmpSec;
}
DWORD MyFile::AlignSize(int nSecSize , DWORD Alignment) //对齐
{
int nSize = nSecSize;
if(nSize % Alignment !=0)
{
nSecSize = (nSize / Alignment +1) * Alignment;
}
return nSecSize;
}
void MyFile::AddSecData(int nSecSize)
{
PBYTE pByte = NULL;
pByte =(PBYTE)malloc(nSecSize);
ZeroMemory(pByte, nSecSize);
DWORD dwNum = 0;
SetFilePointer(m_hFile , NULL , NULL , FILE_END);
WriteFile(m_hFile , pByte , nSecSize , &dwNum , NULL);
FlushFileBuffers(m_hFile);
free(pByte);
}
void MyFile::EnCode()
{
DWORD dwRead = 0;
PBYTE pByte = NULL;
pByte = (PBYTE)malloc(m_SecTextHdr.SizeOfRawData);
/*
CString tmp;
tmp.Format("%ld",SecTextInfo.PointerToRawData); //0x400
MessageBox(tmp);
*/
SetFilePointer(m_hFile , m_SecTextHdr.PointerToRawData , NULL , FILE_BEGIN);
ReadFile(m_hFile , pByte , m_SecTextHdr.SizeOfRawData , &dwRead , NULL);
srand((unsigned)time(NULL));
m_nXorValue = 1 + rand() % 0xFF; //[0,RAND_MAX]
for(DWORD i = 0;i < m_SecTextHdr.SizeOfRawData;i ++)
{
pByte[i]^=m_nXorValue; //异或加密
}
SetFilePointer(m_hFile , m_SecTextHdr.PointerToRawData , NULL , FILE_BEGIN);
WriteFile(m_hFile , pByte , m_SecTextHdr.SizeOfRawData , &dwRead , NULL);
free(pByte);
}
void MyFile::WriteDeCode()
{
char DeCode[]=
"\x60"
"\xB8\x00\x00\x00\x00"
"\x80\x30\x00"
"\x40"
"\x3D\x00\x00\x00\x00"
"\x75\xF5"
"\x61"
"\xB8\x00\x00\x00\x00"
"\xFF\xE0";
*(DWORD *)&DeCode[2] = m_dwImageBase + m_SecTextHdr.VirtualAddress; //代码节起始位置
*(BYTE *)&DeCode[8] = m_nXorValue; //异或加密值
*(DWORD *)&DeCode[11] = m_dwImageBase + m_SecTextHdr.VirtualAddress+m_SecTextHdr.SizeOfRawData -1;
*(DWORD *)&DeCode[19] = m_dwImageBase + m_dwEntryPoint;
DWORD dwWrite = 0;
int nSecNum = m_pNtHdr ->FileHeader.NumberOfSections;
MessageBox((char *)m_SecNewHdr.Name);
SetFilePointer(m_hFile , m_SecNewHdr.PointerToRawData , NULL ,FILE_BEGIN);
WriteFile(m_hFile , (LPVOID)DeCode , sizeof(DeCode) , &dwWrite , NULL);
m_pNtHdr ->OptionalHeader.AddressOfEntryPoint = m_SecNewHdr.VirtualAddress; //修改程序入口
}
void MyFile::Close()
{
UnmapViewOfFile(m_lpBase);
CloseHandle(m_hMap);
CloseHandle(m_hFile);
}
//ShellDlg.h
#define STATUS_OK (0x00)
#define ERROR_FILE_NOT_EXIST (0x01) #define ERROR_FILE_NOT_PE (0x02) #define ERROR_CREATE_FILE (0x03) #define ERROR_CREATE_FILE_MAPPING (0x04) #define ERROR_MAP_VIEW_OF_FILE (0x05) #define XOR_VALUE (0x12) #define SHELL_SECTION_SIZE (0x200) #define SHELL_SECTION_NAME ".sh" #define MSG_FILE_NOT_EXIST "文件不存在" #define MSG_FILE_NOT_PE "不是PE文件" class CShellDlg : public CDialog { // Construction public: int StatusCode; //状态码 CShellDlg(CWnd* pParent = NULL); // standard constructor BOOL CheckFileExists(char* szFilePath); void Process(int StatusCode); //错误处理 // Dialog Data //{{AFX_DATA(CShellDlg) enum { IDD = IDD_SHELL_DIALOG }; CListBox m_lstRet; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CShellDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CShellDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButtonBuild(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; class MyFile : public CShellDlg { public: char* m_szPath; MyFile(); int FileMapViewCreate(); BOOL GetPEInfo(); BOOL Unpacked(); void AddSection(); void EnCode(); void WriteDeCode(); void Close(); private: PIMAGE_DOS_HEADER m_pDosHdr; PIMAGE_NT_HEADERS m_pNtHdr; PIMAGE_SECTION_HEADER m_pSecHdr; IMAGE_SECTION_HEADER m_SecTextHdr; IMAGE_SECTION_HEADER m_SecNewHdr; HANDLE m_hFile; HANDLE m_hMap; LPVOID m_lpBase; DWORD m_dwImageBase; DWORD m_dwEntryPoint; BYTE m_nXorValue; DWORD AlignSize(int nSecSize , DWORD Alignment); void AddSecData(int nSecSize); };