├── Concept.odp ├── Images ├── Concept_01.PNG └── Concept_02.PNG ├── Fatpack ├── CommandLine │ ├── Option.h │ ├── CommandLine.h │ └── CommandLine.cpp ├── Compressor │ ├── lzma │ │ ├── lzma_header.h │ │ ├── pavlov │ │ │ ├── 7zVersion.h │ │ │ ├── 7zCrc.h │ │ │ ├── 7zBuf.c │ │ │ ├── Alloc.h │ │ │ ├── 7zBuf.h │ │ │ ├── Bcj2.h │ │ │ ├── 7zCrc.c │ │ │ ├── 7zBuf2.c │ │ │ ├── 7zFile.h │ │ │ ├── LzmaLib.c │ │ │ ├── BraIA64.c │ │ │ ├── Bra.h │ │ │ ├── LzHash.h │ │ │ ├── CpuArch.h │ │ │ ├── Bra86.c │ │ │ ├── LzmaEnc.h │ │ │ ├── Alloc.c │ │ │ ├── LzFind.h │ │ │ ├── Bra.c │ │ │ ├── Bcj2.c │ │ │ ├── 7zStream.c │ │ │ ├── LzmaLib.h │ │ │ ├── Types.h │ │ │ └── 7zFile.c │ │ ├── lzip_header.h │ │ ├── wrapper │ │ │ ├── easylzmawrapper.h │ │ │ └── easylzmawrapper.cpp │ │ ├── common_internal.c │ │ ├── easylzma │ │ │ ├── decompress.h │ │ │ ├── compress.h │ │ │ └── common.h │ │ ├── common_internal.h │ │ ├── lzip_header.c │ │ └── lzma_header.c │ ├── Compressor.h │ └── Compressor.cpp ├── BinaryFileWriter │ ├── BinaryFileWriter.h │ └── BinaryFileWriter.cpp ├── Console │ ├── Console.h │ └── Console.cpp ├── Error │ └── Error.h ├── PostBuildStep_Debug.bat ├── PostBuildStep_Release.bat ├── IconExtractor │ └── IconExtractor.h ├── Packer │ ├── PackerUtils.h │ ├── ResourcePacker.h │ ├── SectionPacker.h │ ├── ResourcePacker.cpp │ ├── PackerUtils.cpp │ └── SectionPacker.cpp ├── ManifestExtractor │ ├── ManifestExtractor.h │ └── ManifestExtractor.cpp ├── main.cpp └── PEFile │ └── PEFile.h ├── .gitignore ├── Shared ├── Decompressor │ ├── Decompressor.h │ ├── Decompressor.cpp │ └── TinyLzmaDecompress.h ├── ResourceLoader │ ├── ResourceLoader.h │ └── ResourceLoader.cpp ├── PELoader │ ├── PELoader │ │ ├── PEFile.cpp │ │ ├── PEImage.cpp │ │ ├── PEFile.h │ │ ├── PEImage.h │ │ ├── TlsResolver.h │ │ ├── PELoader.h │ │ └── TlsResolver.cpp │ ├── TlsCallbackProxy │ │ └── TlsCallbackProxy.h │ └── TypeDefs │ │ └── peb.h ├── BinaryFileReader │ ├── BinaryFileReader.h │ └── BinaryFileReader.cpp ├── PELoaderStub │ ├── SectionLoaderStub.h │ ├── ResourceLoaderStub.h │ ├── ResourceLoaderStub.cpp │ └── SectionLoaderStub.cpp ├── ApiCaller │ ├── ApiCaller.h │ └── ApiCaller.cpp └── CRT │ ├── crt.h │ ├── crt.cpp │ └── crt_tls.h ├── ResourceAdder ├── ResourceAdder.vcxproj.filters └── main.cpp ├── LICENSE ├── Licenses ├── LICENSE_TinyZZZ.txt ├── LICENSE_PeLoader.txt └── README_Easylzma.txt ├── Loader_Console_Section ├── main.cpp └── Loader_Console_Section.vcxproj.filters ├── Loader_Windows_Section ├── main.cpp └── Loader_Windows_Section.vcxproj.filters ├── Loader_Console_Resource ├── main.cpp └── Loader_Console_Resource.vcxproj.filters ├── Loader_Windows_Resource ├── main.cpp └── Loader_Windows_Resource.vcxproj.filters ├── Fatpack.sln └── README.md /Concept.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fatmike-GH/Fatpack/HEAD/Concept.odp -------------------------------------------------------------------------------- /Images/Concept_01.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fatmike-GH/Fatpack/HEAD/Images/Concept_01.PNG -------------------------------------------------------------------------------- /Images/Concept_02.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fatmike-GH/Fatpack/HEAD/Images/Concept_02.PNG -------------------------------------------------------------------------------- /Fatpack/CommandLine/Option.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace CommandLine 5 | { 6 | enum class Option 7 | { 8 | Resource = 0, 9 | Section 10 | }; 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | *.user 6 | /build 7 | /.vs 8 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/lzma_header.h: -------------------------------------------------------------------------------- 1 | #ifndef __EASYLZMA_LZMA_HEADER__ 2 | #define __EASYLZMA_LZMA_HEADER__ 3 | 4 | #include "common_internal.h" 5 | 6 | /* LZMA-Alone header format gleaned from reading Igor's code */ 7 | 8 | void initializeLZMAFormatHandler(struct elzma_format_handler * hand); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zVersion.h: -------------------------------------------------------------------------------- 1 | #define MY_VER_MAJOR 4 2 | #define MY_VER_MINOR 63 3 | #define MY_VER_BUILD 0 4 | #define MY_VERSION "4.63" 5 | #define MY_DATE "2008-12-31" 6 | #define MY_COPYRIGHT ": Igor Pavlov : Public domain" 7 | #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE 8 | -------------------------------------------------------------------------------- /Shared/Decompressor/Decompressor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Decompressor 5 | { 6 | class Decompressor 7 | { 8 | public: 9 | Decompressor(); 10 | ~Decompressor(); 11 | 12 | bool Decompress(BYTE* source, size_t sourceLength, BYTE** decompressed, size_t* compressedSize); 13 | }; 14 | } -------------------------------------------------------------------------------- /Fatpack/BinaryFileWriter/BinaryFileWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace BinaryFileWriter 5 | { 6 | class BinaryFileWriter 7 | { 8 | public: 9 | BinaryFileWriter(); 10 | ~BinaryFileWriter(); 11 | 12 | bool WriteFile(LPCWSTR fileName, BYTE* buffer, DWORD bufferSize); 13 | }; 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /Fatpack/Compressor/Compressor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Compressor 5 | { 6 | class Compressor 7 | { 8 | public: 9 | Compressor(); 10 | ~Compressor(); 11 | 12 | bool Compress(BYTE* source, size_t sourceLength, BYTE** compressed, size_t* compressedSize); 13 | void Free(BYTE* compressed); 14 | }; 15 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/lzip_header.h: -------------------------------------------------------------------------------- 1 | #ifndef __EASYLZMA_LZIP_HEADER__ 2 | #define __EASYLZMA_LZIP_HEADER__ 3 | 4 | #include "common_internal.h" 5 | 6 | /* lzip file format documented here: 7 | * http://download.savannah.gnu.org/releases-noredirect/lzip/manual/ */ 8 | 9 | void initializeLZIPFormatHandler(struct elzma_format_handler * hand); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Shared/ResourceLoader/ResourceLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ResourceLoader 5 | { 6 | class ResourceLoader 7 | { 8 | public: 9 | ResourceLoader(); 10 | ~ResourceLoader(); 11 | 12 | BYTE* LoadResource(LPCWSTR resourceName, LPCWSTR resourceType, DWORD& resourceSize); 13 | void Free(BYTE* resourceBuffer); 14 | }; 15 | } -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/PEFile.cpp: -------------------------------------------------------------------------------- 1 | #include "PEFile.h" 2 | 3 | namespace PELoader 4 | { 5 | PEFile::PEFile(LPVOID fileBuffer) 6 | { 7 | _buffer = (BYTE*)fileBuffer; 8 | _PIMAGE_DOS_HEADER = (PIMAGE_DOS_HEADER)_buffer; 9 | _PIMAGE_NT_HEADERS = (PIMAGE_NT_HEADERS)(_buffer + _PIMAGE_DOS_HEADER->e_lfanew); 10 | _PIMAGE_SECTION_HEADER = IMAGE_FIRST_SECTION(_PIMAGE_NT_HEADERS); 11 | } 12 | 13 | PEFile::~PEFile() 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /Shared/PELoader/TlsCallbackProxy/TlsCallbackProxy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "..\..\CRT\crt_tls.h" 4 | 5 | void TlsCallbackProxy(PVOID hModule, DWORD dwReason, PVOID pContext); 6 | 7 | #pragma comment (linker, "/INCLUDE:_tls_used") 8 | #pragma comment (linker, "/INCLUDE:tls_callback_func") 9 | 10 | #pragma const_seg(".CRT$XLB") 11 | EXTERN_C const PIMAGE_TLS_CALLBACK tls_callback_func = (PIMAGE_TLS_CALLBACK)TlsCallbackProxy; 12 | 13 | #pragma const_seg() -------------------------------------------------------------------------------- /Shared/BinaryFileReader/BinaryFileReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace BinaryFileReader 5 | { 6 | class BinaryFileReader 7 | { 8 | public: 9 | BinaryFileReader(const wchar_t* fileName); 10 | ~BinaryFileReader(); 11 | 12 | BYTE* GetBuffer() { return _buffer; } 13 | DWORD GetBufferSize() { return _bufferSize; } 14 | 15 | private: 16 | void Cleanup(); 17 | 18 | private: 19 | BYTE* _buffer; 20 | DWORD _bufferSize; 21 | }; 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /Shared/Decompressor/Decompressor.cpp: -------------------------------------------------------------------------------- 1 | #include "Decompressor.h" 2 | #include "TinyLzmaDecompress.h" 3 | #include "..\..\Shared\CRT\crt.h" 4 | 5 | namespace Decompressor 6 | { 7 | Decompressor::Decompressor() 8 | { 9 | } 10 | 11 | Decompressor::~Decompressor() 12 | { 13 | } 14 | 15 | bool Decompressor::Decompress(BYTE* source, size_t sourceLength, BYTE** decompressed, size_t* uncompressedSize) 16 | { 17 | return (tinyLzmaDecompress(source, sourceLength, decompressed, uncompressedSize) == 0); 18 | } 19 | } -------------------------------------------------------------------------------- /Fatpack/Console/Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "..\Error\Error.h" 4 | 5 | namespace Console 6 | { 7 | class Console 8 | { 9 | public: 10 | Console(); 11 | ~Console(); 12 | 13 | void WriteLine(const wchar_t* text); 14 | void WriteError(Error::ErrorCode errorCode); 15 | void WriteError(const wchar_t* text); 16 | void ShowHelp(); 17 | 18 | private: 19 | const wchar_t* GetErrorString(Error::ErrorCode code); 20 | 21 | private: 22 | HANDLE _consoleHandle; 23 | }; 24 | } -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/PEImage.cpp: -------------------------------------------------------------------------------- 1 | #include "PEImage.h" 2 | 3 | namespace PELoader 4 | { 5 | PEImage::PEImage(LPVOID imageBase) 6 | { 7 | _imageBase = imageBase; 8 | _PIMAGE_DOS_HEADER = (PIMAGE_DOS_HEADER)_imageBase; 9 | _PIMAGE_NT_HEADERS = (PIMAGE_NT_HEADERS)((BYTE*)_imageBase + _PIMAGE_DOS_HEADER->e_lfanew); 10 | _PIMAGE_SECTION_HEADER = IMAGE_FIRST_SECTION(_PIMAGE_NT_HEADERS); 11 | _entryPoint = (BYTE*)_imageBase + _PIMAGE_NT_HEADERS->OptionalHeader.AddressOfEntryPoint; 12 | } 13 | 14 | PEImage::~PEImage() 15 | { 16 | } 17 | } -------------------------------------------------------------------------------- /Fatpack/Error/Error.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Error 4 | { 5 | enum class ErrorCode 6 | { 7 | Ok = 0, 8 | Error_Argument_Count, 9 | Error_Equal_Filenames, 10 | Error_Unknown_Option, 11 | Error_Read_File, 12 | Error_Load_Pe_From_Buffer, 13 | Error_Pe_Not_Valid, 14 | Error_Pe_Not_x64, 15 | Error_Pe_Not_Native, 16 | Error_Loading_Loader_Stub, 17 | Error_Saving_Pe, 18 | Error_Adding_Icon, 19 | Error_Adding_Manifest, 20 | Error_Rebasing, 21 | Error_Compressing, 22 | Error_Appending_Compressed_Data 23 | }; 24 | } -------------------------------------------------------------------------------- /Fatpack/PostBuildStep_Debug.bat: -------------------------------------------------------------------------------- 1 | cd.. 2 | cd build 3 | cd x64 4 | cd Debug 5 | 6 | START /WAIT ResourceAdder Loader_Console_Resource.exe Fatpack.exe 1000 7 | powershell -command "Start-Sleep -Milliseconds 1000" 8 | START /WAIT ResourceAdder Loader_Windows_Resource.exe Fatpack.exe 1001 9 | powershell -command "Start-Sleep -Milliseconds 1000" 10 | 11 | START /WAIT ResourceAdder Loader_Console_Section.exe Fatpack.exe 1002 12 | powershell -command "Start-Sleep -Milliseconds 1000" 13 | START /WAIT ResourceAdder Loader_Windows_Section.exe Fatpack.exe 1003 14 | powershell -command "Start-Sleep -Milliseconds 1000" -------------------------------------------------------------------------------- /Fatpack/PostBuildStep_Release.bat: -------------------------------------------------------------------------------- 1 | cd.. 2 | cd build 3 | cd x64 4 | cd Release 5 | 6 | START /WAIT ResourceAdder Loader_Console_Resource.exe Fatpack.exe 1000 7 | powershell -command "Start-Sleep -Milliseconds 1000" 8 | START /WAIT ResourceAdder Loader_Windows_Resource.exe Fatpack.exe 1001 9 | powershell -command "Start-Sleep -Milliseconds 1000" 10 | 11 | START /WAIT ResourceAdder Loader_Console_Section.exe Fatpack.exe 1002 12 | powershell -command "Start-Sleep -Milliseconds 1000" 13 | START /WAIT ResourceAdder Loader_Windows_Section.exe Fatpack.exe 1003 14 | powershell -command "Start-Sleep -Milliseconds 1000" -------------------------------------------------------------------------------- /Fatpack/IconExtractor/IconExtractor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define CUSTOM_ICON_GROUP_ID 100 // Custom ID for RT_GROUP_ICON 5 | #define CUSTOM_ICON_BASE_ID 101 // Custom base ID for RT_ICON entries 6 | 7 | namespace IconExtractor 8 | { 9 | class IconExtractor 10 | { 11 | public: 12 | IconExtractor(); 13 | ~IconExtractor(); 14 | 15 | bool ExtractAndSetIcon(LPWSTR sourceExe, LPWSTR targetExe); 16 | bool ExtractAndSetIconWithCustomIds(LPWSTR sourceExe, LPWSTR targetExe); 17 | 18 | private: 19 | static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam); 20 | }; 21 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zCrc.h: -------------------------------------------------------------------------------- 1 | /* 7zCrc.h -- CRC32 calculation 2 | 2008-03-13 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __7Z_CRC_H 7 | #define __7Z_CRC_H 8 | 9 | #include 10 | 11 | #include "Types.h" 12 | 13 | extern UInt32 g_CrcTable[]; 14 | 15 | void MY_FAST_CALL CrcGenerateTable(void); 16 | 17 | #define CRC_INIT_VAL 0xFFFFFFFF 18 | #define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF) 19 | #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) 20 | 21 | UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); 22 | UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zBuf.c: -------------------------------------------------------------------------------- 1 | /* 7zBuf.c -- Byte Buffer 2 | 2008-03-28 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #include "7zBuf.h" 7 | 8 | void Buf_Init(CBuf *p) 9 | { 10 | p->data = 0; 11 | p->size = 0; 12 | } 13 | 14 | int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) 15 | { 16 | p->size = 0; 17 | if (size == 0) 18 | { 19 | p->data = 0; 20 | return 1; 21 | } 22 | p->data = (Byte *)alloc->Alloc(alloc, size); 23 | if (p->data != 0) 24 | { 25 | p->size = size; 26 | return 1; 27 | } 28 | return 0; 29 | } 30 | 31 | void Buf_Free(CBuf *p, ISzAlloc *alloc) 32 | { 33 | alloc->Free(alloc, p->data); 34 | p->data = 0; 35 | p->size = 0; 36 | } 37 | -------------------------------------------------------------------------------- /Fatpack/Compressor/Compressor.cpp: -------------------------------------------------------------------------------- 1 | #include "Compressor.h" 2 | #include "lzma\wrapper\easylzmawrapper.h" 3 | 4 | namespace Compressor 5 | { 6 | Compressor::Compressor() 7 | { 8 | } 9 | 10 | Compressor::~Compressor() 11 | { 12 | } 13 | 14 | bool Compressor::Compress(BYTE* source, size_t sourceLength, BYTE** compressed, size_t* compressedSize) 15 | { 16 | int result = simpleCompress(ELZMA_lzma, source, sourceLength, compressed, compressedSize); 17 | return (result == ELZMA_E_OK && *compressed != nullptr && *compressedSize != 0); 18 | } 19 | 20 | void Compressor::Free(BYTE* compressed) 21 | { 22 | if (compressed == nullptr) return; 23 | free(compressed); 24 | } 25 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Alloc.h: -------------------------------------------------------------------------------- 1 | /* Alloc.h -- Memory allocation functions 2 | 2008-03-13 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __COMMON_ALLOC_H 7 | #define __COMMON_ALLOC_H 8 | 9 | #include 10 | 11 | void *MyAlloc(size_t size); 12 | void MyFree(void *address); 13 | 14 | #ifdef _WIN32 15 | 16 | void SetLargePageSize(); 17 | 18 | void *MidAlloc(size_t size); 19 | void MidFree(void *address); 20 | void *BigAlloc(size_t size); 21 | void BigFree(void *address); 22 | 23 | #else 24 | 25 | #define MidAlloc(size) MyAlloc(size) 26 | #define MidFree(address) MyFree(address) 27 | #define BigAlloc(size) MyAlloc(size) 28 | #define BigFree(address) MyFree(address) 29 | 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zBuf.h: -------------------------------------------------------------------------------- 1 | /* 7zBuf.h -- Byte Buffer 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_BUF_H 5 | #define __7Z_BUF_H 6 | 7 | #include "Types.h" 8 | 9 | typedef struct 10 | { 11 | Byte *data; 12 | size_t size; 13 | } CBuf; 14 | 15 | void Buf_Init(CBuf *p); 16 | int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); 17 | void Buf_Free(CBuf *p, ISzAlloc *alloc); 18 | 19 | typedef struct 20 | { 21 | Byte *data; 22 | size_t size; 23 | size_t pos; 24 | } CDynBuf; 25 | 26 | void DynBuf_Construct(CDynBuf *p); 27 | void DynBuf_SeekToBeg(CDynBuf *p); 28 | int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); 29 | void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /ResourceAdder/ResourceAdder.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | BinaryFileReader 7 | 8 | 9 | 10 | 11 | {3cefc128-4c6a-46e4-b9ea-532d6421101c} 12 | 13 | 14 | 15 | 16 | BinaryFileReader 17 | 18 | 19 | -------------------------------------------------------------------------------- /Shared/Decompressor/TinyLzmaDecompress.h: -------------------------------------------------------------------------------- 1 | // TinyLZMA 2 | // Source from https://github.com/WangXuan95/TinyLzma 3 | 4 | 5 | #ifndef __TINY_LZMA_DECOMPRESS_H__ 6 | #define __TINY_LZMA_DECOMPRESS_H__ 7 | 8 | #include 9 | 10 | int tinyLzmaDecompress (const uint8_t *p_src, size_t src_len, uint8_t** p_dst, size_t *p_dst_len); 11 | 12 | // return codes of tinyLzmaDecompressor -------------------- 13 | #define R_OK 0 14 | #define R_ERR_MEMORY_RUNOUT 1 15 | #define R_ERR_UNSUPPORTED 2 16 | #define R_ERR_OUTPUT_OVERFLOW 3 17 | #define R_ERR_INPUT_OVERFLOW 4 18 | #define R_ERR_DATA 5 19 | #define R_ERR_OUTPUT_LEN_MISMATCH 6 20 | 21 | #endif // __TINY_LZMA_DECOMPRESS_H__ 22 | -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/PEFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PELoader 5 | { 6 | class PEFile 7 | { 8 | public: 9 | PEFile(LPVOID fileBuffer); 10 | ~PEFile(); 11 | 12 | const PIMAGE_DOS_HEADER DOS_HEADER() { return _PIMAGE_DOS_HEADER; } 13 | const PIMAGE_NT_HEADERS NT_HEADERS() { return _PIMAGE_NT_HEADERS; } 14 | const PIMAGE_SECTION_HEADER SECTION_HEADER() { return _PIMAGE_SECTION_HEADER; } 15 | 16 | BYTE* GetBuffer() { return _buffer; } 17 | uintptr_t GetImageBase() { return _PIMAGE_NT_HEADERS->OptionalHeader.ImageBase; } 18 | 19 | private: 20 | BYTE* _buffer; 21 | 22 | PIMAGE_DOS_HEADER _PIMAGE_DOS_HEADER; 23 | PIMAGE_NT_HEADERS _PIMAGE_NT_HEADERS; 24 | PIMAGE_SECTION_HEADER _PIMAGE_SECTION_HEADER; 25 | }; 26 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Bcj2.h: -------------------------------------------------------------------------------- 1 | /* Bcj2.h -- Converter for x86 code (BCJ2) 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __BCJ2_H 5 | #define __BCJ2_H 6 | 7 | #include "Types.h" 8 | 9 | /* 10 | Conditions: 11 | outSize <= FullOutputSize, 12 | where FullOutputSize is full size of output stream of x86_2 filter. 13 | 14 | If buf0 overlaps outBuf, there are two required conditions: 15 | 1) (buf0 >= outBuf) 16 | 2) (buf0 + size0 >= outBuf + FullOutputSize). 17 | 18 | Returns: 19 | SZ_OK 20 | SZ_ERROR_DATA - Data error 21 | */ 22 | 23 | int Bcj2_Decode( 24 | const Byte *buf0, SizeT size0, 25 | const Byte *buf1, SizeT size1, 26 | const Byte *buf2, SizeT size2, 27 | const Byte *buf3, SizeT size3, 28 | Byte *outBuf, SizeT outSize); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zCrc.c: -------------------------------------------------------------------------------- 1 | /* 7zCrc.c -- CRC32 calculation 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #include "7zCrc.h" 7 | 8 | #define kCrcPoly 0xEDB88320 9 | UInt32 g_CrcTable[256]; 10 | 11 | void MY_FAST_CALL CrcGenerateTable(void) 12 | { 13 | UInt32 i; 14 | for (i = 0; i < 256; i++) 15 | { 16 | UInt32 r = i; 17 | int j; 18 | for (j = 0; j < 8; j++) 19 | r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 20 | g_CrcTable[i] = r; 21 | } 22 | } 23 | 24 | UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) 25 | { 26 | const Byte *p = (const Byte *)data; 27 | for (; size > 0 ; size--, p++) 28 | v = CRC_UPDATE_BYTE(v, *p); 29 | return v; 30 | } 31 | 32 | UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) 33 | { 34 | return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF; 35 | } 36 | -------------------------------------------------------------------------------- /Shared/PELoaderStub/SectionLoaderStub.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PELoader 5 | { 6 | class PEImage; 7 | class TlsResolver; 8 | } 9 | 10 | namespace ResourceLoader 11 | { 12 | class ResourceLoader; 13 | } 14 | 15 | namespace PELoaderStub 16 | { 17 | class SectionLoaderStub 18 | { 19 | public: 20 | SectionLoaderStub(); 21 | ~SectionLoaderStub(); 22 | 23 | PELoader::PEImage* Load(PELoader::TlsResolver* tlsResolver); 24 | 25 | private: 26 | PELoader::PEImage* LoadFromSection(PELoader::TlsResolver* tlsResolver); 27 | BYTE* GetLastSection(DWORD& rawSize, DWORD& virtualSize); 28 | BYTE* Decompress(BYTE* compressedData, DWORD compressedSize, size_t& decompressedSize); 29 | PELoader::PEImage* CreatePEImageFromMemory(BYTE* peFileBuffer, PELoader::TlsResolver* tlsResolver, LPVOID allocatedImageBase = nullptr); 30 | }; 31 | } -------------------------------------------------------------------------------- /Shared/PELoaderStub/ResourceLoaderStub.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PELoader 5 | { 6 | class PEImage; 7 | class TlsResolver; 8 | } 9 | 10 | namespace ResourceLoader 11 | { 12 | class ResourceLoader; 13 | } 14 | 15 | namespace PELoaderStub 16 | { 17 | class ResourceLoaderStub 18 | { 19 | public: 20 | ResourceLoaderStub(); 21 | ~ResourceLoaderStub(); 22 | 23 | PELoader::PEImage* Load(PELoader::TlsResolver* tlsResolver); 24 | 25 | private: 26 | PELoader::PEImage* LoadFromResource(PELoader::TlsResolver* tlsResolver); 27 | BYTE* GetCompressedDataFromResource(DWORD& compressedSize); 28 | BYTE* Decompress(BYTE* compressedData, DWORD compressedSize, size_t& decompressedSize); 29 | PELoader::PEImage* CreatePEImageFromMemory(BYTE* peFileBuffer, PELoader::TlsResolver* tlsResolver, LPVOID allocatedImageBase = nullptr); 30 | }; 31 | } -------------------------------------------------------------------------------- /Fatpack/BinaryFileWriter/BinaryFileWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryFileWriter.h" 2 | 3 | namespace BinaryFileWriter 4 | { 5 | BinaryFileWriter::BinaryFileWriter() 6 | { 7 | } 8 | 9 | BinaryFileWriter::~BinaryFileWriter() 10 | { 11 | } 12 | 13 | bool BinaryFileWriter::WriteFile(LPCWSTR fileName, BYTE* buffer, DWORD bufferSize) 14 | { 15 | if (fileName == nullptr || buffer == nullptr || bufferSize == 0) return false; 16 | 17 | DWORD bytesWritten = 0; 18 | HANDLE outputFileHandle = ::CreateFileW(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); 19 | if (outputFileHandle == INVALID_HANDLE_VALUE) return false; 20 | 21 | bool result = ::WriteFile(outputFileHandle, buffer, bufferSize, &bytesWritten, nullptr); 22 | CloseHandle(outputFileHandle); 23 | 24 | return (result && bytesWritten > 0); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /Fatpack/CommandLine/CommandLine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Option.h" 4 | #include "..\Error\Error.h" 5 | 6 | namespace CommandLine 7 | { 8 | class CommandLine 9 | { 10 | public: 11 | CommandLine(); 12 | ~CommandLine(); 13 | 14 | bool Parse(LPWSTR& inputFileName, LPWSTR& outputFileName, Option& option); 15 | Error::ErrorCode GetLastError() { return _lastError; } 16 | 17 | private: 18 | bool LoadArguments(); 19 | bool ValidateArgumentCount(); 20 | bool SetFileNames(LPWSTR& inputFileName, LPWSTR& outputFileName); 21 | bool AreFileNamesDifferent(LPWSTR inputFileName, LPWSTR outputFileName); 22 | bool ParseOption(Option& option); 23 | void SetLastError(Error::ErrorCode error) { _lastError = error; } 24 | 25 | private: 26 | int _argumentCount = 0; 27 | LPWSTR* _argumentVector = nullptr; 28 | Error::ErrorCode _lastError; 29 | 30 | const DWORD MAX_LEN = 256; 31 | }; 32 | } -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/PEImage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PELoader 5 | { 6 | class PEImage 7 | { 8 | public: 9 | PEImage(LPVOID imageBase); 10 | ~PEImage(); 11 | 12 | const PIMAGE_DOS_HEADER DOS_HEADER() { return _PIMAGE_DOS_HEADER; } 13 | const PIMAGE_NT_HEADERS NT_HEADERS() { return _PIMAGE_NT_HEADERS; } 14 | const PIMAGE_SECTION_HEADER SECTION_HEADER() { return _PIMAGE_SECTION_HEADER; } 15 | 16 | const LPVOID GetImageBase() { return _imageBase; } 17 | const LPVOID GetEntryPoint() { return _entryPoint; } 18 | 19 | WORD GetNumberOfSections() { return _PIMAGE_NT_HEADERS->FileHeader.NumberOfSections; } 20 | PIMAGE_SECTION_HEADER GetSectionHeader(WORD index) { return &_PIMAGE_SECTION_HEADER[index]; } 21 | 22 | private: 23 | PIMAGE_DOS_HEADER _PIMAGE_DOS_HEADER; 24 | PIMAGE_NT_HEADERS _PIMAGE_NT_HEADERS; 25 | PIMAGE_SECTION_HEADER _PIMAGE_SECTION_HEADER; 26 | LPVOID _imageBase; 27 | LPVOID _entryPoint; 28 | }; 29 | } -------------------------------------------------------------------------------- /Fatpack/Packer/PackerUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "..\Error\Error.h" 4 | #include "..\PEFile\PEFile.h" 5 | 6 | namespace Packer 7 | { 8 | class PackerUtils 9 | { 10 | public: 11 | PackerUtils(); 12 | ~PackerUtils(); 13 | 14 | bool ReadPeFile(LPWSTR fileName, PEFile::PEFile& peFile); 15 | bool ValidatePeFile(PEFile::PEFile& peFile); 16 | bool PrepareResourceLoaderStub(PEFile::PEFile& inputFile, PEFile::PEFile& peLoader); 17 | bool PrepareSectionLoaderStub(PEFile::PEFile& inputFile, PEFile::PEFile& peLoader); 18 | 19 | bool SavePeFile(LPWSTR fileName, PEFile::PEFile& peFile); 20 | bool AppendResources(LPWSTR inputFileName, LPWSTR outputFileName); 21 | Error::ErrorCode GetLastError() { return _lastError; } 22 | 23 | private: 24 | bool PrepareLoaderStub(PEFile::PEFile& peLoader, WORD resourceId); 25 | void SetLastError(Error::ErrorCode error) { _lastError = error; } 26 | 27 | private: 28 | Error::ErrorCode _lastError; 29 | }; 30 | } -------------------------------------------------------------------------------- /Fatpack/ManifestExtractor/ManifestExtractor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ManifestExtractor 5 | { 6 | #define MANIFEST_RESOURCE_TYPE RT_MANIFEST // RT_MANIFEST = MAKEINTRESOURCE(24) 7 | #define MAX_MANIFEST_RESOURCES 64 8 | 9 | struct ManifestResource 10 | { 11 | WORD id; 12 | WORD lang; 13 | DWORD size; 14 | LPVOID data; 15 | }; 16 | 17 | class ManifestExtractor 18 | { 19 | public: 20 | ManifestExtractor(); 21 | ~ManifestExtractor(); 22 | 23 | bool ExtractManifestResources(LPWSTR srcPath); 24 | bool AddManifestResourcesToTarget(LPWSTR destPath); 25 | 26 | private: 27 | static BOOL CALLBACK EnumResNameProc(HMODULE moduleHandle, LPCTSTR type, LPTSTR name, LONG_PTR param); 28 | static BOOL CALLBACK EnumResLangProc(HMODULE moduleHandle, LPCTSTR type, LPCTSTR name, WORD language, LONG_PTR param); 29 | 30 | private: 31 | static ManifestResource* _manifestResources; 32 | static DWORD _manifestCount; 33 | HANDLE _heapHandle; 34 | }; 35 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zBuf2.c: -------------------------------------------------------------------------------- 1 | /* 7zBuf2.c -- Byte Buffer 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "7zBuf.h" 5 | 6 | void DynBuf_Construct(CDynBuf *p) 7 | { 8 | p->data = 0; 9 | p->size = 0; 10 | p->pos = 0; 11 | } 12 | 13 | void DynBuf_SeekToBeg(CDynBuf *p) 14 | { 15 | p->pos = 0; 16 | } 17 | 18 | int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) 19 | { 20 | if (size > p->size - p->pos) 21 | { 22 | size_t newSize = p->pos + size; 23 | Byte *data; 24 | newSize += newSize / 4; 25 | data = (Byte *)alloc->Alloc(alloc, newSize); 26 | if (data == 0) 27 | return 0; 28 | p->size = newSize; 29 | memcpy(data, p->data, p->pos); 30 | alloc->Free(alloc, p->data); 31 | p->data = data; 32 | } 33 | memcpy(p->data + p->pos, buf, size); 34 | p->pos += size; 35 | return 1; 36 | } 37 | 38 | void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) 39 | { 40 | alloc->Free(alloc, p->data); 41 | p->data = 0; 42 | p->size = 0; 43 | p->pos = 0; 44 | } 45 | -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/TlsResolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PELoader 5 | { 6 | class PEImage; 7 | } 8 | 9 | namespace PELoader 10 | { 11 | class TlsResolver 12 | { 13 | public: 14 | TlsResolver(); 15 | ~TlsResolver(); 16 | 17 | void InitializeTlsIndex(PEImage* peImage); 18 | void InitializeTlsData(PEImage* peImage); 19 | void ClearTlsData(); 20 | void ExecuteCallbacks(PEImage* peImage, DWORD reason, PVOID context); 21 | 22 | private: 23 | PIMAGE_TLS_DIRECTORY GetTlsDirectory(PEImage* peImage); 24 | 25 | BOOL HasTlsData(PIMAGE_TLS_DIRECTORY tlsDirectory); 26 | BOOL HasTlsCallbacks(PIMAGE_TLS_DIRECTORY tlsDirectory); 27 | 28 | ULONG GetTlsIndex(PEImage* peImage); 29 | void SetTlsIndex(PIMAGE_TLS_DIRECTORY tlsDirectory, ULONG tlsIndex); 30 | 31 | LPVOID CreateTlsData(PIMAGE_TLS_DIRECTORY tlsDirectory); 32 | void SetTlsData(ULONG tlsIndex, LPVOID tlsData); 33 | LPVOID GetTlsData(ULONG tlsIndex); 34 | 35 | private: 36 | ULONG _tlsIndex; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /Fatpack/Packer/ResourcePacker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "..\Error\Error.h" 4 | #include "..\PEFile\PEFile.h" 5 | 6 | namespace Packer 7 | { 8 | class PackerUtils; 9 | } 10 | 11 | namespace Packer 12 | { 13 | class ResourcePacker 14 | { 15 | public: 16 | ResourcePacker(PackerUtils* packerUtils); 17 | ~ResourcePacker(); 18 | 19 | bool Pack(LPWSTR inputFileName, LPWSTR outputFileName); 20 | Error::ErrorCode GetLastError() { return _lastError; } 21 | 22 | private: 23 | bool ReadPeFile(LPWSTR fileName, PEFile::PEFile& peFile); 24 | bool ValidateInputFile(); 25 | bool PrepareLoaderStub(); 26 | bool RebaseIfNeeded(); 27 | bool SavePeLoader(LPWSTR fileName); 28 | bool AppendResourcesToLoader(LPWSTR inputFileName, LPWSTR outputFileName); 29 | bool CompressAndEmbed(LPWSTR outputFileName); 30 | void SetLastError(Error::ErrorCode error) { _lastError = error; } 31 | 32 | private: 33 | PackerUtils* _packerUtils; 34 | PEFile::PEFile _peLoader; 35 | PEFile::PEFile _inputFile; 36 | Error::ErrorCode _lastError; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /Fatpack/Packer/SectionPacker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "..\Error\Error.h" 4 | #include "..\PEFile\PEFile.h" 5 | 6 | namespace Packer 7 | { 8 | class PackerUtils; 9 | } 10 | 11 | namespace Packer 12 | { 13 | class SectionPacker 14 | { 15 | public: 16 | SectionPacker(PackerUtils* packerUtils); 17 | ~SectionPacker(); 18 | 19 | bool Pack(LPWSTR inputFileName, LPWSTR outputFileName); 20 | Error::ErrorCode GetLastError() { return _lastError; } 21 | 22 | private: 23 | bool ReadPeFile(LPWSTR fileName, PEFile::PEFile& peFile); 24 | bool ValidateInputFile(); 25 | bool PrepareLoaderStub(); 26 | bool SavePeLoader(LPWSTR outputFileName); 27 | bool AppendResourcesToLoader(LPWSTR inputFileName, LPWSTR outputFileName); 28 | bool RebaseLoaderToLastSection(); 29 | bool CompressAndAppendToLastSection(); 30 | void SetLastError(Error::ErrorCode error) { _lastError = error; } 31 | 32 | private: 33 | PackerUtils* _packerUtils; 34 | PEFile::PEFile _peLoader; 35 | PEFile::PEFile _inputFile; 36 | Error::ErrorCode _lastError; 37 | }; 38 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Fatmike-GH (https://github.com/Fatmike-GH/Fatpack) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Licenses/LICENSE_TinyZZZ.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 https://github.com/WangXuan95 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ResourceAdder/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "..\Shared\BinaryFileReader\BinaryFileReader.h" 6 | 7 | int wmain(int argc, wchar_t* argv[]) 8 | { 9 | if (argc != 4) 10 | { 11 | std::cout << "Usage: ResourceAdder resourcefile targetfile.exe resource id" << std::endl; 12 | return 0; 13 | } 14 | 15 | std::wstring resourceFile(argv[1]); 16 | std::wstring targetFile(argv[2]); 17 | std::wstring resourceId(argv[3]); 18 | 19 | WORD resourceIdValue = static_cast(std::stoi(resourceId)); 20 | 21 | // Read resourceFile 22 | BinaryFileReader::BinaryFileReader binaryFileReader(resourceFile.c_str()); 23 | if (binaryFileReader.GetBuffer() == nullptr || binaryFileReader.GetBufferSize() == 0) return 0; 24 | 25 | // Add resourceFile as resource to targetFile 26 | HANDLE updateHandle = BeginUpdateResourceW(targetFile.c_str(), FALSE); 27 | UpdateResource(updateHandle, RT_RCDATA, MAKEINTRESOURCE(resourceIdValue), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), binaryFileReader.GetBuffer(), binaryFileReader.GetBufferSize()); 28 | EndUpdateResource(updateHandle, FALSE); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Licenses/LICENSE_PeLoader.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Fatmike (https://github.com/Fatmike-GH/PELoader) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Shared/BinaryFileReader/BinaryFileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryFileReader.h" 2 | 3 | namespace BinaryFileReader 4 | { 5 | BinaryFileReader::BinaryFileReader(const wchar_t* fileName) 6 | { 7 | _buffer = nullptr; 8 | _bufferSize = 0; 9 | 10 | HANDLE fileHandle = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 11 | if (fileHandle == INVALID_HANDLE_VALUE) 12 | { 13 | Cleanup(); 14 | return; 15 | } 16 | 17 | _bufferSize = GetFileSize(fileHandle, NULL); 18 | if (_bufferSize == INVALID_FILE_SIZE) 19 | { 20 | Cleanup(); 21 | CloseHandle(fileHandle); 22 | return; 23 | } 24 | 25 | _buffer = new BYTE[_bufferSize]; 26 | 27 | DWORD bytesRead = 0; 28 | BOOL result = ReadFile(fileHandle, _buffer, _bufferSize, &bytesRead, NULL); 29 | CloseHandle(fileHandle); 30 | 31 | if (result == FALSE) 32 | { 33 | Cleanup(); 34 | } 35 | 36 | return; 37 | } 38 | 39 | BinaryFileReader::~BinaryFileReader() 40 | { 41 | Cleanup(); 42 | } 43 | 44 | void BinaryFileReader::Cleanup() 45 | { 46 | if (_buffer != nullptr) 47 | { 48 | delete[] _buffer; 49 | _buffer = nullptr; 50 | } 51 | _bufferSize = 0; 52 | } 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/PELoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "..\TypeDefs\peb.h" 4 | 5 | namespace PELoader 6 | { 7 | class TlsResolver; 8 | class PEFile; 9 | class PEImage; 10 | } 11 | 12 | namespace PELoader 13 | { 14 | class PELoader 15 | { 16 | public: 17 | PELoader(); 18 | ~PELoader(); 19 | 20 | LPVOID LoadPE(PEFile* pefile, TlsResolver* tlsResolver, LPVOID allocatedImageBase); 21 | 22 | private: 23 | LPVOID AllocateVirtualMemory(PEFile* pefile); 24 | void MapSections(PEFile* pefile, LPVOID allocatedImageBase); 25 | void ApplyRelocations(PEImage* peImage, ULONGLONG originalImageBase); 26 | void UpdatePEB(PEImage* peImage); 27 | void InitializeTlsIndex(TlsResolver* tlsResolver, PEImage* peImage); 28 | void InitializeTlsData(TlsResolver* tlsResolver, PEImage* peImage); 29 | void ResolveImports(PEImage* peImage); 30 | void ResolveDelayImports(PEImage* peImage); 31 | void ResolveDelayImport(PEImage* peImage, const IMAGE_DELAYLOAD_DESCRIPTOR* delayDesc); 32 | void SetupExceptionHandling(PEImage* peImage); 33 | void ExecuteTlsCallbacks(TlsResolver* tlsResolver, PEImage* peImage); 34 | void ApplySectionMemoryProtection( PEImage* peImage); 35 | PLDR_DATA_TABLE_ENTRY GetOwnLdrEntry(PPEB peb); 36 | }; 37 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/wrapper/easylzmawrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | * 10 | * simple.h - a wrapper around easylzma to compress/decompress to memory 11 | */ 12 | 13 | #ifndef __SIMPLE_H__ 14 | #define __SIMPLE_H__ 15 | 16 | #include "..\easylzma\compress.h" 17 | //#include "..\easylzma\decompress.h" 18 | 19 | /* compress a chunk of memory and return a dynamically allocated buffer 20 | * if successful. return value is an easylzma error code */ 21 | int simpleCompress(elzma_file_format format, 22 | const unsigned char * inData, 23 | size_t inLen, 24 | unsigned char ** outData, 25 | size_t * outLen); 26 | 27 | /* decompress a chunk of memory and return a dynamically allocated buffer 28 | * if successful. return value is an easylzma error code */ 29 | //int simpleDecompress(elzma_file_format format, 30 | // const unsigned char * inData, 31 | // size_t inLen, 32 | // unsigned char ** outData, 33 | // size_t * outLen); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /Shared/ResourceLoader/ResourceLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "ResourceLoader.h" 2 | #include "..\ApiCaller\ApiCaller.h" 3 | 4 | namespace ResourceLoader 5 | { 6 | ResourceLoader::ResourceLoader() 7 | { 8 | } 9 | 10 | ResourceLoader::~ResourceLoader() 11 | { 12 | } 13 | 14 | BYTE* ResourceLoader::LoadResource(LPCWSTR resourceName, LPCWSTR resourceType, DWORD& resourceSize) 15 | { 16 | resourceSize = 0; 17 | 18 | HMODULE moduleHandle = ApiCaller::ApiCaller::Instance().CallGetModuleHandle(nullptr); 19 | HRSRC resourceHandle = ApiCaller::ApiCaller::Instance().CallFindResourceW(moduleHandle, resourceName, resourceType); 20 | if (resourceHandle == nullptr) return nullptr; 21 | 22 | resourceSize = ApiCaller::ApiCaller::Instance().CallSizeofResource(moduleHandle, resourceHandle); 23 | if (resourceSize == 0) return nullptr; 24 | 25 | HGLOBAL resourceDataHandle = ApiCaller::ApiCaller::Instance().CallLoadResource(moduleHandle, resourceHandle); 26 | if (resourceDataHandle == nullptr) return nullptr; 27 | 28 | LPVOID resourceData = ApiCaller::ApiCaller::Instance().CallLockResource(resourceDataHandle); 29 | if (resourceData == nullptr) return nullptr; 30 | 31 | BYTE* buffer = new BYTE[resourceSize]; 32 | memcpy(buffer, resourceData, resourceSize); 33 | return buffer; 34 | } 35 | 36 | void ResourceLoader::Free(BYTE* resourceBuffer) 37 | { 38 | if (resourceBuffer == nullptr) return; 39 | delete[] resourceBuffer; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/common_internal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | */ 10 | 11 | #include "common_internal.h" 12 | 13 | static void *elzmaAlloc(void *p, size_t size) { 14 | struct elzma_alloc_struct * as = (struct elzma_alloc_struct *) p; 15 | if (as->clientMallocFunc) { 16 | return as->clientMallocFunc(as->clientMallocContext, size); 17 | } 18 | return malloc(size); 19 | } 20 | 21 | static void elzmaFree(void *p, void *address) { 22 | struct elzma_alloc_struct * as = (struct elzma_alloc_struct *) p; 23 | if (as->clientFreeFunc) { 24 | as->clientFreeFunc(as->clientMallocContext, address); 25 | } else { 26 | free(address); 27 | } 28 | } 29 | 30 | void 31 | init_alloc_struct(struct elzma_alloc_struct * as, 32 | elzma_malloc clientMallocFunc, 33 | void * clientMallocContext, 34 | elzma_free clientFreeFunc, 35 | void * clientFreeContext) 36 | { 37 | as->Alloc = elzmaAlloc; 38 | as->Free = elzmaFree; 39 | as->clientMallocFunc = clientMallocFunc; 40 | as->clientMallocContext = clientMallocContext; 41 | as->clientFreeFunc = clientFreeFunc; 42 | as->clientFreeContext = clientFreeContext; 43 | } 44 | -------------------------------------------------------------------------------- /Shared/ApiCaller/ApiCaller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ApiCaller 5 | { 6 | class ApiCaller 7 | { 8 | public: 9 | static ApiCaller& Instance(); 10 | 11 | HRSRC CallFindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType); 12 | HMODULE CallGetModuleHandle(LPCSTR lpModuleName); 13 | FARPROC CallGetProcAddress(HMODULE hModule, LPCSTR lpProcName); 14 | HANDLE CallGetProcessHeap(); 15 | LPVOID CallHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); 16 | BOOL CallHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); 17 | LPVOID CallHeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); 18 | HMODULE CallLoadLibrary(LPCSTR lpLibFileName); 19 | HGLOBAL CallLoadResource(HMODULE hModule, HRSRC hResInfo); 20 | LPVOID CallLockResource(HGLOBAL hResData); 21 | BOOLEAN CallRtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable, DWORD EntryCount, DWORD64 BaseAddress); 22 | DWORD CallSizeofResource(HMODULE hModule, HRSRC hResInfo); 23 | LPVOID CallVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); 24 | BOOL CallVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType); 25 | BOOL CallVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect); 26 | 27 | private: 28 | ApiCaller(); 29 | ~ApiCaller(); 30 | 31 | FARPROC ResolveKernel32Api(LPCSTR procName); 32 | 33 | private: 34 | static ApiCaller* _instance; 35 | HMODULE _kernel32; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /Fatpack/main.cpp: -------------------------------------------------------------------------------- 1 | #include "CommandLine\CommandLine.h" 2 | #include "Console\Console.h" 3 | #include "Error\Error.h" 4 | #include "Packer\PackerUtils.h" 5 | #include "Packer\ResourcePacker.h" 6 | #include "Packer\SectionPacker.h" 7 | 8 | int main() 9 | { 10 | Console::Console console; 11 | CommandLine::CommandLine commandLine; 12 | 13 | LPWSTR inputFileName = nullptr; 14 | LPWSTR outputFileName = nullptr; 15 | CommandLine::Option option = CommandLine::Option::Resource; 16 | 17 | if (!commandLine.Parse(inputFileName, outputFileName, option)) 18 | { 19 | console.WriteError(commandLine.GetLastError()); 20 | console.ShowHelp(); 21 | return 0; 22 | } 23 | 24 | bool success = false; 25 | Error::ErrorCode error = Error::ErrorCode::Ok; 26 | 27 | Packer::PackerUtils packerUtils; 28 | if (option == CommandLine::Option::Resource) 29 | { 30 | console.WriteLine(L"Using option -r, --resource"); 31 | Packer::ResourcePacker packer(&packerUtils); 32 | success = packer.Pack(inputFileName, outputFileName); 33 | error = packer.GetLastError(); 34 | } 35 | else 36 | { 37 | console.WriteLine(L"Using option -s, --section"); 38 | Packer::SectionPacker packer(&packerUtils); 39 | success = packer.Pack(inputFileName, outputFileName); 40 | error = packer.GetLastError(); 41 | } 42 | 43 | if (success) 44 | { 45 | console.WriteLine(L"Packing finished."); 46 | } 47 | else 48 | { 49 | console.WriteError(L"Packing failed."); 50 | console.WriteError(error); 51 | } 52 | 53 | return 0; 54 | } -------------------------------------------------------------------------------- /Loader_Console_Section/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "..\Shared\PELoaderStub\SectionLoaderStub.h" 3 | #include "..\Shared\PELoader\PELoader\PEImage.h" 4 | #include "..\Shared\PELoader\PELoader\TlsResolver.h" 5 | #include "..\Shared\PELoader\TlsCallbackProxy\TlsCallbackProxy.h" 6 | 7 | PELoader::TlsResolver* _tlsResolver = nullptr; 8 | PELoader::PEImage* _peImage = nullptr; 9 | BOOL _entryPointCalled = FALSE; 10 | 11 | void TlsCallbackProxy(PVOID hModule, DWORD dwReason, PVOID pContext) 12 | { 13 | if (_entryPointCalled == FALSE) return; 14 | 15 | if (dwReason == DLL_THREAD_DETACH) 16 | { 17 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 18 | _tlsResolver->ClearTlsData(); 19 | } 20 | else if (dwReason == DLL_THREAD_ATTACH) 21 | { 22 | _tlsResolver->InitializeTlsData(_peImage); 23 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 24 | } 25 | else if (dwReason == DLL_PROCESS_ATTACH) 26 | { 27 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 28 | } 29 | else if (dwReason == DLL_PROCESS_DETACH) 30 | { 31 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 32 | } 33 | } 34 | 35 | int main() 36 | { 37 | _tlsResolver = new PELoader::TlsResolver(); 38 | 39 | PELoaderStub::SectionLoaderStub* peLoaderStub = new PELoaderStub::SectionLoaderStub(); 40 | _peImage = peLoaderStub->Load(_tlsResolver); 41 | delete peLoaderStub; 42 | 43 | // Call entry point 44 | LPVOID entryPoint = _peImage->GetEntryPoint(); 45 | _entryPointCalled = TRUE; 46 | ((void(*)())(entryPoint))(); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Loader_Windows_Section/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "..\Shared\PELoaderStub\SectionLoaderStub.h" 3 | #include "..\Shared\PELoader\PELoader\PEImage.h" 4 | #include "..\Shared\PELoader\PELoader\TlsResolver.h" 5 | #include "..\Shared\PELoader\TlsCallbackProxy\TlsCallbackProxy.h" 6 | 7 | PELoader::TlsResolver* _tlsResolver = nullptr; 8 | PELoader::PEImage* _peImage = nullptr; 9 | BOOL _entryPointCalled = FALSE; 10 | 11 | void TlsCallbackProxy(PVOID hModule, DWORD dwReason, PVOID pContext) 12 | { 13 | if (_entryPointCalled == FALSE) return; 14 | 15 | if (dwReason == DLL_THREAD_DETACH) 16 | { 17 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 18 | _tlsResolver->ClearTlsData(); 19 | } 20 | else if (dwReason == DLL_THREAD_ATTACH) 21 | { 22 | _tlsResolver->InitializeTlsData(_peImage); 23 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 24 | } 25 | else if (dwReason == DLL_PROCESS_ATTACH) 26 | { 27 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 28 | } 29 | else if (dwReason == DLL_PROCESS_DETACH) 30 | { 31 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 32 | } 33 | } 34 | 35 | int main() 36 | { 37 | _tlsResolver = new PELoader::TlsResolver(); 38 | 39 | PELoaderStub::SectionLoaderStub* peLoaderStub = new PELoaderStub::SectionLoaderStub(); 40 | _peImage = peLoaderStub->Load(_tlsResolver); 41 | delete peLoaderStub; 42 | 43 | // Call entry point 44 | LPVOID entryPoint = _peImage->GetEntryPoint(); 45 | _entryPointCalled = TRUE; 46 | ((void(*)())(entryPoint))(); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Loader_Console_Resource/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "..\Shared\PELoaderStub\ResourceLoaderStub.h" 3 | #include "..\Shared\PELoader\PELoader\PEImage.h" 4 | #include "..\Shared\PELoader\PELoader\TlsResolver.h" 5 | #include "..\Shared\PELoader\TlsCallbackProxy\TlsCallbackProxy.h" 6 | 7 | PELoader::TlsResolver* _tlsResolver = nullptr; 8 | PELoader::PEImage* _peImage = nullptr; 9 | BOOL _entryPointCalled = FALSE; 10 | 11 | void TlsCallbackProxy(PVOID hModule, DWORD dwReason, PVOID pContext) 12 | { 13 | if (_entryPointCalled == FALSE) return; 14 | 15 | if (dwReason == DLL_THREAD_DETACH) 16 | { 17 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 18 | _tlsResolver->ClearTlsData(); 19 | } 20 | else if (dwReason == DLL_THREAD_ATTACH) 21 | { 22 | _tlsResolver->InitializeTlsData(_peImage); 23 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 24 | } 25 | else if (dwReason == DLL_PROCESS_ATTACH) 26 | { 27 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 28 | } 29 | else if (dwReason == DLL_PROCESS_DETACH) 30 | { 31 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 32 | } 33 | } 34 | 35 | int main() 36 | { 37 | _tlsResolver = new PELoader::TlsResolver(); 38 | 39 | PELoaderStub::ResourceLoaderStub* peLoaderStub = new PELoaderStub::ResourceLoaderStub(); 40 | _peImage = peLoaderStub->Load(_tlsResolver); 41 | delete peLoaderStub; 42 | 43 | // Call entry point 44 | LPVOID entryPoint = _peImage->GetEntryPoint(); 45 | _entryPointCalled = TRUE; 46 | ((void(*)())(entryPoint))(); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Loader_Windows_Resource/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "..\Shared\PELoaderStub\ResourceLoaderStub.h" 3 | #include "..\Shared\PELoader\PELoader\PEImage.h" 4 | #include "..\Shared\PELoader\PELoader\TlsResolver.h" 5 | #include "..\Shared\PELoader\TlsCallbackProxy\TlsCallbackProxy.h" 6 | 7 | PELoader::TlsResolver* _tlsResolver = nullptr; 8 | PELoader::PEImage* _peImage = nullptr; 9 | BOOL _entryPointCalled = FALSE; 10 | 11 | void TlsCallbackProxy(PVOID hModule, DWORD dwReason, PVOID pContext) 12 | { 13 | if (_entryPointCalled == FALSE) return; 14 | 15 | if (dwReason == DLL_THREAD_DETACH) 16 | { 17 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 18 | _tlsResolver->ClearTlsData(); 19 | } 20 | else if (dwReason == DLL_THREAD_ATTACH) 21 | { 22 | _tlsResolver->InitializeTlsData(_peImage); 23 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 24 | } 25 | else if (dwReason == DLL_PROCESS_ATTACH) 26 | { 27 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 28 | } 29 | else if (dwReason == DLL_PROCESS_DETACH) 30 | { 31 | _tlsResolver->ExecuteCallbacks(_peImage, dwReason, pContext); 32 | } 33 | } 34 | 35 | int main() 36 | { 37 | _tlsResolver = new PELoader::TlsResolver(); 38 | 39 | PELoaderStub::ResourceLoaderStub* peLoaderStub = new PELoaderStub::ResourceLoaderStub(); 40 | _peImage = peLoaderStub->Load(_tlsResolver); 41 | delete peLoaderStub; 42 | 43 | // Call entry point 44 | LPVOID entryPoint = _peImage->GetEntryPoint(); 45 | _entryPointCalled = TRUE; 46 | ((void(*)())(entryPoint))(); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zFile.h: -------------------------------------------------------------------------------- 1 | /* 7zFile.h -- File IO 2 | 2008-11-22 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_FILE_H 5 | #define __7Z_FILE_H 6 | 7 | #ifdef _WIN32 8 | #define USE_WINDOWS_FILE 9 | #endif 10 | 11 | #ifdef USE_WINDOWS_FILE 12 | #include 13 | #else 14 | #include 15 | #endif 16 | 17 | #include "Types.h" 18 | 19 | 20 | /* ---------- File ---------- */ 21 | 22 | typedef struct 23 | { 24 | #ifdef USE_WINDOWS_FILE 25 | HANDLE handle; 26 | #else 27 | FILE *file; 28 | #endif 29 | } CSzFile; 30 | 31 | void File_Construct(CSzFile *p); 32 | WRes InFile_Open(CSzFile *p, const char *name); 33 | WRes OutFile_Open(CSzFile *p, const char *name); 34 | WRes File_Close(CSzFile *p); 35 | 36 | /* reads max(*size, remain file's size) bytes */ 37 | WRes File_Read(CSzFile *p, void *data, size_t *size); 38 | 39 | /* writes *size bytes */ 40 | WRes File_Write(CSzFile *p, const void *data, size_t *size); 41 | 42 | WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); 43 | WRes File_GetLength(CSzFile *p, UInt64 *length); 44 | 45 | 46 | /* ---------- FileInStream ---------- */ 47 | 48 | typedef struct 49 | { 50 | ISeqInStream s; 51 | CSzFile file; 52 | } CFileSeqInStream; 53 | 54 | void FileSeqInStream_CreateVTable(CFileSeqInStream *p); 55 | 56 | 57 | typedef struct 58 | { 59 | ISeekInStream s; 60 | CSzFile file; 61 | } CFileInStream; 62 | 63 | void FileInStream_CreateVTable(CFileInStream *p); 64 | 65 | 66 | typedef struct 67 | { 68 | ISeqOutStream s; 69 | CSzFile file; 70 | } CFileOutStream; 71 | 72 | void FileOutStream_CreateVTable(CFileOutStream *p); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/LzmaLib.c: -------------------------------------------------------------------------------- 1 | /* LzmaLib.c -- LZMA library wrapper 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #include "LzmaEnc.h" 7 | #include "LzmaDec.h" 8 | #include "Alloc.h" 9 | #include "LzmaLib.h" 10 | 11 | static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } 12 | static void SzFree(void *p, void *address) { p = p; MyFree(address); } 13 | static ISzAlloc g_Alloc = { SzAlloc, SzFree }; 14 | 15 | MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, 16 | unsigned char *outProps, size_t *outPropsSize, 17 | int level, /* 0 <= level <= 9, default = 5 */ 18 | unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ 19 | int lc, /* 0 <= lc <= 8, default = 3 */ 20 | int lp, /* 0 <= lp <= 4, default = 0 */ 21 | int pb, /* 0 <= pb <= 4, default = 2 */ 22 | int fb, /* 5 <= fb <= 273, default = 32 */ 23 | int numThreads /* 1 or 2, default = 2 */ 24 | ) 25 | { 26 | CLzmaEncProps props; 27 | LzmaEncProps_Init(&props); 28 | props.level = level; 29 | props.dictSize = dictSize; 30 | props.lc = lc; 31 | props.lp = lp; 32 | props.pb = pb; 33 | props.fb = fb; 34 | props.numThreads = numThreads; 35 | 36 | return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, 37 | NULL, &g_Alloc, &g_Alloc); 38 | } 39 | 40 | 41 | MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, 42 | const unsigned char *props, size_t propsSize) 43 | { 44 | ELzmaStatus status; 45 | return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); 46 | } 47 | -------------------------------------------------------------------------------- /Fatpack/PEFile/PEFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace PEFile 5 | { 6 | class PEFile 7 | { 8 | public: 9 | PEFile(); 10 | ~PEFile(); 11 | 12 | bool LoadFromBuffer(BYTE* fileBuffer, DWORD size); 13 | bool Resize(DWORD size); 14 | 15 | DWORD GetBufferSize() { return _bufferSize; } 16 | BYTE* GetBuffer() { return _buffer; } 17 | 18 | const PIMAGE_DOS_HEADER DOS_HEADER() { return _PIMAGE_DOS_HEADER; } 19 | const PIMAGE_NT_HEADERS NT_HEADERS() { return _PIMAGE_NT_HEADERS; } 20 | const PIMAGE_SECTION_HEADER SECTION_HEADER() { return _PIMAGE_SECTION_HEADER; } 21 | 22 | uintptr_t GetImageBase(); 23 | DWORD GetSizeOfImage(); 24 | 25 | bool IsPEFile(); 26 | bool Isx64(); 27 | bool IsNative(); 28 | bool IsConsole(); 29 | 30 | 31 | WORD GetSectionCount(); 32 | PIMAGE_SECTION_HEADER GetSectionHeader(WORD index); 33 | 34 | static uintptr_t AlignImageBase(uintptr_t imageBase); 35 | DWORD AlignSection(DWORD value); 36 | DWORD AlignFile(DWORD value); 37 | 38 | bool IntersectsWith(PEFile& other); 39 | bool HasRelocationTable(); 40 | ULONGLONG GetNextImageBase(); 41 | bool Rebase(ULONGLONG newImageBase); 42 | 43 | private: 44 | 45 | bool ApplyRelocations(ULONGLONG imageBase); 46 | void SetImageBase(ULONGLONG imageBase); 47 | void StripRelocations(); 48 | 49 | DWORD Rva2RawOffset(DWORD rva); 50 | DWORD64 GetRawAddress(DWORD rawOffset); 51 | 52 | void DeleteBuffer(); 53 | 54 | private: 55 | BYTE* _buffer; 56 | DWORD _bufferSize; 57 | 58 | PIMAGE_DOS_HEADER _PIMAGE_DOS_HEADER; 59 | PIMAGE_NT_HEADERS _PIMAGE_NT_HEADERS; 60 | PIMAGE_SECTION_HEADER _PIMAGE_SECTION_HEADER; 61 | }; 62 | } -------------------------------------------------------------------------------- /Shared/CRT/crt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | void* __cdecl memset(void* _Dst, int _Val, size_t _Size); 6 | #pragma intrinsic(memset) 7 | 8 | void* __cdecl memcpy(void* _Dst, void const* _Src, size_t _Size); 9 | #pragma intrinsic(memcpy) 10 | 11 | void* __cdecl memmove(void* dest, const void* src, size_t n); 12 | #pragma intrinsic(memmove) 13 | 14 | _Check_return_ 15 | int __cdecl strncmp( 16 | _In_reads_or_z_(_MaxCount) char const* _Str1, 17 | _In_reads_or_z_(_MaxCount) char const* _Str2, 18 | _In_ size_t _MaxCount 19 | ); 20 | 21 | _Check_return_ 22 | _ACRTIMP size_t __cdecl wcslen( 23 | _In_z_ wchar_t const* _String 24 | ); 25 | #pragma intrinsic(wcslen) 26 | 27 | _Check_return_ 28 | _ACRTIMP int __cdecl wcscmp( 29 | _In_z_ wchar_t const* _String1, 30 | _In_z_ wchar_t const* _String2 31 | ); 32 | #pragma intrinsic(wcscmp) 33 | 34 | _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) 35 | _CRTALLOCATOR _CRT_JIT_INTRINSIC _CRTRESTRICT _CRT_HYBRIDPATCHABLE 36 | void* __cdecl malloc( 37 | _In_ _CRT_GUARDOVERFLOW size_t _Size 38 | ); 39 | 40 | _CRT_HYBRIDPATCHABLE 41 | void __cdecl free( 42 | _Pre_maybenull_ _Post_invalid_ void* _Block 43 | ); 44 | 45 | _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size) 46 | _CRTALLOCATOR _CRTRESTRICT _CRT_HYBRIDPATCHABLE 47 | void* __cdecl realloc( 48 | _Pre_maybenull_ _Post_invalid_ void* _Block, 49 | _In_ _CRT_GUARDOVERFLOW size_t _Size 50 | ); 51 | 52 | void* operator new(size_t size); 53 | void* operator new[](size_t size); 54 | void operator delete(void* ptr); 55 | void operator delete[](void* ptr); 56 | void operator delete(void* ptr, size_t size); 57 | void operator delete[](void* ptr, size_t size); 58 | 59 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/easylzma/decompress.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | * 10 | * easylzma/decompress.h - The API for LZMA decompression using easylzma 11 | */ 12 | 13 | #ifndef __EASYLZMADECOMPRESS_H__ 14 | #define __EASYLZMADECOMPRESS_H__ 15 | 16 | #include "common.h" 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | /** an opaque handle to an lzma decompressor */ 23 | typedef struct _elzma_decompress_handle * elzma_decompress_handle; 24 | 25 | /** 26 | * Allocate a handle to an LZMA decompressor object. 27 | */ 28 | elzma_decompress_handle EASYLZMA_API elzma_decompress_alloc(); 29 | 30 | /** 31 | * set allocation routines (optional, if not called malloc & free will 32 | * be used) 33 | */ 34 | void EASYLZMA_API elzma_decompress_set_allocation_callbacks( 35 | elzma_decompress_handle hand, 36 | elzma_malloc mallocFunc, void * mallocFuncContext, 37 | elzma_free freeFunc, void * freeFuncContext); 38 | 39 | /** 40 | * Free all data associated with an LZMA decompressor object. 41 | */ 42 | void EASYLZMA_API elzma_decompress_free(elzma_decompress_handle * hand); 43 | 44 | /** 45 | * Perform decompression 46 | * 47 | * XXX: should the library automatically detect format by reading stream? 48 | * currently it's based on data external to stream (such as extension 49 | * or convention) 50 | */ 51 | int EASYLZMA_API elzma_decompress_run( 52 | elzma_decompress_handle hand, 53 | elzma_read_callback inputStream, void * inputContext, 54 | elzma_write_callback outputStream, void * outputContext, 55 | elzma_file_format format); 56 | 57 | 58 | #ifdef __cplusplus 59 | }; 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/BraIA64.c: -------------------------------------------------------------------------------- 1 | /* BraIA64.c -- Converter for IA-64 code 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bra.h" 5 | 6 | static const Byte kBranchTable[32] = 7 | { 8 | 0, 0, 0, 0, 0, 0, 0, 0, 9 | 0, 0, 0, 0, 0, 0, 0, 0, 10 | 4, 4, 6, 6, 0, 0, 7, 7, 11 | 4, 4, 0, 0, 4, 4, 0, 0 12 | }; 13 | 14 | SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) 15 | { 16 | SizeT i; 17 | if (size < 16) 18 | return 0; 19 | size -= 16; 20 | for (i = 0; i <= size; i += 16) 21 | { 22 | UInt32 instrTemplate = data[i] & 0x1F; 23 | UInt32 mask = kBranchTable[instrTemplate]; 24 | UInt32 bitPos = 5; 25 | int slot; 26 | for (slot = 0; slot < 3; slot++, bitPos += 41) 27 | { 28 | UInt32 bytePos, bitRes; 29 | UInt64 instruction, instNorm; 30 | int j; 31 | if (((mask >> slot) & 1) == 0) 32 | continue; 33 | bytePos = (bitPos >> 3); 34 | bitRes = bitPos & 0x7; 35 | instruction = 0; 36 | for (j = 0; j < 6; j++) 37 | instruction += (UInt64)data[i + j + bytePos] << (8 * j); 38 | 39 | instNorm = instruction >> bitRes; 40 | if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) 41 | { 42 | UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); 43 | UInt32 dest; 44 | src |= ((UInt32)(instNorm >> 36) & 1) << 20; 45 | 46 | src <<= 4; 47 | 48 | if (encoding) 49 | dest = ip + (UInt32)i + src; 50 | else 51 | dest = src - (ip + (UInt32)i); 52 | 53 | dest >>= 4; 54 | 55 | instNorm &= ~((UInt64)(0x8FFFFF) << 13); 56 | instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); 57 | instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); 58 | 59 | instruction &= (1 << bitRes) - 1; 60 | instruction |= (instNorm << bitRes); 61 | for (j = 0; j < 6; j++) 62 | data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); 63 | } 64 | } 65 | } 66 | return i; 67 | } 68 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Bra.h: -------------------------------------------------------------------------------- 1 | /* Bra.h -- Branch converters for executables 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __BRA_H 5 | #define __BRA_H 6 | 7 | #include "Types.h" 8 | 9 | /* 10 | These functions convert relative addresses to absolute addresses 11 | in CALL instructions to increase the compression ratio. 12 | 13 | In: 14 | data - data buffer 15 | size - size of data 16 | ip - current virtual Instruction Pinter (IP) value 17 | state - state variable for x86 converter 18 | encoding - 0 (for decoding), 1 (for encoding) 19 | 20 | Out: 21 | state - state variable for x86 converter 22 | 23 | Returns: 24 | The number of processed bytes. If you call these functions with multiple calls, 25 | you must start next call with first byte after block of processed bytes. 26 | 27 | Type Endian Alignment LookAhead 28 | 29 | x86 little 1 4 30 | ARMT little 2 2 31 | ARM little 4 0 32 | PPC big 4 0 33 | SPARC big 4 0 34 | IA64 little 16 0 35 | 36 | size must be >= Alignment + LookAhead, if it's not last block. 37 | If (size < Alignment + LookAhead), converter returns 0. 38 | 39 | Example: 40 | 41 | UInt32 ip = 0; 42 | for () 43 | { 44 | ; size must be >= Alignment + LookAhead, if it's not last block 45 | SizeT processed = Convert(data, size, ip, 1); 46 | data += processed; 47 | size -= processed; 48 | ip += processed; 49 | } 50 | */ 51 | 52 | #define x86_Convert_Init(state) { state = 0; } 53 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); 54 | SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 55 | SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 56 | SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 57 | SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 58 | SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/LzHash.h: -------------------------------------------------------------------------------- 1 | /* LzHash.h -- HASH functions for LZ algorithms 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZHASH_H 5 | #define __LZHASH_H 6 | 7 | #define kHash2Size (1 << 10) 8 | #define kHash3Size (1 << 16) 9 | #define kHash4Size (1 << 20) 10 | 11 | #define kFix3HashSize (kHash2Size) 12 | #define kFix4HashSize (kHash2Size + kHash3Size) 13 | #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) 14 | 15 | #define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); 16 | 17 | #define HASH3_CALC { \ 18 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 19 | hash2Value = temp & (kHash2Size - 1); \ 20 | hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } 21 | 22 | #define HASH4_CALC { \ 23 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 24 | hash2Value = temp & (kHash2Size - 1); \ 25 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 26 | hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } 27 | 28 | #define HASH5_CALC { \ 29 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 30 | hash2Value = temp & (kHash2Size - 1); \ 31 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 32 | hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ 33 | hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ 34 | hash4Value &= (kHash4Size - 1); } 35 | 36 | /* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ 37 | #define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; 38 | 39 | 40 | #define MT_HASH2_CALC \ 41 | hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); 42 | 43 | #define MT_HASH3_CALC { \ 44 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 45 | hash2Value = temp & (kHash2Size - 1); \ 46 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } 47 | 48 | #define MT_HASH4_CALC { \ 49 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 50 | hash2Value = temp & (kHash2Size - 1); \ 51 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 52 | hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/CpuArch.h: -------------------------------------------------------------------------------- 1 | /* CpuArch.h 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __CPUARCH_H 7 | #define __CPUARCH_H 8 | 9 | /* 10 | LITTLE_ENDIAN_UNALIGN means: 11 | 1) CPU is LITTLE_ENDIAN 12 | 2) it's allowed to make unaligned memory accesses 13 | if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know 14 | about these properties of platform. 15 | */ 16 | 17 | #if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) 18 | #define LITTLE_ENDIAN_UNALIGN 19 | #endif 20 | 21 | #ifdef LITTLE_ENDIAN_UNALIGN 22 | 23 | #define GetUi16(p) (*(const UInt16 *)(p)) 24 | #define GetUi32(p) (*(const UInt32 *)(p)) 25 | #define GetUi64(p) (*(const UInt64 *)(p)) 26 | #define SetUi32(p, d) *(UInt32 *)(p) = (d); 27 | 28 | #else 29 | 30 | #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) 31 | 32 | #define GetUi32(p) ( \ 33 | ((const Byte *)(p))[0] | \ 34 | ((UInt32)((const Byte *)(p))[1] << 8) | \ 35 | ((UInt32)((const Byte *)(p))[2] << 16) | \ 36 | ((UInt32)((const Byte *)(p))[3] << 24)) 37 | 38 | #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) 39 | 40 | #define SetUi32(p, d) { UInt32 _x_ = (d); \ 41 | ((Byte *)(p))[0] = (Byte)_x_; \ 42 | ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ 43 | ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ 44 | ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } 45 | 46 | #endif 47 | 48 | #if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) 49 | 50 | #pragma intrinsic(_byteswap_ulong) 51 | #pragma intrinsic(_byteswap_uint64) 52 | #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) 53 | #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) 54 | 55 | #else 56 | 57 | #define GetBe32(p) ( \ 58 | ((UInt32)((const Byte *)(p))[0] << 24) | \ 59 | ((UInt32)((const Byte *)(p))[1] << 16) | \ 60 | ((UInt32)((const Byte *)(p))[2] << 8) | \ 61 | ((const Byte *)(p))[3] ) 62 | 63 | #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) 64 | 65 | #endif 66 | 67 | #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /Fatpack/CommandLine/CommandLine.cpp: -------------------------------------------------------------------------------- 1 | #include "CommandLine.h" 2 | 3 | namespace CommandLine 4 | { 5 | CommandLine::CommandLine() 6 | { 7 | _lastError = Error::ErrorCode::Ok; 8 | } 9 | 10 | CommandLine::~CommandLine() 11 | { 12 | } 13 | 14 | bool CommandLine::Parse(LPWSTR& inputFileName, LPWSTR& outputFileName, Option& option) 15 | { 16 | SetLastError(Error::ErrorCode::Ok); 17 | 18 | return LoadArguments() && 19 | ValidateArgumentCount() && 20 | SetFileNames(inputFileName, outputFileName) && 21 | AreFileNamesDifferent(inputFileName, outputFileName) && 22 | ParseOption(option); 23 | } 24 | 25 | bool CommandLine::LoadArguments() 26 | { 27 | LPWSTR args = ::GetCommandLine(); 28 | _argumentVector = ::CommandLineToArgvW(args, &_argumentCount); 29 | return (_argumentVector != nullptr); 30 | } 31 | 32 | bool CommandLine::ValidateArgumentCount() 33 | { 34 | if (_argumentCount < 3 || _argumentCount > 4) 35 | { 36 | SetLastError(Error::ErrorCode::Error_Argument_Count); 37 | return false; 38 | } 39 | return true; 40 | } 41 | 42 | bool CommandLine::SetFileNames(LPWSTR& inputFileName, LPWSTR& outputFileName) 43 | { 44 | inputFileName = _argumentVector[1]; 45 | outputFileName = _argumentVector[2]; 46 | return true; 47 | } 48 | 49 | bool CommandLine::AreFileNamesDifferent(LPWSTR inputFileName, LPWSTR outputFileName) 50 | { 51 | if (wcscmp(inputFileName, outputFileName) == 0) 52 | { 53 | SetLastError(Error::ErrorCode::Error_Equal_Filenames); 54 | return false; 55 | } 56 | return true; 57 | } 58 | 59 | bool CommandLine::ParseOption(Option& option) 60 | { 61 | option = Option::Resource; 62 | if (_argumentCount == 4) 63 | { 64 | LPWSTR input = _argumentVector[3]; 65 | if (wcscmp(input, L"-r") == 0 || wcscmp(input, L"--resource") == 0) 66 | { 67 | option = Option::Resource; 68 | } 69 | else if (wcscmp(input, L"-s") == 0 || wcscmp(input, L"--section") == 0) 70 | { 71 | option = Option::Section; 72 | } 73 | else 74 | { 75 | SetLastError(Error::ErrorCode::Error_Unknown_Option); 76 | return false; 77 | } 78 | } 79 | return true; 80 | } 81 | } -------------------------------------------------------------------------------- /Shared/PELoaderStub/ResourceLoaderStub.cpp: -------------------------------------------------------------------------------- 1 | #include "ResourceLoaderStub.h" 2 | #include "..\..\Shared\ResourceLoader\ResourceLoader.h" 3 | #include "..\..\Shared\Decompressor\Decompressor.h" 4 | #include "..\..\Shared\PELoader\PELoader\PELoader.h" 5 | #include "..\..\Shared\PELoader\PELoader\PEImage.h" 6 | #include "..\..\Shared\PELoader\PELoader\PEFile.h" 7 | #include "..\..\Shared\ApiCaller\ApiCaller.h" 8 | 9 | namespace PELoaderStub 10 | { 11 | ResourceLoaderStub::ResourceLoaderStub() 12 | { 13 | } 14 | 15 | ResourceLoaderStub::~ResourceLoaderStub() 16 | { 17 | } 18 | 19 | PELoader::PEImage* ResourceLoaderStub::Load(PELoader::TlsResolver* tlsResolver) 20 | { 21 | return LoadFromResource(tlsResolver); 22 | } 23 | 24 | PELoader::PEImage* ResourceLoaderStub::LoadFromResource(PELoader::TlsResolver* tlsResolver) 25 | { 26 | DWORD compressedSize = 0; 27 | BYTE* compressedData = GetCompressedDataFromResource(compressedSize); 28 | if (!compressedData || compressedSize == 0) return nullptr; 29 | 30 | size_t decompressedSize = 0; 31 | BYTE* decompressedData = Decompress(compressedData, compressedSize, decompressedSize); 32 | delete[] compressedData; 33 | 34 | return CreatePEImageFromMemory(decompressedData, tlsResolver); 35 | } 36 | 37 | BYTE* ResourceLoaderStub::GetCompressedDataFromResource(DWORD& compressedSize) 38 | { 39 | ResourceLoader::ResourceLoader resourceLoader; 40 | return resourceLoader.LoadResource(L"FPACK", RT_RCDATA, compressedSize); 41 | } 42 | 43 | BYTE* ResourceLoaderStub::Decompress(BYTE* compressedData, DWORD compressedSize, size_t& decompressedSize) 44 | { 45 | BYTE* decompressedData = nullptr; 46 | Decompressor::Decompressor decompressor; 47 | decompressor.Decompress(compressedData, compressedSize, &decompressedData, &decompressedSize); 48 | return decompressedData; 49 | } 50 | 51 | PELoader::PEImage* ResourceLoaderStub::CreatePEImageFromMemory(BYTE* peFileBuffer, PELoader::TlsResolver* tlsResolver, LPVOID allocatedImageBase /*= nullptr*/) 52 | { 53 | if (!peFileBuffer) return nullptr; 54 | 55 | PELoader::PELoader peLoader; 56 | PELoader::PEFile peFile(peFileBuffer); 57 | 58 | allocatedImageBase = peLoader.LoadPE(&peFile, tlsResolver, allocatedImageBase); 59 | 60 | delete[] peFileBuffer; 61 | return new PELoader::PEImage(allocatedImageBase); 62 | } 63 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/common_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __ELZMA_COMMON_INTERNAL_H__ 2 | #define __ELZMA_COMMON_INTERNAL_H__ 3 | 4 | #include "easylzma/common.h" 5 | 6 | /** a structure which may be cast and passed into Igor's allocate 7 | * routines */ 8 | struct elzma_alloc_struct { 9 | void *(*Alloc)(void *p, size_t size); 10 | void (*Free)(void *p, void *address); /* address can be 0 */ 11 | 12 | elzma_malloc clientMallocFunc; 13 | void * clientMallocContext; 14 | 15 | elzma_free clientFreeFunc; 16 | void * clientFreeContext; 17 | }; 18 | 19 | /* initialize an allocation structure, may be called safely multiple 20 | * times */ 21 | void init_alloc_struct(struct elzma_alloc_struct * allocStruct, 22 | elzma_malloc clientMallocFunc, 23 | void * clientMallocContext, 24 | elzma_free clientFreeFunc, 25 | void * clientFreeContext); 26 | 27 | /** superset representation of a compressed file header */ 28 | struct elzma_file_header { 29 | unsigned char pb; 30 | unsigned char lp; 31 | unsigned char lc; 32 | unsigned char isStreamed; 33 | long long unsigned int uncompressedSize; 34 | unsigned int dictSize; 35 | }; 36 | 37 | /** superset representation of a compressed file footer */ 38 | struct elzma_file_footer { 39 | unsigned int crc32; 40 | long long unsigned int uncompressedSize; 41 | }; 42 | 43 | /** a structure which encapsulates information about the particular 44 | * file header and footer in use (lzip vs lzma vs (eventually) xz. 45 | * The intention of this structure is to simplify compression and 46 | * decompression logic by abstracting the file format details a bit. */ 47 | struct elzma_format_handler 48 | { 49 | unsigned int header_size; 50 | void (*init_header)(struct elzma_file_header * hdr); 51 | int (*parse_header)(const unsigned char * hdrBuf, 52 | struct elzma_file_header * hdr); 53 | int (*serialize_header)(unsigned char * hdrBuf, 54 | const struct elzma_file_header * hdr); 55 | 56 | unsigned int footer_size; 57 | int (*serialize_footer)(struct elzma_file_footer * ftr, 58 | unsigned char * ftrBuf); 59 | int (*parse_footer)(const unsigned char * ftrBuf, 60 | struct elzma_file_footer * ftr); 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Bra86.c: -------------------------------------------------------------------------------- 1 | /* Bra86.c -- Converter for x86 code (BCJ) 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bra.h" 5 | 6 | #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) 7 | 8 | const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; 9 | const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; 10 | 11 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) 12 | { 13 | SizeT bufferPos = 0, prevPosT; 14 | UInt32 prevMask = *state & 0x7; 15 | if (size < 5) 16 | return 0; 17 | ip += 5; 18 | prevPosT = (SizeT)0 - 1; 19 | 20 | for (;;) 21 | { 22 | Byte *p = data + bufferPos; 23 | Byte *limit = data + size - 4; 24 | for (; p < limit; p++) 25 | if ((*p & 0xFE) == 0xE8) 26 | break; 27 | bufferPos = (SizeT)(p - data); 28 | if (p >= limit) 29 | break; 30 | prevPosT = bufferPos - prevPosT; 31 | if (prevPosT > 3) 32 | prevMask = 0; 33 | else 34 | { 35 | prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; 36 | if (prevMask != 0) 37 | { 38 | Byte b = p[4 - kMaskToBitNumber[prevMask]]; 39 | if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) 40 | { 41 | prevPosT = bufferPos; 42 | prevMask = ((prevMask << 1) & 0x7) | 1; 43 | bufferPos++; 44 | continue; 45 | } 46 | } 47 | } 48 | prevPosT = bufferPos; 49 | 50 | if (Test86MSByte(p[4])) 51 | { 52 | UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); 53 | UInt32 dest; 54 | for (;;) 55 | { 56 | Byte b; 57 | int index; 58 | if (encoding) 59 | dest = (ip + (UInt32)bufferPos) + src; 60 | else 61 | dest = src - (ip + (UInt32)bufferPos); 62 | if (prevMask == 0) 63 | break; 64 | index = kMaskToBitNumber[prevMask] * 8; 65 | b = (Byte)(dest >> (24 - index)); 66 | if (!Test86MSByte(b)) 67 | break; 68 | src = dest ^ ((1 << (32 - index)) - 1); 69 | } 70 | p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); 71 | p[3] = (Byte)(dest >> 16); 72 | p[2] = (Byte)(dest >> 8); 73 | p[1] = (Byte)dest; 74 | bufferPos += 5; 75 | } 76 | else 77 | { 78 | prevMask = ((prevMask << 1) & 0x7) | 1; 79 | bufferPos++; 80 | } 81 | } 82 | prevPosT = bufferPos - prevPosT; 83 | *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); 84 | return bufferPos; 85 | } 86 | -------------------------------------------------------------------------------- /Shared/PELoaderStub/SectionLoaderStub.cpp: -------------------------------------------------------------------------------- 1 | #include "SectionLoaderStub.h" 2 | #include "..\..\Shared\Decompressor\Decompressor.h" 3 | #include "..\..\Shared\PELoader\PELoader\PELoader.h" 4 | #include "..\..\Shared\PELoader\PELoader\PEImage.h" 5 | #include "..\..\Shared\PELoader\PELoader\PEFile.h" 6 | #include "..\..\Shared\ApiCaller\ApiCaller.h" 7 | 8 | namespace PELoaderStub 9 | { 10 | SectionLoaderStub::SectionLoaderStub() 11 | { 12 | } 13 | 14 | SectionLoaderStub::~SectionLoaderStub() 15 | { 16 | } 17 | 18 | PELoader::PEImage* SectionLoaderStub::Load(PELoader::TlsResolver* tlsResolver) 19 | { 20 | return LoadFromSection(tlsResolver); 21 | } 22 | 23 | PELoader::PEImage* SectionLoaderStub::LoadFromSection(PELoader::TlsResolver* tlsResolver) 24 | { 25 | DWORD rawSize = 0, virtualSize = 0; 26 | BYTE* sectionBase = GetLastSection(rawSize, virtualSize); 27 | if (!sectionBase || rawSize == 0) return nullptr; 28 | 29 | size_t decompressedSize = 0; 30 | BYTE* decompressedData = Decompress(sectionBase, rawSize, decompressedSize); 31 | SecureZeroMemory(sectionBase, virtualSize); 32 | 33 | return CreatePEImageFromMemory(decompressedData, tlsResolver, sectionBase); 34 | } 35 | 36 | BYTE* SectionLoaderStub::GetLastSection(DWORD& rawSize, DWORD& virtualSize) 37 | { 38 | PELoader::PEImage self(ApiCaller::ApiCaller::Instance().CallGetModuleHandle(nullptr)); 39 | WORD lastSectionIndex = self.GetNumberOfSections() - 1; 40 | PIMAGE_SECTION_HEADER lastSectionHeader = self.GetSectionHeader(lastSectionIndex); 41 | 42 | BYTE* sectionStart = (BYTE*)self.GetImageBase() + lastSectionHeader->VirtualAddress; 43 | rawSize = lastSectionHeader->SizeOfRawData; 44 | virtualSize = lastSectionHeader->Misc.VirtualSize; 45 | 46 | DWORD oldProtect = 0; 47 | ApiCaller::ApiCaller::Instance().CallVirtualProtect(sectionStart, virtualSize, PAGE_EXECUTE_READWRITE, &oldProtect); 48 | 49 | return sectionStart; 50 | } 51 | 52 | BYTE* SectionLoaderStub::Decompress(BYTE* compressedData, DWORD compressedSize, size_t& decompressedSize) 53 | { 54 | BYTE* decompressedData = nullptr; 55 | Decompressor::Decompressor decompressor; 56 | decompressor.Decompress(compressedData, compressedSize, &decompressedData, &decompressedSize); 57 | return decompressedData; 58 | } 59 | 60 | PELoader::PEImage* SectionLoaderStub::CreatePEImageFromMemory(BYTE* peFileBuffer, PELoader::TlsResolver* tlsResolver, LPVOID allocatedImageBase /*= nullptr*/) 61 | { 62 | if (!peFileBuffer) return nullptr; 63 | 64 | PELoader::PELoader peLoader; 65 | PELoader::PEFile peFile(peFileBuffer); 66 | 67 | allocatedImageBase = peLoader.LoadPE(&peFile, tlsResolver, allocatedImageBase); 68 | 69 | delete[] peFileBuffer; 70 | return new PELoader::PEImage(allocatedImageBase); 71 | } 72 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/easylzma/compress.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | * 10 | * easylzma/compress.h - the API for LZMA compression using easylzma 11 | */ 12 | 13 | #ifndef __EASYLZMACOMPRESS_H__ 14 | #define __EASYLZMACOMPRESS_H__ 15 | 16 | #include "common.h" 17 | #include 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /** suggested default values */ 24 | #define ELZMA_LC_DEFAULT 3 25 | #define ELZMA_LP_DEFAULT 0 26 | #define ELZMA_PB_DEFAULT 2 27 | #define ELZMA_DICT_SIZE_DEFAULT_MAX (1 << 24) 28 | 29 | /** an opaque handle to an lzma compressor */ 30 | typedef struct _elzma_compress_handle * elzma_compress_handle; 31 | 32 | /** 33 | * Allocate a handle to an LZMA compressor object. 34 | */ 35 | elzma_compress_handle EASYLZMA_API elzma_compress_alloc(); 36 | 37 | /** 38 | * set allocation routines (optional, if not called malloc & free will 39 | * be used) 40 | */ 41 | void EASYLZMA_API elzma_compress_set_allocation_callbacks( 42 | elzma_compress_handle hand, 43 | elzma_malloc mallocFunc, void * mallocFuncContext, 44 | elzma_free freeFunc, void * freeFuncContext); 45 | 46 | /** 47 | * Free all data associated with an LZMA compressor object. 48 | */ 49 | void EASYLZMA_API elzma_compress_free(elzma_compress_handle * hand); 50 | 51 | /** 52 | * Set configuration paramters for a compression run. If not called, 53 | * reasonable defaults will be used. 54 | */ 55 | int EASYLZMA_API elzma_compress_config(elzma_compress_handle hand, 56 | unsigned char lc, 57 | unsigned char lp, 58 | unsigned char pb, 59 | unsigned char level, 60 | unsigned int dictionarySize, 61 | elzma_file_format format, 62 | unsigned long long uncompressedSize); 63 | 64 | /** 65 | * Run compression 66 | */ 67 | int EASYLZMA_API elzma_compress_run( 68 | elzma_compress_handle hand, 69 | elzma_read_callback inputStream, void * inputContext, 70 | elzma_write_callback outputStream, void * outputContext, 71 | elzma_progress_callback progressCallback, void * progressContext); 72 | 73 | 74 | /** 75 | * a heuristic utility routine to guess a dictionary size that gets near 76 | * optimal compression while reducing memory usage. 77 | * accepts a size in bytes, returns a proposed dictionary size 78 | */ 79 | unsigned int EASYLZMA_API elzma_get_dict_size(unsigned long long size); 80 | 81 | #ifdef __cplusplus 82 | }; 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/lzip_header.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "lzip_header.h" 3 | 4 | #define ELZMA_LZIP_HEADER_SIZE 6 5 | #define ELZMA_LZIP_FOOTER_SIZE 12 6 | 7 | static 8 | void initLzipHeader(struct elzma_file_header * hdr) 9 | { 10 | memset((void *) hdr, 0, sizeof(struct elzma_file_header)); 11 | } 12 | 13 | static 14 | int parseLzipHeader(const unsigned char * hdrBuf, 15 | struct elzma_file_header * hdr) 16 | { 17 | if (0 != strncmp("LZIP", (char *) hdrBuf, 4)) return 1; 18 | /* XXX: ignore version for now */ 19 | hdr->pb = 2; 20 | hdr->lp = 0; 21 | hdr->lc = 3; 22 | /* unknown at this point */ 23 | hdr->isStreamed = 1; 24 | hdr->uncompressedSize = 0; 25 | hdr->dictSize = 1 << (hdrBuf[5] & 0x1F); 26 | return 0; 27 | } 28 | 29 | static int 30 | serializeLzipHeader(unsigned char * hdrBuf, 31 | const struct elzma_file_header * hdr) 32 | { 33 | hdrBuf[0] = 'L'; 34 | hdrBuf[1] = 'Z'; 35 | hdrBuf[2] = 'I'; 36 | hdrBuf[3] = 'P'; 37 | hdrBuf[4] = 0; 38 | { 39 | int r = 0; 40 | while ((hdr->dictSize >> r) != 0) r++; 41 | hdrBuf[5] = (unsigned char) (r-1) & 0x1F; 42 | } 43 | return 0; 44 | } 45 | 46 | static int 47 | serializeLzipFooter(struct elzma_file_footer * ftr, 48 | unsigned char * ftrBuf) 49 | { 50 | unsigned int i = 0; 51 | 52 | /* first crc32 */ 53 | for (i = 0; i < 4; i++) { 54 | *(ftrBuf++) = (unsigned char) (ftr->crc32 >> (i * 8)); 55 | } 56 | 57 | /* next data size */ 58 | for (i = 0; i < 8; i++) { 59 | *(ftrBuf++) = (unsigned char) (ftr->uncompressedSize >> (i * 8)); 60 | } 61 | 62 | /* write version 0 files, omit member length for now*/ 63 | 64 | return 0; 65 | } 66 | 67 | static int 68 | parseLzipFooter(const unsigned char * ftrBuf, 69 | struct elzma_file_footer * ftr) 70 | { 71 | unsigned int i = 0; 72 | ftr->crc32 = 0; 73 | ftr->uncompressedSize = 0; 74 | 75 | /* first crc32 */ 76 | for (i = 0; i < 4; i++) 77 | { 78 | ftr->crc32 += ((unsigned int) *(ftrBuf++) << (i * 8)); 79 | } 80 | 81 | /* next data size */ 82 | for (i = 0; i < 8; i++) { 83 | ftr->uncompressedSize += 84 | (unsigned long long) *(ftrBuf++) << (i * 8); 85 | } 86 | /* read version 0 files, omit member length for now*/ 87 | 88 | return 0; 89 | } 90 | 91 | void 92 | initializeLZIPFormatHandler(struct elzma_format_handler * hand) 93 | { 94 | hand->header_size = ELZMA_LZIP_HEADER_SIZE; 95 | hand->init_header = initLzipHeader; 96 | hand->parse_header = parseLzipHeader; 97 | hand->serialize_header = serializeLzipHeader; 98 | hand->footer_size = ELZMA_LZIP_FOOTER_SIZE; 99 | hand->serialize_footer = serializeLzipFooter; 100 | hand->parse_footer = parseLzipFooter; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/LzmaEnc.h: -------------------------------------------------------------------------------- 1 | /* LzmaEnc.h -- LZMA Encoder 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZMAENC_H 5 | #define __LZMAENC_H 6 | 7 | #include "Types.h" 8 | 9 | #define LZMA_PROPS_SIZE 5 10 | 11 | typedef struct _CLzmaEncProps 12 | { 13 | int level; /* 0 <= level <= 9 */ 14 | UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version 15 | (1 << 12) <= dictSize <= (1 << 30) for 64-bit version 16 | default = (1 << 24) */ 17 | int lc; /* 0 <= lc <= 8, default = 3 */ 18 | int lp; /* 0 <= lp <= 4, default = 0 */ 19 | int pb; /* 0 <= pb <= 4, default = 2 */ 20 | int algo; /* 0 - fast, 1 - normal, default = 1 */ 21 | int fb; /* 5 <= fb <= 273, default = 32 */ 22 | int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ 23 | int numHashBytes; /* 2, 3 or 4, default = 4 */ 24 | UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ 25 | unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ 26 | int numThreads; /* 1 or 2, default = 2 */ 27 | } CLzmaEncProps; 28 | 29 | void LzmaEncProps_Init(CLzmaEncProps *p); 30 | void LzmaEncProps_Normalize(CLzmaEncProps *p); 31 | UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); 32 | 33 | 34 | /* ---------- CLzmaEncHandle Interface ---------- */ 35 | 36 | /* LzmaEnc_* functions can return the following exit codes: 37 | Returns: 38 | SZ_OK - OK 39 | SZ_ERROR_MEM - Memory allocation error 40 | SZ_ERROR_PARAM - Incorrect paramater in props 41 | SZ_ERROR_WRITE - Write callback error. 42 | SZ_ERROR_PROGRESS - some break from progress callback 43 | SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 44 | */ 45 | 46 | typedef void * CLzmaEncHandle; 47 | 48 | CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); 49 | void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); 50 | SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); 51 | SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); 52 | SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, 53 | ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 54 | SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 55 | int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 56 | 57 | /* ---------- One Call Interface ---------- */ 58 | 59 | /* LzmaEncode 60 | Return code: 61 | SZ_OK - OK 62 | SZ_ERROR_MEM - Memory allocation error 63 | SZ_ERROR_PARAM - Incorrect paramater 64 | SZ_ERROR_OUTPUT_EOF - output buffer overflow 65 | SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 66 | */ 67 | 68 | SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 69 | const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, 70 | ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /Fatpack/Console/Console.cpp: -------------------------------------------------------------------------------- 1 | #include "Console.h" 2 | 3 | namespace Console 4 | { 5 | Console::Console() 6 | { 7 | _consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 8 | } 9 | 10 | Console::~Console() 11 | { 12 | } 13 | 14 | void Console::WriteLine(const wchar_t* text) 15 | { 16 | DWORD written = 0; 17 | WriteConsoleW(_consoleHandle, text, (DWORD)wcslen(text), &written, NULL); 18 | WriteConsoleW(_consoleHandle, L"\n", 1, &written, NULL); 19 | } 20 | 21 | void Console::WriteError(Error::ErrorCode errorCode) 22 | { 23 | if (errorCode == Error::ErrorCode::Ok) return; 24 | WriteError(GetErrorString(errorCode)); 25 | } 26 | 27 | void Console::ShowHelp() 28 | { 29 | WriteLine(L"\n..::[Fatmike 2025]::..\n"); 30 | WriteLine(L"Version: Fatpack v1.5.2"); 31 | WriteLine(L"Usage:\t fatpack.exe inputfile.exe outputfile.exe [OPTIONS]\n"); 32 | WriteLine(L"[OPTIONS]"); 33 | WriteLine(L"-r, --resource\t Packs inputfile.exe as resource (DEFAULT)"); 34 | WriteLine(L"-s, --section\t Packs inputfile.exe as section (EXPERIMENTAL)"); 35 | WriteLine(L"\nNOTES"); 36 | WriteLine(L"-s, --section is the preferred option as it requires less memory at runtime.\nHowever, it may cause issues with certain targets in specific cases."); 37 | } 38 | 39 | void Console::WriteError(const wchar_t* text) 40 | { 41 | DWORD written = 0; 42 | const wchar_t* error = L"Error : "; 43 | WriteConsoleW(_consoleHandle, error, (DWORD)wcslen(error), &written, NULL); 44 | WriteConsoleW(_consoleHandle, text, (DWORD)wcslen(text), &written, NULL); 45 | WriteConsoleW(_consoleHandle, L"\n", 1, &written, NULL); 46 | } 47 | 48 | const wchar_t* Console::GetErrorString(Error::ErrorCode code) 49 | { 50 | switch (code) 51 | { 52 | case Error::ErrorCode::Ok: return L"Success."; 53 | case Error::ErrorCode::Error_Argument_Count: return L"Invalid number of arguments."; 54 | case Error::ErrorCode::Error_Equal_Filenames: return L"Input and output files must be different."; 55 | case Error::ErrorCode::Error_Unknown_Option: return L"Unknown option."; 56 | case Error::ErrorCode::Error_Read_File: return L"Failed to read file."; 57 | case Error::ErrorCode::Error_Load_Pe_From_Buffer: return L"Failed to load PE file from buffer."; 58 | case Error::ErrorCode::Error_Pe_Not_Valid: return L"Input file is not a valid PE file."; 59 | case Error::ErrorCode::Error_Pe_Not_x64: return L"Input file is not a x64 PE file."; 60 | case Error::ErrorCode::Error_Pe_Not_Native: return L"Input file is not a native PE file."; 61 | case Error::ErrorCode::Error_Loading_Loader_Stub: return L"Loading loader stub failed."; 62 | case Error::ErrorCode::Error_Saving_Pe: return L"Failed to save PE file."; 63 | case Error::ErrorCode::Error_Adding_Icon: return L"Adding icon failed."; 64 | case Error::ErrorCode::Error_Adding_Manifest: return L"Adding manifest failed."; 65 | case Error::ErrorCode::Error_Rebasing: return L"Rebasing failed."; 66 | case Error::ErrorCode::Error_Compressing: return L"Compressing failed."; 67 | case Error::ErrorCode::Error_Appending_Compressed_Data: return L"Appending compressed data failed."; 68 | default: return L"Unknown error code."; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Alloc.c: -------------------------------------------------------------------------------- 1 | /* Alloc.c -- Memory allocation functions 2 | 2008-09-24 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifdef _WIN32 7 | #include 8 | #endif 9 | #include 10 | 11 | #include "Alloc.h" 12 | 13 | /* #define _SZ_ALLOC_DEBUG */ 14 | 15 | /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ 16 | #ifdef _SZ_ALLOC_DEBUG 17 | #include 18 | int g_allocCount = 0; 19 | int g_allocCountMid = 0; 20 | int g_allocCountBig = 0; 21 | #endif 22 | 23 | void *MyAlloc(size_t size) 24 | { 25 | if (size == 0) 26 | return 0; 27 | #ifdef _SZ_ALLOC_DEBUG 28 | { 29 | void *p = malloc(size); 30 | fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); 31 | return p; 32 | } 33 | #else 34 | return malloc(size); 35 | #endif 36 | } 37 | 38 | void MyFree(void *address) 39 | { 40 | #ifdef _SZ_ALLOC_DEBUG 41 | if (address != 0) 42 | fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); 43 | #endif 44 | free(address); 45 | } 46 | 47 | #ifdef _WIN32 48 | 49 | void *MidAlloc(size_t size) 50 | { 51 | if (size == 0) 52 | return 0; 53 | #ifdef _SZ_ALLOC_DEBUG 54 | fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); 55 | #endif 56 | return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); 57 | } 58 | 59 | void MidFree(void *address) 60 | { 61 | #ifdef _SZ_ALLOC_DEBUG 62 | if (address != 0) 63 | fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); 64 | #endif 65 | if (address == 0) 66 | return; 67 | VirtualFree(address, 0, MEM_RELEASE); 68 | } 69 | 70 | #ifndef MEM_LARGE_PAGES 71 | #undef _7ZIP_LARGE_PAGES 72 | #endif 73 | 74 | #ifdef _7ZIP_LARGE_PAGES 75 | SIZE_T g_LargePageSize = 0; 76 | typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); 77 | #endif 78 | 79 | void SetLargePageSize() 80 | { 81 | #ifdef _7ZIP_LARGE_PAGES 82 | SIZE_T size = 0; 83 | GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) 84 | GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); 85 | if (largePageMinimum == 0) 86 | return; 87 | size = largePageMinimum(); 88 | if (size == 0 || (size & (size - 1)) != 0) 89 | return; 90 | g_LargePageSize = size; 91 | #endif 92 | } 93 | 94 | 95 | void *BigAlloc(size_t size) 96 | { 97 | if (size == 0) 98 | return 0; 99 | #ifdef _SZ_ALLOC_DEBUG 100 | fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); 101 | #endif 102 | 103 | #ifdef _7ZIP_LARGE_PAGES 104 | if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) 105 | { 106 | void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), 107 | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); 108 | if (res != 0) 109 | return res; 110 | } 111 | #endif 112 | return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); 113 | } 114 | 115 | void BigFree(void *address) 116 | { 117 | #ifdef _SZ_ALLOC_DEBUG 118 | if (address != 0) 119 | fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); 120 | #endif 121 | 122 | if (address == 0) 123 | return; 124 | VirtualFree(address, 0, MEM_RELEASE); 125 | } 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /Fatpack/ManifestExtractor/ManifestExtractor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ManifestExtractor.h" 3 | #include "..\..\Shared\ApiCaller\ApiCaller.h" 4 | namespace ManifestExtractor 5 | { 6 | ManifestResource* ManifestExtractor::_manifestResources = nullptr; 7 | DWORD ManifestExtractor::_manifestCount = 0; 8 | 9 | ManifestExtractor::ManifestExtractor() 10 | { 11 | _heapHandle = ApiCaller::ApiCaller::Instance().CallGetProcessHeap(); 12 | _manifestResources = (ManifestResource*)ApiCaller::ApiCaller::Instance().CallHeapAlloc(_heapHandle, HEAP_ZERO_MEMORY, MAX_MANIFEST_RESOURCES * sizeof(ManifestResource)); 13 | _manifestCount = 0; 14 | } 15 | 16 | ManifestExtractor::~ManifestExtractor() 17 | { 18 | if (_manifestResources) 19 | { 20 | HeapFree(_heapHandle, 0, _manifestResources); 21 | _manifestResources = nullptr; 22 | } 23 | _manifestCount = 0; 24 | } 25 | 26 | bool ManifestExtractor::ExtractManifestResources(LPWSTR fileName) 27 | { 28 | _manifestCount = 0; 29 | 30 | HMODULE sourceModuleHandle = LoadLibraryExW(fileName, nullptr, LOAD_LIBRARY_AS_DATAFILE); 31 | if (!sourceModuleHandle) 32 | { 33 | return false; 34 | } 35 | 36 | if (!EnumResourceNames(sourceModuleHandle, MANIFEST_RESOURCE_TYPE, EnumResNameProc, 0)) 37 | { 38 | FreeLibrary(sourceModuleHandle); 39 | return false; 40 | } 41 | 42 | return (_manifestCount > 0); 43 | } 44 | 45 | bool ManifestExtractor::AddManifestResourcesToTarget(LPWSTR destinationPath) 46 | { 47 | HANDLE updateHandle = BeginUpdateResourceW(destinationPath, FALSE); 48 | if (!updateHandle) 49 | { 50 | return false; 51 | } 52 | 53 | for (DWORD i = 0; i < _manifestCount; ++i) 54 | { 55 | ManifestResource& res = _manifestResources[i]; 56 | if (!UpdateResource(updateHandle, MANIFEST_RESOURCE_TYPE, MAKEINTRESOURCE(res.id), res.lang, res.data, res.size)) 57 | { 58 | EndUpdateResource(updateHandle, TRUE); 59 | return false; 60 | } 61 | } 62 | 63 | if (!EndUpdateResource(updateHandle, FALSE)) 64 | { 65 | return false; 66 | } 67 | 68 | return true; 69 | } 70 | 71 | BOOL CALLBACK ManifestExtractor::EnumResNameProc(HMODULE moduleHandle, LPCTSTR type, LPTSTR name, LONG_PTR param) 72 | { 73 | EnumResourceLanguages(moduleHandle, type, name, EnumResLangProc, param); 74 | return TRUE; 75 | } 76 | 77 | BOOL CALLBACK ManifestExtractor::EnumResLangProc(HMODULE moduleHandle, LPCTSTR type, LPCTSTR name, WORD language, LONG_PTR param) 78 | { 79 | if (_manifestCount >= MAX_MANIFEST_RESOURCES) 80 | { 81 | return FALSE; // Stop enumeration 82 | } 83 | 84 | HRSRC hRes = FindResourceEx(moduleHandle, type, name, language); 85 | if (!hRes) return TRUE; 86 | 87 | DWORD resourceSize = SizeofResource(moduleHandle, hRes); 88 | HGLOBAL resourceDataHandle = LoadResource(moduleHandle, hRes); 89 | LPVOID resourceData = LockResource(resourceDataHandle); 90 | 91 | if (resourceData && resourceSize > 0) 92 | { 93 | ManifestResource& res = _manifestResources[_manifestCount++]; 94 | res.id = (WORD)(IS_INTRESOURCE(name) ? (WORD)(uintptr_t)name : 1); 95 | res.lang = language; 96 | res.size = resourceSize; 97 | res.data = resourceData; 98 | } 99 | 100 | return TRUE; // Continue enumeration 101 | } 102 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/LzFind.h: -------------------------------------------------------------------------------- 1 | /* LzFind.h -- Match finder for LZ algorithms 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZFIND_H 5 | #define __LZFIND_H 6 | 7 | #include "Types.h" 8 | 9 | typedef UInt32 CLzRef; 10 | 11 | typedef struct _CMatchFinder 12 | { 13 | Byte *buffer; 14 | UInt32 pos; 15 | UInt32 posLimit; 16 | UInt32 streamPos; 17 | UInt32 lenLimit; 18 | 19 | UInt32 cyclicBufferPos; 20 | UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ 21 | 22 | UInt32 matchMaxLen; 23 | CLzRef *hash; 24 | CLzRef *son; 25 | UInt32 hashMask; 26 | UInt32 cutValue; 27 | 28 | Byte *bufferBase; 29 | ISeqInStream *stream; 30 | int streamEndWasReached; 31 | 32 | UInt32 blockSize; 33 | UInt32 keepSizeBefore; 34 | UInt32 keepSizeAfter; 35 | 36 | UInt32 numHashBytes; 37 | int directInput; 38 | int btMode; 39 | /* int skipModeBits; */ 40 | int bigHash; 41 | UInt32 historySize; 42 | UInt32 fixedHashSize; 43 | UInt32 hashSizeSum; 44 | UInt32 numSons; 45 | SRes result; 46 | UInt32 crc[256]; 47 | } CMatchFinder; 48 | 49 | #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) 50 | #define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) 51 | 52 | #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) 53 | 54 | int MatchFinder_NeedMove(CMatchFinder *p); 55 | Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); 56 | void MatchFinder_MoveBlock(CMatchFinder *p); 57 | void MatchFinder_ReadIfRequired(CMatchFinder *p); 58 | 59 | void MatchFinder_Construct(CMatchFinder *p); 60 | 61 | /* Conditions: 62 | historySize <= 3 GB 63 | keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB 64 | */ 65 | int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, 66 | UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, 67 | ISzAlloc *alloc); 68 | void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); 69 | void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); 70 | void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); 71 | 72 | UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, 73 | UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, 74 | UInt32 *distances, UInt32 maxLen); 75 | 76 | /* 77 | Conditions: 78 | Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. 79 | Mf_GetPointerToCurrentPos_Func's result must be used only before any other function 80 | */ 81 | 82 | typedef void (*Mf_Init_Func)(void *object); 83 | typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); 84 | typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); 85 | typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); 86 | typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); 87 | typedef void (*Mf_Skip_Func)(void *object, UInt32); 88 | 89 | typedef struct _IMatchFinder 90 | { 91 | Mf_Init_Func Init; 92 | Mf_GetIndexByte_Func GetIndexByte; 93 | Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; 94 | Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; 95 | Mf_GetMatches_Func GetMatches; 96 | Mf_Skip_Func Skip; 97 | } IMatchFinder; 98 | 99 | void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); 100 | 101 | void MatchFinder_Init(CMatchFinder *p); 102 | UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); 103 | UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); 104 | void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); 105 | void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Bra.c: -------------------------------------------------------------------------------- 1 | /* Bra.c -- Converters for RISC code 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bra.h" 5 | 6 | SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) 7 | { 8 | SizeT i; 9 | if (size < 4) 10 | return 0; 11 | size -= 4; 12 | ip += 8; 13 | for (i = 0; i <= size; i += 4) 14 | { 15 | if (data[i + 3] == 0xEB) 16 | { 17 | UInt32 dest; 18 | UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); 19 | src <<= 2; 20 | if (encoding) 21 | dest = ip + (UInt32)i + src; 22 | else 23 | dest = src - (ip + (UInt32)i); 24 | dest >>= 2; 25 | data[i + 2] = (Byte)(dest >> 16); 26 | data[i + 1] = (Byte)(dest >> 8); 27 | data[i + 0] = (Byte)dest; 28 | } 29 | } 30 | return i; 31 | } 32 | 33 | SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) 34 | { 35 | SizeT i; 36 | if (size < 4) 37 | return 0; 38 | size -= 4; 39 | ip += 4; 40 | for (i = 0; i <= size; i += 2) 41 | { 42 | if ((data[i + 1] & 0xF8) == 0xF0 && 43 | (data[i + 3] & 0xF8) == 0xF8) 44 | { 45 | UInt32 dest; 46 | UInt32 src = 47 | (((UInt32)data[i + 1] & 0x7) << 19) | 48 | ((UInt32)data[i + 0] << 11) | 49 | (((UInt32)data[i + 3] & 0x7) << 8) | 50 | (data[i + 2]); 51 | 52 | src <<= 1; 53 | if (encoding) 54 | dest = ip + (UInt32)i + src; 55 | else 56 | dest = src - (ip + (UInt32)i); 57 | dest >>= 1; 58 | 59 | data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); 60 | data[i + 0] = (Byte)(dest >> 11); 61 | data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); 62 | data[i + 2] = (Byte)dest; 63 | i += 2; 64 | } 65 | } 66 | return i; 67 | } 68 | 69 | SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) 70 | { 71 | SizeT i; 72 | if (size < 4) 73 | return 0; 74 | size -= 4; 75 | for (i = 0; i <= size; i += 4) 76 | { 77 | if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) 78 | { 79 | UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | 80 | ((UInt32)data[i + 1] << 16) | 81 | ((UInt32)data[i + 2] << 8) | 82 | ((UInt32)data[i + 3] & (~3)); 83 | 84 | UInt32 dest; 85 | if (encoding) 86 | dest = ip + (UInt32)i + src; 87 | else 88 | dest = src - (ip + (UInt32)i); 89 | data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); 90 | data[i + 1] = (Byte)(dest >> 16); 91 | data[i + 2] = (Byte)(dest >> 8); 92 | data[i + 3] &= 0x3; 93 | data[i + 3] |= dest; 94 | } 95 | } 96 | return i; 97 | } 98 | 99 | SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) 100 | { 101 | UInt32 i; 102 | if (size < 4) 103 | return 0; 104 | size -= 4; 105 | for (i = 0; i <= size; i += 4) 106 | { 107 | if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || 108 | data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) 109 | { 110 | UInt32 src = 111 | ((UInt32)data[i + 0] << 24) | 112 | ((UInt32)data[i + 1] << 16) | 113 | ((UInt32)data[i + 2] << 8) | 114 | ((UInt32)data[i + 3]); 115 | UInt32 dest; 116 | 117 | src <<= 2; 118 | if (encoding) 119 | dest = ip + i + src; 120 | else 121 | dest = src - (ip + i); 122 | dest >>= 2; 123 | 124 | dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; 125 | 126 | data[i + 0] = (Byte)(dest >> 24); 127 | data[i + 1] = (Byte)(dest >> 16); 128 | data[i + 2] = (Byte)(dest >> 8); 129 | data[i + 3] = (Byte)dest; 130 | } 131 | } 132 | return i; 133 | } 134 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Bcj2.c: -------------------------------------------------------------------------------- 1 | /* Bcj2.c -- Converter for x86 code (BCJ2) 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bcj2.h" 5 | 6 | #ifdef _LZMA_PROB32 7 | #define CProb UInt32 8 | #else 9 | #define CProb UInt16 10 | #endif 11 | 12 | #define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) 13 | #define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) 14 | 15 | #define kNumTopBits 24 16 | #define kTopValue ((UInt32)1 << kNumTopBits) 17 | 18 | #define kNumBitModelTotalBits 11 19 | #define kBitModelTotal (1 << kNumBitModelTotalBits) 20 | #define kNumMoveBits 5 21 | 22 | #define RC_READ_BYTE (*buffer++) 23 | #define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } 24 | #define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ 25 | { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} 26 | 27 | #define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } 28 | 29 | #define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 30 | #define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; 31 | #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; 32 | 33 | int Bcj2_Decode( 34 | const Byte *buf0, SizeT size0, 35 | const Byte *buf1, SizeT size1, 36 | const Byte *buf2, SizeT size2, 37 | const Byte *buf3, SizeT size3, 38 | Byte *outBuf, SizeT outSize) 39 | { 40 | CProb p[256 + 2]; 41 | SizeT inPos = 0, outPos = 0; 42 | 43 | const Byte *buffer, *bufferLim; 44 | UInt32 range, code; 45 | Byte prevByte = 0; 46 | 47 | unsigned int i; 48 | for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) 49 | p[i] = kBitModelTotal >> 1; 50 | 51 | buffer = buf3; 52 | bufferLim = buffer + size3; 53 | RC_INIT2 54 | 55 | if (outSize == 0) 56 | return SZ_OK; 57 | 58 | for (;;) 59 | { 60 | Byte b; 61 | CProb *prob; 62 | UInt32 bound; 63 | UInt32 ttt; 64 | 65 | SizeT limit = size0 - inPos; 66 | if (outSize - outPos < limit) 67 | limit = outSize - outPos; 68 | while (limit != 0) 69 | { 70 | Byte b = buf0[inPos]; 71 | outBuf[outPos++] = b; 72 | if (IsJ(prevByte, b)) 73 | break; 74 | inPos++; 75 | prevByte = b; 76 | limit--; 77 | } 78 | 79 | if (limit == 0 || outPos == outSize) 80 | break; 81 | 82 | b = buf0[inPos++]; 83 | 84 | if (b == 0xE8) 85 | prob = p + prevByte; 86 | else if (b == 0xE9) 87 | prob = p + 256; 88 | else 89 | prob = p + 257; 90 | 91 | IF_BIT_0(prob) 92 | { 93 | UPDATE_0(prob) 94 | prevByte = b; 95 | } 96 | else 97 | { 98 | UInt32 dest; 99 | const Byte *v; 100 | UPDATE_1(prob) 101 | if (b == 0xE8) 102 | { 103 | v = buf1; 104 | if (size1 < 4) 105 | return SZ_ERROR_DATA; 106 | buf1 += 4; 107 | size1 -= 4; 108 | } 109 | else 110 | { 111 | v = buf2; 112 | if (size2 < 4) 113 | return SZ_ERROR_DATA; 114 | buf2 += 4; 115 | size2 -= 4; 116 | } 117 | dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | 118 | ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); 119 | outBuf[outPos++] = (Byte)dest; 120 | if (outPos == outSize) 121 | break; 122 | outBuf[outPos++] = (Byte)(dest >> 8); 123 | if (outPos == outSize) 124 | break; 125 | outBuf[outPos++] = (Byte)(dest >> 16); 126 | if (outPos == outSize) 127 | break; 128 | outBuf[outPos++] = prevByte = (Byte)(dest >> 24); 129 | } 130 | } 131 | return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; 132 | } 133 | -------------------------------------------------------------------------------- /Fatpack/Packer/ResourcePacker.cpp: -------------------------------------------------------------------------------- 1 | #include "ResourcePacker.h" 2 | #include "PackerUtils.h" 3 | #include "..\Compressor\Compressor.h" 4 | 5 | namespace Packer 6 | { 7 | ResourcePacker::ResourcePacker(PackerUtils* packerUtils) 8 | { 9 | _packerUtils = packerUtils; 10 | _lastError = Error::ErrorCode::Ok; 11 | } 12 | 13 | ResourcePacker::~ResourcePacker() 14 | { 15 | } 16 | 17 | bool ResourcePacker::Pack(LPWSTR inputFileName, LPWSTR outputFileName) 18 | { 19 | SetLastError(Error::ErrorCode::Ok); 20 | 21 | return ReadPeFile(inputFileName, _inputFile) && 22 | ValidateInputFile() && 23 | PrepareLoaderStub() && 24 | RebaseIfNeeded() && 25 | SavePeLoader(outputFileName) && 26 | AppendResourcesToLoader(inputFileName, outputFileName) && 27 | CompressAndEmbed(outputFileName); 28 | } 29 | 30 | bool ResourcePacker::ReadPeFile(LPWSTR fileName, PEFile::PEFile& peFile) 31 | { 32 | if (!_packerUtils->ReadPeFile(fileName, peFile)) 33 | { 34 | SetLastError(_packerUtils->GetLastError()); 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | bool ResourcePacker::ValidateInputFile() 41 | { 42 | if (!_packerUtils->ValidatePeFile(_inputFile)) 43 | { 44 | SetLastError(_packerUtils->GetLastError()); 45 | return false; 46 | } 47 | return true; 48 | } 49 | 50 | bool ResourcePacker::PrepareLoaderStub() 51 | { 52 | if (!_packerUtils->PrepareResourceLoaderStub(_inputFile, _peLoader)) 53 | { 54 | SetLastError(_packerUtils->GetLastError()); 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | bool ResourcePacker::RebaseIfNeeded() 61 | { 62 | if (!_inputFile.HasRelocationTable() && _inputFile.IntersectsWith(_peLoader)) 63 | { 64 | ULONGLONG newBase = _inputFile.GetNextImageBase(); 65 | if (!_peLoader.Rebase(newBase)) 66 | { 67 | SetLastError(Error::ErrorCode::Error_Rebasing); 68 | return false; 69 | } 70 | } 71 | return true; 72 | } 73 | 74 | bool ResourcePacker::SavePeLoader(LPWSTR fileName) 75 | { 76 | if (!_packerUtils->SavePeFile(fileName, _peLoader)) 77 | { 78 | SetLastError(_packerUtils->GetLastError()); 79 | return false; 80 | } 81 | return true; 82 | } 83 | 84 | bool ResourcePacker::AppendResourcesToLoader(LPWSTR inputFileName, LPWSTR outputFileName) 85 | { 86 | if (!_packerUtils->AppendResources(inputFileName, outputFileName)) 87 | { 88 | SetLastError(_packerUtils->GetLastError()); 89 | return false; 90 | } 91 | return true; 92 | } 93 | 94 | bool ResourcePacker::CompressAndEmbed(LPWSTR outputFileName) 95 | { 96 | Compressor::Compressor compressor; 97 | BYTE* compressed = nullptr; 98 | size_t compressedSize = 0; 99 | 100 | if (!compressor.Compress(_inputFile.GetBuffer(), _inputFile.GetBufferSize(), &compressed, &compressedSize)) 101 | { 102 | SetLastError(Error::ErrorCode::Error_Compressing); 103 | return false; 104 | } 105 | 106 | HANDLE updateHandle = BeginUpdateResourceW(outputFileName, FALSE); 107 | if (updateHandle == nullptr) 108 | { 109 | SetLastError(Error::ErrorCode::Error_Appending_Compressed_Data); 110 | return false; 111 | } 112 | if (UpdateResource(updateHandle, RT_RCDATA, L"FPACK", MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), compressed, (DWORD)compressedSize) == FALSE) 113 | { 114 | SetLastError(Error::ErrorCode::Error_Appending_Compressed_Data); 115 | return false; 116 | } 117 | if (EndUpdateResource(updateHandle, FALSE) == FALSE) 118 | { 119 | SetLastError(Error::ErrorCode::Error_Appending_Compressed_Data); 120 | return false; 121 | } 122 | 123 | compressor.Free(compressed); 124 | 125 | return true; 126 | } 127 | } -------------------------------------------------------------------------------- /Fatpack/Packer/PackerUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "PackerUtils.h" 2 | #include "..\BinaryFileWriter\BinaryFileWriter.h" 3 | #include "..\IconExtractor\IconExtractor.h" 4 | #include "..\ManifestExtractor\ManifestExtractor.h" 5 | #include "..\..\Shared\BinaryFileReader\BinaryFileReader.h" 6 | #include "..\..\Shared\ResourceLoader\ResourceLoader.h" 7 | 8 | namespace Packer 9 | { 10 | PackerUtils::PackerUtils() 11 | { 12 | _lastError = Error::ErrorCode::Ok; 13 | } 14 | 15 | PackerUtils::~PackerUtils() 16 | { 17 | } 18 | 19 | bool PackerUtils::ReadPeFile(LPWSTR fileName, PEFile::PEFile& peFile) 20 | { 21 | BinaryFileReader::BinaryFileReader reader(fileName); 22 | if (reader.GetBufferSize() == 0 || reader.GetBuffer() == nullptr) 23 | { 24 | SetLastError(Error::ErrorCode::Error_Read_File); 25 | return false; 26 | } 27 | 28 | if (!peFile.LoadFromBuffer(reader.GetBuffer(), reader.GetBufferSize())) 29 | { 30 | SetLastError(Error::ErrorCode::Error_Load_Pe_From_Buffer); 31 | return false; 32 | } 33 | return true; 34 | } 35 | 36 | bool PackerUtils::ValidatePeFile(PEFile::PEFile& peFile) 37 | { 38 | if (!peFile.IsPEFile()) 39 | { 40 | SetLastError(Error::ErrorCode::Error_Pe_Not_Valid); 41 | return false; 42 | } 43 | if (!peFile.Isx64()) 44 | { 45 | SetLastError(Error::ErrorCode::Error_Pe_Not_x64); 46 | return false; 47 | } 48 | if (!peFile.IsNative()) 49 | { 50 | SetLastError(Error::ErrorCode::Error_Pe_Not_Native); 51 | return false; 52 | } 53 | return true; 54 | } 55 | 56 | bool PackerUtils::PrepareResourceLoaderStub(PEFile::PEFile& inputFile, PEFile::PEFile& peLoader) 57 | { 58 | if (inputFile.IsConsole()) 59 | { 60 | return PrepareLoaderStub(peLoader, 1000); 61 | } 62 | else 63 | { 64 | return PrepareLoaderStub(peLoader, 1001); 65 | } 66 | } 67 | 68 | bool PackerUtils::PrepareSectionLoaderStub(PEFile::PEFile& inputFile, PEFile::PEFile& peLoader) 69 | { 70 | if (inputFile.IsConsole()) 71 | { 72 | return PrepareLoaderStub(peLoader, 1002); 73 | } 74 | else 75 | { 76 | return PrepareLoaderStub(peLoader, 1003); 77 | } 78 | } 79 | 80 | bool PackerUtils::PrepareLoaderStub(PEFile::PEFile& peLoader, WORD resourceId) 81 | { 82 | ResourceLoader::ResourceLoader resourceLoader; 83 | DWORD size = 0; 84 | BYTE* buffer = nullptr; 85 | 86 | buffer = resourceLoader.LoadResource(MAKEINTRESOURCE(resourceId), RT_RCDATA, size); 87 | 88 | if (!buffer || size == 0 || !peLoader.LoadFromBuffer(buffer, size)) 89 | { 90 | SetLastError(Error::ErrorCode::Error_Loading_Loader_Stub); 91 | return false; 92 | } 93 | 94 | resourceLoader.Free(buffer); 95 | return true; 96 | } 97 | 98 | bool PackerUtils::SavePeFile(LPWSTR fileName, PEFile::PEFile& peFile) 99 | { 100 | BinaryFileWriter::BinaryFileWriter writer; 101 | if (!writer.WriteFile(fileName, peFile.GetBuffer(), peFile.GetBufferSize())) 102 | { 103 | SetLastError(Error::ErrorCode::Error_Saving_Pe); 104 | return false; 105 | } 106 | return true; 107 | } 108 | 109 | bool PackerUtils::AppendResources(LPWSTR inputFileName, LPWSTR outputFileName) 110 | { 111 | IconExtractor::IconExtractor iconExtractor; 112 | if (!iconExtractor.ExtractAndSetIconWithCustomIds(inputFileName, outputFileName)) 113 | { 114 | SetLastError(Error::ErrorCode::Error_Adding_Icon); 115 | return false; 116 | } 117 | 118 | ManifestExtractor::ManifestExtractor manifestExtractor; 119 | if (manifestExtractor.ExtractManifestResources(inputFileName)) 120 | { 121 | if (!manifestExtractor.AddManifestResourcesToTarget(outputFileName)) 122 | { 123 | SetLastError(Error::ErrorCode::Error_Adding_Manifest); 124 | return false; 125 | } 126 | } 127 | 128 | return true; 129 | } 130 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/wrapper/easylzmawrapper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | * 10 | * simple.c - a wrapper around easylzma to compress/decompress to memory 11 | */ 12 | 13 | #include 14 | #include "easylzmawrapper.h" 15 | 16 | struct dataStream 17 | { 18 | const unsigned char * inData; 19 | size_t inLen; 20 | 21 | unsigned char * outData; 22 | size_t outLen; 23 | }; 24 | 25 | static int 26 | inputCallback(void *ctx, void *buf, size_t * size) 27 | { 28 | size_t rd = 0; 29 | struct dataStream * ds = (struct dataStream *) ctx; 30 | 31 | rd = (ds->inLen < *size) ? ds->inLen : *size; 32 | 33 | if (rd > 0) { 34 | memcpy(buf, (void *) ds->inData, rd); 35 | ds->inData += rd; 36 | ds->inLen -= rd; 37 | } 38 | 39 | *size = rd; 40 | 41 | return 0; 42 | } 43 | 44 | static size_t 45 | outputCallback(void *ctx, const void *buf, size_t size) 46 | { 47 | struct dataStream * ds = (struct dataStream *) ctx; 48 | 49 | if (size > 0) { 50 | ds->outData = (unsigned char*)realloc(ds->outData, ds->outLen + size); 51 | memcpy((void *) (ds->outData + ds->outLen), buf, size); 52 | ds->outLen += size; 53 | } 54 | 55 | return size; 56 | } 57 | 58 | int 59 | simpleCompress(elzma_file_format format, const unsigned char * inData, 60 | size_t inLen, unsigned char ** outData, 61 | size_t * outLen) 62 | { 63 | int rc; 64 | elzma_compress_handle hand; 65 | 66 | /* allocate compression handle */ 67 | hand = elzma_compress_alloc(); 68 | 69 | rc = elzma_compress_config(hand, ELZMA_LC_DEFAULT, 70 | ELZMA_LP_DEFAULT, ELZMA_PB_DEFAULT, 71 | 9, (1 << 20) /* 1mb */, 72 | format, inLen); 73 | 74 | if (rc != ELZMA_E_OK) { 75 | elzma_compress_free(&hand); 76 | return rc; 77 | } 78 | 79 | /* now run the compression */ 80 | { 81 | struct dataStream ds; 82 | ds.inData = inData; 83 | ds.inLen = inLen; 84 | ds.outData = NULL; 85 | ds.outLen = 0; 86 | 87 | rc = elzma_compress_run(hand, inputCallback, (void *) &ds, 88 | outputCallback, (void *) &ds, 89 | NULL, NULL); 90 | 91 | if (rc != ELZMA_E_OK) { 92 | if (ds.outData != NULL) free(ds.outData); 93 | elzma_compress_free(&hand); 94 | return rc; 95 | } 96 | 97 | *outData = ds.outData; 98 | *outLen = ds.outLen; 99 | } 100 | 101 | return rc; 102 | } 103 | 104 | //int 105 | //simpleDecompress(elzma_file_format format, const unsigned char * inData, 106 | // size_t inLen, unsigned char ** outData, 107 | // size_t * outLen) 108 | //{ 109 | // int rc; 110 | // elzma_decompress_handle hand; 111 | // 112 | // hand = elzma_decompress_alloc(); 113 | // 114 | // /* now run the compression */ 115 | // { 116 | // struct dataStream ds; 117 | // ds.inData = inData; 118 | // ds.inLen = inLen; 119 | // ds.outData = NULL; 120 | // ds.outLen = 0; 121 | // 122 | // rc = elzma_decompress_run(hand, inputCallback, (void *) &ds, 123 | // outputCallback, (void *) &ds, format); 124 | // 125 | // if (rc != ELZMA_E_OK) { 126 | // if (ds.outData != NULL) free(ds.outData); 127 | // elzma_decompress_free(&hand); 128 | // return rc; 129 | // } 130 | // 131 | // *outData = ds.outData; 132 | // *outLen = ds.outLen; 133 | // } 134 | // 135 | // return rc; 136 | //} 137 | -------------------------------------------------------------------------------- /Fatpack.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.13.35818.85 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fatpack", "Fatpack\Fatpack.vcxproj", "{23B3307D-097A-4F6F-BD3D-AB61BEA6D30C}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {1378C489-F61E-4A00-9757-34D7A88B42E9} = {1378C489-F61E-4A00-9757-34D7A88B42E9} 9 | {6482B097-A9DE-4D2F-B103-7DF0BC56B231} = {6482B097-A9DE-4D2F-B103-7DF0BC56B231} 10 | {7B2040C9-F75E-4D32-9D50-B34DAA46FDB4} = {7B2040C9-F75E-4D32-9D50-B34DAA46FDB4} 11 | {D6392848-12A3-4B94-BF4C-1CE727F12D0B} = {D6392848-12A3-4B94-BF4C-1CE727F12D0B} 12 | {E373949F-E084-4DD4-A445-43B2672C42AA} = {E373949F-E084-4DD4-A445-43B2672C42AA} 13 | EndProjectSection 14 | EndProject 15 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loader_Console_Resource", "Loader_Console_Resource\Loader_Console_Resource.vcxproj", "{E373949F-E084-4DD4-A445-43B2672C42AA}" 16 | EndProject 17 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ResourceAdder", "ResourceAdder\ResourceAdder.vcxproj", "{D6392848-12A3-4B94-BF4C-1CE727F12D0B}" 18 | EndProject 19 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loader_Windows_Resource", "Loader_Windows_Resource\Loader_Windows_Resource.vcxproj", "{6482B097-A9DE-4D2F-B103-7DF0BC56B231}" 20 | EndProject 21 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loader_Console_Section", "Loader_Console_Section\Loader_Console_Section.vcxproj", "{1378C489-F61E-4A00-9757-34D7A88B42E9}" 22 | EndProject 23 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Loader_Windows_Section", "Loader_Windows_Section\Loader_Windows_Section.vcxproj", "{7B2040C9-F75E-4D32-9D50-B34DAA46FDB4}" 24 | EndProject 25 | Global 26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 27 | Debug|x64 = Debug|x64 28 | Release|x64 = Release|x64 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {23B3307D-097A-4F6F-BD3D-AB61BEA6D30C}.Debug|x64.ActiveCfg = Debug|x64 32 | {23B3307D-097A-4F6F-BD3D-AB61BEA6D30C}.Debug|x64.Build.0 = Debug|x64 33 | {23B3307D-097A-4F6F-BD3D-AB61BEA6D30C}.Release|x64.ActiveCfg = Release|x64 34 | {23B3307D-097A-4F6F-BD3D-AB61BEA6D30C}.Release|x64.Build.0 = Release|x64 35 | {E373949F-E084-4DD4-A445-43B2672C42AA}.Debug|x64.ActiveCfg = Debug|x64 36 | {E373949F-E084-4DD4-A445-43B2672C42AA}.Debug|x64.Build.0 = Debug|x64 37 | {E373949F-E084-4DD4-A445-43B2672C42AA}.Release|x64.ActiveCfg = Release|x64 38 | {E373949F-E084-4DD4-A445-43B2672C42AA}.Release|x64.Build.0 = Release|x64 39 | {D6392848-12A3-4B94-BF4C-1CE727F12D0B}.Debug|x64.ActiveCfg = Debug|x64 40 | {D6392848-12A3-4B94-BF4C-1CE727F12D0B}.Debug|x64.Build.0 = Debug|x64 41 | {D6392848-12A3-4B94-BF4C-1CE727F12D0B}.Release|x64.ActiveCfg = Release|x64 42 | {D6392848-12A3-4B94-BF4C-1CE727F12D0B}.Release|x64.Build.0 = Release|x64 43 | {6482B097-A9DE-4D2F-B103-7DF0BC56B231}.Debug|x64.ActiveCfg = Debug|x64 44 | {6482B097-A9DE-4D2F-B103-7DF0BC56B231}.Debug|x64.Build.0 = Debug|x64 45 | {6482B097-A9DE-4D2F-B103-7DF0BC56B231}.Release|x64.ActiveCfg = Release|x64 46 | {6482B097-A9DE-4D2F-B103-7DF0BC56B231}.Release|x64.Build.0 = Release|x64 47 | {1378C489-F61E-4A00-9757-34D7A88B42E9}.Debug|x64.ActiveCfg = Debug|x64 48 | {1378C489-F61E-4A00-9757-34D7A88B42E9}.Debug|x64.Build.0 = Debug|x64 49 | {1378C489-F61E-4A00-9757-34D7A88B42E9}.Release|x64.ActiveCfg = Release|x64 50 | {1378C489-F61E-4A00-9757-34D7A88B42E9}.Release|x64.Build.0 = Release|x64 51 | {7B2040C9-F75E-4D32-9D50-B34DAA46FDB4}.Debug|x64.ActiveCfg = Debug|x64 52 | {7B2040C9-F75E-4D32-9D50-B34DAA46FDB4}.Debug|x64.Build.0 = Debug|x64 53 | {7B2040C9-F75E-4D32-9D50-B34DAA46FDB4}.Release|x64.ActiveCfg = Release|x64 54 | {7B2040C9-F75E-4D32-9D50-B34DAA46FDB4}.Release|x64.Build.0 = Release|x64 55 | EndGlobalSection 56 | GlobalSection(SolutionProperties) = preSolution 57 | HideSolutionNode = FALSE 58 | EndGlobalSection 59 | GlobalSection(ExtensibilityGlobals) = postSolution 60 | SolutionGuid = {F47E0CEF-F1B0-4324-BAEC-C9C8D43B0C73} 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /Shared/CRT/crt.cpp: -------------------------------------------------------------------------------- 1 | #include "crt.h" 2 | 3 | #pragma function(memset) 4 | void* memset(void* _Dst, int _Val, size_t _Size) 5 | { 6 | __stosb(static_cast(_Dst), 7 | static_cast(_Val), _Size); 8 | return _Dst; 9 | } 10 | 11 | #pragma function(memcpy) 12 | void* __cdecl memcpy(void* _Dst, void const* _Src, size_t _Size) 13 | { 14 | __movsb(static_cast(_Dst), 15 | static_cast(_Src), _Size); 16 | return _Dst; 17 | } 18 | 19 | #pragma function(memmove) 20 | void* __cdecl memmove(void* dest, const void* src, size_t n) 21 | { 22 | unsigned char* from = (unsigned char*)src; 23 | unsigned char* to = (unsigned char*)dest; 24 | 25 | if (from == to || n == 0) 26 | return dest; 27 | if (to > from && to - from < (int)n) { 28 | /* to overlaps with from */ 29 | /* */ 30 | /* */ 31 | /* copy in reverse, to avoid overwriting from */ 32 | size_t i; 33 | for (i = n - 1; i >= 0; i--) 34 | to[i] = from[i]; 35 | return dest; 36 | } 37 | if (from > to && from - to < (int)n) { 38 | /* to overlaps with from */ 39 | /* */ 40 | /* */ 41 | /* copy forwards, to avoid overwriting from */ 42 | size_t i; 43 | for (i = 0; i < n; i++) 44 | to[i] = from[i]; 45 | return dest; 46 | } 47 | memcpy(dest, src, n); 48 | return dest; 49 | } 50 | 51 | _Check_return_ 52 | int __cdecl strncmp( 53 | _In_reads_or_z_(n) char const* s1, 54 | _In_reads_or_z_(n) char const* s2, 55 | _In_ size_t n 56 | ) 57 | { 58 | register unsigned char u1, u2; 59 | 60 | while (n-- > 0) 61 | { 62 | u1 = (unsigned char)*s1++; 63 | u2 = (unsigned char)*s2++; 64 | if (u1 != u2) 65 | return u1 - u2; 66 | if (u1 == '\0') 67 | return 0; 68 | } 69 | return 0; 70 | } 71 | 72 | #pragma function(wcslen) 73 | _Check_return_ 74 | _ACRTIMP size_t __cdecl wcslen( 75 | _In_z_ wchar_t const* _String 76 | ) 77 | { 78 | const wchar_t* _Start = _String; 79 | while (*_String) 80 | { 81 | ++_String; 82 | } 83 | return (size_t)(_String - _Start); 84 | } 85 | 86 | #pragma function(wcscmp) 87 | _Check_return_ 88 | _ACRTIMP int __cdecl wcscmp( 89 | _In_z_ wchar_t const* _String1, 90 | _In_z_ wchar_t const* _String2 91 | ) 92 | { 93 | while (*_String1 && (*_String1 == *_String2)) 94 | { 95 | _String1++; 96 | _String2++; 97 | } 98 | return (int)((unsigned int)*_String1 - (unsigned int)*_String2); 99 | } 100 | 101 | _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size) 102 | _CRTALLOCATOR _CRT_JIT_INTRINSIC _CRTRESTRICT _CRT_HYBRIDPATCHABLE 103 | void* __cdecl malloc( 104 | _In_ _CRT_GUARDOVERFLOW size_t size 105 | ) 106 | { 107 | return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 108 | } 109 | 110 | _CRT_HYBRIDPATCHABLE 111 | void __cdecl free( 112 | _Pre_maybenull_ _Post_invalid_ void* ptr 113 | ) 114 | { 115 | HeapFree(GetProcessHeap(), 0, ptr); 116 | } 117 | 118 | _Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size) 119 | _CRTALLOCATOR _CRTRESTRICT _CRT_HYBRIDPATCHABLE 120 | void* __cdecl realloc( 121 | _Pre_maybenull_ _Post_invalid_ void* ptr, 122 | _In_ _CRT_GUARDOVERFLOW size_t size 123 | ) 124 | { 125 | if (ptr == NULL) 126 | { 127 | return malloc(size); 128 | } 129 | if (size == 0) 130 | { 131 | free(ptr); 132 | return NULL; 133 | } 134 | 135 | return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, size); 136 | } 137 | 138 | void* operator new(size_t size) 139 | { 140 | if (size == 0) return nullptr; 141 | return malloc(size); 142 | } 143 | 144 | void* operator new[](size_t size) 145 | { 146 | if (size == 0) return nullptr; 147 | return malloc(size); 148 | } 149 | 150 | void operator delete(void* ptr) 151 | { 152 | free(ptr); 153 | } 154 | 155 | void operator delete[](void* ptr) 156 | { 157 | free(ptr); 158 | } 159 | 160 | void operator delete(void* ptr, size_t size) 161 | { 162 | free(ptr); 163 | } 164 | 165 | void operator delete[](void* ptr, size_t size) 166 | { 167 | free(ptr); 168 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/lzma_header.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | */ 10 | 11 | /* XXX: clean this up, it's mostly lifted from pavel */ 12 | 13 | #include "lzma_header.h" 14 | 15 | #define ELZMA_LZMA_HEADER_SIZE 13 16 | #define ELZMA_LZMA_PROPSBUF_SIZE 5 17 | 18 | /**************** 19 | Header parsing 20 | ****************/ 21 | 22 | #ifndef UINT64_MAX 23 | #define UINT64_MAX ((unsigned long long) -1) 24 | #endif 25 | 26 | /* Parse the properties byte */ 27 | static char 28 | lzmadec_header_properties ( 29 | unsigned char *pb, unsigned char *lp, unsigned char *lc, const unsigned char c) 30 | { 31 | /* pb, lp and lc are encoded into a single byte. */ 32 | if (c > (9 * 5 * 5)) 33 | return -1; 34 | *pb = c / (9 * 5); /* 0 <= pb <= 4 */ 35 | *lp = (c % (9 * 5)) / 9; /* 0 <= lp <= 4 */ 36 | *lc = c % 9; /* 0 <= lc <= 8 */ 37 | 38 | return 0; 39 | } 40 | 41 | /* Parse the dictionary size (4 bytes, little endian) */ 42 | static char 43 | lzmadec_header_dictionary (unsigned int *size, const unsigned char *buffer) 44 | { 45 | unsigned int i; 46 | *size = 0; 47 | for (i = 0; i < 4; i++) 48 | *size += (unsigned int)(*buffer++) << (i * 8); 49 | /* The dictionary size is limited to 256 MiB (checked from 50 | * LZMA SDK 4.30) */ 51 | if (*size > (1 << 28)) 52 | return -1; 53 | return 0; 54 | } 55 | 56 | /* Parse the uncompressed size field (8 bytes, little endian) */ 57 | static void 58 | lzmadec_header_uncompressed (unsigned long long *size, 59 | unsigned char *is_streamed, 60 | const unsigned char *buffer) 61 | { 62 | unsigned int i; 63 | 64 | /* Streamed files have all 64 bits set in the size field. 65 | * We don't know the uncompressed size beforehand. */ 66 | *is_streamed = 1; /* Assume streamed. */ 67 | *size = 0; 68 | for (i = 0; i < 8; i++) { 69 | *size += (unsigned long long)buffer[i] << (i * 8); 70 | if (buffer[i] != 255) 71 | *is_streamed = 0; 72 | } 73 | } 74 | 75 | static void 76 | initLzmaHeader(struct elzma_file_header * hdr) 77 | { 78 | memset((void *) hdr, 0, sizeof(struct elzma_file_header)); 79 | } 80 | 81 | static int 82 | parseLzmaHeader(const unsigned char * hdrBuf, 83 | struct elzma_file_header * hdr) 84 | { 85 | if (lzmadec_header_properties(&(hdr->pb), &(hdr->lp), &(hdr->lc), 86 | *hdrBuf) || 87 | lzmadec_header_dictionary(&(hdr->dictSize), hdrBuf + 1)) 88 | { 89 | return 1; 90 | } 91 | lzmadec_header_uncompressed(&(hdr->uncompressedSize), 92 | &(hdr->isStreamed), 93 | hdrBuf + 5); 94 | 95 | return 0; 96 | } 97 | 98 | static int 99 | serializeLzmaHeader(unsigned char * hdrBuf, 100 | const struct elzma_file_header * hdr) 101 | { 102 | unsigned int i; 103 | 104 | memset((void *) hdrBuf, 0, ELZMA_LZMA_HEADER_SIZE); 105 | 106 | /* encode lc, pb, and lp */ 107 | *hdrBuf++ = hdr->lc + (hdr->pb * 45) + (hdr->lp * 45 * 9); 108 | 109 | /* encode dictionary size */ 110 | for (i = 0; i < 4; i++) { 111 | *(hdrBuf++) = (unsigned char) (hdr->dictSize >> (i * 8)); 112 | } 113 | 114 | /* encode uncompressed size */ 115 | for (i = 0; i < 8; i++) { 116 | if (hdr->isStreamed) { 117 | *(hdrBuf++) = 0xff; 118 | } else { 119 | *(hdrBuf++) = (unsigned char) (hdr->uncompressedSize >> (i * 8)); 120 | } 121 | } 122 | 123 | return 0; 124 | } 125 | 126 | void 127 | initializeLZMAFormatHandler(struct elzma_format_handler * hand) 128 | { 129 | hand->header_size = ELZMA_LZMA_HEADER_SIZE; 130 | hand->init_header = initLzmaHeader; 131 | hand->parse_header = parseLzmaHeader; 132 | hand->serialize_header = serializeLzmaHeader; 133 | hand->footer_size = 0; 134 | hand->serialize_footer = NULL; 135 | } 136 | -------------------------------------------------------------------------------- /Shared/CRT/crt_tls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #pragma section(".CRT$XCA", long, read) // First C++ Initializer 5 | #pragma section(".CRT$XCAA", long, read) // Startup C++ Initializer 6 | #pragma section(".CRT$XCZ", long, read) // Last C++ Initializer 7 | 8 | #pragma section(".CRT$XDA", long, read) // First Dynamic TLS Initializer 9 | #pragma section(".CRT$XDZ", long, read) // Last Dynamic TLS Initializer 10 | 11 | #pragma section(".CRT$XIA", long, read) // First C Initializer 12 | #pragma section(".CRT$XIAA", long, read) // Startup C Initializer 13 | #pragma section(".CRT$XIAB", long, read) // PGO C Initializer 14 | #pragma section(".CRT$XIAC", long, read) // Post-PGO C Initializer 15 | #pragma section(".CRT$XIC", long, read) // CRT C Initializers 16 | #pragma section(".CRT$XIYA", long, read) // VCCorLib Threading Model Initializer 17 | #pragma section(".CRT$XIYAA", long, read) // XAML Designer Threading Model Override Initializer 18 | #pragma section(".CRT$XIYB", long, read) // VCCorLib Main Initializer 19 | #pragma section(".CRT$XIZ", long, read) // Last C Initializer 20 | 21 | #pragma section(".CRT$XLA", long, read) // First Loader TLS Callback 22 | #pragma section(".CRT$XLC", long, read) // CRT TLS Constructor 23 | #pragma section(".CRT$XLD", long, read) // CRT TLS Terminator 24 | #pragma section(".CRT$XLZ", long, read) // Last Loader TLS Callback 25 | 26 | #pragma section(".CRT$XPA", long, read) // First Pre-Terminator 27 | #pragma section(".CRT$XPB", long, read) // CRT ConcRT Pre-Terminator 28 | #pragma section(".CRT$XPX", long, read) // CRT Pre-Terminators 29 | #pragma section(".CRT$XPXA", long, read) // CRT stdio Pre-Terminator 30 | #pragma section(".CRT$XPZ", long, read) // Last Pre-Terminator 31 | 32 | #pragma section(".CRT$XTA", long, read) // First Terminator 33 | #pragma section(".CRT$XTZ", long, read) // Last Terminator 34 | 35 | #pragma section(".CRTMA$XCA", long, read) // First Managed C++ Initializer 36 | #pragma section(".CRTMA$XCZ", long, read) // Last Managed C++ Initializer 37 | 38 | #pragma section(".CRTVT$XCA", long, read) // First Managed VTable Initializer 39 | #pragma section(".CRTVT$XCZ", long, read) // Last Managed VTable Initializer 40 | 41 | #pragma section(".rdata$T", long, read) 42 | 43 | #pragma section(".rtc$IAA", long, read) // First RTC Initializer 44 | #pragma section(".rtc$IZZ", long, read) // Last RTC Initializer 45 | 46 | #pragma section(".rtc$TAA", long, read) // First RTC Terminator 47 | #pragma section(".rtc$TZZ", long, read) // Last RTC Terminator 48 | 49 | #define _CRTALLOC(x) __declspec(allocate(x)) 50 | 51 | typedef int(__cdecl* _PIFV)(void); 52 | typedef void(__cdecl* _PVFV)(void); 53 | 54 | extern "C" _CRTALLOC(".CRT$XIA") _PIFV __xi_a[] = { nullptr }; // C initializers (first) 55 | extern "C" _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[] = { nullptr }; // C initializers (last) 56 | extern "C" _CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { nullptr }; // C++ initializers (first) 57 | extern "C" _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = { nullptr }; // C++ initializers (last) 58 | extern "C" _CRTALLOC(".CRT$XPA") _PVFV __xp_a[] = { nullptr }; // C pre-terminators (first) 59 | extern "C" _CRTALLOC(".CRT$XPZ") _PVFV __xp_z[] = { nullptr }; // C pre-terminators (last) 60 | extern "C" _CRTALLOC(".CRT$XTA") _PVFV __xt_a[] = { nullptr }; // C terminators (first) 61 | extern "C" _CRTALLOC(".CRT$XTZ") _PVFV __xt_z[] = { nullptr }; // C terminators (last) 62 | 63 | #pragma comment(linker, "/merge:.CRT=.rdata") 64 | 65 | extern "C" 66 | { 67 | ULONG _tls_index = 0; 68 | 69 | #pragma data_seg(".tls") 70 | _CRTALLOC(".tls") 71 | char _tls_start = 0; 72 | 73 | #pragma data_seg(".tls$ZZZ") 74 | _CRTALLOC(".tls$ZZZ") 75 | char _tls_end = 0; 76 | 77 | #pragma data_seg() 78 | 79 | 80 | //NOTE: Start of TLS callback generated by os loader code 81 | _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0; 82 | 83 | //NOTE: Terminator of TLS callback array 84 | _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0; 85 | 86 | //NOTE: TLS array.. 87 | _CRTALLOC(".rdata$T") 88 | extern const IMAGE_TLS_DIRECTORY64 _tls_used = 89 | { 90 | (ULONGLONG)&_tls_start, 91 | (ULONGLONG)&_tls_end, 92 | (ULONGLONG)&_tls_index, 93 | (ULONGLONG)(&__xl_a + 1), 94 | (ULONG)0, 95 | (LONG)0 96 | }; 97 | } -------------------------------------------------------------------------------- /Loader_Console_Section/Loader_Console_Section.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CRT 7 | 8 | 9 | PELoader 10 | 11 | 12 | PELoader 13 | 14 | 15 | PELoader 16 | 17 | 18 | PELoader 19 | 20 | 21 | ResourceLoader 22 | 23 | 24 | Decompressor 25 | 26 | 27 | Decompressor 28 | 29 | 30 | ApiCaller 31 | 32 | 33 | PELoaderStub 34 | 35 | 36 | 37 | 38 | {8bc8722f-41fb-405d-a2f5-48c040013e7d} 39 | 40 | 41 | {8cd4ed16-89d6-4c5c-b102-26b5626249e3} 42 | 43 | 44 | {b5a4e8a5-6067-4597-ac61-8c68e7e2e6c7} 45 | 46 | 47 | {f83fac1d-c5cf-4b1f-99d8-19371c40002f} 48 | 49 | 50 | {a247ea49-dee8-4075-8bb7-aaf43fe552d2} 51 | 52 | 53 | {89b152b3-51c6-4a6c-90ec-7f8f0de1026d} 54 | 55 | 56 | {54e5439f-4789-4650-a902-4c2da15d678f} 57 | 58 | 59 | {bb7cb992-0b8e-444d-8d03-b46546268647} 60 | 61 | 62 | 63 | 64 | CRT 65 | 66 | 67 | CRT 68 | 69 | 70 | PELoader 71 | 72 | 73 | PELoader 74 | 75 | 76 | PELoader 77 | 78 | 79 | PELoader 80 | 81 | 82 | TlsCallbackProxy 83 | 84 | 85 | TypeDefs 86 | 87 | 88 | ResourceLoader 89 | 90 | 91 | Decompressor 92 | 93 | 94 | Decompressor 95 | 96 | 97 | ApiCaller 98 | 99 | 100 | PELoaderStub 101 | 102 | 103 | -------------------------------------------------------------------------------- /Loader_Windows_Section/Loader_Windows_Section.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CRT 7 | 8 | 9 | PELoader 10 | 11 | 12 | PELoader 13 | 14 | 15 | PELoader 16 | 17 | 18 | PELoader 19 | 20 | 21 | ResourceLoader 22 | 23 | 24 | Decompressor 25 | 26 | 27 | Decompressor 28 | 29 | 30 | ApiCaller 31 | 32 | 33 | PELoaderStub 34 | 35 | 36 | 37 | 38 | {26ee8355-4a30-474e-9804-2a5dd66241ef} 39 | 40 | 41 | {f26f6ac7-016a-4050-92a7-fa09dd2d02ba} 42 | 43 | 44 | {76cc35a7-9632-4fb7-abdf-ad58935b1ea4} 45 | 46 | 47 | {99f38114-3632-4185-9806-112071789014} 48 | 49 | 50 | {15defd60-dee7-4278-b7d5-caa308c1731f} 51 | 52 | 53 | {5779bd0d-7384-41a8-85b9-7496dd4e3b8c} 54 | 55 | 56 | {ccd74711-d078-4364-8337-d80c7b100c2d} 57 | 58 | 59 | {c4d1676c-238a-4714-b491-4d5e7062b75a} 60 | 61 | 62 | 63 | 64 | CRT 65 | 66 | 67 | CRT 68 | 69 | 70 | PELoader 71 | 72 | 73 | PELoader 74 | 75 | 76 | PELoader 77 | 78 | 79 | PELoader 80 | 81 | 82 | TlsCallbackProxy 83 | 84 | 85 | TypeDefs 86 | 87 | 88 | ResourceLoader 89 | 90 | 91 | Decompressor 92 | 93 | 94 | Decompressor 95 | 96 | 97 | ApiCaller 98 | 99 | 100 | PELoaderStub 101 | 102 | 103 | -------------------------------------------------------------------------------- /Loader_Console_Resource/Loader_Console_Resource.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CRT 7 | 8 | 9 | PELoader 10 | 11 | 12 | PELoader 13 | 14 | 15 | PELoader 16 | 17 | 18 | PELoader 19 | 20 | 21 | ResourceLoader 22 | 23 | 24 | Decompressor 25 | 26 | 27 | Decompressor 28 | 29 | 30 | ApiCaller 31 | 32 | 33 | PELoaderStub 34 | 35 | 36 | 37 | 38 | {8bc8722f-41fb-405d-a2f5-48c040013e7d} 39 | 40 | 41 | {8cd4ed16-89d6-4c5c-b102-26b5626249e3} 42 | 43 | 44 | {b5a4e8a5-6067-4597-ac61-8c68e7e2e6c7} 45 | 46 | 47 | {f83fac1d-c5cf-4b1f-99d8-19371c40002f} 48 | 49 | 50 | {a247ea49-dee8-4075-8bb7-aaf43fe552d2} 51 | 52 | 53 | {89b152b3-51c6-4a6c-90ec-7f8f0de1026d} 54 | 55 | 56 | {54e5439f-4789-4650-a902-4c2da15d678f} 57 | 58 | 59 | {bb7cb992-0b8e-444d-8d03-b46546268647} 60 | 61 | 62 | 63 | 64 | CRT 65 | 66 | 67 | CRT 68 | 69 | 70 | PELoader 71 | 72 | 73 | PELoader 74 | 75 | 76 | PELoader 77 | 78 | 79 | PELoader 80 | 81 | 82 | TlsCallbackProxy 83 | 84 | 85 | TypeDefs 86 | 87 | 88 | ResourceLoader 89 | 90 | 91 | Decompressor 92 | 93 | 94 | Decompressor 95 | 96 | 97 | ApiCaller 98 | 99 | 100 | PELoaderStub 101 | 102 | 103 | -------------------------------------------------------------------------------- /Loader_Windows_Resource/Loader_Windows_Resource.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CRT 7 | 8 | 9 | PELoader 10 | 11 | 12 | PELoader 13 | 14 | 15 | PELoader 16 | 17 | 18 | PELoader 19 | 20 | 21 | ResourceLoader 22 | 23 | 24 | Decompressor 25 | 26 | 27 | Decompressor 28 | 29 | 30 | ApiCaller 31 | 32 | 33 | PELoaderStub 34 | 35 | 36 | 37 | 38 | {26ee8355-4a30-474e-9804-2a5dd66241ef} 39 | 40 | 41 | {f26f6ac7-016a-4050-92a7-fa09dd2d02ba} 42 | 43 | 44 | {76cc35a7-9632-4fb7-abdf-ad58935b1ea4} 45 | 46 | 47 | {99f38114-3632-4185-9806-112071789014} 48 | 49 | 50 | {15defd60-dee7-4278-b7d5-caa308c1731f} 51 | 52 | 53 | {5779bd0d-7384-41a8-85b9-7496dd4e3b8c} 54 | 55 | 56 | {ccd74711-d078-4364-8337-d80c7b100c2d} 57 | 58 | 59 | {c4d1676c-238a-4714-b491-4d5e7062b75a} 60 | 61 | 62 | 63 | 64 | CRT 65 | 66 | 67 | CRT 68 | 69 | 70 | PELoader 71 | 72 | 73 | PELoader 74 | 75 | 76 | PELoader 77 | 78 | 79 | PELoader 80 | 81 | 82 | TlsCallbackProxy 83 | 84 | 85 | TypeDefs 86 | 87 | 88 | ResourceLoader 89 | 90 | 91 | Decompressor 92 | 93 | 94 | Decompressor 95 | 96 | 97 | ApiCaller 98 | 99 | 100 | PELoaderStub 101 | 102 | 103 | -------------------------------------------------------------------------------- /Licenses/README_Easylzma.txt: -------------------------------------------------------------------------------- 1 | Overview 2 | 3 | Easylzma is a C library and command line tools for LZMA compression and 4 | decompression. It uses a Igor Pavlov's reference implementation and SDK 5 | written in C. 6 | 7 | License 8 | 9 | All the cruft you find here is public domain. You don't have to credit 10 | anyone to use this code, but my personal request is that you mention 11 | Igor Pavlov for his hard, high quality work. 12 | 13 | Project Goals 14 | 15 | 1. A tiny C wrapper and portable build system around a subset of 16 | Igor Pavlov's public domain LZMA compression and decompression 17 | implementation. 18 | 2. A tiny and straighforward API 19 | 3. Support for multiple different prominent LZMA file formats (see section on 20 | file formats below) 21 | 4. easy to build and use everywhere (doze and nix alike) 22 | 5. public domain licensing through and through. (hats off to Igor) 23 | 24 | Current State: 25 | 26 | THIS IS A WORK IN PROGRESS. The code here should be considered pre-alpha, 27 | and this should only be used by tinkerers or hackers at this point. Once 28 | feature completion is attained this message will be updated. See the 29 | TODO file distributed with the source for remaining work to be done. 30 | 31 | Platforms Supported 32 | 33 | 0.0.2 has been successfully compiled and run basic round trip testing 34 | on the following platforms & compilers: 35 | 36 | * win32 - visual studio 2005 37 | * osx - 10.4 & 10.5 (intel) 38 | * netbsd ppc - 4.0.1 with gcc 4.1.2 39 | (NOTE: memory allocation errors when dict size is default) 40 | * freebsd 6.1 - amd64 gcc 3.4.4 41 | 42 | Features 43 | 44 | XXX: write me (and the code) 45 | 46 | Usage 47 | 48 | XXX: write me (and the code) 49 | 50 | The Saga of LZMA File Formats, and a couple cents. 51 | 52 | As far as I can tell, there are at least four different ways to put LZMA 53 | compressed data in a stream: 54 | 55 | 1. The LZMA-Alone format, which consists of a 13 byte header including 56 | compression properties, dictionary size, and the uncompressed size of 57 | the file, followed by compressed data. This format has some support 58 | in Igor Pavlov's reference implementation and is in widespread use, as 59 | it's supported by lzmautils: http://tukaani.org/lzma/ 60 | 61 | The canonical (afaict) implementation of this format (lzmautis) is 62 | BSD licensed. 63 | 64 | 2. The lzip format (http://www.nongnu.org/lzip/lzip.html) - which 65 | includes a CRC footer and leading "magic number". The former 66 | affords data integrity gaurantees, while the latter simplifies 67 | heuristic determination of file format. This format looks to have 68 | reasonably widespread usage, though not quite as significant as 69 | LZMA-Alone. 70 | 71 | The only implementation of this format I can find (lzip) is GPL licensed. 72 | 73 | 3. the xz format ( http://tukaani.org/xz/xz-file-format.txt ) which is 74 | a more complex representation that includes CRC support and a magic 75 | number. This format is to be supported by the next iteration of 76 | XZ Utils which is currently in beta. The source may be obtained 77 | here: git://ctrl.tukaani.org/xz.git 78 | 79 | This format will address some criticisms to the LZMA-Alone format and 80 | was developed collaboratively by Lasse Collin (the current maintainer 81 | of XZ utils) and Igor Pavlov (the author of 7zip and the refrence 82 | implementation of LZMA). 83 | 84 | The xz format will employ LZMA2 which consists of extensions on top 85 | of LZMA, in the xz utils maintainer's words: 86 | 87 | "The primary compression algorithm in .xz is currently LZMA2, which 88 | is an extension on top of the orignal LZMA to fix a few practical 89 | issues, like adding support for flushing the encoder (equivalent 90 | to zlib's Z_SYNC_FLUSH), which isn't possible with the original 91 | LZMA." 92 | 93 | Again, maintainers words, regarding licensing: 94 | 95 | "XZ Utils currently contains a zlib-like compression library and a 96 | gzip-like command line tool. It's currently under LGPLv2.1+ but I will 97 | put it into the public domain before the first stable release." 98 | 99 | 4. The 7zip disk format which can contain multiple files possibly stored in 100 | LZMA compressed format. 101 | 102 | Given the state of things, the goal of this project is to develop something 103 | based on the existing formats, and quickly leverage code generated by the XZ 104 | Utils project, or simply kill this thing if that project produces something 105 | that's easy to embed and has a clean API at a similar level of abstraction 106 | as easylzma. 107 | 108 | lloyd - sometime in oh nine. 109 | -------------------------------------------------------------------------------- /Shared/ApiCaller/ApiCaller.cpp: -------------------------------------------------------------------------------- 1 | #include "ApiCaller.h" 2 | 3 | namespace ApiCaller 4 | { 5 | ApiCaller* ApiCaller::_instance = nullptr; 6 | 7 | ApiCaller::ApiCaller() 8 | { 9 | _kernel32 = CallLoadLibrary("kernel32.dll"); 10 | } 11 | 12 | ApiCaller::~ApiCaller() 13 | { 14 | delete _instance; 15 | } 16 | 17 | ApiCaller& ApiCaller::Instance() 18 | { 19 | if (_instance == nullptr) 20 | { 21 | _instance = new ApiCaller(); 22 | } 23 | return *_instance; 24 | } 25 | 26 | HRSRC ApiCaller::CallFindResourceW(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType) 27 | { 28 | auto function = (decltype(FindResourceW)*)ResolveKernel32Api("FindResourceW"); 29 | return function(hModule, lpName, lpType); 30 | //return FindResourceW(hModule, lpName, lpType); 31 | } 32 | 33 | HMODULE ApiCaller::CallGetModuleHandle(LPCSTR lpModuleName) 34 | { 35 | /*auto function = (decltype(GetModuleHandleA)*)ResolveKernel32Api("GetModuleHandleA"); 36 | return function(lpModuleName);*/ 37 | return GetModuleHandleA(lpModuleName); 38 | } 39 | 40 | FARPROC ApiCaller::CallGetProcAddress(HMODULE hModule, LPCSTR lpProcName) 41 | { 42 | return GetProcAddress(hModule, lpProcName); 43 | } 44 | 45 | HANDLE ApiCaller::CallGetProcessHeap() 46 | { 47 | /*auto function = (decltype(GetProcessHeap)*)ResolveKernel32Api("GetProcessHeap"); 48 | return function();*/ 49 | return GetProcessHeap(); 50 | } 51 | 52 | LPVOID ApiCaller::CallHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) 53 | { 54 | /*auto function = (decltype(HeapAlloc)*)ResolveKernel32Api("HeapAlloc"); 55 | return function(hHeap, dwFlags, dwBytes);*/ 56 | return HeapAlloc(hHeap, dwFlags, dwBytes); 57 | } 58 | 59 | BOOL ApiCaller::CallHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) 60 | { 61 | /*auto function = (decltype(HeapFree)*)ResolveKernel32Api("HeapFree"); 62 | return function(hHeap, dwFlags, lpMem);*/ 63 | return HeapFree(hHeap, dwFlags, lpMem); 64 | } 65 | 66 | LPVOID ApiCaller::CallHeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes) 67 | { 68 | /*auto function = (decltype(HeapReAlloc)*)ResolveKernel32Api("HeapReAlloc"); 69 | return function(hHeap, dwFlags, lpMem, dwBytes);*/ 70 | return HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes); 71 | } 72 | 73 | HMODULE ApiCaller::CallLoadLibrary(LPCSTR lpLibFileName) 74 | { 75 | /*auto function = (decltype(LoadLibraryA)*)ResolveKernel32Api("LoadLibraryA"); 76 | return function(lpLibFileName);*/ 77 | return LoadLibraryA(lpLibFileName); 78 | } 79 | 80 | HGLOBAL ApiCaller::CallLoadResource(HMODULE hModule, HRSRC hResInfo) 81 | { 82 | auto function = (decltype(LoadResource)*)ResolveKernel32Api("LoadResource"); 83 | return function(hModule, hResInfo); 84 | //return LoadResource(hModule, hResInfo); 85 | } 86 | 87 | LPVOID ApiCaller::CallLockResource(HGLOBAL hResData) 88 | { 89 | auto function = (decltype(LockResource)*)ResolveKernel32Api("LockResource"); 90 | return function(hResData); 91 | } 92 | 93 | BOOLEAN ApiCaller::CallRtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable, DWORD EntryCount, DWORD64 BaseAddress) 94 | { 95 | auto function = (decltype(RtlAddFunctionTable)*)ResolveKernel32Api("RtlAddFunctionTable"); 96 | return function(FunctionTable, EntryCount, BaseAddress); 97 | } 98 | 99 | DWORD ApiCaller::CallSizeofResource(HMODULE hModule, HRSRC hResInfo) 100 | { 101 | auto function = (decltype(SizeofResource)*)ResolveKernel32Api("SizeofResource"); 102 | return function(hModule, hResInfo); 103 | //return SizeofResource(hModule, hResInfo); 104 | } 105 | 106 | LPVOID ApiCaller::CallVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) 107 | { 108 | auto function = (decltype(VirtualAlloc)*)ResolveKernel32Api("VirtualAlloc"); 109 | return function(lpAddress, dwSize, flAllocationType, flProtect); 110 | } 111 | 112 | BOOL ApiCaller::CallVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) 113 | { 114 | auto function = (decltype(VirtualFree)*)ResolveKernel32Api("VirtualFree"); 115 | return function(lpAddress, dwSize, dwFreeType); 116 | } 117 | 118 | BOOL ApiCaller::CallVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) 119 | { 120 | auto function = (decltype(VirtualProtect)*)ResolveKernel32Api("VirtualProtect"); 121 | return function(lpAddress, dwSize, flNewProtect, lpflOldProtect); 122 | } 123 | 124 | FARPROC ApiCaller::ResolveKernel32Api(LPCSTR procName) 125 | { 126 | return CallGetProcAddress(_kernel32, procName); 127 | } 128 | } -------------------------------------------------------------------------------- /Shared/PELoader/TypeDefs/peb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef struct _CLIENT_ID 5 | { 6 | HANDLE UniqueProcess; 7 | HANDLE UniqueThread; 8 | } CLIENT_ID, * PCLIENT_ID; 9 | 10 | typedef struct _UNICODE_STRING { 11 | USHORT Length; 12 | USHORT MaximumLength; 13 | PWSTR Buffer; 14 | } UNICODE_STRING; 15 | 16 | typedef struct _LDR_DATA_TABLE_ENTRY 17 | { 18 | LIST_ENTRY InLoadOrderLinks; 19 | LIST_ENTRY InMemoryOrderLinks; 20 | union 21 | { 22 | LIST_ENTRY InInitializationOrderLinks; 23 | LIST_ENTRY InProgressLinks; 24 | }; 25 | PVOID DllBase; 26 | PVOID EntryPoint; 27 | ULONG SizeOfImage; 28 | UNICODE_STRING FullDllName; 29 | UNICODE_STRING BaseDllName; 30 | union 31 | { 32 | UCHAR FlagGroup[4]; 33 | ULONG Flags; 34 | struct 35 | { 36 | ULONG PackagedBinary : 1; 37 | ULONG MarkedForRemoval : 1; 38 | ULONG ImageDll : 1; 39 | ULONG LoadNotificationsSent : 1; 40 | ULONG TelemetryEntryProcessed : 1; 41 | ULONG ProcessStaticImport : 1; 42 | ULONG InLegacyLists : 1; 43 | ULONG InIndexes : 1; 44 | ULONG ShimDll : 1; 45 | ULONG InExceptionTable : 1; 46 | ULONG ReservedFlags1 : 2; 47 | ULONG LoadInProgress : 1; 48 | ULONG LoadConfigProcessed : 1; 49 | ULONG EntryProcessed : 1; 50 | ULONG ProtectDelayLoad : 1; 51 | ULONG ReservedFlags3 : 2; 52 | ULONG DontCallForThreads : 1; 53 | ULONG ProcessAttachCalled : 1; 54 | ULONG ProcessAttachFailed : 1; 55 | ULONG CorDeferredValidate : 1; 56 | ULONG CorImage : 1; 57 | ULONG DontRelocate : 1; 58 | ULONG CorILOnly : 1; 59 | ULONG ReservedFlags5 : 3; 60 | ULONG Redirected : 1; 61 | ULONG ReservedFlags6 : 2; 62 | ULONG CompatDatabaseProcessed : 1; 63 | } s; 64 | } u; 65 | USHORT ObsoleteLoadCount; 66 | USHORT TlsIndex; 67 | // other fields omitted 68 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 69 | 70 | typedef struct _PEB_LDR_DATA 71 | { 72 | ULONG Length; 73 | BOOLEAN Initialized; 74 | HANDLE SsHandle; 75 | LIST_ENTRY InLoadOrderModuleList; 76 | LIST_ENTRY InMemoryOrderModuleList; 77 | LIST_ENTRY InInitializationOrderModuleList; 78 | PVOID EntryInProgress; 79 | BOOLEAN ShutdownInProgress; 80 | HANDLE ShutdownThreadId; 81 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 82 | 83 | typedef struct _RTL_USER_PROCESS_PARAMETERS { 84 | ULONG MaximumLength; 85 | ULONG Length; 86 | ULONG Flags; 87 | ULONG DebugFlags; 88 | PVOID ConsoleHandle; 89 | ULONG ConsoleFlags; 90 | HANDLE StandardInput; 91 | HANDLE StandardOutput; 92 | HANDLE StandardError; 93 | UNICODE_STRING CurrentDirectoryPath; 94 | HANDLE CurrentDirectoryHandle; 95 | UNICODE_STRING DllPath; 96 | UNICODE_STRING ImagePathName; 97 | UNICODE_STRING CommandLine; 98 | PVOID Environment; 99 | ULONG StartingX; 100 | ULONG StartingY; 101 | ULONG CountX; 102 | ULONG CountY; 103 | ULONG CountCharsX; 104 | ULONG CountCharsY; 105 | ULONG FillAttribute; 106 | ULONG WindowFlags; 107 | ULONG ShowWindowFlags; 108 | UNICODE_STRING WindowTitle; 109 | UNICODE_STRING DesktopInfo; 110 | UNICODE_STRING ShellInfo; 111 | UNICODE_STRING RuntimeData; 112 | PVOID CurrentDirectories; 113 | ULONG EnvironmentSize; 114 | ULONG EnvironmentVersion; 115 | PVOID PackageDependencyData; 116 | ULONG ProcessGroupId; 117 | ULONG LoaderThreads; 118 | } RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; 119 | 120 | typedef struct _PEB { 121 | BOOLEAN InheritedAddressSpace; 122 | BOOLEAN ReadImageFileExecOptions; 123 | BOOLEAN BeingDebugged; 124 | BOOLEAN BitField; 125 | PVOID Mutant; 126 | PVOID ImageBaseAddress; // Base address of the loaded image 127 | PPEB_LDR_DATA Ldr; // Pointer to the loader data 128 | PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 129 | PVOID SubSystemData; 130 | PVOID ProcessHeap; 131 | PVOID FastPebLock; 132 | PVOID AtlThunkSListPtr; 133 | PVOID IFEOKey; 134 | ULONG CrossProcessFlags; 135 | PVOID KernelCallbackTable; 136 | ULONG SystemReserved; 137 | ULONG AtlThunkSListPtr32; 138 | PVOID ApiSetMap; 139 | ULONG TlsExpansionCounter; 140 | PVOID TlsBitmap; 141 | ULONG TlsBitmapBits[2]; 142 | PVOID ReadOnlySharedMemoryBase; 143 | PVOID HotpatchInformation; 144 | PVOID* TlsExpansionSlots; // TLS slots for tls index >= 64 145 | } PEB, * PPEB; 146 | 147 | typedef struct _TEB { 148 | NT_TIB NtTib; 149 | PVOID EnvironmentPointer; 150 | CLIENT_ID ClientId; 151 | PVOID ActiveRpcHandle; 152 | PVOID ThreadLocalStoragePointer; // TLS slots for tls index < 64 153 | PPEB ProcessEnvironmentBlock; 154 | // other fields omitted 155 | } TEB, * PTEB; -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zStream.c: -------------------------------------------------------------------------------- 1 | /* 7zStream.c -- 7z Stream functions 2 | 2008-11-23 : Igor Pavlov : Public domain */ 3 | 4 | #include "Types.h" 5 | 6 | SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) 7 | { 8 | while (size != 0) 9 | { 10 | size_t processed = size; 11 | RINOK(stream->Read(stream, buf, &processed)); 12 | if (processed == 0) 13 | return errorType; 14 | buf = (void *)((Byte *)buf + processed); 15 | size -= processed; 16 | } 17 | return SZ_OK; 18 | } 19 | 20 | SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) 21 | { 22 | return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 23 | } 24 | 25 | SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) 26 | { 27 | size_t processed = 1; 28 | RINOK(stream->Read(stream, buf, &processed)); 29 | return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; 30 | } 31 | 32 | SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) 33 | { 34 | Int64 t = offset; 35 | return stream->Seek(stream, &t, SZ_SEEK_SET); 36 | } 37 | 38 | SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) 39 | { 40 | void *lookBuf; 41 | if (*size == 0) 42 | return SZ_OK; 43 | RINOK(stream->Look(stream, &lookBuf, size)); 44 | memcpy(buf, lookBuf, *size); 45 | return stream->Skip(stream, *size); 46 | } 47 | 48 | SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) 49 | { 50 | while (size != 0) 51 | { 52 | size_t processed = size; 53 | RINOK(stream->Read(stream, buf, &processed)); 54 | if (processed == 0) 55 | return errorType; 56 | buf = (void *)((Byte *)buf + processed); 57 | size -= processed; 58 | } 59 | return SZ_OK; 60 | } 61 | 62 | SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) 63 | { 64 | return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); 65 | } 66 | 67 | static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) 68 | { 69 | SRes res = SZ_OK; 70 | CLookToRead *p = (CLookToRead *)pp; 71 | size_t size2 = p->size - p->pos; 72 | if (size2 == 0 && *size > 0) 73 | { 74 | p->pos = 0; 75 | size2 = LookToRead_BUF_SIZE; 76 | res = p->realStream->Read(p->realStream, p->buf, &size2); 77 | p->size = size2; 78 | } 79 | if (size2 < *size) 80 | *size = size2; 81 | *buf = p->buf + p->pos; 82 | return res; 83 | } 84 | 85 | static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) 86 | { 87 | SRes res = SZ_OK; 88 | CLookToRead *p = (CLookToRead *)pp; 89 | size_t size2 = p->size - p->pos; 90 | if (size2 == 0 && *size > 0) 91 | { 92 | p->pos = 0; 93 | if (*size > LookToRead_BUF_SIZE) 94 | *size = LookToRead_BUF_SIZE; 95 | res = p->realStream->Read(p->realStream, p->buf, size); 96 | size2 = p->size = *size; 97 | } 98 | if (size2 < *size) 99 | *size = size2; 100 | *buf = p->buf + p->pos; 101 | return res; 102 | } 103 | 104 | static SRes LookToRead_Skip(void *pp, size_t offset) 105 | { 106 | CLookToRead *p = (CLookToRead *)pp; 107 | p->pos += offset; 108 | return SZ_OK; 109 | } 110 | 111 | static SRes LookToRead_Read(void *pp, void *buf, size_t *size) 112 | { 113 | CLookToRead *p = (CLookToRead *)pp; 114 | size_t rem = p->size - p->pos; 115 | if (rem == 0) 116 | return p->realStream->Read(p->realStream, buf, size); 117 | if (rem > *size) 118 | rem = *size; 119 | memcpy(buf, p->buf + p->pos, rem); 120 | p->pos += rem; 121 | *size = rem; 122 | return SZ_OK; 123 | } 124 | 125 | static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) 126 | { 127 | CLookToRead *p = (CLookToRead *)pp; 128 | p->pos = p->size = 0; 129 | return p->realStream->Seek(p->realStream, pos, origin); 130 | } 131 | 132 | void LookToRead_CreateVTable(CLookToRead *p, int lookahead) 133 | { 134 | p->s.Look = lookahead ? 135 | LookToRead_Look_Lookahead : 136 | LookToRead_Look_Exact; 137 | p->s.Skip = LookToRead_Skip; 138 | p->s.Read = LookToRead_Read; 139 | p->s.Seek = LookToRead_Seek; 140 | } 141 | 142 | void LookToRead_Init(CLookToRead *p) 143 | { 144 | p->pos = p->size = 0; 145 | } 146 | 147 | static SRes SecToLook_Read(void *pp, void *buf, size_t *size) 148 | { 149 | CSecToLook *p = (CSecToLook *)pp; 150 | return LookInStream_LookRead(p->realStream, buf, size); 151 | } 152 | 153 | void SecToLook_CreateVTable(CSecToLook *p) 154 | { 155 | p->s.Read = SecToLook_Read; 156 | } 157 | 158 | static SRes SecToRead_Read(void *pp, void *buf, size_t *size) 159 | { 160 | CSecToRead *p = (CSecToRead *)pp; 161 | return p->realStream->Read(p->realStream, buf, size); 162 | } 163 | 164 | void SecToRead_CreateVTable(CSecToRead *p) 165 | { 166 | p->s.Read = SecToRead_Read; 167 | } 168 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/easylzma/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Written in 2009 by Lloyd Hilaiel 3 | * 4 | * License 5 | * 6 | * All the cruft you find here is public domain. You don't have to credit 7 | * anyone to use this code, but my personal request is that you mention 8 | * Igor Pavlov for his hard, high quality work. 9 | * 10 | * easylzma/common.h - definitions common to both compression and 11 | * decompression 12 | */ 13 | 14 | #ifndef __EASYLZMACOMMON_H__ 15 | #define __EASYLZMACOMMON_H__ 16 | 17 | #include 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* msft dll export gunk. To build a DLL on windows, you 24 | * must define WIN32, EASYLZMA_SHARED, and EASYLZMA_BUILD. To use a 25 | * DLL, you must define EASYLZMA_SHARED and WIN32 */ 26 | #if defined(WIN32) && defined(EASYLZMA_SHARED) 27 | # ifdef EASYLZMA_BUILD 28 | # define EASYLZMA_API __declspec(dllexport) 29 | # else 30 | # define EASYLZMA_API __declspec(dllimport) 31 | # endif 32 | #else 33 | # define EASYLZMA_API 34 | #endif 35 | 36 | /** error codes */ 37 | 38 | /** no error */ 39 | #define ELZMA_E_OK 0 40 | /** bad parameters passed to an ELZMA function */ 41 | #define ELZMA_E_BAD_PARAMS 10 42 | /** could not initialize the encode with configured parameters. */ 43 | #define ELZMA_E_ENCODING_PROPERTIES_ERROR 11 44 | /** an error occured during compression (XXX: be more specific) */ 45 | #define ELZMA_E_COMPRESS_ERROR 12 46 | /** currently unsupported lzma file format was specified*/ 47 | #define ELZMA_E_UNSUPPORTED_FORMAT 13 48 | /** an error occured when reading input */ 49 | #define ELZMA_E_INPUT_ERROR 14 50 | /** an error occured when writing output */ 51 | #define ELZMA_E_OUTPUT_ERROR 15 52 | /** LZMA header couldn't be parsed */ 53 | #define ELZMA_E_CORRUPT_HEADER 16 54 | /** an error occured during decompression (XXX: be more specific) */ 55 | #define ELZMA_E_DECOMPRESS_ERROR 17 56 | /** the input stream returns EOF before the decompression could complete */ 57 | #define ELZMA_E_INSUFFICIENT_INPUT 18 58 | /** for formats which have an emebedded crc, this error would indicated that 59 | * what came out was not what went in, i.e. data corruption */ 60 | #define ELZMA_E_CRC32_MISMATCH 19 61 | /** for formats which have an emebedded uncompressed content length, 62 | * this error indicates that the amount we read was not what we expected */ 63 | #define ELZMA_E_SIZE_MISMATCH 20 64 | 65 | 66 | /** Supported file formats */ 67 | typedef enum { 68 | ELZMA_lzip, /**< the lzip format which includes a magic number and 69 | * CRC check */ 70 | ELZMA_lzma /**< the LZMA-Alone format, originally designed by 71 | * Igor Pavlov and in widespread use due to lzmautils, 72 | * lacking both aforementioned features of lzip */ 73 | /* XXX: future, potentially , 74 | ELZMA_xz 75 | */ 76 | } elzma_file_format; 77 | 78 | /** 79 | * A callback invoked during elzma_[de]compress_run when the [de]compression 80 | * process has generated [de]compressed output. 81 | * 82 | * the size parameter indicates how much data is in buf to be written. 83 | * it is required that the write callback consume all data, and a return 84 | * value not equal to input size indicates and error. 85 | */ 86 | typedef size_t (*elzma_write_callback)(void *ctx, const void *buf, 87 | size_t size); 88 | 89 | /** 90 | * A callback invoked during elzma_[de]compress_run when the [de]compression 91 | * process requires more [un]compressed input. 92 | * 93 | * the size parameter is an in/out argument. on input it indicates 94 | * the buffer size. on output it indicates the amount of data read into 95 | * buf. when *size is zero on output it indicates EOF. 96 | * 97 | * \returns the read callback should return nonzero on failure. 98 | */ 99 | typedef int (*elzma_read_callback)(void *ctx, void *buf, 100 | size_t *size); 101 | 102 | /** 103 | * A callback invoked during elzma_[de]compress_run to report progress 104 | * on the [de]compression. 105 | * 106 | * \returns the read callback should return nonzero on failure. 107 | */ 108 | typedef void (*elzma_progress_callback)(void *ctx, size_t complete, 109 | size_t total); 110 | 111 | 112 | /** pointer to a malloc function, supporting client overriding memory 113 | * allocation routines */ 114 | typedef void * (*elzma_malloc)(void *ctx, unsigned int sz); 115 | 116 | /** pointer to a free function, supporting client overriding memory 117 | * allocation routines */ 118 | typedef void (*elzma_free)(void *ctx, void * ptr); 119 | 120 | #ifdef __cplusplus 121 | }; 122 | #endif 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /Fatpack/Packer/SectionPacker.cpp: -------------------------------------------------------------------------------- 1 | #include "SectionPacker.h" 2 | #include "PackerUtils.h" 3 | #include "..\Compressor\Compressor.h" 4 | 5 | namespace Packer 6 | { 7 | SectionPacker::SectionPacker(PackerUtils* packerUtils) 8 | { 9 | _packerUtils = packerUtils; 10 | _lastError = Error::ErrorCode::Ok; 11 | } 12 | 13 | SectionPacker::~SectionPacker() 14 | { 15 | } 16 | 17 | bool SectionPacker::Pack(LPWSTR inputFileName, LPWSTR outputFileName) 18 | { 19 | SetLastError(Error::ErrorCode::Ok); 20 | 21 | return ReadPeFile(inputFileName, _inputFile) && 22 | ValidateInputFile() && 23 | PrepareLoaderStub() && 24 | SavePeLoader(outputFileName) && 25 | AppendResourcesToLoader(inputFileName, outputFileName) && 26 | ReadPeFile(outputFileName, _peLoader) && 27 | RebaseLoaderToLastSection() && 28 | CompressAndAppendToLastSection() && 29 | SavePeLoader(outputFileName); 30 | } 31 | 32 | bool SectionPacker::ReadPeFile(LPWSTR fileName, PEFile::PEFile& peFile) 33 | { 34 | if (!_packerUtils->ReadPeFile(fileName, peFile)) 35 | { 36 | SetLastError(_packerUtils->GetLastError()); 37 | return false; 38 | } 39 | return true; 40 | } 41 | 42 | bool SectionPacker::ValidateInputFile() 43 | { 44 | if (!_packerUtils->ValidatePeFile(_inputFile)) 45 | { 46 | SetLastError(_packerUtils->GetLastError()); 47 | return false; 48 | } 49 | return true; 50 | } 51 | 52 | bool SectionPacker::PrepareLoaderStub() 53 | { 54 | if (!_packerUtils->PrepareSectionLoaderStub(_inputFile, _peLoader)) 55 | { 56 | SetLastError(_packerUtils->GetLastError()); 57 | return false; 58 | } 59 | return true; 60 | } 61 | 62 | bool SectionPacker::SavePeLoader(LPWSTR outputFileName) 63 | { 64 | if (!_packerUtils->SavePeFile(outputFileName, _peLoader)) 65 | { 66 | SetLastError(_packerUtils->GetLastError()); 67 | return false; 68 | } 69 | return true; 70 | } 71 | 72 | bool SectionPacker::AppendResourcesToLoader(LPWSTR inputFileName, LPWSTR outputFileName) 73 | { 74 | if (!_packerUtils->AppendResources(inputFileName, outputFileName)) 75 | { 76 | SetLastError(_packerUtils->GetLastError()); 77 | return false; 78 | } 79 | return true; 80 | } 81 | 82 | bool SectionPacker::RebaseLoaderToLastSection() 83 | { 84 | WORD lastIndex = _peLoader.GetSectionCount() - 1; 85 | PIMAGE_SECTION_HEADER lastSection = _peLoader.GetSectionHeader(lastIndex); 86 | uintptr_t newImageBase = _inputFile.GetImageBase() - lastSection->VirtualAddress; 87 | uintptr_t alignedBase = PEFile::PEFile::AlignImageBase(newImageBase); 88 | 89 | if (!_peLoader.Rebase(alignedBase)) 90 | { 91 | SetLastError(Error::ErrorCode::Error_Rebasing); 92 | return false; 93 | } 94 | 95 | PIMAGE_SECTION_HEADER prevSection = _peLoader.GetSectionHeader(lastIndex - 1); 96 | DWORD gap = (DWORD)(newImageBase - alignedBase); 97 | if (gap != 0) 98 | { 99 | prevSection->Misc.VirtualSize += gap; 100 | } 101 | 102 | lastSection->VirtualAddress = _peLoader.AlignSection(prevSection->VirtualAddress + prevSection->Misc.VirtualSize); 103 | lastSection->Misc.VirtualSize = _peLoader.AlignSection(_inputFile.GetSizeOfImage()); 104 | _peLoader.NT_HEADERS()->OptionalHeader.SizeOfImage = _peLoader.AlignSection(lastSection->VirtualAddress + lastSection->Misc.VirtualSize); 105 | 106 | return true; 107 | } 108 | 109 | bool SectionPacker::CompressAndAppendToLastSection() 110 | { 111 | Compressor::Compressor compressor; 112 | BYTE* compressed = nullptr; 113 | size_t compressedSize = 0; 114 | 115 | if (!compressor.Compress(_inputFile.GetBuffer(), _inputFile.GetBufferSize(), &compressed, &compressedSize)) 116 | { 117 | SetLastError(Error::ErrorCode::Error_Compressing); 118 | return false; 119 | } 120 | 121 | WORD lastIndex = _peLoader.GetSectionCount() - 1; 122 | PIMAGE_SECTION_HEADER lastSection = _peLoader.GetSectionHeader(lastIndex); 123 | 124 | DWORD oldRawSize = lastSection->SizeOfRawData; 125 | DWORD newRawSize = _peLoader.AlignFile((DWORD)compressedSize); 126 | DWORD delta = newRawSize - oldRawSize; 127 | 128 | DWORD oldBufferSize = _peLoader.GetBufferSize(); 129 | DWORD newBufferSize = oldBufferSize + delta; 130 | lastSection->SizeOfRawData = newRawSize; 131 | 132 | if (!_peLoader.Resize(newBufferSize)) 133 | { 134 | SetLastError(Error::ErrorCode::Error_Appending_Compressed_Data); 135 | compressor.Free(compressed); 136 | return false; 137 | } 138 | 139 | lastSection = _peLoader.GetSectionHeader(lastIndex); 140 | memcpy(_peLoader.GetBuffer() + lastSection->PointerToRawData, compressed, compressedSize); 141 | memcpy(lastSection->Name, ".fpack ", 8); 142 | 143 | compressor.Free(compressed); 144 | return true; 145 | } 146 | } -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/LzmaLib.h: -------------------------------------------------------------------------------- 1 | /* LzmaLib.h -- LZMA library interface 2 | 2008-08-05 3 | Igor Pavlov 4 | Public domain */ 5 | 6 | #ifndef __LZMALIB_H 7 | #define __LZMALIB_H 8 | 9 | #include "Types.h" 10 | 11 | #ifdef __cplusplus 12 | #define MY_EXTERN_C extern "C" 13 | #else 14 | #define MY_EXTERN_C extern 15 | #endif 16 | 17 | #define MY_STDAPI MY_EXTERN_C int MY_STD_CALL 18 | 19 | #define LZMA_PROPS_SIZE 5 20 | 21 | /* 22 | RAM requirements for LZMA: 23 | for compression: (dictSize * 11.5 + 6 MB) + state_size 24 | for decompression: dictSize + state_size 25 | state_size = (4 + (1.5 << (lc + lp))) KB 26 | by default (lc=3, lp=0), state_size = 16 KB. 27 | 28 | LZMA properties (5 bytes) format 29 | Offset Size Description 30 | 0 1 lc, lp and pb in encoded form. 31 | 1 4 dictSize (little endian). 32 | */ 33 | 34 | /* 35 | LzmaCompress 36 | ------------ 37 | 38 | outPropsSize - 39 | In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. 40 | Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. 41 | 42 | LZMA Encoder will use defult values for any parameter, if it is 43 | -1 for any from: level, loc, lp, pb, fb, numThreads 44 | 0 for dictSize 45 | 46 | level - compression level: 0 <= level <= 9; 47 | 48 | level dictSize algo fb 49 | 0: 16 KB 0 32 50 | 1: 64 KB 0 32 51 | 2: 256 KB 0 32 52 | 3: 1 MB 0 32 53 | 4: 4 MB 0 32 54 | 5: 16 MB 1 32 55 | 6: 32 MB 1 32 56 | 7+: 64 MB 1 64 57 | 58 | The default value for "level" is 5. 59 | 60 | algo = 0 means fast method 61 | algo = 1 means normal method 62 | 63 | dictSize - The dictionary size in bytes. The maximum value is 64 | 128 MB = (1 << 27) bytes for 32-bit version 65 | 1 GB = (1 << 30) bytes for 64-bit version 66 | The default value is 16 MB = (1 << 24) bytes. 67 | It's recommended to use the dictionary that is larger than 4 KB and 68 | that can be calculated as (1 << N) or (3 << N) sizes. 69 | 70 | lc - The number of literal context bits (high bits of previous literal). 71 | It can be in the range from 0 to 8. The default value is 3. 72 | Sometimes lc=4 gives the gain for big files. 73 | 74 | lp - The number of literal pos bits (low bits of current position for literals). 75 | It can be in the range from 0 to 4. The default value is 0. 76 | The lp switch is intended for periodical data when the period is equal to 2^lp. 77 | For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's 78 | better to set lc=0, if you change lp switch. 79 | 80 | pb - The number of pos bits (low bits of current position). 81 | It can be in the range from 0 to 4. The default value is 2. 82 | The pb switch is intended for periodical data when the period is equal 2^pb. 83 | 84 | fb - Word size (the number of fast bytes). 85 | It can be in the range from 5 to 273. The default value is 32. 86 | Usually, a big number gives a little bit better compression ratio and 87 | slower compression process. 88 | 89 | numThreads - The number of thereads. 1 or 2. The default value is 2. 90 | Fast mode (algo = 0) can use only 1 thread. 91 | 92 | Out: 93 | destLen - processed output size 94 | Returns: 95 | SZ_OK - OK 96 | SZ_ERROR_MEM - Memory allocation error 97 | SZ_ERROR_PARAM - Incorrect paramater 98 | SZ_ERROR_OUTPUT_EOF - output buffer overflow 99 | SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 100 | */ 101 | 102 | MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, 103 | unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ 104 | int level, /* 0 <= level <= 9, default = 5 */ 105 | unsigned dictSize, /* default = (1 << 24) */ 106 | int lc, /* 0 <= lc <= 8, default = 3 */ 107 | int lp, /* 0 <= lp <= 4, default = 0 */ 108 | int pb, /* 0 <= pb <= 4, default = 2 */ 109 | int fb, /* 5 <= fb <= 273, default = 32 */ 110 | int numThreads /* 1 or 2, default = 2 */ 111 | ); 112 | 113 | /* 114 | LzmaUncompress 115 | -------------- 116 | In: 117 | dest - output data 118 | destLen - output data size 119 | src - input data 120 | srcLen - input data size 121 | Out: 122 | destLen - processed output size 123 | srcLen - processed input size 124 | Returns: 125 | SZ_OK - OK 126 | SZ_ERROR_DATA - Data error 127 | SZ_ERROR_MEM - Memory allocation arror 128 | SZ_ERROR_UNSUPPORTED - Unsupported properties 129 | SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) 130 | */ 131 | 132 | MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, 133 | const unsigned char *props, size_t propsSize); 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/Types.h: -------------------------------------------------------------------------------- 1 | /* Types.h -- Basic types 2 | 2008-11-23 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_TYPES_H 5 | #define __7Z_TYPES_H 6 | 7 | #include 8 | 9 | #ifdef _WIN32 10 | #include 11 | #endif 12 | 13 | #define SZ_OK 0 14 | 15 | #define SZ_ERROR_DATA 1 16 | #define SZ_ERROR_MEM 2 17 | #define SZ_ERROR_CRC 3 18 | #define SZ_ERROR_UNSUPPORTED 4 19 | #define SZ_ERROR_PARAM 5 20 | #define SZ_ERROR_INPUT_EOF 6 21 | #define SZ_ERROR_OUTPUT_EOF 7 22 | #define SZ_ERROR_READ 8 23 | #define SZ_ERROR_WRITE 9 24 | #define SZ_ERROR_PROGRESS 10 25 | #define SZ_ERROR_FAIL 11 26 | #define SZ_ERROR_THREAD 12 27 | 28 | #define SZ_ERROR_ARCHIVE 16 29 | #define SZ_ERROR_NO_ARCHIVE 17 30 | 31 | typedef int SRes; 32 | 33 | #ifdef _WIN32 34 | typedef DWORD WRes; 35 | #else 36 | typedef int WRes; 37 | #endif 38 | 39 | #ifndef RINOK 40 | #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } 41 | #endif 42 | 43 | typedef unsigned char Byte; 44 | typedef short Int16; 45 | typedef unsigned short UInt16; 46 | 47 | #ifdef _LZMA_UINT32_IS_ULONG 48 | typedef long Int32; 49 | typedef unsigned long UInt32; 50 | #else 51 | typedef int Int32; 52 | typedef unsigned int UInt32; 53 | #endif 54 | 55 | #ifdef _SZ_NO_INT_64 56 | 57 | /* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. 58 | NOTES: Some code will work incorrectly in that case! */ 59 | 60 | typedef long Int64; 61 | typedef unsigned long UInt64; 62 | 63 | #else 64 | 65 | #if defined(_MSC_VER) || defined(__BORLANDC__) 66 | typedef __int64 Int64; 67 | typedef unsigned __int64 UInt64; 68 | #else 69 | typedef long long int Int64; 70 | typedef unsigned long long int UInt64; 71 | #endif 72 | 73 | #endif 74 | 75 | #ifdef _LZMA_NO_SYSTEM_SIZE_T 76 | typedef UInt32 SizeT; 77 | #else 78 | typedef size_t SizeT; 79 | #endif 80 | 81 | typedef int Bool; 82 | #define True 1 83 | #define False 0 84 | 85 | 86 | #ifdef _MSC_VER 87 | 88 | #if _MSC_VER >= 1300 89 | #define MY_NO_INLINE __declspec(noinline) 90 | #else 91 | #define MY_NO_INLINE 92 | #endif 93 | 94 | #define MY_CDECL __cdecl 95 | #define MY_STD_CALL __stdcall 96 | #define MY_FAST_CALL MY_NO_INLINE __fastcall 97 | 98 | #else 99 | 100 | #define MY_CDECL 101 | #define MY_STD_CALL 102 | #define MY_FAST_CALL 103 | 104 | #endif 105 | 106 | 107 | /* The following interfaces use first parameter as pointer to structure */ 108 | 109 | typedef struct 110 | { 111 | SRes (*Read)(void *p, void *buf, size_t *size); 112 | /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 113 | (output(*size) < input(*size)) is allowed */ 114 | } ISeqInStream; 115 | 116 | /* it can return SZ_ERROR_INPUT_EOF */ 117 | SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); 118 | SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); 119 | SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); 120 | 121 | typedef struct 122 | { 123 | size_t (*Write)(void *p, const void *buf, size_t size); 124 | /* Returns: result - the number of actually written bytes. 125 | (result < size) means error */ 126 | } ISeqOutStream; 127 | 128 | typedef enum 129 | { 130 | SZ_SEEK_SET = 0, 131 | SZ_SEEK_CUR = 1, 132 | SZ_SEEK_END = 2 133 | } ESzSeek; 134 | 135 | typedef struct 136 | { 137 | SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ 138 | SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 139 | } ISeekInStream; 140 | 141 | typedef struct 142 | { 143 | SRes (*Look)(void *p, void **buf, size_t *size); 144 | /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 145 | (output(*size) > input(*size)) is not allowed 146 | (output(*size) < input(*size)) is allowed */ 147 | SRes (*Skip)(void *p, size_t offset); 148 | /* offset must be <= output(*size) of Look */ 149 | 150 | SRes (*Read)(void *p, void *buf, size_t *size); 151 | /* reads directly (without buffer). It's same as ISeqInStream::Read */ 152 | SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 153 | } ILookInStream; 154 | 155 | SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); 156 | SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); 157 | 158 | /* reads via ILookInStream::Read */ 159 | SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); 160 | SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); 161 | 162 | #define LookToRead_BUF_SIZE (1 << 14) 163 | 164 | typedef struct 165 | { 166 | ILookInStream s; 167 | ISeekInStream *realStream; 168 | size_t pos; 169 | size_t size; 170 | Byte buf[LookToRead_BUF_SIZE]; 171 | } CLookToRead; 172 | 173 | void LookToRead_CreateVTable(CLookToRead *p, int lookahead); 174 | void LookToRead_Init(CLookToRead *p); 175 | 176 | typedef struct 177 | { 178 | ISeqInStream s; 179 | ILookInStream *realStream; 180 | } CSecToLook; 181 | 182 | void SecToLook_CreateVTable(CSecToLook *p); 183 | 184 | typedef struct 185 | { 186 | ISeqInStream s; 187 | ILookInStream *realStream; 188 | } CSecToRead; 189 | 190 | void SecToRead_CreateVTable(CSecToRead *p); 191 | 192 | typedef struct 193 | { 194 | SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); 195 | /* Returns: result. (result != SZ_OK) means break. 196 | Value (UInt64)(Int64)-1 for size means unknown value. */ 197 | } ICompressProgress; 198 | 199 | typedef struct 200 | { 201 | void *(*Alloc)(void *p, size_t size); 202 | void (*Free)(void *p, void *address); /* address can be 0 */ 203 | } ISzAlloc; 204 | 205 | #define IAlloc_Alloc(p, size) (p)->Alloc((p), size) 206 | #define IAlloc_Free(p, a) (p)->Free((p), a) 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /Shared/PELoader/PELoader/TlsResolver.cpp: -------------------------------------------------------------------------------- 1 | #include "TlsResolver.h" 2 | #include "PEFile.h" 3 | #include "PEImage.h" 4 | #include "..\TypeDefs\peb.h" 5 | #include "..\..\..\Shared\ApiCaller\ApiCaller.h" 6 | 7 | namespace PELoader 8 | { 9 | TlsResolver::TlsResolver() 10 | { 11 | PEImage peLoaderImage(ApiCaller::ApiCaller::Instance().CallGetModuleHandle(nullptr)); 12 | _tlsIndex = GetTlsIndex(&peLoaderImage); // Get tls index of pe loader. It has been initialized by windows loader. Since we do not use tls data (only one tls callback (TlsCallbackProxy)) we can use this index. 13 | } 14 | 15 | TlsResolver::~TlsResolver() 16 | { 17 | } 18 | 19 | void TlsResolver::InitializeTlsIndex(PEImage* peImage) 20 | { 21 | PIMAGE_TLS_DIRECTORY tlsDirectory = GetTlsDirectory(peImage); 22 | if (tlsDirectory == nullptr || !HasTlsData(tlsDirectory)) return; 23 | SetTlsIndex(tlsDirectory, _tlsIndex); 24 | } 25 | 26 | void TlsResolver::InitializeTlsData(PEImage* peImage) 27 | { 28 | PIMAGE_TLS_DIRECTORY tlsDirectory = GetTlsDirectory(peImage); 29 | if (tlsDirectory == nullptr || !HasTlsData(tlsDirectory)) return; 30 | 31 | LPVOID tlsData = CreateTlsData(tlsDirectory); 32 | if (tlsData == nullptr) return; 33 | 34 | SetTlsData(_tlsIndex, tlsData); 35 | } 36 | 37 | void TlsResolver::ClearTlsData() 38 | { 39 | if (_tlsIndex == TLS_OUT_OF_INDEXES) return; 40 | LPVOID tlsData = GetTlsData(_tlsIndex); 41 | if (tlsData != nullptr) 42 | { 43 | ApiCaller::ApiCaller::Instance().CallVirtualFree(tlsData, 0, MEM_RELEASE); 44 | } 45 | SetTlsData(_tlsIndex, nullptr); 46 | } 47 | 48 | void TlsResolver::ExecuteCallbacks(PEImage* peImage, DWORD reason, PVOID context) 49 | { 50 | // AddressOfCallBacks points to an array of function pointers (VAs). 51 | // These VAs are absolute addresses and can be used after relocation. 52 | 53 | PIMAGE_TLS_DIRECTORY tlsDirectory = GetTlsDirectory(peImage); 54 | if (tlsDirectory == nullptr || !HasTlsCallbacks(tlsDirectory)) return; 55 | 56 | PIMAGE_TLS_CALLBACK* tlsCallbacks = (PIMAGE_TLS_CALLBACK*)(tlsDirectory->AddressOfCallBacks); 57 | while (*tlsCallbacks) 58 | { 59 | (*tlsCallbacks)(peImage->GetImageBase(), reason, context); 60 | tlsCallbacks++; 61 | } 62 | } 63 | 64 | PIMAGE_TLS_DIRECTORY TlsResolver::GetTlsDirectory(PEImage* peImage) 65 | { 66 | PIMAGE_DATA_DIRECTORY tlsDataDir = &peImage->NT_HEADERS()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]; 67 | if (tlsDataDir->Size == 0 || tlsDataDir->VirtualAddress == 0) return nullptr; 68 | 69 | PIMAGE_TLS_DIRECTORY tlsDirectory = (PIMAGE_TLS_DIRECTORY)((BYTE*)peImage->GetImageBase() + tlsDataDir->VirtualAddress); 70 | return tlsDirectory; 71 | } 72 | 73 | BOOL TlsResolver::HasTlsData(PIMAGE_TLS_DIRECTORY tlsDirectory) 74 | { 75 | if (tlsDirectory != nullptr && tlsDirectory->AddressOfIndex != 0 && tlsDirectory->StartAddressOfRawData != 0 && tlsDirectory->EndAddressOfRawData != 0) 76 | { 77 | return TRUE; 78 | } 79 | return FALSE; 80 | } 81 | 82 | BOOL TlsResolver::HasTlsCallbacks(PIMAGE_TLS_DIRECTORY tlsDirectory) 83 | { 84 | if (tlsDirectory != nullptr && tlsDirectory->AddressOfCallBacks != 0) 85 | { 86 | PIMAGE_TLS_CALLBACK* tlsCallbacks = (PIMAGE_TLS_CALLBACK*)(tlsDirectory->AddressOfCallBacks); 87 | return (*tlsCallbacks != nullptr); 88 | } 89 | return FALSE; 90 | } 91 | 92 | ULONG TlsResolver::GetTlsIndex(PEImage* peImage) 93 | { 94 | PIMAGE_TLS_DIRECTORY tlsDirectory = GetTlsDirectory(peImage); 95 | if (tlsDirectory == nullptr) return 0; 96 | ULONG* tlsIndexAddress = (ULONG*)(tlsDirectory->AddressOfIndex); // This is an absolute VA after relocations 97 | if (tlsIndexAddress == nullptr) return 0; 98 | 99 | return *tlsIndexAddress; 100 | } 101 | 102 | void TlsResolver::SetTlsIndex(PIMAGE_TLS_DIRECTORY tlsDirectory, ULONG tlsIndex) 103 | { 104 | ULONG* tlsIndexAddress = (ULONG*)(tlsDirectory->AddressOfIndex); // This is an absolute VA after relocations 105 | if (tlsIndexAddress == nullptr) return; 106 | *tlsIndexAddress = tlsIndex; 107 | } 108 | 109 | LPVOID TlsResolver::CreateTlsData(PIMAGE_TLS_DIRECTORY tlsDirectory) 110 | { 111 | size_t rawDataSize = (BYTE*)tlsDirectory->EndAddressOfRawData - (BYTE*)tlsDirectory->StartAddressOfRawData; 112 | size_t totalDataSize = rawDataSize + tlsDirectory->SizeOfZeroFill; 113 | 114 | // Allocate memory for the TLS data for the current thread 115 | LPVOID tlsDataBlock = ApiCaller::ApiCaller::Instance().CallVirtualAlloc(nullptr, totalDataSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 116 | if (!tlsDataBlock) return nullptr; 117 | 118 | // Copy the default TLS data to the thread specific memory 119 | if (rawDataSize > 0 && tlsDirectory->StartAddressOfRawData != 0) 120 | { 121 | // StartAddressOfRawData is a VA, it should be an absolute pointer after relocations. 122 | memcpy(tlsDataBlock, (void*)tlsDirectory->StartAddressOfRawData, rawDataSize); 123 | } 124 | 125 | if (tlsDirectory->SizeOfZeroFill > 0) 126 | { 127 | memset((BYTE*)tlsDataBlock + rawDataSize, 0, tlsDirectory->SizeOfZeroFill); 128 | } 129 | 130 | return tlsDataBlock; 131 | } 132 | 133 | void TlsResolver::SetTlsData(ULONG tlsIndex, LPVOID tlsData) 134 | { 135 | // Update the TEB directly, because TlsSetValue will NOT set it in TEB. 136 | PTEB teb = NtCurrentTeb(); 137 | if (teb) 138 | { 139 | if (tlsIndex < 64) 140 | { 141 | // DWORD64* ThreadLocalStoragePointer = (DWORD64*)__readgsqword(0x58); 142 | // Directly set the TEB slot 143 | ((ULONG_PTR*)teb->ThreadLocalStoragePointer)[tlsIndex] = (ULONG_PTR)tlsData; 144 | } 145 | else 146 | { 147 | PEB* peb = teb->ProcessEnvironmentBlock; 148 | PVOID* tlsArray = (PVOID*)peb->TlsExpansionSlots; 149 | if (!tlsArray) 150 | { 151 | peb->TlsExpansionSlots = (PVOID*)ApiCaller::ApiCaller::Instance().CallHeapAlloc(ApiCaller::ApiCaller::Instance().CallGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PVOID) * 1024); 152 | } 153 | if (peb->TlsExpansionSlots) 154 | { 155 | peb->TlsExpansionSlots[tlsIndex - 64] = tlsData; 156 | } 157 | } 158 | } 159 | } 160 | 161 | LPVOID TlsResolver::GetTlsData(ULONG tlsIndex) 162 | { 163 | PTEB teb = NtCurrentTeb(); 164 | if (teb) 165 | { 166 | if (tlsIndex < 64) 167 | { 168 | return (LPVOID)((ULONG_PTR*)teb->ThreadLocalStoragePointer)[tlsIndex]; 169 | } 170 | else 171 | { 172 | PEB* peb = teb->ProcessEnvironmentBlock; 173 | if (peb->TlsExpansionSlots) 174 | { 175 | return peb->TlsExpansionSlots[tlsIndex - 64]; 176 | } 177 | } 178 | } 179 | return nullptr; 180 | } 181 | } 182 | 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fatpack 2 | 3 | A Windows PE packer for executables (x64) with LZMA compression and with full TLS (Thread Local Storage) support. 4 | 5 | Keywords: PE packer, PE loader, executable packer, manual mapping, manual mapper, portable executable, LZMA, UPX, EXE 6 | 7 | ## Motivation 8 | 9 | A practical application of my PE loader (manual mapper): https://github.com/Fatmike-GH/PELoader 10 | 11 | ## Usage 12 | 13 | ``Fatpack.exe inputfile.exe outputfile.exe [OPTIONS]`` 14 | ``[OPTIONS]`` 15 | ``-r, --resource : Packs inputfile.exe as resource (DEFAULT)`` 16 | ``-s, --section : Packs inputfile.exe as section (EXPERIMENTAL)`` 17 | 18 | ## Features 19 | 20 | ### Functional Features 21 | 22 | - Support for native Console- and Windows executables (x64 only, no .NET support) 23 | - LZMA compression 24 | - Full TLS (Thread Local Storage) support 25 | - Therefore supports Rust- and Delphi exectuables for example 26 | - No CRT usage in Fatpack.exe and Stubs (WinAPI only) and therefore no C/C++ redistributables are required 27 | - Icon extraction 28 | - Packing options 29 | - Resource Packing : The packed target is embedded as a resource in the loader stub, including rebasing if necessary. 30 | - Section Packing : The packed target is appended as section within the loader stub. 31 | 32 | ### Technical Features 33 | 34 | - Relocations 35 | - Imports 36 | - Delay Imports 37 | - Exception Handlers 38 | - Proper Memory Section Protection 39 | - Full TLS (Thread Local Storage) support 40 | - TLS Callbacks 41 | - DLL_PROCESS_ATTACH 42 | - DLL_THREAD_ATTACH 43 | - DLL_THREAD_DETACH 44 | - DLL_PROCESS_DETACH 45 | - TLS Data 46 | - Manifest extraction (required, if specfic module versions of the target executable are specified) 47 | 48 | ## Solution Overview 49 | 50 | The solution consists of four projects: 51 | 52 | - ``Fatpack`` 53 | - The console application ``Fatpack.exe``, which the user employs to pack their target executable. 54 | 55 | - Loader stubs 56 | - The loader stubs serve as containers for the packed target executable and are responsible for loading and executing it. 57 | - ``Loader_Console`` 58 | - ``Loader_Windows`` 59 | 60 | - ``ResourceAdder`` 61 | - ``ResourceAdder.exe``, a helper executable that adds the loader stubs to ``Fatpack.exe`` as post-build step, using the scripts ``PostBuildStep_Debug.bat`` and ``PostBuildStep_Release.bat``. 62 | 63 | ### Loader Stubs 64 | 65 | Both ``Loader_Console`` and ``Loader_Windows`` serve as loader stubs. Upon startup, they retrieve the packed target executable from their embedded resources (``-r`` option), or from ``.fpack`` section (``-s`` option), unpack it in memory, and execute it. 66 | The loader logic is available at: https://github.com/Fatmike-GH/PELoader 67 | 68 | - ``Loader_Console``: The loader stub for loading console applications. 69 | - ``Loader_Windows``: The loader stub for loading windows applications. 70 | 71 | ### ResourceAdder 72 | 73 | A simple console application used to embed the loader stubs into ``Fatpack.exe`` as post-build step. This integration is handled via the scripts ``PostBuildStep_Debug.bat`` and ``PostBuildStep_Release.bat``. 74 | 75 | >**Note:** Always use **"Rebuild Solution"** after making changes to ensure that the post-build steps execute correctly. 76 | 77 | ### Fatpack 78 | 79 | The console application (``Fatpack.exe``) is used by the user to package their target executable. Its main responsibilities include: 80 | 81 | - Determining the appropriate loader stub (Loader_Console or Loader_Windows) based on the type of the target executable, loading it from an embedded resource, and saving it to disk. 82 | - Rebasing the loader stub if the target does not have a relocation table and there is an image base conflict. 83 | - Extracting the icon from the target executable and embedding it into the selected loader stub. 84 | - Extracting and embedding the application manifest from the target executable. This step is essential, as the manifest may specify specific module versions required for correct execution. 85 | - Compressing the target executable using the LZMA algorithm and appending it to the loader stub. 86 | - Depending on the selected option (``--resource`` or ``--section``), the packed target is appended to the loader stub in different ways: 87 | - Option ``--resource`` 88 | ![image](Images/Concept_01.PNG) 89 | The packed target is appended to the loader stub as a resource. It remains in memory, while the unpacked target is mapped to a new memory location (allocated using *VirtualAlloc*) and executed from there. 90 | 91 | - Option ``--section`` 92 | ![image](Images/Concept_02.PNG) 93 | The loader stub is rebased so that its ``.reloc`` section aligns with the image base of the target executable. The virtual size of the ``.reloc`` section is adjusted to match the image size of the unpacked target, allowing it to fit entirely within this section at runtime after unpacking. As a result, no additional memory allocation is necessary. As a final step, the ``.reloc`` section is renamed to ``.fpack``. 94 | >This is the preferred option as it requires less memory at runtime. However, it may cause issues with certain targets in specific cases. 95 | 96 | ## Fatpack vs UPX 5.0.1 97 | 98 | | Target size | UPX | UPX -9 | Fatpack | Target info | 99 | |------------- |--------- |--------- |--------- |----------------------------------------------- | 100 | | 6744 kb | 1735 kb | 1669 kb | **1608 kb** | Embarcadero Delphi(XE3-X4)[Professional] | 101 | | 2728 kb | 1052 kb | **1034 kb** | 1035 kb | Rust | 102 | | 611 kb | 86 kb | 83 kb | **80 kb** | Microsoft Visual C/C++(19.36.34808)[C++] | 103 | | 533 kb | 213 kb | 210 kb | **199 kb** | Rust | 104 | | 448 kb | - | - | **193 kb** | Rust | 105 | | 233 kb | 89 kb | 89 kb | **85 kb** | Microsoft Visual C/C++(19.36.34436)[LTCG/C++] | 106 | | 32 kb | **9 kb** | **9 kb** | 16 kb | Microsoft Visual C/C++(19.29.30139)[LTCG/C] | 107 | | 20 kb | **11 kb** | **11 kb** | 18 kb | Microsoft Visual C/C++(19.36.34808)[LTCG/C++] | 108 | | 15 kb | **10 kb** | **10 kb** | 17 kb | Microsoft Visual C/C++(19.36.34808)[LTCG/C++] | 109 | 110 | Since the loader stubs (``Loader_Console`` and ``Loader_Windows``) are relatively large,approximately 10 KB each, the compression ratio is less favorable when packing very small target executables. However, for larger executables, the results are significantly more efficient, yielding much better overall compression ratios. 111 | 112 | > **Note:** UPX did not support the 448 kb target 113 | 114 | ## Third Party Software 115 | 116 | ### EasyLZMA 117 | 118 | https://github.com/lloyd/easylzma 119 | 120 | ### TinyZZZ 121 | 122 | https://github.com/WangXuan95/TinyZZZ 123 | 124 | ### Fatmike's PE Loader 125 | 126 | https://github.com/Fatmike-GH/PELoader 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /Fatpack/Compressor/lzma/pavlov/7zFile.c: -------------------------------------------------------------------------------- 1 | /* 7zFile.c -- File IO 2 | 2008-11-22 : Igor Pavlov : Public domain */ 3 | 4 | #include "7zFile.h" 5 | 6 | #ifndef USE_WINDOWS_FILE 7 | 8 | #include 9 | 10 | #endif 11 | 12 | #ifdef USE_WINDOWS_FILE 13 | 14 | /* 15 | ReadFile and WriteFile functions in Windows have BUG: 16 | If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) 17 | from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES 18 | (Insufficient system resources exist to complete the requested service). 19 | Probably in some version of Windows there are problems with other sizes: 20 | for 32 MB (maybe also for 16 MB). 21 | And message can be "Network connection was lost" 22 | */ 23 | 24 | #define kChunkSizeMax (1 << 22) 25 | 26 | #endif 27 | 28 | void File_Construct(CSzFile *p) 29 | { 30 | #ifdef USE_WINDOWS_FILE 31 | p->handle = INVALID_HANDLE_VALUE; 32 | #else 33 | p->file = NULL; 34 | #endif 35 | } 36 | 37 | static WRes File_Open(CSzFile *p, const char *name, int writeMode) 38 | { 39 | #ifdef USE_WINDOWS_FILE 40 | p->handle = CreateFileA(name, 41 | writeMode ? GENERIC_WRITE : GENERIC_READ, 42 | FILE_SHARE_READ, NULL, 43 | writeMode ? CREATE_ALWAYS : OPEN_EXISTING, 44 | FILE_ATTRIBUTE_NORMAL, NULL); 45 | return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); 46 | #else 47 | p->file = fopen(name, writeMode ? "wb+" : "rb"); 48 | return (p->file != 0) ? 0 : errno; 49 | #endif 50 | } 51 | 52 | WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } 53 | WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } 54 | 55 | WRes File_Close(CSzFile *p) 56 | { 57 | #ifdef USE_WINDOWS_FILE 58 | if (p->handle != INVALID_HANDLE_VALUE) 59 | { 60 | if (!CloseHandle(p->handle)) 61 | return GetLastError(); 62 | p->handle = INVALID_HANDLE_VALUE; 63 | } 64 | #else 65 | if (p->file != NULL) 66 | { 67 | int res = fclose(p->file); 68 | if (res != 0) 69 | return res; 70 | p->file = NULL; 71 | } 72 | #endif 73 | return 0; 74 | } 75 | 76 | WRes File_Read(CSzFile *p, void *data, size_t *size) 77 | { 78 | size_t originalSize = *size; 79 | if (originalSize == 0) 80 | return 0; 81 | 82 | #ifdef USE_WINDOWS_FILE 83 | 84 | *size = 0; 85 | do 86 | { 87 | DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; 88 | DWORD processed = 0; 89 | BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); 90 | data = (void *)((Byte *)data + processed); 91 | originalSize -= processed; 92 | *size += processed; 93 | if (!res) 94 | return GetLastError(); 95 | if (processed == 0) 96 | break; 97 | } 98 | while (originalSize > 0); 99 | return 0; 100 | 101 | #else 102 | 103 | *size = fread(data, 1, originalSize, p->file); 104 | if (*size == originalSize) 105 | return 0; 106 | return ferror(p->file); 107 | 108 | #endif 109 | } 110 | 111 | WRes File_Write(CSzFile *p, const void *data, size_t *size) 112 | { 113 | size_t originalSize = *size; 114 | if (originalSize == 0) 115 | return 0; 116 | 117 | #ifdef USE_WINDOWS_FILE 118 | 119 | *size = 0; 120 | do 121 | { 122 | DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; 123 | DWORD processed = 0; 124 | BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); 125 | data = (void *)((Byte *)data + processed); 126 | originalSize -= processed; 127 | *size += processed; 128 | if (!res) 129 | return GetLastError(); 130 | if (processed == 0) 131 | break; 132 | } 133 | while (originalSize > 0); 134 | return 0; 135 | 136 | #else 137 | 138 | *size = fwrite(data, 1, originalSize, p->file); 139 | if (*size == originalSize) 140 | return 0; 141 | return ferror(p->file); 142 | 143 | #endif 144 | } 145 | 146 | WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) 147 | { 148 | #ifdef USE_WINDOWS_FILE 149 | 150 | LARGE_INTEGER value; 151 | DWORD moveMethod; 152 | value.LowPart = (DWORD)*pos; 153 | value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ 154 | switch (origin) 155 | { 156 | case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; 157 | case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; 158 | case SZ_SEEK_END: moveMethod = FILE_END; break; 159 | default: return ERROR_INVALID_PARAMETER; 160 | } 161 | value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); 162 | if (value.LowPart == 0xFFFFFFFF) 163 | { 164 | WRes res = GetLastError(); 165 | if (res != NO_ERROR) 166 | return res; 167 | } 168 | *pos = ((Int64)value.HighPart << 32) | value.LowPart; 169 | return 0; 170 | 171 | #else 172 | 173 | int moveMethod; 174 | int res; 175 | switch (origin) 176 | { 177 | case SZ_SEEK_SET: moveMethod = SEEK_SET; break; 178 | case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; 179 | case SZ_SEEK_END: moveMethod = SEEK_END; break; 180 | default: return 1; 181 | } 182 | res = fseek(p->file, (long)*pos, moveMethod); 183 | *pos = ftell(p->file); 184 | return res; 185 | 186 | #endif 187 | } 188 | 189 | WRes File_GetLength(CSzFile *p, UInt64 *length) 190 | { 191 | #ifdef USE_WINDOWS_FILE 192 | 193 | DWORD sizeHigh; 194 | DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); 195 | if (sizeLow == 0xFFFFFFFF) 196 | { 197 | DWORD res = GetLastError(); 198 | if (res != NO_ERROR) 199 | return res; 200 | } 201 | *length = (((UInt64)sizeHigh) << 32) + sizeLow; 202 | return 0; 203 | 204 | #else 205 | 206 | long pos = ftell(p->file); 207 | int res = fseek(p->file, 0, SEEK_END); 208 | *length = ftell(p->file); 209 | fseek(p->file, pos, SEEK_SET); 210 | return res; 211 | 212 | #endif 213 | } 214 | 215 | 216 | /* ---------- FileSeqInStream ---------- */ 217 | 218 | static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) 219 | { 220 | CFileSeqInStream *p = (CFileSeqInStream *)pp; 221 | return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; 222 | } 223 | 224 | void FileSeqInStream_CreateVTable(CFileSeqInStream *p) 225 | { 226 | p->s.Read = FileSeqInStream_Read; 227 | } 228 | 229 | 230 | /* ---------- FileInStream ---------- */ 231 | 232 | static SRes FileInStream_Read(void *pp, void *buf, size_t *size) 233 | { 234 | CFileInStream *p = (CFileInStream *)pp; 235 | return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; 236 | } 237 | 238 | static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) 239 | { 240 | CFileInStream *p = (CFileInStream *)pp; 241 | return File_Seek(&p->file, pos, origin); 242 | } 243 | 244 | void FileInStream_CreateVTable(CFileInStream *p) 245 | { 246 | p->s.Read = FileInStream_Read; 247 | p->s.Seek = FileInStream_Seek; 248 | } 249 | 250 | 251 | /* ---------- FileOutStream ---------- */ 252 | 253 | static size_t FileOutStream_Write(void *pp, const void *data, size_t size) 254 | { 255 | CFileOutStream *p = (CFileOutStream *)pp; 256 | File_Write(&p->file, data, &size); 257 | return size; 258 | } 259 | 260 | void FileOutStream_CreateVTable(CFileOutStream *p) 261 | { 262 | p->s.Write = FileOutStream_Write; 263 | } 264 | --------------------------------------------------------------------------------