mirror of
https://github.com/r00tkiter/PE2Shellcode
synced 2026-06-08 16:53:41 +00:00
335 lines
6.5 KiB
C++
335 lines
6.5 KiB
C++
#include "PePacket.h"
|
|
#include "ProccessData.h"
|
|
#include "resource.h"
|
|
CPePacket::CPePacket()
|
|
{
|
|
rc4Flag = FALSE;
|
|
cmpFlag = FALSE;
|
|
data = NULL;
|
|
head = NULL;
|
|
shellcode = NULL;
|
|
dataSize = 0;
|
|
}
|
|
CPePacket::~CPePacket()
|
|
{
|
|
if (data != NULL)
|
|
delete data;
|
|
data = NULL;
|
|
|
|
if (head != NULL)
|
|
delete head;
|
|
head = NULL;
|
|
|
|
if (shellcode != NULL)
|
|
delete shellcode;
|
|
shellcode = NULL;
|
|
|
|
dataSize = 0;
|
|
headSize = 0;
|
|
shellSize = 0;
|
|
}
|
|
|
|
|
|
int CPePacket::ParsePara(int argc, wchar_t ** argv)
|
|
{
|
|
if (argc <= 2)
|
|
{
|
|
printf("Used : PE2Shellcode.exe <path of PE>[output path] [-?]\n");
|
|
printf("[-r] Rc4 encrypt\n");
|
|
printf("[-c] Compress PE file\n");
|
|
return 1;
|
|
}
|
|
|
|
srcExePath = argv[1];
|
|
targetBinPath = argv[2];
|
|
|
|
if (argc > 2)
|
|
{
|
|
for (int i = 3; i < argc; i++)
|
|
{
|
|
if (wcscmp(L"-r", argv[i]) == 0 && wcslen(argv[i]) == 2)
|
|
rc4Flag = true;
|
|
|
|
else if (wcscmp(L"-c", argv[i]) == 0 && wcslen(argv[i]) == 2)
|
|
cmpFlag = true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL CPePacket::IsExeFile()
|
|
{
|
|
#ifdef _WIN64
|
|
int bit = 64;
|
|
#else
|
|
int bit = 32;
|
|
#endif
|
|
|
|
|
|
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)data;
|
|
|
|
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(data + pDos->e_lfanew);
|
|
|
|
if (pDos->e_magic != IMAGE_DOS_SIGNATURE)
|
|
{
|
|
printf("[!] The file is not PE file.\n");
|
|
return 1;
|
|
}
|
|
if (pNt->Signature != IMAGE_NT_SIGNATURE)
|
|
{
|
|
printf("[!] The file is not PE file.\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((pNt->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL)
|
|
{
|
|
printf("[!] DLL file is not supported.\n");
|
|
return 1;
|
|
}
|
|
|
|
DWORD offsetDonet = pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
|
|
if (offsetDonet)
|
|
{
|
|
printf("[!] .NET applications are not supported.\n");
|
|
return 1;
|
|
}
|
|
|
|
if (pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && bit == 32)
|
|
{
|
|
return 0;
|
|
}
|
|
else if ((pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 ||
|
|
pNt->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) && bit == 64)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
printf("[!] Bits of PE file is not match.\n");
|
|
return 1;
|
|
}
|
|
|
|
int CPePacket::ReadFileContent()
|
|
{
|
|
|
|
char buffer[1024];
|
|
DWORD filesize;
|
|
DWORD dwReadBytes;
|
|
int Result = 0;
|
|
|
|
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
do
|
|
{
|
|
hFile = CreateFileW(srcExePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Open src file failed.ErrorCode:%d\n", Result);
|
|
break;
|
|
}
|
|
filesize = GetFileSize(hFile, NULL);
|
|
data = new char[filesize];
|
|
char *p = data;
|
|
while (1)
|
|
{
|
|
if (!ReadFile(hFile, buffer, 1024, &dwReadBytes, NULL))
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] ReadFile failed.ErrorCode:%d\n", Result);
|
|
break;
|
|
}
|
|
if (dwReadBytes == 0)
|
|
break;
|
|
memcpy(p, buffer, dwReadBytes);
|
|
p += dwReadBytes;
|
|
dataSize += dwReadBytes;
|
|
}
|
|
} while (FALSE);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hFile);
|
|
|
|
return Result;
|
|
}
|
|
|
|
int CPePacket::CreateBinFile()
|
|
{
|
|
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
DWORD dwWriteBytes;
|
|
int Result = 0;
|
|
do
|
|
{
|
|
hFile = CreateFileW(targetBinPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Create bin file failed. ErrorCode:%d\n", Result);
|
|
break;
|
|
}
|
|
if (!WriteFile(hFile, shellcode, shellSize, &dwWriteBytes, NULL) ||
|
|
!WriteFile(hFile, head, headSize, &dwWriteBytes, NULL) ||
|
|
!WriteFile(hFile, data, dataSize, &dwWriteBytes, NULL)
|
|
)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Write bin file failed. ErrorCode:%d\n", Result);
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
if(hFile != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hFile);
|
|
return Result;
|
|
}
|
|
|
|
|
|
int CPePacket::GetCustomHead()
|
|
{
|
|
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)data;
|
|
|
|
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(data + pDos->e_lfanew);
|
|
|
|
customHead.size = dataSize;
|
|
customHead.numberOfSection = pNt->FileHeader.NumberOfSections;
|
|
customHead.entryPoint = pNt->OptionalHeader.AddressOfEntryPoint;
|
|
customHead.offsetImportTable = pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
|
customHead.offsetRelocation = pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
|
customHead.offsetSection = (DA)((char *)IMAGE_FIRST_SECTION(pNt) - (char *)data);
|
|
customHead.imageAddr = pNt->OptionalHeader.ImageBase;
|
|
|
|
//clear DOS head and NT head
|
|
memset(data, 0, customHead.offsetSection);
|
|
return 0;
|
|
}
|
|
|
|
int CPePacket::GenerateShellCode()
|
|
{
|
|
if (
|
|
ReadFileContent() ||
|
|
IsExeFile() ||
|
|
GetCustomHead() ||
|
|
ProcessData() ||
|
|
GetResourceFile() ||
|
|
PacthCustomHead() ||
|
|
CreateBinFile()
|
|
)
|
|
{
|
|
printf("[-] Generate failed.\n");
|
|
}
|
|
else
|
|
{
|
|
printf("[+] Generate success.\n");
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CPePacket::ProcessData()
|
|
{
|
|
if (cmpFlag)
|
|
{
|
|
if (CProcsData::CompressData(data, dataSize, data, dataSize))
|
|
{
|
|
printf("[-] Compress PE failed.\n");
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
customHead.flag1 = 1;
|
|
customHead.compressSize = dataSize;
|
|
}
|
|
}
|
|
|
|
if (rc4Flag)
|
|
{
|
|
if (CProcsData::Rc4Encrypt(data, dataSize, rc4Key, RC4_KEY_SIZE))
|
|
{
|
|
printf("[-] Rc4 encrypt failed.\n");
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
customHead.flag2 = 1;
|
|
customHead.rc4Size = dataSize;
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CPePacket::GetResourceFile()
|
|
{
|
|
HRSRC hRsrc = NULL;
|
|
DWORD dwSize = 0;
|
|
HGLOBAL hGlobal = NULL;
|
|
LPVOID pBuffer = NULL;
|
|
int Result = 0;
|
|
do
|
|
{
|
|
#ifdef _WIN64
|
|
hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_BIN2), L"BIN");
|
|
#else
|
|
hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_BIN1), L"BIN");
|
|
#endif // _WIN64
|
|
|
|
if (hRsrc == NULL)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Find resource failed. ErrCode:%d\n", Result);
|
|
}
|
|
|
|
DWORD dwSize = SizeofResource(NULL, hRsrc);
|
|
if (dwSize == 0)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Get resource size failed. ErrCode:%d\n", Result);
|
|
}
|
|
|
|
|
|
hGlobal = LoadResource(NULL, hRsrc);
|
|
if (hGlobal == NULL)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Load resource failed. ErrCode:%d\n", Result);
|
|
}
|
|
|
|
pBuffer = LockResource(hGlobal);
|
|
|
|
if (pBuffer == NULL)
|
|
{
|
|
Result = GetLastError();
|
|
printf("[-] Lock resource failed. ErrCode:%d\n", Result);
|
|
}
|
|
|
|
|
|
shellcode = new char[dwSize];
|
|
|
|
memcpy(shellcode, pBuffer, dwSize);
|
|
shellSize = dwSize;
|
|
|
|
} while (FALSE);
|
|
|
|
if(hGlobal != NULL)
|
|
GlobalUnlock(hGlobal);
|
|
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
int CPePacket::PacthCustomHead()
|
|
{
|
|
//patch head
|
|
head = new char[headSize];
|
|
unsigned char sign[] = { '\xaa','\xbb', '\xcc', '\xdd', '\x01', '\x01', '\x01', '\x01'};
|
|
memcpy(head, sign, 8);
|
|
memcpy(head + 8, &customHead, sizeof(CustomHead));
|
|
memcpy(head + 8 + sizeof(CustomHead), rc4Key, sizeof(rc4Key));
|
|
return 0;
|
|
}
|