Skip to content

Instantly share code, notes, and snippets.

@Wra7h
Created December 2, 2021 08:00
Show Gist options
  • Save Wra7h/4d56791c2d0b5c1f27a67f3bc0ab924d to your computer and use it in GitHub Desktop.
Save Wra7h/4d56791c2d0b5c1f27a67f3bc0ab924d to your computer and use it in GitHub Desktop.
C# Compression using Windows API
//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