├── MyPack001.sln ├── MyPack001 ├── CMyPack.cpp ├── CMyPack.h ├── MyPack001.cpp ├── MyPack001.vcxproj ├── MyPack001.vcxproj.filters ├── MyPack001.vcxproj.user ├── demo.exe ├── lz4.cpp └── lz4.h ├── MyStub ├── MyStub.aps ├── MyStub.rc ├── MyStub.vcxproj ├── MyStub.vcxproj.filters ├── MyStub.vcxproj.user ├── dllmain.cpp ├── framework.h ├── lz4.cpp ├── lz4.h ├── pch.cpp ├── pch.h └── resource.h └── README.md /MyPack001.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29411.108 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyPack001", "MyPack001\MyPack001.vcxproj", "{7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB} = {D2BE684B-6E7A-4109-B949-B97D9CD0CECB} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyStub", "MyStub\MyStub.vcxproj", "{D2BE684B-6E7A-4109-B949-B97D9CD0CECB}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|x64 = Release|x64 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Debug|x64.ActiveCfg = Debug|x64 22 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Debug|x64.Build.0 = Debug|x64 23 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Debug|x86.ActiveCfg = Debug|Win32 24 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Debug|x86.Build.0 = Debug|Win32 25 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Release|x64.ActiveCfg = Release|x64 26 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Release|x64.Build.0 = Release|x64 27 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Release|x86.ActiveCfg = Release|Win32 28 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32}.Release|x86.Build.0 = Release|Win32 29 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Debug|x64.ActiveCfg = Debug|x64 30 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Debug|x64.Build.0 = Debug|x64 31 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Debug|x86.ActiveCfg = Release|Win32 32 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Debug|x86.Build.0 = Release|Win32 33 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Release|x64.ActiveCfg = Release|x64 34 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Release|x64.Build.0 = Release|x64 35 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Release|x86.ActiveCfg = Release|Win32 36 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB}.Release|x86.Build.0 = Release|Win32 37 | EndGlobalSection 38 | GlobalSection(SolutionProperties) = preSolution 39 | HideSolutionNode = FALSE 40 | EndGlobalSection 41 | GlobalSection(ExtensibilityGlobals) = postSolution 42 | SolutionGuid = {DF49E286-D090-4FD2-B355-743442D3C1F1} 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /MyPack001/CMyPack.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lracker/MyPack/b4af8d4ccf0e6f050d6550c57437ce426484ce9a/MyPack001/CMyPack.cpp -------------------------------------------------------------------------------- /MyPack001/CMyPack.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lracker/MyPack/b4af8d4ccf0e6f050d6550c57437ce426484ce9a/MyPack001/CMyPack.h -------------------------------------------------------------------------------- /MyPack001/MyPack001.cpp: -------------------------------------------------------------------------------- 1 | // MyPack001.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 2 | // 3 | 4 | #include 5 | #include "CMyPack.h" 6 | 7 | int main() 8 | { 9 | char Path[256] = {}; 10 | printf("请输入文件路径:"); 11 | scanf_s("%s", Path, 256); 12 | // 保存新添加区段的名字 13 | CMyPack File((LPCSTR)".MyPack"); 14 | // 读取被加壳程序 15 | File.LoadFile(Path); 16 | // 读取壳代码 17 | File.LoadStub((LPCSTR)"MyStub"); 18 | // 保存TLS段的信息 19 | // File.SaveTLS(); 20 | // 复制壳区段信息 21 | File.CopySectionInfo(".MyPack", ".text"); 22 | // 复制dll的.reloc到这个程序新创建的.reloc里面 23 | File.CopySectionInfo(".nreloc", ".reloc"); 24 | // 设置新的OEP 25 | File.SetOEP(); 26 | // 设置导入表 27 | File.SetImport(); 28 | // 加密区段 29 | File.EncrySection(); 30 | // 保留旧的重定位表信息 31 | File.KeepReloc(); 32 | // 复制壳段内容 33 | File.CopySectionContent(".MyPack", ".text"); 34 | // 修复壳的重定位 35 | File.FixReloc(); 36 | // 复制.reloc内容 37 | File.CopySectionContent(".nreloc", ".reloc"); 38 | // 保存TLS 39 | // File.SetTLS(); 40 | // 保存文件 41 | File.SaveFile((LPCSTR)"demo_2.exe"); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /MyPack001/MyPack001.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {7FBDC3F0-2FCE-41CE-BA90-46F86459CC32} 24 | Win32Proj 25 | MyPack001 26 | 10.0.17763.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | MultiByte 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | ..\Debug 76 | 77 | 78 | true 79 | 80 | 81 | false 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | Level3 91 | Disabled 92 | true 93 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 94 | true 95 | 96 | 97 | Console 98 | true 99 | 100 | 101 | 102 | 103 | 104 | 105 | Level3 106 | Disabled 107 | true 108 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 109 | true 110 | 111 | 112 | Console 113 | true 114 | 115 | 116 | 117 | 118 | 119 | 120 | Level3 121 | MaxSpeed 122 | true 123 | true 124 | true 125 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 126 | true 127 | 128 | 129 | Console 130 | true 131 | true 132 | true 133 | 134 | 135 | 136 | 137 | 138 | 139 | Level3 140 | MaxSpeed 141 | true 142 | true 143 | true 144 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 145 | true 146 | 147 | 148 | Console 149 | true 150 | true 151 | true 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /MyPack001/MyPack001.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | -------------------------------------------------------------------------------- /MyPack001/MyPack001.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | WindowsLocalDebugger 6 | ..\Debug 7 | 8 | 9 | ..\Debug 10 | WindowsLocalDebugger 11 | 12 | -------------------------------------------------------------------------------- /MyPack001/demo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lracker/MyPack/b4af8d4ccf0e6f050d6550c57437ce426484ce9a/MyPack001/demo.exe -------------------------------------------------------------------------------- /MyPack001/lz4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 - Fast LZ compression algorithm 3 | Copyright (C) 2011-2014, Yann Collet. 4 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following disclaimer 14 | in the documentation and/or other materials provided with the 15 | distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | You can contact the author at : 30 | - LZ4 source repository : http://code.google.com/p/lz4/ 31 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 32 | */ 33 | 34 | /************************************** 35 | Tuning parameters 36 | **************************************/ 37 | /* 38 | * MEMORY_USAGE : 39 | * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 40 | * Increasing memory usage improves compression ratio 41 | * Reduced memory usage can improve speed, due to cache effect 42 | * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 43 | */ 44 | #define MEMORY_USAGE 14 45 | 46 | /* 47 | * HEAPMODE : 48 | * Select how default compression functions will allocate memory for their hash table, 49 | * in memory stack (0:default, fastest), or in memory heap (1:requires memory allocation (malloc)). 50 | */ 51 | #define HEAPMODE 0 52 | 53 | 54 | /************************************** 55 | CPU Feature Detection 56 | **************************************/ 57 | /* 32 or 64 bits ? */ 58 | #if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \ 59 | || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ 60 | || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \ 61 | || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) /* Detects 64 bits mode */ 62 | # define LZ4_ARCH64 1 63 | #else 64 | # define LZ4_ARCH64 0 65 | #endif 66 | 67 | /* 68 | * Little Endian or Big Endian ? 69 | * Overwrite the #define below if you know your architecture endianess 70 | */ 71 | #if defined (__GLIBC__) 72 | # include 73 | # if (__BYTE_ORDER == __BIG_ENDIAN) 74 | # define LZ4_BIG_ENDIAN 1 75 | # endif 76 | #elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) 77 | # define LZ4_BIG_ENDIAN 1 78 | #elif defined(__sparc) || defined(__sparc__) \ 79 | || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \ 80 | || defined(__hpux) || defined(__hppa) \ 81 | || defined(_MIPSEB) || defined(__s390__) 82 | # define LZ4_BIG_ENDIAN 1 83 | #else 84 | /* Little Endian assumed. PDP Endian and other very rare endian format are unsupported. */ 85 | #endif 86 | 87 | /* 88 | * Unaligned memory access is automatically enabled for "common" CPU, such as x86. 89 | * For others CPU, such as ARM, the compiler may be more cautious, inserting unnecessary extra code to ensure aligned access property 90 | * If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance 91 | */ 92 | #if defined(__ARM_FEATURE_UNALIGNED) 93 | # define LZ4_FORCE_UNALIGNED_ACCESS 1 94 | #endif 95 | 96 | /* Define this parameter if your target system or compiler does not support hardware bit count */ 97 | #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ 98 | # define LZ4_FORCE_SW_BITCOUNT 99 | #endif 100 | 101 | /* 102 | * BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE : 103 | * This option may provide a small boost to performance for some big endian cpu, although probably modest. 104 | * You may set this option to 1 if data will remain within closed environment. 105 | * This option is useless on Little_Endian CPU (such as x86) 106 | */ 107 | 108 | /* #define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 */ 109 | 110 | 111 | /************************************** 112 | Compiler Options 113 | **************************************/ 114 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ 115 | /* "restrict" is a known keyword */ 116 | #else 117 | # define restrict /* Disable restrict */ 118 | #endif 119 | 120 | #ifdef _MSC_VER /* Visual Studio */ 121 | # define FORCE_INLINE static __forceinline 122 | # include /* For Visual 2005 */ 123 | # if LZ4_ARCH64 /* 64-bits */ 124 | # pragma intrinsic(_BitScanForward64) /* For Visual 2005 */ 125 | # pragma intrinsic(_BitScanReverse64) /* For Visual 2005 */ 126 | # else /* 32-bits */ 127 | # pragma intrinsic(_BitScanForward) /* For Visual 2005 */ 128 | # pragma intrinsic(_BitScanReverse) /* For Visual 2005 */ 129 | # endif 130 | # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 131 | #else 132 | # ifdef __GNUC__ 133 | # define FORCE_INLINE static inline __attribute__((always_inline)) 134 | # else 135 | # define FORCE_INLINE static inline 136 | # endif 137 | #endif 138 | 139 | #ifdef _MSC_VER /* Visual Studio */ 140 | # define lz4_bswap16(x) _byteswap_ushort(x) 141 | #else 142 | # define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) 143 | #endif 144 | 145 | #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 146 | 147 | #if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) 148 | # define expect(expr,value) (__builtin_expect ((expr),(value)) ) 149 | #else 150 | # define expect(expr,value) (expr) 151 | #endif 152 | 153 | #define likely(expr) expect((expr) != 0, 1) 154 | #define unlikely(expr) expect((expr) != 0, 0) 155 | 156 | 157 | /************************************** 158 | Memory routines 159 | **************************************/ 160 | #include /* malloc, calloc, free */ 161 | #define ALLOCATOR(n,s) calloc(n,s) 162 | #define FREEMEM free 163 | #include /* memset, memcpy */ 164 | #define MEM_INIT memset 165 | 166 | 167 | /************************************** 168 | Includes 169 | **************************************/ 170 | #include "lz4.h" 171 | 172 | 173 | /************************************** 174 | Basic Types 175 | **************************************/ 176 | #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ 177 | # include 178 | typedef uint8_t BYTE; 179 | typedef uint16_t U16; 180 | typedef uint32_t U32; 181 | typedef int32_t S32; 182 | typedef uint64_t U64; 183 | #else 184 | typedef unsigned char BYTE; 185 | typedef unsigned short U16; 186 | typedef unsigned int U32; 187 | typedef signed int S32; 188 | typedef unsigned long long U64; 189 | #endif 190 | 191 | #if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS) 192 | # define _PACKED __attribute__ ((packed)) 193 | #else 194 | # define _PACKED 195 | #endif 196 | 197 | #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) 198 | # if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) 199 | # pragma pack(1) 200 | # else 201 | # pragma pack(push, 1) 202 | # endif 203 | #endif 204 | 205 | typedef struct { U16 v; } _PACKED U16_S; 206 | typedef struct { U32 v; } _PACKED U32_S; 207 | typedef struct { U64 v; } _PACKED U64_S; 208 | typedef struct {size_t v;} _PACKED size_t_S; 209 | 210 | #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) 211 | # if defined(__SUNPRO_C) || defined(__SUNPRO_CC) 212 | # pragma pack(0) 213 | # else 214 | # pragma pack(pop) 215 | # endif 216 | #endif 217 | 218 | #define A16(x) (((U16_S *)(x))->v) 219 | #define A32(x) (((U32_S *)(x))->v) 220 | #define A64(x) (((U64_S *)(x))->v) 221 | #define AARCH(x) (((size_t_S *)(x))->v) 222 | 223 | 224 | /************************************** 225 | Constants 226 | **************************************/ 227 | #define LZ4_HASHLOG (MEMORY_USAGE-2) 228 | #define HASHTABLESIZE (1 << MEMORY_USAGE) 229 | #define HASHNBCELLS4 (1 << LZ4_HASHLOG) 230 | 231 | #define MINMATCH 4 232 | 233 | #define COPYLENGTH 8 234 | #define LASTLITERALS 5 235 | #define MFLIMIT (COPYLENGTH+MINMATCH) 236 | static const int LZ4_minLength = (MFLIMIT+1); 237 | 238 | #define KB *(1U<<10) 239 | #define MB *(1U<<20) 240 | #define GB *(1U<<30) 241 | 242 | #define LZ4_64KLIMIT ((64 KB) + (MFLIMIT-1)) 243 | #define SKIPSTRENGTH 6 /* Increasing this value will make the compression run slower on incompressible data */ 244 | 245 | #define MAXD_LOG 16 246 | #define MAX_DISTANCE ((1 << MAXD_LOG) - 1) 247 | 248 | #define ML_BITS 4 249 | #define ML_MASK ((1U<=e; */ 294 | #else 295 | # define LZ4_WILDCOPY(d,s,e) { if (likely(e-d <= 8)) LZ4_COPY8(d,s) else do { LZ4_COPY8(d,s) } while (d>3); 312 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 313 | return (__builtin_clzll(val) >> 3); 314 | # else 315 | int r; 316 | if (!(val>>32)) { r=4; } else { r=0; val>>=32; } 317 | if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } 318 | r += (!val); 319 | return r; 320 | # endif 321 | # else 322 | # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 323 | unsigned long r = 0; 324 | _BitScanForward64( &r, val ); 325 | return (int)(r>>3); 326 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 327 | return (__builtin_ctzll(val) >> 3); 328 | # else 329 | static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; 330 | return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; 331 | # endif 332 | # endif 333 | } 334 | 335 | #else 336 | 337 | FORCE_INLINE int LZ4_NbCommonBytes (register U32 val) 338 | { 339 | # if defined(LZ4_BIG_ENDIAN) 340 | # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 341 | unsigned long r = 0; 342 | _BitScanReverse( &r, val ); 343 | return (int)(r>>3); 344 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 345 | return (__builtin_clz(val) >> 3); 346 | # else 347 | int r; 348 | if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } 349 | r += (!val); 350 | return r; 351 | # endif 352 | # else 353 | # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 354 | unsigned long r; 355 | _BitScanForward( &r, val ); 356 | return (int)(r>>3); 357 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 358 | return (__builtin_ctz(val) >> 3); 359 | # else 360 | static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; 361 | return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; 362 | # endif 363 | # endif 364 | } 365 | 366 | #endif 367 | 368 | 369 | /**************************** 370 | Compression functions 371 | ****************************/ 372 | int LZ4API LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } 373 | 374 | FORCE_INLINE int LZ4_hashSequence(U32 sequence, tableType_t tableType) 375 | { 376 | if (tableType == byU16) 377 | return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); 378 | else 379 | return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); 380 | } 381 | 382 | FORCE_INLINE int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); } 383 | 384 | FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) 385 | { 386 | switch (tableType) 387 | { 388 | case byPtr: { const BYTE** hashTable = (const BYTE**) tableBase; hashTable[h] = p; break; } 389 | case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); break; } 390 | case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); break; } 391 | } 392 | } 393 | 394 | FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) 395 | { 396 | U32 h = LZ4_hashPosition(p, tableType); 397 | LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); 398 | } 399 | 400 | FORCE_INLINE const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) 401 | { 402 | if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } 403 | if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } 404 | { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ 405 | } 406 | 407 | FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) 408 | { 409 | U32 h = LZ4_hashPosition(p, tableType); 410 | return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); 411 | } 412 | 413 | 414 | FORCE_INLINE int LZ4_compress_generic( 415 | void* ctx, 416 | const char* source, 417 | char* dest, 418 | int inputSize, 419 | int maxOutputSize, 420 | 421 | limitedOutput_directive limitedOutput, 422 | tableType_t tableType, 423 | prefix64k_directive prefix) 424 | { 425 | const BYTE* ip = (const BYTE*) source; 426 | const BYTE* const base = (prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->base : (const BYTE*) source; 427 | const BYTE* const lowLimit = ((prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->bufferStart : (const BYTE*)source); 428 | const BYTE* anchor = (const BYTE*) source; 429 | const BYTE* const iend = ip + inputSize; 430 | const BYTE* const mflimit = iend - MFLIMIT; 431 | const BYTE* const matchlimit = iend - LASTLITERALS; 432 | 433 | BYTE* op = (BYTE*) dest; 434 | BYTE* const oend = op + maxOutputSize; 435 | 436 | int length; 437 | const int skipStrength = SKIPSTRENGTH; 438 | U32 forwardH; 439 | 440 | /* Init conditions */ 441 | if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ 442 | if ((prefix==withPrefix) && (ip != ((LZ4_Data_Structure*)ctx)->nextBlock)) return 0; /* must continue from end of previous block */ 443 | if (prefix==withPrefix) ((LZ4_Data_Structure*)ctx)->nextBlock=iend; /* do it now, due to potential early exit */ 444 | if ((tableType == byU16) && (inputSize>=(int)LZ4_64KLIMIT)) return 0; /* Size too large (not within 64K limit) */ 445 | if (inputSize> skipStrength; 463 | ip = forwardIp; 464 | forwardIp = ip + step; 465 | 466 | if (unlikely(forwardIp > mflimit)) { goto _last_literals; } 467 | 468 | forwardH = LZ4_hashPosition(forwardIp, tableType); 469 | ref = LZ4_getPositionOnHash(h, ctx, tableType, base); 470 | LZ4_putPositionOnHash(ip, h, ctx, tableType, base); 471 | 472 | } while ((ref + MAX_DISTANCE < ip) || (A32(ref) != A32(ip))); 473 | 474 | /* Catch up */ 475 | while ((ip>anchor) && (ref > lowLimit) && (unlikely(ip[-1]==ref[-1]))) { ip--; ref--; } 476 | 477 | /* Encode Literal length */ 478 | length = (int)(ip - anchor); 479 | token = op++; 480 | if ((limitedOutput) && (unlikely(op + length + (2 + 1 + LASTLITERALS) + (length/255) > oend))) return 0; /* Check output limit */ 481 | if (length>=(int)RUN_MASK) 482 | { 483 | int len = length-RUN_MASK; 484 | *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; 486 | *op++ = (BYTE)len; 487 | } 488 | else *token = (BYTE)(length<>8) > oend))) return 0; /* Check output limit */ 515 | if (length>=(int)ML_MASK) 516 | { 517 | *token += ML_MASK; 518 | length -= ML_MASK; 519 | for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; } 520 | if (length >= 255) { length-=255; *op++ = 255; } 521 | *op++ = (BYTE)length; 522 | } 523 | else *token += (BYTE)(length); 524 | 525 | /* Test end of chunk */ 526 | if (ip > mflimit) { anchor = ip; break; } 527 | 528 | /* Fill table */ 529 | LZ4_putPosition(ip-2, ctx, tableType, base); 530 | 531 | /* Test next position */ 532 | ref = LZ4_getPosition(ip, ctx, tableType, base); 533 | LZ4_putPosition(ip, ctx, tableType, base); 534 | if ((ref + MAX_DISTANCE >= ip) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; } 535 | 536 | /* Prepare next loop */ 537 | anchor = ip++; 538 | forwardH = LZ4_hashPosition(ip, tableType); 539 | } 540 | 541 | _last_literals: 542 | /* Encode Last Literals */ 543 | { 544 | int lastRun = (int)(iend - anchor); 545 | if ((limitedOutput) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ 546 | if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 547 | else *op++ = (BYTE)(lastRun<hashTable, 0, sizeof(lz4ds->hashTable)); 641 | lz4ds->bufferStart = base; 642 | lz4ds->base = base; 643 | lz4ds->nextBlock = base; 644 | } 645 | 646 | int LZ4API LZ4_resetStreamState(void* state, const char* inputBuffer) 647 | { 648 | if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ 649 | LZ4_init((LZ4_Data_Structure*)state, (const BYTE*)inputBuffer); 650 | return 0; 651 | } 652 | 653 | void* LZ4API LZ4_create (const char* inputBuffer) 654 | { 655 | void* lz4ds = ALLOCATOR(1, sizeof(LZ4_Data_Structure)); 656 | LZ4_init ((LZ4_Data_Structure*)lz4ds, (const BYTE*)inputBuffer); 657 | return lz4ds; 658 | } 659 | 660 | 661 | int LZ4API LZ4_free (void* LZ4_Data) 662 | { 663 | FREEMEM(LZ4_Data); 664 | return (0); 665 | } 666 | 667 | 668 | char* LZ4API LZ4_slideInputBuffer (void* LZ4_Data) 669 | { 670 | LZ4_Data_Structure* lz4ds = (LZ4_Data_Structure*)LZ4_Data; 671 | size_t delta = lz4ds->nextBlock - (lz4ds->bufferStart + 64 KB); 672 | 673 | if ( (lz4ds->base - delta > lz4ds->base) /* underflow control */ 674 | || ((size_t)(lz4ds->nextBlock - lz4ds->base) > 0xE0000000) ) /* close to 32-bits limit */ 675 | { 676 | size_t deltaLimit = (lz4ds->nextBlock - 64 KB) - lz4ds->base; 677 | int nH; 678 | 679 | for (nH=0; nH < HASHNBCELLS4; nH++) 680 | { 681 | if ((size_t)(lz4ds->hashTable[nH]) < deltaLimit) lz4ds->hashTable[nH] = 0; 682 | else lz4ds->hashTable[nH] -= (U32)deltaLimit; 683 | } 684 | memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); 685 | lz4ds->base = lz4ds->bufferStart; 686 | lz4ds->nextBlock = lz4ds->base + 64 KB; 687 | } 688 | else 689 | { 690 | memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); 691 | lz4ds->nextBlock -= delta; 692 | lz4ds->base -= delta; 693 | } 694 | 695 | return (char*)(lz4ds->nextBlock); 696 | } 697 | 698 | 699 | int LZ4API LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize) 700 | { 701 | return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, 0, notLimited, byU32, withPrefix); 702 | } 703 | 704 | 705 | int LZ4API LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize) 706 | { 707 | return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, maxOutputSize, limited, byU32, withPrefix); 708 | } 709 | 710 | 711 | /**************************** 712 | Decompression functions 713 | ****************************/ 714 | /* 715 | * This generic decompression function cover all use cases. 716 | * It shall be instanciated several times, using different sets of directives 717 | * Note that it is essential this generic function is really inlined, 718 | * in order to remove useless branches during compilation optimisation. 719 | */ 720 | FORCE_INLINE int LZ4_decompress_generic( 721 | const char* source, 722 | char* dest, 723 | int inputSize, 724 | int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ 725 | 726 | int endOnInput, /* endOnOutputSize, endOnInputSize */ 727 | int prefix64k, /* noPrefix, withPrefix */ 728 | int partialDecoding, /* full, partial */ 729 | int targetOutputSize /* only used if partialDecoding==partial */ 730 | ) 731 | { 732 | /* Local Variables */ 733 | const BYTE* restrict ip = (const BYTE*) source; 734 | const BYTE* ref; 735 | const BYTE* const iend = ip + inputSize; 736 | 737 | BYTE* op = (BYTE*) dest; 738 | BYTE* const oend = op + outputSize; 739 | BYTE* cpy; 740 | BYTE* oexit = op + targetOutputSize; 741 | 742 | /*const size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; / static reduces speed for LZ4_decompress_safe() on GCC64 */ 743 | const size_t dec32table[] = {4-0, 4-3, 4-2, 4-3, 4-0, 4-0, 4-0, 4-0}; /* static reduces speed for LZ4_decompress_safe() on GCC64 */ 744 | static const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; 745 | 746 | 747 | /* Special cases */ 748 | if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ 749 | if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ 750 | if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); 751 | 752 | 753 | /* Main Loop */ 754 | while (1) 755 | { 756 | unsigned token; 757 | size_t length; 758 | 759 | /* get runlength */ 760 | token = *ip++; 761 | if ((length=(token>>ML_BITS)) == RUN_MASK) 762 | { 763 | unsigned s=255; 764 | while (((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) 774 | || ((!endOnInput) && (cpy>oend-COPYLENGTH))) 775 | { 776 | if (partialDecoding) 777 | { 778 | if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ 779 | if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ 780 | } 781 | else 782 | { 783 | if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ 784 | if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ 785 | } 786 | memcpy(op, ip, length); 787 | ip += length; 788 | op += length; 789 | break; /* Necessarily EOF, due to parsing restrictions */ 790 | } 791 | LZ4_WILDCOPY(op, ip, cpy); ip -= (op-cpy); op = cpy; 792 | 793 | /* get offset */ 794 | LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2; 795 | if ((prefix64k==noPrefix) && (unlikely(ref < (BYTE* const)dest))) goto _output_error; /* Error : offset outside destination buffer */ 796 | 797 | /* get matchlength */ 798 | if ((length=(token&ML_MASK)) == ML_MASK) 799 | { 800 | while ((!endOnInput) || (ipoend-COPYLENGTH-(STEPSIZE-4))) 827 | { 828 | if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last 5 bytes must be literals */ 829 | LZ4_SECURECOPY(op, ref, (oend-COPYLENGTH)); 830 | while(op (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) 94 | 95 | /* 96 | LZ4_compressBound() : 97 | Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible) 98 | primarily useful for memory allocation of output buffer. 99 | inline function is recommended for the general case, 100 | macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation). 101 | 102 | isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE 103 | return : maximum output size in a "worst case" scenario 104 | or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) 105 | */ 106 | int LZ4API LZ4_compressBound(int isize); 107 | 108 | 109 | /* 110 | LZ4_compress_limitedOutput() : 111 | Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. 112 | If it cannot achieve it, compression will stop, and result of the function will be zero. 113 | This function never writes outside of provided output buffer. 114 | 115 | inputSize : Max supported value is LZ4_MAX_INPUT_VALUE 116 | maxOutputSize : is the size of the destination buffer (which must be already allocated) 117 | return : the number of bytes written in buffer 'dest' 118 | or 0 if the compression fails 119 | */ 120 | int LZ4API LZ4_compress_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); 121 | 122 | 123 | /* 124 | LZ4_decompress_fast() : 125 | originalSize : is the original and therefore uncompressed size 126 | return : the number of bytes read from the source buffer (in other words, the compressed size) 127 | If the source stream is malformed, the function will stop decoding and return a negative result. 128 | note : This function is a bit faster than LZ4_decompress_safe() 129 | This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet. 130 | Use this function preferably into a trusted environment (data to decode comes from a trusted source). 131 | Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. 132 | */ 133 | int LZ4API LZ4_decompress_fast (const char* source, char* dest, int originalSize); 134 | 135 | 136 | /* 137 | LZ4_decompress_safe_partial() : 138 | This function decompress a compressed block of size 'inputSize' at position 'source' 139 | into output buffer 'dest' of size 'maxOutputSize'. 140 | The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, 141 | reducing decompression time. 142 | return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) 143 | Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. 144 | Always control how many bytes were decoded. 145 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 146 | This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets 147 | */ 148 | int LZ4API LZ4_decompress_safe_partial (const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); 149 | 150 | 151 | /* 152 | These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. 153 | To know how much memory must be allocated for the compression tables, use : 154 | int LZ4_sizeofState(); 155 | 156 | Note that tables must be aligned on 4-bytes boundaries, otherwise compression will fail (return code 0). 157 | 158 | The allocated memory can be provided to the compressions functions using 'void* state' parameter. 159 | LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. 160 | They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). 161 | */ 162 | int LZ4API LZ4_sizeofState(void); 163 | int LZ4API LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); 164 | int LZ4API LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 165 | 166 | 167 | /************************************** 168 | Streaming Functions 169 | **************************************/ 170 | void* LZ4API LZ4_create (const char* inputBuffer); 171 | int LZ4API LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize); 172 | int LZ4API LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); 173 | char* LZ4API LZ4_slideInputBuffer (void* LZ4_Data); 174 | int LZ4API LZ4_free (void* LZ4_Data); 175 | 176 | /* 177 | These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. 178 | In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function : 179 | 180 | void* LZ4_create (const char* inputBuffer); 181 | The result of the function is the (void*) pointer on the LZ4 Data Structure. 182 | This pointer will be needed in all other functions. 183 | If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. 184 | The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. 185 | The input buffer must be already allocated, and size at least 192KB. 186 | 'inputBuffer' will also be the 'const char* source' of the first block. 187 | 188 | All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. 189 | To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(). 190 | Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(), 191 | but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one. 192 | If next block does not begin immediately after the previous one, the compression will fail (return 0). 193 | 194 | When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : 195 | char* LZ4_slideInputBuffer(void* LZ4_Data); 196 | must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. 197 | Note that, for this function to work properly, minimum size of an input buffer must be 192KB. 198 | ==> The memory position where the next input data block must start is provided as the result of the function. 199 | 200 | Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual. 201 | 202 | When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure. 203 | */ 204 | 205 | 206 | int LZ4API LZ4_sizeofStreamState(void); 207 | int LZ4API LZ4_resetStreamState(void* state, const char* inputBuffer); 208 | 209 | /* 210 | These functions achieve the same result as : 211 | void* LZ4_create (const char* inputBuffer); 212 | 213 | They are provided here to allow the user program to allocate memory using its own routines. 214 | 215 | To know how much space must be allocated, use LZ4_sizeofStreamState(); 216 | Note also that space must be 4-bytes aligned. 217 | 218 | Once space is allocated, you must initialize it using : LZ4_resetStreamState(void* state, const char* inputBuffer); 219 | void* state is a pointer to the space allocated. 220 | It must be aligned on 4-bytes boundaries, and be large enough. 221 | The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. 222 | The input buffer must be already allocated, and size at least 192KB. 223 | 'inputBuffer' will also be the 'const char* source' of the first block. 224 | 225 | The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). 226 | return value of LZ4_resetStreamState() must be 0 is OK. 227 | Any other value means there was an error (typically, pointer is not aligned on 4-bytes boundaries). 228 | */ 229 | 230 | 231 | int LZ4API LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int inputSize, int maxOutputSize); 232 | int LZ4API LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int outputSize); 233 | 234 | /* 235 | *_withPrefix64k() : 236 | These decoding functions work the same as their "normal name" versions, 237 | but can use up to 64KB of data in front of 'char* dest'. 238 | These functions are necessary to decode inter-dependant blocks. 239 | */ 240 | 241 | 242 | /************************************** 243 | Obsolete Functions 244 | **************************************/ 245 | /* 246 | These functions are deprecated and should no longer be used. 247 | They are provided here for compatibility with existing user programs. 248 | */ 249 | int LZ4API LZ4_uncompress (const char* source, char* dest, int outputSize); 250 | int LZ4API LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); 251 | 252 | 253 | #if defined (__cplusplus) 254 | } 255 | #endif 256 | -------------------------------------------------------------------------------- /MyStub/MyStub.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lracker/MyPack/b4af8d4ccf0e6f050d6550c57437ce426484ce9a/MyStub/MyStub.aps -------------------------------------------------------------------------------- /MyStub/MyStub.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | 5 | #include "resource.h" 6 | 7 | #define APSTUDIO_READONLY_SYMBOLS 8 | ///////////////////////////////////////////////////////////////////////////// 9 | // 10 | // Generated from the TEXTINCLUDE 2 resource. 11 | // 12 | #include "winres.h" 13 | 14 | ///////////////////////////////////////////////////////////////////////////// 15 | #undef APSTUDIO_READONLY_SYMBOLS 16 | 17 | ///////////////////////////////////////////////////////////////////////////// 18 | // 中文(简体,中国) resources 19 | 20 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) 21 | LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED 22 | 23 | #ifdef APSTUDIO_INVOKED 24 | ///////////////////////////////////////////////////////////////////////////// 25 | // 26 | // TEXTINCLUDE 27 | // 28 | 29 | 1 TEXTINCLUDE 30 | BEGIN 31 | "resource.h\0" 32 | END 33 | 34 | 2 TEXTINCLUDE 35 | BEGIN 36 | "#include ""winres.h""\r\n" 37 | "\0" 38 | END 39 | 40 | 3 TEXTINCLUDE 41 | BEGIN 42 | "\r\n" 43 | "\0" 44 | END 45 | 46 | #endif // APSTUDIO_INVOKED 47 | 48 | #endif // 中文(简体,中国) resources 49 | ///////////////////////////////////////////////////////////////////////////// 50 | 51 | 52 | 53 | #ifndef APSTUDIO_INVOKED 54 | ///////////////////////////////////////////////////////////////////////////// 55 | // 56 | // Generated from the TEXTINCLUDE 3 resource. 57 | // 58 | 59 | 60 | ///////////////////////////////////////////////////////////////////////////// 61 | #endif // not APSTUDIO_INVOKED 62 | 63 | -------------------------------------------------------------------------------- /MyStub/MyStub.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {D2BE684B-6E7A-4109-B949-B97D9CD0CECB} 24 | Win32Proj 25 | MyStub 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | MultiByte 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | MultiByte 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | ..\Debug 82 | 83 | 84 | false 85 | 86 | 87 | 88 | Use 89 | Level3 90 | Disabled 91 | true 92 | WIN32;_DEBUG;MYSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 93 | true 94 | pch.h 95 | 96 | 97 | Windows 98 | true 99 | false 100 | 101 | 102 | 103 | 104 | Use 105 | Level3 106 | Disabled 107 | true 108 | _DEBUG;MYSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 109 | true 110 | pch.h 111 | 112 | 113 | Windows 114 | true 115 | false 116 | 117 | 118 | 119 | 120 | Use 121 | Level3 122 | MaxSpeed 123 | true 124 | true 125 | true 126 | WIN32;NDEBUG;MYSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 127 | true 128 | pch.h 129 | MultiThreaded 130 | false 131 | 132 | 133 | Windows 134 | true 135 | true 136 | true 137 | false 138 | 139 | 140 | 141 | 142 | Use 143 | Level3 144 | MaxSpeed 145 | true 146 | true 147 | true 148 | NDEBUG;MYSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 149 | true 150 | pch.h 151 | 152 | 153 | Windows 154 | true 155 | true 156 | true 157 | false 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | Create 171 | Create 172 | Create 173 | Create 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /MyStub/MyStub.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件 29 | 30 | 31 | 32 | 33 | 源文件 34 | 35 | 36 | 源文件 37 | 38 | 39 | 源文件 40 | 41 | 42 | 43 | 44 | 资源文件 45 | 46 | 47 | -------------------------------------------------------------------------------- /MyStub/MyStub.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\Users\Canary\Desktop\15PB\第三阶段\软件写壳\MyPack001\Debug\MyPack001.exe 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /MyStub/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 2 | #include "pch.h" 3 | #include "lz4.h" 4 | #include 5 | #include 6 | 7 | #pragma comment(lib, "DbgHelp.lib") 8 | #pragma comment(linker,"/merge:.data=.text") 9 | #pragma comment(linker,"/merge:.rdata=.text") 10 | #pragma comment(linker,"/section:.text,RWE") 11 | 12 | DWORD GetFunAddr(DWORD* DllBase, char* FunName); 13 | #define DefApiFun(name)\ 14 | decltype(name)* My_##name = NULL; 15 | #define DefineFuncPtr(base, name)\ 16 | My_##name = (decltype(name)*)GetFunAddr(base, (char*)#name) 17 | 18 | typedef HANDLE(CALLBACK* HHeapCreate)(_In_ DWORD flOptions, _In_ SIZE_T dwInitialSize, _In_ SIZE_T dwMaximumSize); 19 | typedef LPVOID(CALLBACK* LPHeapAlloc)(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ SIZE_T dwBytes); 20 | typedef BOOL(CALLBACK* BHeapFree)(_Inout_ HANDLE hHeap, _In_ DWORD dwFlags, __drv_freesMem(Mem) _Frees_ptr_opt_ LPVOID lpMem); 21 | 22 | DefApiFun(GetProcAddress); 23 | DefApiFun(VirtualProtect); 24 | DefApiFun(LoadLibraryA); 25 | DefApiFun(GetMessageA); 26 | DefApiFun(TranslateMessage); 27 | DefApiFun(DispatchMessageA); 28 | DefApiFun(RegisterClassExA); 29 | DefApiFun(CreateWindowExA); 30 | DefApiFun(ShowWindow); 31 | DefApiFun(UpdateWindow); 32 | DefApiFun(GetModuleHandleA); 33 | DefApiFun(DefWindowProcA); 34 | DefApiFun(GetWindowTextA); 35 | DefApiFun(PostQuitMessage); 36 | DefApiFun(GetStockObject); 37 | DefApiFun(MessageBoxA); 38 | DefApiFun(VirtualAlloc); 39 | DefApiFun(GetCurrentProcess); 40 | DefApiFun(ExitProcess); 41 | 42 | 43 | //定义函数NtQueryInformationProcess的指针类型 44 | typedef NTSTATUS(NTAPI* PNtQueryInformationProcess)( 45 | IN HANDLE ProcessHandle, 46 | IN PROCESSINFOCLASS ProcessInformationClass, 47 | OUT PVOID ProcessInformation, 48 | IN ULONG ProcessInformationLength, 49 | OUT PULONG ReturnLength OPTIONAL 50 | ); 51 | 52 | PNtQueryInformationProcess pNtQueryInformationProcess; 53 | 54 | // 使得产生TLS表 55 | _declspec(thread) int g_num; 56 | 57 | struct TypeOffset 58 | { 59 | WORD Offset : 12; 60 | WORD Type : 4; 61 | }; 62 | 63 | typedef struct _SHAREDATA 64 | { 65 | // 原始OEP 66 | LONG OldOep = 0; 67 | // 区段的大小 68 | DWORD dwSize = 0; 69 | // 区段的RVA 70 | DWORD dwRVA = 0; 71 | // 密钥 72 | BYTE bKey = 0; 73 | // 原始数据大小 74 | INT nSrcSize = 0; 75 | // 压缩后数据大小 76 | INT nDestSize = 0; 77 | // 压缩数据的FOA 78 | DWORD dwSectionRVA = 0; 79 | // 保留文件重定位表的RVA 80 | DWORD dwRelocRVA = 0; 81 | // 保留文件的ImageBase 82 | DWORD dwFileImageBase = 0; 83 | // 保留原程序导入表的RVA 84 | DWORD dwOldImportRVA = 0; 85 | // TLS是否存在 86 | BOOL bTLSEnable = TRUE; 87 | // Index一般为0 88 | DWORD TlsIndex = 0; 89 | // 保存TLS表的信息 90 | IMAGE_TLS_DIRECTORY pOldTls; 91 | }SHAREDATA, * PSHAREDATA; 92 | 93 | DWORD GetFunAddr(DWORD* DllBase, char* FunName) 94 | { 95 | // 遍历导出表 96 | PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)DllBase; 97 | PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)pDos); 98 | PIMAGE_OPTIONAL_HEADER pOt = (PIMAGE_OPTIONAL_HEADER)&pNt->OptionalHeader; 99 | PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)(pOt->DataDirectory[0].VirtualAddress + (DWORD)DllBase); 100 | // 获取到ENT、EOT、EAT 101 | DWORD* pENT = (DWORD*)(pExport->AddressOfNames + (DWORD)DllBase); 102 | WORD* pEOT = (WORD*)(pExport->AddressOfNameOrdinals + (DWORD)DllBase); 103 | DWORD* pEAT = (DWORD*)(pExport->AddressOfFunctions + (DWORD)DllBase); 104 | for (int i = 0; i < pExport->NumberOfNames; ++i) 105 | { 106 | char* Name = (char*)(pENT[i] + (DWORD)DllBase); 107 | if (!strcmp(Name, FunName)) 108 | return pEAT[pEOT[i]] + (DWORD)DllBase; 109 | } 110 | return -1; 111 | } 112 | 113 | extern "C" 114 | { 115 | 116 | __declspec(naked) DWORD* GetKernel32() 117 | { 118 | __asm 119 | { 120 | mov eax, fs: [0x30] ; 121 | mov eax, [eax + 0xC]; 122 | mov eax, [eax + 0x1C]; 123 | mov eax, [eax]; 124 | mov eax, [eax]; 125 | mov eax, [eax + 8]; 126 | ret; 127 | } 128 | } 129 | 130 | __declspec(dllexport) SHAREDATA ShareData; 131 | 132 | //****************************************************************************** 133 | // 函数名称: GetImageBase 134 | // 函数说明: 获取到加载基址 135 | // 作 者: lracker 136 | // 时 间: 2019/12/09 137 | // 返 回 值: void 138 | //****************************************************************************** 139 | __declspec(naked) DWORD GetImageBase() 140 | { 141 | __asm 142 | { 143 | mov eax, fs: [0x30] ; 144 | mov eax, [eax + 0x8]; 145 | ret; 146 | } 147 | } 148 | 149 | VOID GetApi() 150 | { 151 | DWORD* KernelBase = GetKernel32(); 152 | DefineFuncPtr(KernelBase, GetProcAddress); 153 | DefineFuncPtr(KernelBase, VirtualProtect); 154 | DefineFuncPtr(KernelBase, VirtualAlloc); 155 | DefineFuncPtr(KernelBase, GetModuleHandleA); 156 | DefineFuncPtr(KernelBase, LoadLibraryA); 157 | DefineFuncPtr(KernelBase, GetCurrentProcess); 158 | DefineFuncPtr(KernelBase, ExitProcess); 159 | 160 | HMODULE hUser32 = My_LoadLibraryA("user32.dll"); 161 | DefineFuncPtr((DWORD*)hUser32, CreateWindowExA); 162 | DefineFuncPtr((DWORD*)hUser32, GetMessageA); 163 | DefineFuncPtr((DWORD*)hUser32, RegisterClassExA); 164 | DefineFuncPtr((DWORD*)hUser32, TranslateMessage); 165 | DefineFuncPtr((DWORD*)hUser32, DispatchMessageA); 166 | DefineFuncPtr((DWORD*)hUser32, ShowWindow); 167 | DefineFuncPtr((DWORD*)hUser32, UpdateWindow); 168 | DefineFuncPtr((DWORD*)hUser32, GetWindowTextA); 169 | DefineFuncPtr((DWORD*)hUser32, PostQuitMessage); 170 | DefineFuncPtr((DWORD*)hUser32, DefWindowProcA); 171 | DefineFuncPtr((DWORD*)hUser32, MessageBoxA); 172 | 173 | HMODULE hNtdll = My_LoadLibraryA("Ntdll.dll"); 174 | pNtQueryInformationProcess = (PNtQueryInformationProcess)My_GetProcAddress(hNtdll, "NtQueryInformationProcess"); 175 | HMODULE hGDI = My_LoadLibraryA("Gdi32.dll"); 176 | DefineFuncPtr((DWORD*)hGDI, GetStockObject); 177 | } 178 | 179 | //****************************************************************************** 180 | // 函数名称: Decry 181 | // 函数说明: 解密我们的代码段 182 | // 作 者: lracker 183 | // 时 间: 2019/12/09 184 | // 返 回 值: void 185 | //****************************************************************************** 186 | void Decry() 187 | { 188 | // 修改属性 189 | DWORD dwOldProtect = 0; 190 | My_VirtualProtect((LPVOID)(ShareData.dwRVA + GetImageBase()), ShareData.dwSize, PAGE_READWRITE, &dwOldProtect); 191 | BYTE* Data = (BYTE*)(ShareData.dwRVA + GetImageBase()); 192 | for (int i = 0; i < ShareData.dwSize; ++i) 193 | Data[i] ^= ShareData.bKey; 194 | My_VirtualProtect((LPVOID)(ShareData.dwRVA + GetImageBase()), ShareData.dwSize, dwOldProtect, &dwOldProtect); 195 | } 196 | 197 | //****************************************************************************** 198 | // 函数名称: JmpOEP 199 | // 函数说明: 跳回到原始的OEP 200 | // 作 者: lracker 201 | // 时 间: 2019/12/09 202 | // 返 回 值: void 203 | //****************************************************************************** 204 | __declspec(naked) void JmpOEP() 205 | { 206 | __asm 207 | { 208 | mov eax, fs: [0x30] ; 209 | mov eax, [eax + 0x8]; 210 | mov ebx, ShareData.OldOep; 211 | add ebx, eax; 212 | jmp ebx; 213 | __emit(0xE8); 214 | } 215 | } 216 | 217 | //****************************************************************************** 218 | // 函数名称: WndProc 219 | // 函数说明: 弹窗的回调函数 220 | // 作 者: lracker 221 | // 时 间: 2019/12/12 222 | // 参 数: HWND hWnd 223 | // 参 数: UINT uMsg 224 | // 参 数: WPARAM wParam 225 | // 参 数: LPARAM lParam 226 | // 返 回 值: LRESULT CALLBACK 227 | //****************************************************************************** 228 | LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 229 | { // 保存编辑框句柄 230 | static HWND EditHwnd = 0; 231 | switch (uMsg) 232 | { 233 | case WM_CREATE: 234 | { 235 | EditHwnd = My_CreateWindowExA(0, "edit", NULL, WS_CHILD | WS_BORDER | WS_VISIBLE, 20, 20, 150, 20, hWnd, (HMENU)0x1000, (HINSTANCE)GetImageBase(), NULL); 236 | My_CreateWindowExA(0, "button", "确定", WS_CHILD | WS_VISIBLE, 50, 70, 100, 20, hWnd, (HMENU)0x1001, (HINSTANCE)GetImageBase(), NULL); 237 | break; 238 | } 239 | case WM_COMMAND: 240 | { 241 | if (wParam == 0x1001) 242 | { 243 | char Buff[100] = {}; 244 | My_GetWindowTextA(EditHwnd, Buff, 100); 245 | if (!strcmp(Buff, "hello")) 246 | { 247 | My_PostQuitMessage(0); 248 | My_ShowWindow(hWnd, SW_HIDE); 249 | break; 250 | } 251 | } 252 | break; 253 | } 254 | } 255 | return My_DefWindowProcA(hWnd, uMsg, wParam, lParam); 256 | } 257 | 258 | //****************************************************************************** 259 | // 函数名称: Enter 260 | // 函数说明: 弹出窗口看看是否进入主程序 261 | // 作 者: lracker 262 | // 时 间: 2019/12/09 263 | // 返 回 值: BOOL 264 | //****************************************************************************** 265 | VOID Enter() 266 | { 267 | // 创建窗口类 268 | WNDCLASSEXA WndClass = { sizeof(WndClass) }; 269 | WndClass.style = CS_HREDRAW | CS_VREDRAW; 270 | WndClass.hInstance = (HINSTANCE)GetImageBase(); 271 | WndClass.hbrBackground = (HBRUSH)My_GetStockObject(WHITE_BRUSH); 272 | WndClass.lpszClassName = "MyWindow"; 273 | WndClass.lpfnWndProc = WndProc; 274 | // 注册窗口类 275 | My_RegisterClassExA(&WndClass); 276 | HWND hWnd = My_CreateWindowExA(0, "MyWindow", "Hello", WS_OVERLAPPEDWINDOW, 277 | 100, 100, 250, 250, NULL, NULL, 278 | (HINSTANCE)GetImageBase(), NULL); 279 | // 显示更新 280 | My_ShowWindow(hWnd, SW_SHOW); 281 | My_UpdateWindow(hWnd); 282 | // 消息循环 283 | MSG msg = {}; //消息 284 | while (My_GetMessageA(&msg, 0, 0, 0)) 285 | { 286 | // 转换消息 分发消息 287 | My_TranslateMessage(&msg); 288 | My_DispatchMessageA(&msg); 289 | } 290 | } 291 | 292 | //****************************************************************************** 293 | // 函数名称: UnPackSection 294 | // 函数说明: 解压代码段 295 | // 作 者: lracker 296 | // 时 间: 2019/12/10 297 | // 参 数: LPCSTR SectionName 298 | // 参 数: DWORD * DllBase 299 | // 返 回 值: CHAR* 300 | //****************************************************************************** 301 | VOID UnPackSection(LPCSTR SectionName, DWORD* DllBase) 302 | { 303 | // 修改属性 304 | DWORD dwOldProtect = 0; 305 | My_VirtualProtect((LPVOID)(ShareData.dwRVA + (DWORD)DllBase), ShareData.nSrcSize, PAGE_READWRITE, &dwOldProtect); 306 | CHAR* Data = (CHAR*)(ShareData.dwSectionRVA + (DWORD)DllBase); 307 | // 申请空间 308 | HHeapCreate HeapCreate = (HHeapCreate)My_GetProcAddress((HMODULE)GetKernel32(), "HeapCreate"); 309 | HANDLE hHeap = HeapCreate(0, 0, 0); 310 | LPHeapAlloc lpHeapAlloc = (LPHeapAlloc)My_GetProcAddress((HMODULE)GetKernel32(), "HeapAlloc"); 311 | CHAR* pBuff = (CHAR*)lpHeapAlloc(hHeap, HEAP_ZERO_MEMORY, ShareData.nSrcSize); 312 | // 解压 313 | LZ4_uncompress_unknownOutputSize(Data, pBuff, ShareData.nDestSize, ShareData.nSrcSize); 314 | memcpy(Data, pBuff, ShareData.nSrcSize); 315 | My_VirtualProtect((LPVOID)(ShareData.dwRVA + (DWORD)DllBase), ShareData.nSrcSize, dwOldProtect, &dwOldProtect); 316 | // 释放掉空间 317 | BHeapFree bHeapFree = (BHeapFree)My_GetProcAddress((HMODULE)GetKernel32(), "HeapFree"); 318 | bHeapFree(hHeap, 0, pBuff); 319 | } 320 | 321 | //****************************************************************************** 322 | // 函数名称: FixIAT 323 | // 函数说明: 修复IAT表 324 | // 作 者: lracker 325 | // 时 间: 2019/12/12 326 | // 返 回 值: VOID 327 | //****************************************************************************** 328 | //00FE12B2 | 50 | push eax | 329 | //00FE12B3 | 58 | pop eax | push eip; jmp xxxxxxxxx 330 | //00FE12B4 | 60 | pushad | 331 | //00FE12B5 | 61 | popad | 332 | //00FE12B6 | B8 11111111 | mov eax, 11111111 | 333 | //00FE12BB | FFE0 | jmp eax | 334 | VOID FixIAT() 335 | { 336 | char ShellCode[] = { "\x50\x58\x60\x61\xB8\x11\x11\x11\x11\xFF\xE0" }; 337 | PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(ShareData.dwOldImportRVA + (DWORD)GetImageBase()); 338 | // 遍历导入表 339 | while (pImport->Name) 340 | { 341 | char* DllName = (char*)(pImport->Name + (DWORD)GetImageBase()); 342 | // 加载当前DLL 343 | HMODULE MoDule = My_LoadLibraryA(DllName); 344 | DWORD* pInt = (DWORD*)(pImport->OriginalFirstThunk + (DWORD)GetImageBase()); 345 | DWORD* pIat = (DWORD*)(pImport->FirstThunk + (DWORD)GetImageBase()); 346 | while (*pInt) 347 | { 348 | // 保存真正的函数地址 349 | LPVOID Fun; 350 | // 导入的函数是序号还是名称 351 | if (*pInt & 0x80000000) 352 | { 353 | DWORD Order = (*pIat) & 0xFFFF; 354 | Fun = My_GetProcAddress(MoDule, (char*)Order); 355 | } 356 | else 357 | { 358 | PIMAGE_IMPORT_BY_NAME FunName = (PIMAGE_IMPORT_BY_NAME)(*pInt + (DWORD)GetImageBase()); 359 | Fun = My_GetProcAddress(MoDule, (char*)FunName->Name); 360 | } 361 | // 申请空间 362 | char* pBuff = (char*)My_VirtualAlloc(0, 100, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 363 | // 拷贝shellcode 364 | memcpy(pBuff, ShellCode, sizeof(ShellCode)); 365 | // 写入真正的函数 366 | *(DWORD*)&pBuff[5] = (DWORD)Fun; 367 | // 修改IAT表中的函数地址,需要权限 368 | DWORD dwOld = 0; 369 | My_VirtualProtect(pIat, 4, PAGE_EXECUTE_READWRITE, &dwOld); 370 | // 填充IAT 371 | *pIat = (DWORD)pBuff; 372 | My_VirtualProtect(pIat, 4, dwOld, &dwOld); 373 | pInt++; 374 | pIat++; 375 | } 376 | pImport++; 377 | } 378 | } 379 | 380 | //****************************************************************************** 381 | // 函数名称: FixFileReloc 382 | // 函数说明: 修复文件内的重定位 383 | // 作 者: lracker 384 | // 时 间: 2019/12/11 385 | // 返 回 值: VOID 386 | //****************************************************************************** 387 | VOID FixFileReloc() 388 | { 389 | DWORD dwBase = GetImageBase(); 390 | DWORD dwSize = 0, dwOldProtect = 0; 391 | // 获取到程序的重定位表 392 | PIMAGE_BASE_RELOCATION RelocTable = (PIMAGE_BASE_RELOCATION)(ShareData.dwRelocRVA + dwBase); 393 | // 如果SizeOfBlock不为空,则说明存在重定位块 394 | while (RelocTable->SizeOfBlock) 395 | { 396 | // 如果重定位的数据在代码段,就需要修改访问属性 397 | My_VirtualProtect((LPVOID)(RelocTable->VirtualAddress + dwBase), 0x2000, PAGE_EXECUTE_READWRITE, &dwOldProtect); 398 | int nCount = (RelocTable->SizeOfBlock - 8) / 2; 399 | TypeOffset* to = (TypeOffset*)(RelocTable + 1); 400 | for (int i = 0; i < nCount; ++i) 401 | { 402 | // 如果type的值为3,则需要重定位 403 | if (to[i].Type == 3) 404 | { 405 | // 获取到需要重定位的地址所在的位置 406 | DWORD* addr = (DWORD*)(dwBase + RelocTable->VirtualAddress + to[i].Offset); 407 | // 计算重定位后的地址 408 | *addr = *addr - ShareData.dwFileImageBase + dwBase; 409 | } 410 | } 411 | // 还原区段的保护属性 412 | // My_VirtualProtect((LPVOID)(RelocTable->VirtualAddress + dwBase), 0x2000, dwOldProtect, &dwOldProtect); 413 | // 找到下一个重定位块 414 | RelocTable = (PIMAGE_BASE_RELOCATION)((DWORD)RelocTable + RelocTable->SizeOfBlock); 415 | } 416 | } 417 | 418 | //****************************************************************************** 419 | // 函数名称: SetTls 420 | // 函数说明: 设置TLS 421 | // 作 者: lracker 422 | // 时 间: 2019/12/12 423 | // 返 回 值: VOID 424 | //****************************************************************************** 425 | VOID SetTls() 426 | { 427 | DWORD dwBase = GetImageBase(); 428 | PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)dwBase; 429 | PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + dwBase); 430 | PIMAGE_OPTIONAL_HEADER32 pOpt = (PIMAGE_OPTIONAL_HEADER32)&pNt->OptionalHeader; 431 | if (ShareData.bTLSEnable == TRUE) 432 | { 433 | // 将TLS回调函数指针设置回去 434 | DWORD dwRVA = pOpt->DataDirectory[9].VirtualAddress; 435 | PIMAGE_TLS_DIRECTORY pTlsDir = (PIMAGE_TLS_DIRECTORY)(dwRVA + dwBase); 436 | pTlsDir->AddressOfCallBacks = ShareData.pOldTls.AddressOfCallBacks; 437 | PIMAGE_TLS_CALLBACK* lpTlsFun = (PIMAGE_TLS_CALLBACK*)(ShareData.pOldTls.AddressOfCallBacks - ShareData.dwFileImageBase + dwBase); 438 | while ((*lpTlsFun) != NULL) 439 | { 440 | (*lpTlsFun)((PVOID)dwBase, DLL_THREAD_ATTACH, NULL); 441 | lpTlsFun++; 442 | } 443 | } 444 | } 445 | 446 | // 下面是虚拟机壳的 447 | // push 0x12345678 push一个4字节的数 448 | #define vPushData 0x10 449 | // call 0x12345678 call一个4字节的地址 450 | #define vCall 0x12 451 | // 结束符 452 | #define vEnd 0xff 453 | char* str = (char*)"这是虚拟机"; 454 | /* 455 | 这是我们构造的虚拟指令 456 | push 0 457 | push offset str 458 | push offset str 459 | push 0 460 | call MessageBoxA 461 | */ 462 | BYTE g_bVmData[] = { 463 | vPushData,0x00,0x00,0x00,0x00, 464 | vPushData,0x00,0x00,0x00,0x00, 465 | vPushData,0x00,0x00,0x00,0x00, 466 | vPushData,0x00,0x00,0x00,0x00, 467 | vCall,0x00,0x00,0x00,0x00, 468 | vEnd 469 | }; 470 | // 简单的虚拟引擎 471 | _declspec(naked) void VM(PVOID pvmData) 472 | { 473 | __asm 474 | { 475 | push ebp; 476 | mov ebp, esp; 477 | sub esp, 0x64; 478 | // 取vCode地址放入ecx 479 | mov ecx, dword ptr ss : [ebp + 8] ; 480 | __vStart: 481 | // 取第一个字节到al中 482 | mov al, byte ptr ds : [ecx] ; 483 | cmp al, vPushData; 484 | je __vPushData; 485 | cmp al, vCall; 486 | je __vCall; 487 | cmp al, vEnd; 488 | je __vEnd; 489 | int 3; 490 | __vPushData: 491 | inc ecx; 492 | mov edx, dword ptr ds : [ecx] ; 493 | push edx; 494 | add ecx, 4; 495 | jmp __vStart; 496 | __vCall: 497 | inc ecx; 498 | mov edx, dword ptr ds : [ecx] ; 499 | //保存ecx的值 500 | mov dword ptr ds : [ebp + 0x10] , ecx 501 | call edx; 502 | //返回ecx的值 503 | mov ecx, dword ptr ds : [ebp + 0x10] 504 | add ecx, 4; 505 | jmp __vstart; 506 | __vEnd: 507 | //平衡堆栈 508 | add esp, 0x64 509 | pop ebp 510 | ret; 511 | } 512 | } 513 | VOID VMStart() 514 | { 515 | //修改虚拟指令的数据 516 | 517 | *(DWORD*)(g_bVmData + 5 + 1) = (DWORD)str; 518 | *(DWORD*)(g_bVmData + 10 + 1) = (DWORD)str; 519 | *(DWORD*)(g_bVmData + 20 + 1) = (DWORD)My_MessageBoxA; 520 | 521 | //执行虚拟指令 522 | VM(g_bVmData); 523 | } 524 | 525 | //****************************************************************************** 526 | // 函数名称: CheckProcessDebugPort 527 | // 函数说明: 检查端口是否被调试了 528 | // 作 者: lracker 529 | // 时 间: 2019/12/13 530 | // 返 回 值: BOOL 531 | //****************************************************************************** 532 | BOOL CheckProcessDebugPort() 533 | { 534 | int nDebugPort = 0; 535 | pNtQueryInformationProcess(My_GetCurrentProcess(), (PROCESSINFOCLASS)ProcessDebugPort, &nDebugPort, sizeof(nDebugPort), NULL); 536 | return nDebugPort == 0xFFFFFFFF ? true : false; 537 | } 538 | 539 | //****************************************************************************** 540 | // 函数名称: AntiDebug 541 | // 函数说明: 反调试 542 | // 作 者: lracker 543 | // 时 间: 2019/12/13 544 | // 返 回 值: VOID 545 | //****************************************************************************** 546 | VOID AntiDebug() 547 | { 548 | if (CheckProcessDebugPort()) 549 | { 550 | My_MessageBoxA(0, "正在被调试", 0, 0); 551 | My_ExitProcess(0); 552 | } 553 | 554 | } 555 | __declspec(dllexport) __declspec(naked) void start() 556 | { 557 | g_num; 558 | __asm 559 | { 560 | xor eax, eax; 561 | TEST eax, eax; 562 | jz _Start; 563 | jnz _Start; 564 | __emit(0xE8); 565 | 566 | _Start: 567 | xor eax, 3; 568 | add eax, 4; 569 | xor eax, 5; 570 | } 571 | 572 | // 获取需要的API 573 | GetApi(); 574 | // 虚拟机的代码 575 | VMStart(); 576 | // 反调试 577 | // AntiDebug(); 578 | // 弹窗 579 | Enter(); 580 | // 解密咱们的代码段 581 | Decry(); 582 | // 解压代码 583 | UnPackSection(".text", (DWORD*)GetImageBase()); 584 | // 修复文件的重定位 585 | FixFileReloc(); 586 | // 修复IAT 587 | FixIAT(); 588 | // 设置TLS 589 | // SetTls(); 590 | // 跳回到原始OEP 591 | JmpOEP(); 592 | } 593 | } -------------------------------------------------------------------------------- /MyStub/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 4 | // Windows 头文件 5 | #include 6 | -------------------------------------------------------------------------------- /MyStub/lz4.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | /* 3 | LZ4 - Fast LZ compression algorithm 4 | Copyright (C) 2011-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 source repository : http://code.google.com/p/lz4/ 32 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 33 | */ 34 | 35 | /************************************** 36 | Tuning parameters 37 | **************************************/ 38 | /* 39 | * MEMORY_USAGE : 40 | * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 41 | * Increasing memory usage improves compression ratio 42 | * Reduced memory usage can improve speed, due to cache effect 43 | * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 44 | */ 45 | #define MEMORY_USAGE 14 46 | 47 | /* 48 | * HEAPMODE : 49 | * Select how default compression functions will allocate memory for their hash table, 50 | * in memory stack (0:default, fastest), or in memory heap (1:requires memory allocation (malloc)). 51 | */ 52 | #define HEAPMODE 0 53 | 54 | 55 | /************************************** 56 | CPU Feature Detection 57 | **************************************/ 58 | /* 32 or 64 bits ? */ 59 | #if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \ 60 | || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ 61 | || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \ 62 | || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) /* Detects 64 bits mode */ 63 | # define LZ4_ARCH64 1 64 | #else 65 | # define LZ4_ARCH64 0 66 | #endif 67 | 68 | /* 69 | * Little Endian or Big Endian ? 70 | * Overwrite the #define below if you know your architecture endianess 71 | */ 72 | #if defined (__GLIBC__) 73 | # include 74 | # if (__BYTE_ORDER == __BIG_ENDIAN) 75 | # define LZ4_BIG_ENDIAN 1 76 | # endif 77 | #elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) 78 | # define LZ4_BIG_ENDIAN 1 79 | #elif defined(__sparc) || defined(__sparc__) \ 80 | || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \ 81 | || defined(__hpux) || defined(__hppa) \ 82 | || defined(_MIPSEB) || defined(__s390__) 83 | # define LZ4_BIG_ENDIAN 1 84 | #else 85 | /* Little Endian assumed. PDP Endian and other very rare endian format are unsupported. */ 86 | #endif 87 | 88 | /* 89 | * Unaligned memory access is automatically enabled for "common" CPU, such as x86. 90 | * For others CPU, such as ARM, the compiler may be more cautious, inserting unnecessary extra code to ensure aligned access property 91 | * If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance 92 | */ 93 | #if defined(__ARM_FEATURE_UNALIGNED) 94 | # define LZ4_FORCE_UNALIGNED_ACCESS 1 95 | #endif 96 | 97 | /* Define this parameter if your target system or compiler does not support hardware bit count */ 98 | #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ 99 | # define LZ4_FORCE_SW_BITCOUNT 100 | #endif 101 | 102 | /* 103 | * BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE : 104 | * This option may provide a small boost to performance for some big endian cpu, although probably modest. 105 | * You may set this option to 1 if data will remain within closed environment. 106 | * This option is useless on Little_Endian CPU (such as x86) 107 | */ 108 | 109 | /* #define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 */ 110 | 111 | 112 | /************************************** 113 | Compiler Options 114 | **************************************/ 115 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ 116 | /* "restrict" is a known keyword */ 117 | #else 118 | # define restrict /* Disable restrict */ 119 | #endif 120 | 121 | #ifdef _MSC_VER /* Visual Studio */ 122 | # define FORCE_INLINE static __forceinline 123 | # include /* For Visual 2005 */ 124 | # if LZ4_ARCH64 /* 64-bits */ 125 | # pragma intrinsic(_BitScanForward64) /* For Visual 2005 */ 126 | # pragma intrinsic(_BitScanReverse64) /* For Visual 2005 */ 127 | # else /* 32-bits */ 128 | # pragma intrinsic(_BitScanForward) /* For Visual 2005 */ 129 | # pragma intrinsic(_BitScanReverse) /* For Visual 2005 */ 130 | # endif 131 | # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 132 | #else 133 | # ifdef __GNUC__ 134 | # define FORCE_INLINE static inline __attribute__((always_inline)) 135 | # else 136 | # define FORCE_INLINE static inline 137 | # endif 138 | #endif 139 | 140 | #ifdef _MSC_VER /* Visual Studio */ 141 | # define lz4_bswap16(x) _byteswap_ushort(x) 142 | #else 143 | # define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) 144 | #endif 145 | 146 | #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 147 | 148 | #if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) 149 | # define expect(expr,value) (__builtin_expect ((expr),(value)) ) 150 | #else 151 | # define expect(expr,value) (expr) 152 | #endif 153 | 154 | #define likely(expr) expect((expr) != 0, 1) 155 | #define unlikely(expr) expect((expr) != 0, 0) 156 | 157 | 158 | /************************************** 159 | Memory routines 160 | **************************************/ 161 | #include /* malloc, calloc, free */ 162 | #define ALLOCATOR(n,s) calloc(n,s) 163 | #define FREEMEM free 164 | #include /* memset, memcpy */ 165 | #define MEM_INIT memset 166 | 167 | 168 | /************************************** 169 | Includes 170 | **************************************/ 171 | #include "lz4.h" 172 | 173 | 174 | /************************************** 175 | Basic Types 176 | **************************************/ 177 | #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ 178 | # include 179 | typedef uint8_t BYTE; 180 | typedef uint16_t U16; 181 | typedef uint32_t U32; 182 | typedef int32_t S32; 183 | typedef uint64_t U64; 184 | #else 185 | typedef unsigned char BYTE; 186 | typedef unsigned short U16; 187 | typedef unsigned int U32; 188 | typedef signed int S32; 189 | typedef unsigned long long U64; 190 | #endif 191 | 192 | #if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS) 193 | # define _PACKED __attribute__ ((packed)) 194 | #else 195 | # define _PACKED 196 | #endif 197 | 198 | #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) 199 | # if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) 200 | # pragma pack(1) 201 | # else 202 | # pragma pack(push, 1) 203 | # endif 204 | #endif 205 | 206 | typedef struct { U16 v; } _PACKED U16_S; 207 | typedef struct { U32 v; } _PACKED U32_S; 208 | typedef struct { U64 v; } _PACKED U64_S; 209 | typedef struct {size_t v;} _PACKED size_t_S; 210 | 211 | #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) 212 | # if defined(__SUNPRO_C) || defined(__SUNPRO_CC) 213 | # pragma pack(0) 214 | # else 215 | # pragma pack(pop) 216 | # endif 217 | #endif 218 | 219 | #define A16(x) (((U16_S *)(x))->v) 220 | #define A32(x) (((U32_S *)(x))->v) 221 | #define A64(x) (((U64_S *)(x))->v) 222 | #define AARCH(x) (((size_t_S *)(x))->v) 223 | 224 | 225 | /************************************** 226 | Constants 227 | **************************************/ 228 | #define LZ4_HASHLOG (MEMORY_USAGE-2) 229 | #define HASHTABLESIZE (1 << MEMORY_USAGE) 230 | #define HASHNBCELLS4 (1 << LZ4_HASHLOG) 231 | 232 | #define MINMATCH 4 233 | 234 | #define COPYLENGTH 8 235 | #define LASTLITERALS 5 236 | #define MFLIMIT (COPYLENGTH+MINMATCH) 237 | static const int LZ4_minLength = (MFLIMIT+1); 238 | 239 | #define KB *(1U<<10) 240 | #define MB *(1U<<20) 241 | #define GB *(1U<<30) 242 | 243 | #define LZ4_64KLIMIT ((64 KB) + (MFLIMIT-1)) 244 | #define SKIPSTRENGTH 6 /* Increasing this value will make the compression run slower on incompressible data */ 245 | 246 | #define MAXD_LOG 16 247 | #define MAX_DISTANCE ((1 << MAXD_LOG) - 1) 248 | 249 | #define ML_BITS 4 250 | #define ML_MASK ((1U<=e; */ 295 | #else 296 | # define LZ4_WILDCOPY(d,s,e) { if (likely(e-d <= 8)) LZ4_COPY8(d,s) else do { LZ4_COPY8(d,s) } while (d>3); 313 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 314 | return (__builtin_clzll(val) >> 3); 315 | # else 316 | int r; 317 | if (!(val>>32)) { r=4; } else { r=0; val>>=32; } 318 | if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } 319 | r += (!val); 320 | return r; 321 | # endif 322 | # else 323 | # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 324 | unsigned long r = 0; 325 | _BitScanForward64( &r, val ); 326 | return (int)(r>>3); 327 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 328 | return (__builtin_ctzll(val) >> 3); 329 | # else 330 | static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; 331 | return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; 332 | # endif 333 | # endif 334 | } 335 | 336 | #else 337 | 338 | FORCE_INLINE int LZ4_NbCommonBytes (register U32 val) 339 | { 340 | # if defined(LZ4_BIG_ENDIAN) 341 | # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 342 | unsigned long r = 0; 343 | _BitScanReverse( &r, val ); 344 | return (int)(r>>3); 345 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 346 | return (__builtin_clz(val) >> 3); 347 | # else 348 | int r; 349 | if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } 350 | r += (!val); 351 | return r; 352 | # endif 353 | # else 354 | # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 355 | unsigned long r; 356 | _BitScanForward( &r, val ); 357 | return (int)(r>>3); 358 | # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) 359 | return (__builtin_ctz(val) >> 3); 360 | # else 361 | static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; 362 | return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; 363 | # endif 364 | # endif 365 | } 366 | 367 | #endif 368 | 369 | 370 | /**************************** 371 | Compression functions 372 | ****************************/ 373 | int LZ4API LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } 374 | 375 | FORCE_INLINE int LZ4_hashSequence(U32 sequence, tableType_t tableType) 376 | { 377 | if (tableType == byU16) 378 | return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); 379 | else 380 | return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); 381 | } 382 | 383 | FORCE_INLINE int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); } 384 | 385 | FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) 386 | { 387 | switch (tableType) 388 | { 389 | case byPtr: { const BYTE** hashTable = (const BYTE**) tableBase; hashTable[h] = p; break; } 390 | case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); break; } 391 | case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); break; } 392 | } 393 | } 394 | 395 | FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) 396 | { 397 | U32 h = LZ4_hashPosition(p, tableType); 398 | LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); 399 | } 400 | 401 | FORCE_INLINE const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) 402 | { 403 | if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } 404 | if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } 405 | { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ 406 | } 407 | 408 | FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) 409 | { 410 | U32 h = LZ4_hashPosition(p, tableType); 411 | return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); 412 | } 413 | 414 | 415 | FORCE_INLINE int LZ4_compress_generic( 416 | void* ctx, 417 | const char* source, 418 | char* dest, 419 | int inputSize, 420 | int maxOutputSize, 421 | 422 | limitedOutput_directive limitedOutput, 423 | tableType_t tableType, 424 | prefix64k_directive prefix) 425 | { 426 | const BYTE* ip = (const BYTE*) source; 427 | const BYTE* const base = (prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->base : (const BYTE*) source; 428 | const BYTE* const lowLimit = ((prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->bufferStart : (const BYTE*)source); 429 | const BYTE* anchor = (const BYTE*) source; 430 | const BYTE* const iend = ip + inputSize; 431 | const BYTE* const mflimit = iend - MFLIMIT; 432 | const BYTE* const matchlimit = iend - LASTLITERALS; 433 | 434 | BYTE* op = (BYTE*) dest; 435 | BYTE* const oend = op + maxOutputSize; 436 | 437 | int length; 438 | const int skipStrength = SKIPSTRENGTH; 439 | U32 forwardH; 440 | 441 | /* Init conditions */ 442 | if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ 443 | if ((prefix==withPrefix) && (ip != ((LZ4_Data_Structure*)ctx)->nextBlock)) return 0; /* must continue from end of previous block */ 444 | if (prefix==withPrefix) ((LZ4_Data_Structure*)ctx)->nextBlock=iend; /* do it now, due to potential early exit */ 445 | if ((tableType == byU16) && (inputSize>=(int)LZ4_64KLIMIT)) return 0; /* Size too large (not within 64K limit) */ 446 | if (inputSize> skipStrength; 464 | ip = forwardIp; 465 | forwardIp = ip + step; 466 | 467 | if (unlikely(forwardIp > mflimit)) { goto _last_literals; } 468 | 469 | forwardH = LZ4_hashPosition(forwardIp, tableType); 470 | ref = LZ4_getPositionOnHash(h, ctx, tableType, base); 471 | LZ4_putPositionOnHash(ip, h, ctx, tableType, base); 472 | 473 | } while ((ref + MAX_DISTANCE < ip) || (A32(ref) != A32(ip))); 474 | 475 | /* Catch up */ 476 | while ((ip>anchor) && (ref > lowLimit) && (unlikely(ip[-1]==ref[-1]))) { ip--; ref--; } 477 | 478 | /* Encode Literal length */ 479 | length = (int)(ip - anchor); 480 | token = op++; 481 | if ((limitedOutput) && (unlikely(op + length + (2 + 1 + LASTLITERALS) + (length/255) > oend))) return 0; /* Check output limit */ 482 | if (length>=(int)RUN_MASK) 483 | { 484 | int len = length-RUN_MASK; 485 | *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; 487 | *op++ = (BYTE)len; 488 | } 489 | else *token = (BYTE)(length<>8) > oend))) return 0; /* Check output limit */ 516 | if (length>=(int)ML_MASK) 517 | { 518 | *token += ML_MASK; 519 | length -= ML_MASK; 520 | for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; } 521 | if (length >= 255) { length-=255; *op++ = 255; } 522 | *op++ = (BYTE)length; 523 | } 524 | else *token += (BYTE)(length); 525 | 526 | /* Test end of chunk */ 527 | if (ip > mflimit) { anchor = ip; break; } 528 | 529 | /* Fill table */ 530 | LZ4_putPosition(ip-2, ctx, tableType, base); 531 | 532 | /* Test next position */ 533 | ref = LZ4_getPosition(ip, ctx, tableType, base); 534 | LZ4_putPosition(ip, ctx, tableType, base); 535 | if ((ref + MAX_DISTANCE >= ip) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; } 536 | 537 | /* Prepare next loop */ 538 | anchor = ip++; 539 | forwardH = LZ4_hashPosition(ip, tableType); 540 | } 541 | 542 | _last_literals: 543 | /* Encode Last Literals */ 544 | { 545 | int lastRun = (int)(iend - anchor); 546 | if ((limitedOutput) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ 547 | if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 548 | else *op++ = (BYTE)(lastRun<hashTable, 0, sizeof(lz4ds->hashTable)); 642 | lz4ds->bufferStart = base; 643 | lz4ds->base = base; 644 | lz4ds->nextBlock = base; 645 | } 646 | 647 | int LZ4API LZ4_resetStreamState(void* state, const char* inputBuffer) 648 | { 649 | if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ 650 | LZ4_init((LZ4_Data_Structure*)state, (const BYTE*)inputBuffer); 651 | return 0; 652 | } 653 | 654 | void* LZ4API LZ4_create (const char* inputBuffer) 655 | { 656 | void* lz4ds = ALLOCATOR(1, sizeof(LZ4_Data_Structure)); 657 | LZ4_init ((LZ4_Data_Structure*)lz4ds, (const BYTE*)inputBuffer); 658 | return lz4ds; 659 | } 660 | 661 | 662 | int LZ4API LZ4_free (void* LZ4_Data) 663 | { 664 | FREEMEM(LZ4_Data); 665 | return (0); 666 | } 667 | 668 | 669 | char* LZ4API LZ4_slideInputBuffer (void* LZ4_Data) 670 | { 671 | LZ4_Data_Structure* lz4ds = (LZ4_Data_Structure*)LZ4_Data; 672 | size_t delta = lz4ds->nextBlock - (lz4ds->bufferStart + 64 KB); 673 | 674 | if ( (lz4ds->base - delta > lz4ds->base) /* underflow control */ 675 | || ((size_t)(lz4ds->nextBlock - lz4ds->base) > 0xE0000000) ) /* close to 32-bits limit */ 676 | { 677 | size_t deltaLimit = (lz4ds->nextBlock - 64 KB) - lz4ds->base; 678 | int nH; 679 | 680 | for (nH=0; nH < HASHNBCELLS4; nH++) 681 | { 682 | if ((size_t)(lz4ds->hashTable[nH]) < deltaLimit) lz4ds->hashTable[nH] = 0; 683 | else lz4ds->hashTable[nH] -= (U32)deltaLimit; 684 | } 685 | memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); 686 | lz4ds->base = lz4ds->bufferStart; 687 | lz4ds->nextBlock = lz4ds->base + 64 KB; 688 | } 689 | else 690 | { 691 | memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); 692 | lz4ds->nextBlock -= delta; 693 | lz4ds->base -= delta; 694 | } 695 | 696 | return (char*)(lz4ds->nextBlock); 697 | } 698 | 699 | 700 | int LZ4API LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize) 701 | { 702 | return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, 0, notLimited, byU32, withPrefix); 703 | } 704 | 705 | 706 | int LZ4API LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize) 707 | { 708 | return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, maxOutputSize, limited, byU32, withPrefix); 709 | } 710 | 711 | 712 | /**************************** 713 | Decompression functions 714 | ****************************/ 715 | /* 716 | * This generic decompression function cover all use cases. 717 | * It shall be instanciated several times, using different sets of directives 718 | * Note that it is essential this generic function is really inlined, 719 | * in order to remove useless branches during compilation optimisation. 720 | */ 721 | FORCE_INLINE int LZ4_decompress_generic( 722 | const char* source, 723 | char* dest, 724 | int inputSize, 725 | int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ 726 | 727 | int endOnInput, /* endOnOutputSize, endOnInputSize */ 728 | int prefix64k, /* noPrefix, withPrefix */ 729 | int partialDecoding, /* full, partial */ 730 | int targetOutputSize /* only used if partialDecoding==partial */ 731 | ) 732 | { 733 | /* Local Variables */ 734 | const BYTE* restrict ip = (const BYTE*) source; 735 | const BYTE* ref; 736 | const BYTE* const iend = ip + inputSize; 737 | 738 | BYTE* op = (BYTE*) dest; 739 | BYTE* const oend = op + outputSize; 740 | BYTE* cpy; 741 | BYTE* oexit = op + targetOutputSize; 742 | 743 | /*const size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; / static reduces speed for LZ4_decompress_safe() on GCC64 */ 744 | const size_t dec32table[] = {4-0, 4-3, 4-2, 4-3, 4-0, 4-0, 4-0, 4-0}; /* static reduces speed for LZ4_decompress_safe() on GCC64 */ 745 | static const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; 746 | 747 | 748 | /* Special cases */ 749 | if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ 750 | if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ 751 | if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); 752 | 753 | 754 | /* Main Loop */ 755 | while (1) 756 | { 757 | unsigned token; 758 | size_t length; 759 | 760 | /* get runlength */ 761 | token = *ip++; 762 | if ((length=(token>>ML_BITS)) == RUN_MASK) 763 | { 764 | unsigned s=255; 765 | while (((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) 775 | || ((!endOnInput) && (cpy>oend-COPYLENGTH))) 776 | { 777 | if (partialDecoding) 778 | { 779 | if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ 780 | if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ 781 | } 782 | else 783 | { 784 | if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ 785 | if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ 786 | } 787 | memcpy(op, ip, length); 788 | ip += length; 789 | op += length; 790 | break; /* Necessarily EOF, due to parsing restrictions */ 791 | } 792 | LZ4_WILDCOPY(op, ip, cpy); ip -= (op-cpy); op = cpy; 793 | 794 | /* get offset */ 795 | LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2; 796 | if ((prefix64k==noPrefix) && (unlikely(ref < (BYTE* const)dest))) goto _output_error; /* Error : offset outside destination buffer */ 797 | 798 | /* get matchlength */ 799 | if ((length=(token&ML_MASK)) == ML_MASK) 800 | { 801 | while ((!endOnInput) || (ipoend-COPYLENGTH-(STEPSIZE-4))) 828 | { 829 | if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last 5 bytes must be literals */ 830 | LZ4_SECURECOPY(op, ref, (oend-COPYLENGTH)); 831 | while(op (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) 94 | 95 | /* 96 | LZ4_compressBound() : 97 | Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible) 98 | primarily useful for memory allocation of output buffer. 99 | inline function is recommended for the general case, 100 | macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation). 101 | 102 | isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE 103 | return : maximum output size in a "worst case" scenario 104 | or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) 105 | */ 106 | int LZ4API LZ4_compressBound(int isize); 107 | 108 | 109 | /* 110 | LZ4_compress_limitedOutput() : 111 | Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. 112 | If it cannot achieve it, compression will stop, and result of the function will be zero. 113 | This function never writes outside of provided output buffer. 114 | 115 | inputSize : Max supported value is LZ4_MAX_INPUT_VALUE 116 | maxOutputSize : is the size of the destination buffer (which must be already allocated) 117 | return : the number of bytes written in buffer 'dest' 118 | or 0 if the compression fails 119 | */ 120 | int LZ4API LZ4_compress_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); 121 | 122 | 123 | /* 124 | LZ4_decompress_fast() : 125 | originalSize : is the original and therefore uncompressed size 126 | return : the number of bytes read from the source buffer (in other words, the compressed size) 127 | If the source stream is malformed, the function will stop decoding and return a negative result. 128 | note : This function is a bit faster than LZ4_decompress_safe() 129 | This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet. 130 | Use this function preferably into a trusted environment (data to decode comes from a trusted source). 131 | Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. 132 | */ 133 | int LZ4API LZ4_decompress_fast (const char* source, char* dest, int originalSize); 134 | 135 | 136 | /* 137 | LZ4_decompress_safe_partial() : 138 | This function decompress a compressed block of size 'inputSize' at position 'source' 139 | into output buffer 'dest' of size 'maxOutputSize'. 140 | The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, 141 | reducing decompression time. 142 | return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) 143 | Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. 144 | Always control how many bytes were decoded. 145 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 146 | This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets 147 | */ 148 | int LZ4API LZ4_decompress_safe_partial (const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); 149 | 150 | 151 | /* 152 | These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. 153 | To know how much memory must be allocated for the compression tables, use : 154 | int LZ4_sizeofState(); 155 | 156 | Note that tables must be aligned on 4-bytes boundaries, otherwise compression will fail (return code 0). 157 | 158 | The allocated memory can be provided to the compressions functions using 'void* state' parameter. 159 | LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. 160 | They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). 161 | */ 162 | int LZ4API LZ4_sizeofState(void); 163 | int LZ4API LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); 164 | int LZ4API LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 165 | 166 | 167 | /************************************** 168 | Streaming Functions 169 | **************************************/ 170 | void* LZ4API LZ4_create (const char* inputBuffer); 171 | int LZ4API LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize); 172 | int LZ4API LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); 173 | char* LZ4API LZ4_slideInputBuffer (void* LZ4_Data); 174 | int LZ4API LZ4_free (void* LZ4_Data); 175 | 176 | /* 177 | These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. 178 | In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function : 179 | 180 | void* LZ4_create (const char* inputBuffer); 181 | The result of the function is the (void*) pointer on the LZ4 Data Structure. 182 | This pointer will be needed in all other functions. 183 | If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. 184 | The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. 185 | The input buffer must be already allocated, and size at least 192KB. 186 | 'inputBuffer' will also be the 'const char* source' of the first block. 187 | 188 | All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. 189 | To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(). 190 | Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(), 191 | but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one. 192 | If next block does not begin immediately after the previous one, the compression will fail (return 0). 193 | 194 | When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : 195 | char* LZ4_slideInputBuffer(void* LZ4_Data); 196 | must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. 197 | Note that, for this function to work properly, minimum size of an input buffer must be 192KB. 198 | ==> The memory position where the next input data block must start is provided as the result of the function. 199 | 200 | Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual. 201 | 202 | When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure. 203 | */ 204 | 205 | 206 | int LZ4API LZ4_sizeofStreamState(void); 207 | int LZ4API LZ4_resetStreamState(void* state, const char* inputBuffer); 208 | 209 | /* 210 | These functions achieve the same result as : 211 | void* LZ4_create (const char* inputBuffer); 212 | 213 | They are provided here to allow the user program to allocate memory using its own routines. 214 | 215 | To know how much space must be allocated, use LZ4_sizeofStreamState(); 216 | Note also that space must be 4-bytes aligned. 217 | 218 | Once space is allocated, you must initialize it using : LZ4_resetStreamState(void* state, const char* inputBuffer); 219 | void* state is a pointer to the space allocated. 220 | It must be aligned on 4-bytes boundaries, and be large enough. 221 | The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. 222 | The input buffer must be already allocated, and size at least 192KB. 223 | 'inputBuffer' will also be the 'const char* source' of the first block. 224 | 225 | The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). 226 | return value of LZ4_resetStreamState() must be 0 is OK. 227 | Any other value means there was an error (typically, pointer is not aligned on 4-bytes boundaries). 228 | */ 229 | 230 | 231 | int LZ4API LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int inputSize, int maxOutputSize); 232 | int LZ4API LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int outputSize); 233 | 234 | /* 235 | *_withPrefix64k() : 236 | These decoding functions work the same as their "normal name" versions, 237 | but can use up to 64KB of data in front of 'char* dest'. 238 | These functions are necessary to decode inter-dependant blocks. 239 | */ 240 | 241 | 242 | /************************************** 243 | Obsolete Functions 244 | **************************************/ 245 | /* 246 | These functions are deprecated and should no longer be used. 247 | They are provided here for compatibility with existing user programs. 248 | */ 249 | int LZ4API LZ4_uncompress (const char* source, char* dest, int outputSize); 250 | int LZ4API LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); 251 | 252 | 253 | #if defined (__cplusplus) 254 | } 255 | #endif 256 | -------------------------------------------------------------------------------- /MyStub/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: 与预编译标头对应的源文件 2 | 3 | #include "pch.h" 4 | 5 | // 当使用预编译的头时,需要使用此源文件,编译才能成功。 6 | -------------------------------------------------------------------------------- /MyStub/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: 这是预编译标头文件。 2 | // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 3 | // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 4 | // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 5 | // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // 添加要在此处预编译的标头 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /MyStub/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lracker/MyPack/b4af8d4ccf0e6f050d6550c57437ce426484ce9a/MyStub/resource.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MyPack 2 | 加密壳 3 | 包括以下功能:添加区段、加密压缩代码、花指令、密码弹窗、修复重定位、IAT加密、反调试等功能。 4 | MyStub 壳代码需要release版本并且静态编译。 5 | --------------------------------------------------------------------------------