#include <Windows.h> #include <iostream> #include <windef.h>
typedef NTSTATUS(WINAPI *typedef_RtlGetCompressionWorkSpaceSize)( _In_ USHORT CompressionFormatAndEngine, _Out_ PULONG CompressBufferWorkSpaceSize, _Out_ PULONG CompressFragmentWorkSpaceSize );
typedef NTSTATUS(WINAPI *typedef_RtlCompressBuffer)( _In_ USHORT CompressionFormatAndEngine, _In_ PUCHAR UncompressedBuffer, _In_ ULONG UncompressedBufferSize, _Out_ PUCHAR CompressedBuffer, _In_ ULONG CompressedBufferSize, _In_ ULONG UncompressedChunkSize, _Out_ PULONG FinalCompressedSize, _In_ PVOID WorkSpace );
typedef NTSTATUS(WINAPI *typedef_RtlDecompressBuffer)( _In_ USHORT CompressionFormat, _Out_ PUCHAR UncompressedBuffer, _In_ ULONG UncompressedBufferSize, _In_ PUCHAR CompressedBuffer, _In_ ULONG CompressedBufferSize, _Out_ PULONG FinalUncompressedSize );
BOOL CompressData(BYTE *pUncompressData, DWORD dwUncompressDataLength, BYTE **ppCompressData, DWORD *pdwCompressDataLength) { BOOL bRet = FALSE; NTSTATUS status = 0; HMODULE hModule = NULL; typedef_RtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize = NULL; typedef_RtlCompressBuffer RtlCompressBuffer = NULL; DWORD dwWorkSpaceSize = 0, dwFragmentWorkSpaceSize = 0; BYTE *pWorkSpace = NULL; BYTE *pCompressData = NULL; DWORD dwCompressDataLength = 4096; DWORD dwFinalCompressSize = 0; do { hModule = ::LoadLibrary("ntdll.dll"); if (NULL == hModule) { ShowError("LoadLibrary"); break; }
RtlGetCompressionWorkSpaceSize = (typedef_RtlGetCompressionWorkSpaceSize)::GetProcAddress(hModule, "RtlGetCompressionWorkSpaceSize"); if (NULL == RtlGetCompressionWorkSpaceSize) { ShowError("GetProcAddress"); break; }
RtlCompressBuffer = (typedef_RtlCompressBuffer)::GetProcAddress(hModule, "RtlCompressBuffer"); if (NULL == RtlCompressBuffer) { ShowError("GetProcAddress"); break; }
status = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, &dwWorkSpaceSize, &dwFragmentWorkSpaceSize); if (0 != status) { break; }
pWorkSpace = new BYTE[dwWorkSpaceSize]; if (NULL == pWorkSpace) { break; } ::RtlZeroMemory(pWorkSpace, dwWorkSpaceSize);
while (TRUE) { pCompressData = new BYTE[dwCompressDataLength]; if (NULL == pCompressData) { break; } ::RtlZeroMemory(pCompressData, dwCompressDataLength);
RtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, pUncompressData, dwUncompressDataLength, pCompressData, dwCompressDataLength, 4096, &dwFinalCompressSize, (PVOID)pWorkSpace); if (dwCompressDataLength < dwFinalCompressSize) { if (pCompressData) { delete[]pCompressData; pCompressData = NULL; } dwCompressDataLength = dwFinalCompressSize; } else { break; } }
*ppCompressData = pCompressData; *pdwCompressDataLength = dwFinalCompressSize; bRet = TRUE;
} while (FALSE);
if (pWorkSpace) { delete[]pWorkSpace; pWorkSpace = NULL; } if (hModule) { ::FreeLibrary(hModule); }
return bRet; }
BOOL UncompressData(BYTE *pCompressData, DWORD dwCompressDataLength, BYTE **ppUncompressData, DWORD *pdwUncompressDataLength) { BOOL bRet = FALSE; HMODULE hModule = NULL; typedef_RtlDecompressBuffer RtlDecompressBuffer = NULL; BYTE *pUncompressData = NULL; DWORD dwUncompressDataLength = 4096; DWORD dwFinalUncompressSize = 0; do { hModule = ::LoadLibrary("ntdll.dll"); if (NULL == hModule) { break; }
RtlDecompressBuffer = (typedef_RtlDecompressBuffer)::GetProcAddress(hModule, "RtlDecompressBuffer"); if (NULL == RtlDecompressBuffer) { break; }
while (TRUE) { pUncompressData = new BYTE[dwUncompressDataLength]; if (NULL == pUncompressData) { break; } ::RtlZeroMemory(pUncompressData, dwUncompressDataLength);
RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, pUncompressData, dwUncompressDataLength, pCompressData, dwCompressDataLength, &dwFinalUncompressSize); if (dwUncompressDataLength < dwFinalUncompressSize) { if (pUncompressData) { delete[]pUncompressData; pUncompressData = NULL; } dwUncompressDataLength = dwFinalUncompressSize; } else { break; } }
*ppUncompressData = pUncompressData; *pdwUncompressDataLength = dwFinalUncompressSize; bRet = TRUE;
} while (FALSE);
if (hModule) { ::FreeLibrary(hModule); }
return bRet; }
int main(int argc, char *argv[]) { DWORD i = 0; BOOL bRet = FALSE; char szBuffer[] = "DDDDDDDDDDGGGGGGGGGGGG"; DWORD dwBufferLength = ::lstrlen(szBuffer); BYTE *pCompressData = NULL; DWORD dwCompressDataLength = 0; BYTE *pUncompressData = NULL; DWORD dwUncompressDataLength = 0;
CompressData((BYTE *)szBuffer, dwBufferLength, &pCompressData, &dwCompressDataLength);
UncompressData(pCompressData, dwCompressDataLength, &pUncompressData, &dwUncompressDataLength);
printf("原数据为:\n"); for (i = 0; i < dwBufferLength; i++) { printf("%X ", szBuffer[i]); } printf("\n\n压缩数据为:\n"); for (i = 0; i < dwCompressDataLength; i++) { printf("%X ", pCompressData[i]); } printf("\n\n解压缩数据为:\n"); for (i = 0; i < dwUncompressDataLength; i++) { printf("%X ", pUncompressData[i]); } printf("\n");
if (pUncompressData) { delete[]pUncompressData; pUncompressData = NULL; } if (pCompressData) { delete[]pCompressData; pCompressData = NULL; }
system("pause"); return 0; }
|