Compress and Decompress Buffer using C language

winapi
programming

#1

Hello guys

I’m still beginner in C language, I was wondering if there is a C Function or winapi function that compress and decompress a buffer , an example will be great :smile:

thank you


#2

What sort of buffer would this be? How to compress or decompress depends on what the data has been compressed with in the first place, and if it isn’t compressed then what sort of data it is.

I’m not familiar with winapi, but I feel like those questions will need answering regardless.


#3

RtlCompressBuffer and related functions provided by ntdll.dll. You’ll need to dynamically retrieve them:

Example using RtlCompressBuffer and RtlDecompressBuffer in C++:

bool CompressBuffer(std::vector<BYTE>& out, std::vector<BYTE>& in, PULONG puFinalCompressedSize) {
	DWORD(WINAPI *fnRtlGetCompressionWorkSpaceSize)(USHORT, PULONG, PULONG)
		= (DWORD(WINAPI *)(USHORT, PULONG, PULONG))
		(::GetProcAddress(::GetModuleHandle(TEXT("ntdll.dll")), "RtlGetCompressionWorkSpaceSize"));

	DWORD(WINAPI *fnRtlCompressBuffer)(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID)
		= (DWORD(WINAPI *)(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID))
		(::GetProcAddress(::GetModuleHandle(TEXT("ntdll.dll")), "RtlCompressBuffer"));

	ULONG uCompressBufferWorkSpaceSize, uCompressFragmentWorkSpaceSize;
	if (fnRtlGetCompressionWorkSpaceSize(
		COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
		&uCompressBufferWorkSpaceSize,
		&uCompressFragmentWorkSpaceSize)) {
		return false;
	}

	PVOID pWorkSpace = new BYTE[uCompressBufferWorkSpaceSize];
	std::vector<BYTE> outData(in.size());
	if (fnRtlCompressBuffer(
		COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
		in.data(),
		in.size(),
		out.data(),
		out.size(),
		4096,
		puFinalCompressedSize,
		pWorkSpace)) {
		return false;
	}
	delete[] pWorkSpace;

	return true;
}

bool DecompressBuffer(std::vector<BYTE>& out, std::vector<BYTE>& in, PULONG puFinalCompressedSize) {
	DWORD(WINAPI *fnRtlDecompressBuffer)(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, PULONG)
		= (DWORD(WINAPI *)(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, PULONG))
		(::GetProcAddress(::GetModuleHandle(TEXT("ntdll.dll")), "RtlDecompressBuffer"));

	if (fnRtlDecompressBuffer(
		COMPRESSION_FORMAT_LZNT1,
		out.data(),
		out.size(),
		in.data(),
		in.size(),
		puFinalCompressedSize)) {
		return false;
	}

	return true;
}

Alternatively, you can use a third party library like QuickLZ or zlib.


#4

thank you @dtm I used zlib .


(system) #5

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.