How to write your own WinZip

2006 November 11
by Ilya

Have you ever want to make your very own data compression utility to beat WinZip, but always failed at all that math? Well, there is your chance. There are three Win32 functions will do the trick:

  • RtlCompressBuffer
  • RtlDecompressBuffer
  • RtlGetCompressionWorkSpaceSize

And without further ado here is the C code example of how to use these functions:

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

/*
#define COMPRESSION_FORMAT_LZNT1    0x0002
#define COMPRESSION_ENGINE_STANDARD 0x0000 // Standart compression
#define COMPRESSION_ENGINE_MAXIMUM  0x0100 // Maximum (slowest but better)
*/

#define CMP_FRM     COMPRESSION_FORMAT_LZNT1|COMPRESSION_ENGINE_MAXIMUM

typedef DWORD (__stdcall *RtlCompressBuffer_Fn)(
                    IN ULONG    CompressionFormat,
                    IN PVOID    SourceBuffer,
                    IN ULONG    SourceBufferLength,
                    OUT PVOID   DestinationBuffer,
                    IN ULONG    DestinationBufferLength,
                    IN ULONG    Unknown,
                    OUT PULONG  pDestinationSize,
                    IN PVOID    WorkspaceBuffer );

typedef DWORD (__stdcall *RtlDecompressBuffer_Fn)(
                    IN ULONG    CompressionFormat,
                    OUT PVOID   DestinationBuffer,
                    IN ULONG    DestinationBufferLength,
                    IN PVOID    SourceBuffer,
                    IN ULONG    SourceBufferLength,
                    OUT PULONG  pDestinationSize );

typedef DWORD (__stdcall *RtlGetCompressionWorkSpaceSize_Fn)(
                    IN ULONG    CompressionFormat,
                    OUT PULONG  pNeededBufferSize,
                    OUT PULONG  pUnknown );

int main (void)
{
   char dst[512] = {0};
   char buf[] = "abcabcabcabcabcabcabc";
   HANDLE hDLL;
   RtlCompressBuffer_Fn fcmp;
   RtlDecompressBuffer_Fn fdcp;
   RtlGetCompressionWorkSpaceSize_Fn fgcw;
   DWORD dw, xx, rc;
   void *tmpMem;
   register unsigned char i;

   hDLL = LoadLibrary ("ntdll.dll");
   if ( hDLL != NULL )
   {
     fcmp = (RtlCompressBuffer_Fn) GetProcAddress(hDLL, "RtlCompressBuffer");
     fdcp = (RtlDecompressBuffer_Fn) GetProcAddress(hDLL, "RtlDecompressBuffer");
     fgcw = (RtlGetCompressionWorkSpaceSize_Fn) GetProcAddress(hDLL, "RtlGetCompressionWorkSpaceSize");

     if ( fcmp && fdcp && fgcw)
     {
        rc = (*fgcw)(CMP_FRM, &dw,  &xx);
        tmpMem = LocalAlloc(LPTR, dw);
        rc = (*fcmp)(CMP_FRM, buf, sizeof(buf), dst, sizeof(dst), xx, &dw, tmpMem);
        LocalFree(tmpMem);
        for (i = 0; i< dw; i++) printf("%c", (BYTE) dst[i]); printf("\n--\n");
        for (i = 0; i< sizeof(buf); i++) buf[i] = 0;

        rc = (*fdcp)(CMP_FRM, buf, sizeof(buf), dst, dw, &xx);
        for (i = 0; i< xx; i++) printf("%c", (BYTE) buf[i]); printf("\n");
     }

     FreeLibrary(hDLL);
   }

   return 0;
}
Reddit this / Add to del.icio.us / Digg this!
3 Comments leave one →
2006 December 18

[...] The last time we described semi- and undocumented functions in Windows, these were compression functions. Today’s subject is cryptographic functions. There are such functions in Windows core that allows you to use few cryptographic primitives easier, without whole CAPI overhead and hassle. Here is an example of how to generate secure random numbers and calculate SHA-1 hash. First, a C header file capix.h which you may use in your own programs right away: [...]

Pingback
2009 July 4
Chris_F permalink

Just wanted to point out that you called these functions Win32, when in fact, they are lower level then the Win32 API. Everything belonging to NTDLL.DLL is a part of the native NT API, which is what the Win32 API is actually built on.

Also keep in mind that while this works, it’s considered a hack as Microsoft never intended nor encourages for people to interface with the NT API directly (at least in User-Mode, some NT API is necessary for Kernel-Mode drivers.) Microsoft can at any time change the way the NT API works via any type of OS update (and inadvertently breaking your application.) Win32 programs *should* stick to the standard Win32 API by using the proper Win32 DLLs (kernel32.dll, user32.dll, ect)

It’s fun to use these tricks, and to learn how Win32 and NT get along, but there are always these things to consider.

Leave A Comment

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS