Created
December 2, 2021 08:00
-
-
Save Wra7h/4d56791c2d0b5c1f27a67f3bc0ab924d to your computer and use it in GitHub Desktop.
C# Compression using Windows API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Compresses a file using the Windows API | |
//Compile: C:\windows\Microsoft.NET\Framework64\v3.5\csc.exe C:\Path\To\Compress.cs | |
//Windows Compression API: https://docs.microsoft.com/en-us/windows/win32/api/_cmpapi/ | |
//Supported Algorithms: https://docs.microsoft.com/en-us/windows/win32/api/compressapi/nf-compressapi-createcompressor | |
// Takes a file, compresses it using one of the supported algorithms and creates a file with the compressed data. | |
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
namespace Compress | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
if (args.Contains("-h", StringComparer.OrdinalIgnoreCase) || args.Length == 0) | |
{ | |
Console.WriteLine("\n Compression with Windows Api"); | |
Console.WriteLine("\n -in : File to compress"); | |
Console.WriteLine(" -out : Path for output file"); | |
Console.WriteLine(" -alg : Algorithm to use. "); | |
Console.WriteLine(" -block : includes COMPRESS_RAW to create a block mode compressor"); | |
Console.WriteLine("\n Available Algorithms:"); | |
Console.WriteLine(" 2 = MSZIP"); | |
Console.WriteLine(" 3 = XPRESS"); | |
Console.WriteLine(" 4 = XPRESS_HUFF"); | |
Console.WriteLine(" 5 = LZMS"); | |
Console.WriteLine("\n Example Usage: compress.exe -in C:\\path\\to\\input.txt -out .\\outputfile -alg 5"); | |
Environment.Exit(0); | |
} | |
string inputFile = ""; | |
string outputFile = ""; | |
bool blockMode = false; | |
COMPRESS_ALGORITHM alg = 0; | |
for (int i = 0; i < args.Length; i++) | |
{ | |
if (args[i] == "-in" && !args[i + 1].StartsWith("-")) | |
{ | |
if (File.Exists(args[i + 1])) | |
{ | |
inputFile = Path.GetFullPath(args[i + 1]); | |
} | |
} | |
if (args[i] == "-out" && !args[i + 1].StartsWith("-")) | |
{ | |
outputFile = Path.GetFullPath(args[i + 1]); | |
} | |
if (args[i] == "-block") | |
{ | |
blockMode = true; | |
} | |
if (args[i] == "-alg" && !args[i + 1].StartsWith("-")) | |
{ | |
switch (args[i + 1]) | |
{ | |
case "2": | |
alg = COMPRESS_ALGORITHM.COMPRESS_ALGORITHM_MSZIP; | |
break; | |
case "3": | |
alg = COMPRESS_ALGORITHM.COMPRESS_ALGORITHM_XPRESS; | |
break; | |
case "4": | |
alg = COMPRESS_ALGORITHM.COMPRESS_ALGORITHM_XPRESS_HUFF; | |
break; | |
case "5": | |
alg = COMPRESS_ALGORITHM.COMPRESS_ALGORITHM_LZMS; | |
break; | |
} | |
} | |
} | |
if (inputFile == "") | |
{ | |
Console.WriteLine(" [!] No input file specified.\n Use -in to specify an input file."); | |
Environment.Exit(1); | |
} | |
if (outputFile == "") | |
{ | |
Console.WriteLine(" [!] No output file specified.\n Use -out to specify an output file."); | |
Environment.Exit(1); | |
} | |
if (alg == 0) | |
{ | |
Console.WriteLine(" [!] No Algorithm specified!\n Use -alg to specify an algorithm"); | |
Environment.Exit(1); | |
} | |
byte[] payload = File.ReadAllBytes(inputFile); | |
IntPtr hCompressor = IntPtr.Zero; | |
if (alg != 0) { | |
if (!blockMode) { | |
CreateCompressor((uint)alg, IntPtr.Zero, out hCompressor); | |
} | |
else | |
{ | |
CreateCompressor((uint)(alg | COMPRESS_ALGORITHM.COMPRESS_RAW), IntPtr.Zero, out hCompressor); | |
} | |
} | |
if (hCompressor != IntPtr.Zero) | |
{ | |
byte[] Trash = new byte[] { }; //Don't really care about this | |
uint CompressedDataSize = 0; | |
//Get Compressed Data Size | |
if (!Compress(hCompressor, payload, (uint)payload.Length, Trash, 0, out CompressedDataSize)) | |
{ | |
if (CompressedDataSize > 0) | |
{ | |
uint CompressedDataSize2 = 0; //Don't really care about this | |
byte[] CompressedBuffer = new byte[CompressedDataSize]; | |
if (!Compress(hCompressor, payload, (uint)payload.Length, CompressedBuffer, CompressedDataSize, out CompressedDataSize2)) //Compress for real this time | |
{ | |
Console.WriteLine("[!] Compress error: {0}", Marshal.GetLastWin32Error().ToString()); | |
} | |
else | |
{ | |
Console.WriteLine("\n[+] Success! Writing {0} bytes to {1}", CompressedDataSize,outputFile); | |
File.WriteAllBytes(outputFile, CompressedBuffer); | |
} | |
} | |
} | |
CloseCompressor(hCompressor); | |
} | |
} | |
[DllImport("Cabinet.dll")] | |
static extern bool CreateCompressor(uint Algorithm, IntPtr AllocationRoutines, out IntPtr CompressorHandle); | |
[DllImport("Cabinet.dll")] | |
static extern bool CloseCompressor(IntPtr CompressHandle); | |
[DllImport("Cabinet.dll")] | |
static extern bool Compress(IntPtr CompressorHandle, byte[] UncompressedData, uint UncompressedDataSize, byte[] CompressedBuffer, uint CompressedBufferSize, out uint CompressedDataSize); | |
[Flags] | |
public enum COMPRESS_ALGORITHM | |
{ | |
COMPRESS_ALGORITHM_MSZIP = 2, | |
COMPRESS_ALGORITHM_XPRESS = 3, | |
COMPRESS_ALGORITHM_XPRESS_HUFF = 4, | |
COMPRESS_ALGORITHM_LZMS = 5, | |
COMPRESS_RAW = 1 << 29 | |
} | |
//[DllImport("Cabinet.dll")] | |
//static extern bool Compress(IntPtr CompressorHandle, IntPtr UncompressedData, uint UncompressedDataSize, IntPtr CompressedBuffer, uint CompressedBufferSize, out uint CompressedDataSize); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment