The Code Is as Follows:
#include <iostream>
#include <windows.h>
using namespace std;
//typedef unsigned long NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000UL)
#define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS)0x00000117UL)
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DUL)
#define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS)0xC000025FUL)
#define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS)0xC0000300UL)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023UL)
#define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xC0000242UL)
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
typedef NTSTATUS(__stdcall* _RtlCompressBuffer)(
USHORT CompressionFormatAndEngine,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
ULONG UncompressedChunkSize,
PULONG FinalCompressedSize,
PVOID WorkSpace
);
typedef NTSTATUS(__stdcall* _RtlDecompressBuffer)(
USHORT CompressionFormat,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalUncompressedSize
);
typedef NTSTATUS(__stdcall* _RtlGetCompressionWorkSpaceSize)(
USHORT CompressionFormatAndEngine,
PULONG CompressBufferWorkSpaceSize,
PULONG CompressFragmentWorkSpaceSize
);
char* ReadFileWs(const char* FilePath, DWORD& bufferLen) {
HANDLE File = CreateFileA(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (File == INVALID_HANDLE_VALUE) {
return NULL;
}
DWORD _size = GetFileSize(File, 0);
char* Buffer = new char[_size + 1];
bool result = ReadFile(File, Buffer, _size, &bufferLen, 0);
CloseHandle(File);
if (result)return Buffer;
else return NULL;
}
bool WriteFileWs(const char* FilePath, char* Buffer, DWORD bufferLen, DWORD& numberBytesRead) {
HANDLE File = CreateFileA(FilePath, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
if (File == INVALID_HANDLE_VALUE) {
return false;
}
bool result = WriteFile(File, Buffer, bufferLen, &numberBytesRead, NULL);
CloseHandle(File);
return result;
}
UCHAR* compress_buffer(const char* buffer, const ULONG bufferLen, ULONG compBufferLen, ULONG* compBufferSize)
{
_RtlCompressBuffer RtlCompressBuffer = (_RtlCompressBuffer)GetProcAddress(ntdll, "RtlCompressBuffer");
_RtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize = (_RtlGetCompressionWorkSpaceSize)GetProcAddress(ntdll, "RtlGetCompressionWorkSpaceSize");
ULONG bufWorkspaceSize; // Workspace Size
ULONG fragWorkspaceSize; // Fragmented Workspace Size (Unused)
NTSTATUS ret = RtlGetCompressionWorkSpaceSize(
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, // CompressionFormatAndEngine
&bufWorkspaceSize, // CompressBufferWorkSpaceSize
&fragWorkspaceSize // CompressFragmentWorkSpaceSize
);
if (ret != STATUS_SUCCESS) return 0;
VOID* workspace = (VOID*)LocalAlloc(LMEM_FIXED, bufWorkspaceSize);
if (workspace == NULL) return 0;
UCHAR* compBuffer = new UCHAR[compBufferLen];
NTSTATUS result = RtlCompressBuffer(
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, // CompressionFormatAndEngine
(UCHAR*)buffer, // UncompressedBuffer
bufferLen, // UncompressedBufferSize
compBuffer, // CompressedBuffer
compBufferLen, // CompressedBufferSize
4096, // UncompressedChunkSize
compBufferSize, // FinalCompressedSize
workspace // WorkSpace
);
LocalFree(workspace);
if (result != STATUS_SUCCESS) {
return 0;
}
return compBuffer;
}
int main(int argc, char* argv[])
{
char* origin_path = argv[1]; // origin file path
char* new_path = argv[2]; // compressed file path
DWORD bufferLen, numberBytesRead, compBufferSize, realDecompSize;
char* data = ReadFileWs(origin_path, bufferLen);
UCHAR* bufferComprimido = compress_buffer(data, bufferLen, bufferLen + 512, &compBufferSize);
cout << "Read and Compress file" << endl;
WriteFileWs(new_path, (char*)bufferComprimido, compBufferSize, numberBytesRead);
cout << "Write compressed file to specific path" << endl;
delete[] data;
delete[] bufferComprimido;
return 0;
}
Reproduction Process:
- Compile with visual studio 2022

.\RtlCompressBuffer.exe 文件原路径 目标路径
- Try executing the program to compress a file

- As shown above, the execution succeeded