Hi,
I’m trying to write a script to decode compressed windows prefetch files (MAM\04).To achieve this you have to decompress the data section using two function calls in NTDLL.DLL:
RtlGetCompressionWorkSpaceSize(…) and RtlDecompressBufferEx(…)
The function protoypes (see below) use pointers to the buffers. Does anyone know if there is a way to pass pointers to these external functions?
Code example:
const ushort COMPRESSION_FORMAT_XPRESSHUFF = 4;
/*
long RtlGetCompressionWorkSpaceSize(
USHORT CompressionFormatAndEngine,
PULONG CompressBufferWorkSpaceSize,
PULONG CompressFragmentWorkSpaceSize
);
long RtlDecompressBufferEx(
USHORT CompressionFormat,
PVOID UncompressedBuffer,
ULONG UncompressedBufferSize,
PVOID CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalUncompressedSize,
PVOID WorkSpace
);
*/
#link “c:\windows\system32\ntdll.dll”
long RtlGetCompressionWorkSpaceSize(ushort compressionFormat, ulong &compressBufferWorkSpaceSize, ulong &compressFragmentWorkSpaceSize);
long RtlDecompressBufferEx(ushort compressionFormat, byte uncompressedBuffer, uint32 uncompressedBufferSize, byte compressedBuffer, uint32 compressedBufferSize, uint32 &finalUncompressedSize, byte workSpace);
#endlink
typedef struct CompressedPF {
uint32 Signature <format=hex>;
uint32 UnCompressedSz;
byte CompressedBuffer[FileSize()-FTell()];
};
// -------------------- Main --------------------
LittleEndian();
// Read in raw file
CompressedPF Header;
// Decode
local byte UnCompressedBuffer[Header.UnCompressedSz];
local ulong compressBufferWorkSpaceSize = 0;
local ulong compressFragmentWorkSpaceSize = 0;
local ushort ret;
local uint32 finalUncompressedSize;
//get the size of what our workspace needs to be
ret = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_XPRESSHUFF, &compressBufferWorkSpaceSize, &compressFragmentWorkSpaceSize);
if (ret != 0) {
Printf(“Error: RtlGetCompressionWorkSpaceSize() failed\n”);
} else {
byte workSpace[compressFragmentWorkSpaceSize];
ulong dstSize = 0;
ret = RtlDecompressBufferEx(COMPRESSION_FORMAT_XPRESSHUFF, UnCompressedBuffer, Header.UnCompressedSz, CompressedBuffer, sizeof(Header.Compressedbuffer), &dstSize, workSpace);
if (ret == 0) {
Printf(“Error: RtlGetCompressionWorkSpaceSize() failed\n”);
};
};