mirror of
https://github.com/gmh5225/awesome-game-security
synced 2026-06-21 13:56:22 +00:00
archive: add 5 repo prompt(s) [skip ci]
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,462 @@
|
||||
Project Path: arc_SamLarenN_PePacker_vbahns_o
|
||||
|
||||
Source Tree:
|
||||
|
||||
```txt
|
||||
arc_SamLarenN_PePacker_vbahns_o
|
||||
├── PeCrypter.cpp
|
||||
├── PeCrypter.h
|
||||
├── PeExplorer.cpp
|
||||
├── PeExplorer.h
|
||||
├── README.md
|
||||
├── includes.h
|
||||
└── main.cpp
|
||||
|
||||
```
|
||||
|
||||
`PeCrypter.cpp`:
|
||||
|
||||
```cpp
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
|
||||
PeCrypter::~PeCrypter()
|
||||
{
|
||||
TextSection = nullptr;
|
||||
LastSection = nullptr;
|
||||
g_pPe = nullptr;
|
||||
Key = 0;
|
||||
}
|
||||
|
||||
PeCrypter::PeCrypter(PeExplorer* Pe)
|
||||
{
|
||||
g_pPe = Pe;
|
||||
srand(time(NULL));
|
||||
Key = rand() % 255;
|
||||
|
||||
TextSection = g_pPe->GetSectionByCharacteristics(IMAGE_SCN_CNT_CODE);
|
||||
TextSection->Characteristics |= IMAGE_SCN_MEM_WRITE;
|
||||
|
||||
LastSection = g_pPe->GetLastSection();
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool PeCrypter::PatchBytesByVal(DWORD DestAddress, DWORD SizeOfCode, LPVOID SrcAddress, T ValToLookFor)
|
||||
{
|
||||
for (int i = 0; i < SizeOfCode; ++i)
|
||||
{
|
||||
if (*(T*)(DestAddress + i) == ValToLookFor)
|
||||
{
|
||||
memcpy((PVOID)(DestAddress + i), SrcAddress, sizeof(T));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PeCrypter::EncryptBytes(DWORD Source, DWORD Size)
|
||||
{
|
||||
for (int i = 0; i < Size; ++i)
|
||||
*(BYTE*)(Source + i) ^= Key;
|
||||
}
|
||||
|
||||
|
||||
bool PeCrypter::Crypt(const char* ShellPtr, DWORD ShellSize)
|
||||
{
|
||||
printf("Crypting .text section...\n");
|
||||
|
||||
srand(time(NULL));
|
||||
Key = rand() % 255; // Generate random key
|
||||
|
||||
TextSection = g_pPe->GetSectionByCharacteristics(IMAGE_SCN_CNT_CODE); // Get code section, the name of it might variate. Therefore search for characteristics
|
||||
if (TextSection == nullptr)
|
||||
goto cleanup;
|
||||
TextSection->Characteristics |= IMAGE_SCN_MEM_WRITE; // Add write characteristics for encrypting the section
|
||||
|
||||
LastSection = g_pPe->GetLastSection(); // Get last section for adding stub
|
||||
if (LastSection == nullptr)
|
||||
goto cleanup;
|
||||
|
||||
EncryptBytes((DWORD)g_pPe->pMap + TextSection->PointerToRawData, TextSection->SizeOfRawData); // Encrypt section, keep in mind that the base of the PE mapped into memory is based at pMap not ImageBase
|
||||
// Encrypt the whole section, including alignment, not only VirtualSize
|
||||
|
||||
LastSection->Characteristics |= IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; // Add characteristics for LastSection, preparing it for stub
|
||||
|
||||
DWORD NewEIP = LastSection->VirtualAddress + LastSection->Misc.VirtualSize; // NewEIP should be the VirtualAddress + VirtualSize of the section before adding the stub size
|
||||
DWORD OldEIP = g_pPe->GetOptionalHeader()->AddressOfEntryPoint + g_pPe->GetOptionalHeader()->ImageBase;
|
||||
g_pPe->GetOptionalHeader()->AddressOfEntryPoint = NewEIP;
|
||||
|
||||
LastSection->Misc.VirtualSize += ShellSize; // Add stub size
|
||||
|
||||
DWORD OldRawSize = LastSection->SizeOfRawData;
|
||||
|
||||
DWORD NewRawSize = AlignUp(LastSection->Misc.VirtualSize, g_pPe->GetOptionalHeader()->FileAlignment); // Align the section with FileAlignment. The RawDataSize should be dividable by the FileAlignment
|
||||
LastSection->SizeOfRawData = NewRawSize; // Thats why it should be the VirtualSize rounded up to be dividable by FileAlignment
|
||||
|
||||
g_pPe->GetOptionalHeader()->SizeOfImage += (NewRawSize - OldRawSize); // Add the potentially added size of the section RawSize to SizeOfImage
|
||||
|
||||
DWORD Dst = (DWORD)g_pPe->pMap + LastSection->Misc.VirtualSize - ShellSize + LastSection->PointerToRawData; // The destination to copy the stub to should be the base of the mapped PE + Pointer2RawData - StubSize
|
||||
// This will point to the end of the section VirtualSize and to the beginning of the stub
|
||||
|
||||
DWORD size = TextSection->SizeOfRawData; // The size to be decrypted should be the RawSize of the code section
|
||||
|
||||
DWORD start = TextSection->VirtualAddress + g_pPe->GetOptionalHeader()->ImageBase; // And the start address of the decryption should be the VirtualAddress of the code section + ImageBase, for it's loaded.
|
||||
|
||||
|
||||
memcpy((PVOID)Dst, ShellPtr, ShellSize);
|
||||
|
||||
if (!PatchBytesByVal<DWORD>(Dst, ShellSize, &start, 0xAAAAAAAA)) // Replace the first DWORD of A's with the start address
|
||||
goto cleanup;
|
||||
if (!PatchBytesByVal<DWORD>(Dst, ShellSize, &size, 0xAAAAAAAA)) // Replace the second DWORD of A's with the size
|
||||
goto cleanup;
|
||||
if (!PatchBytesByVal<DWORD>(Dst, ShellSize, &Key, 0xAAAAAAAA)) // Replace the third DWORD of A's with the key
|
||||
goto cleanup;
|
||||
if (!PatchBytesByVal<DWORD>(Dst, ShellSize, &OldEIP, 0xAAAAAAAA)) // Replace the fourth DWORD of A's with the Old Entry Point to return to
|
||||
goto cleanup;
|
||||
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
PeCrypter::~PeCrypter();
|
||||
return false;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`PeCrypter.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
class PeCrypter
|
||||
{
|
||||
public:
|
||||
~PeCrypter();
|
||||
PeCrypter(PeExplorer* g_pPe);
|
||||
bool Crypt(const char* ShellPtr, DWORD ShellSize);
|
||||
|
||||
private:
|
||||
DWORD AlignDown(DWORD val, DWORD align)
|
||||
{
|
||||
return (val & ~(align - 1));
|
||||
}
|
||||
|
||||
DWORD AlignUp(DWORD val, DWORD align)
|
||||
{
|
||||
return ((val & (align - 1)) ? AlignDown(val, align) + align : val);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool PatchBytesByVal(DWORD DestAddress, DWORD SizeOfCode, LPVOID SrcAddress, T ValToLookFor);
|
||||
void EncryptBytes(DWORD Source, DWORD Size);
|
||||
|
||||
DWORD Key = 0;
|
||||
PIMAGE_SECTION_HEADER LastSection = nullptr;
|
||||
PIMAGE_SECTION_HEADER TextSection = nullptr;
|
||||
PeExplorer* g_pPe = nullptr;
|
||||
};
|
||||
|
||||
|
||||
```
|
||||
|
||||
`PeExplorer.cpp`:
|
||||
|
||||
```cpp
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
|
||||
PeExplorer::~PeExplorer()
|
||||
{
|
||||
|
||||
if (pMap != nullptr)
|
||||
{
|
||||
UnmapViewOfFile(pMap);
|
||||
FileSize = -1;
|
||||
pMap = nullptr;
|
||||
}
|
||||
|
||||
SectionHeaderList.clear();
|
||||
pDosHeader = nullptr;
|
||||
pNtHeaders = nullptr;
|
||||
pFileHeader = nullptr;
|
||||
pOptionalHeader = nullptr;
|
||||
}
|
||||
|
||||
// Overloaded Function to map a PE file to memory
|
||||
bool PeExplorer::Explore(const char* FileName, DWORD ExtraSize)
|
||||
{
|
||||
printf("Mapping PE File...\n");
|
||||
|
||||
int retries = 0;
|
||||
HANDLE FileHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
do
|
||||
{
|
||||
FileHandle = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
++retries;
|
||||
Sleep(250);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while (retries < 10);
|
||||
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
PeExplorer::~PeExplorer();
|
||||
printf("File Could Not Be Read. Error: 0x%X\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
FileSize = GetFileSize(FileHandle, NULL);
|
||||
FileSize += ExtraSize;
|
||||
|
||||
HANDLE hMap = CreateFileMapping(FileHandle, NULL, PAGE_READWRITE, 0, FileSize, NULL);
|
||||
if (hMap == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(FileHandle);
|
||||
printf("Could not CreateFileMapping. Error: 0x%X\n", GetLastError());
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMap = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, FileSize);
|
||||
if (pMap == nullptr)
|
||||
{
|
||||
CloseHandle(FileHandle);
|
||||
CloseHandle(hMap);
|
||||
printf("Could not Map File. Error: 0x%X\n", GetLastError());
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CloseHandle(FileHandle);
|
||||
CloseHandle(hMap);
|
||||
|
||||
if (!Explore(pMap))
|
||||
{
|
||||
PeExplorer::~PeExplorer();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overloaded Function to map a PE file to memory
|
||||
bool PeExplorer::Explore(PVOID pPe)
|
||||
{
|
||||
printf("Reading PE File...\n");
|
||||
|
||||
pMap = pPe;
|
||||
|
||||
pDosHeader = static_cast<PIMAGE_DOS_HEADER>(pPe);
|
||||
if (!VerifyDosHeader(pDosHeader->e_magic))
|
||||
{
|
||||
PeExplorer::~PeExplorer();
|
||||
printf("Could not verify DOS header\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD)pDosHeader + pDosHeader->e_lfanew); // pDosHeader + sizeof(DosHeader) + sizeof(DosStub) = pNtHeaders. Keep in mind that dos header + stub does not have constant size
|
||||
if (!VerifyPeHeader(pNtHeaders->Signature))
|
||||
{
|
||||
PeExplorer::~PeExplorer();
|
||||
printf("Could not verify PE header\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pFileHeader = static_cast<PIMAGE_FILE_HEADER>(&pNtHeaders->FileHeader); // Get FileHeader pointer
|
||||
pOptionalHeader = static_cast<PIMAGE_OPTIONAL_HEADER>(&pNtHeaders->OptionalHeader); // Get OptionalHeader pointer
|
||||
|
||||
PIMAGE_SECTION_HEADER pFirstSection = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader); // Address of first section header = pOptionalHeader + sizeof(OptionalHeader)
|
||||
// Keep in mind that OptionalHeader size is not constant use ->SizeOfOptionalHeader
|
||||
for (int i = 0; i < pFileHeader->NumberOfSections; ++i)
|
||||
SectionHeaderList.push_back(pFirstSection + i); // The section headers comes after each other in memory
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PIMAGE_SECTION_HEADER PeExplorer::GetSectionByName(const char* SectionName)
|
||||
{
|
||||
for (auto Section : SectionHeaderList)
|
||||
{
|
||||
if (!memcmp(Section->Name, SectionName, strlen(SectionName)))
|
||||
return Section;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER PeExplorer::GetSectionByCharacteristics(DWORD Characteristics)
|
||||
{
|
||||
for (auto Section : SectionHeaderList)
|
||||
{
|
||||
if (Section->Characteristics & Characteristics)
|
||||
return Section;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER PeExplorer::GetLastSection()
|
||||
{
|
||||
PIMAGE_SECTION_HEADER LastSection = new IMAGE_SECTION_HEADER();
|
||||
for (auto Section : SectionHeaderList)
|
||||
{
|
||||
if (Section->PointerToRawData > LastSection->PointerToRawData)
|
||||
LastSection = Section;
|
||||
}
|
||||
return LastSection;
|
||||
}
|
||||
|
||||
std::vector<PIMAGE_SECTION_HEADER> PeExplorer::GetSectionList()
|
||||
{
|
||||
return SectionHeaderList;
|
||||
}
|
||||
|
||||
PIMAGE_DOS_HEADER PeExplorer::GetDosHeader()
|
||||
{
|
||||
return pDosHeader;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS PeExplorer::GetNtHeaders()
|
||||
{
|
||||
return pNtHeaders;
|
||||
}
|
||||
|
||||
PIMAGE_FILE_HEADER PeExplorer::GetFileHeader()
|
||||
{
|
||||
return pFileHeader;
|
||||
}
|
||||
|
||||
PIMAGE_OPTIONAL_HEADER PeExplorer::GetOptionalHeader()
|
||||
{
|
||||
return pOptionalHeader;
|
||||
}
|
||||
```
|
||||
|
||||
`PeExplorer.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
#define VerifyDosHeader(signature) (signature == (WORD)'ZM' ? true : false)
|
||||
#define VerifyPeHeader(signature) (signature == (WORD)'EP' ? true : false)
|
||||
|
||||
class PeExplorer
|
||||
{
|
||||
public:
|
||||
|
||||
bool Explore(PVOID pPe);
|
||||
bool Explore(const char* FileName, DWORD ExtraSize);
|
||||
PIMAGE_SECTION_HEADER GetSectionByName(const char* SectionName);
|
||||
PIMAGE_SECTION_HEADER GetSectionByCharacteristics(DWORD Characteristics);
|
||||
PIMAGE_SECTION_HEADER GetLastSection();
|
||||
~PeExplorer();
|
||||
|
||||
std::vector<PIMAGE_SECTION_HEADER> GetSectionList();
|
||||
PIMAGE_DOS_HEADER GetDosHeader();
|
||||
PIMAGE_NT_HEADERS GetNtHeaders();
|
||||
PIMAGE_FILE_HEADER GetFileHeader();
|
||||
PIMAGE_OPTIONAL_HEADER GetOptionalHeader();
|
||||
|
||||
LPVOID pMap = nullptr;
|
||||
|
||||
private:
|
||||
|
||||
DWORD FileSize = -1;
|
||||
|
||||
PIMAGE_DOS_HEADER pDosHeader = nullptr;
|
||||
PIMAGE_NT_HEADERS pNtHeaders = nullptr;
|
||||
PIMAGE_FILE_HEADER pFileHeader = nullptr;
|
||||
PIMAGE_OPTIONAL_HEADER pOptionalHeader = nullptr;
|
||||
std::vector<PIMAGE_SECTION_HEADER> SectionHeaderList;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
`README.md`:
|
||||
|
||||
```md
|
||||
# PePacker
|
||||
Simple PE Packer Which Encrypts .text Section
|
||||
I release a simple PE file packer which encrypts the .text section and adds a decryption stub to the end of the last section. The encryption is a simple xor encryption which can easily be developed to something more stronger.
|
||||
|
||||
```
|
||||
|
||||
`includes.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <time.h>
|
||||
|
||||
#include "PeExplorer.h"
|
||||
#include "PeCrypter.h"
|
||||
```
|
||||
|
||||
`main.cpp`:
|
||||
|
||||
```cpp
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
const char shell[] = { 0xB8, 0xAA, 0xAA, 0xAA, 0xAA, // mov eax, 0xAAAAAAAA
|
||||
0x89, 0xC1, // mov ecx, eax
|
||||
0x81, 0xC1, 0xAA, 0xAA, 0xAA, 0xAA, // add ecx, 0xAAAAAAAA
|
||||
0xBA, 0xAA, 0xAA, 0xAA, 0xAA, // mov edx, 0xAAAAAAAA
|
||||
// l1:
|
||||
0x30, 0x10, // xor byte[eax], edx
|
||||
0x40, // inc eax
|
||||
0x39, 0xC8, // cmp eax, ecx
|
||||
0x75, 0xF9, // jne l1
|
||||
0x68, 0xAA, 0xAA, 0xAA, 0xAA, // push 0xAAAAAAAA
|
||||
0xC3 }; // ret
|
||||
|
||||
DWORD Size = sizeof(shell);
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("usage: filename.exe");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PeExplorer* g_pPe = new PeExplorer();
|
||||
|
||||
if (!g_pPe->Explore(argv[1], Size))
|
||||
{
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PeCrypter* g_pCrypt = new PeCrypter(g_pPe);
|
||||
if (!g_pCrypt->Crypt(shell, Size))
|
||||
{
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
g_pPe->~PeExplorer();
|
||||
g_pCrypt->~PeCrypter();
|
||||
|
||||
|
||||
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user