最近在分析一个远程控制木马,用OD分析出其中发送和接收的数据利用ntdll中的RtlCompressBuffer和RtlDecompressBuffer进行了压缩和解压缩,并抓包得到了其中发送的压缩后的数据。在网上搜到了简单的代码,能够以用户态调用ntdll中的这两个方法进行解压,但是每次运行得到的解压后大小都是一个很大的随机值,于是尝试了比较短的明文字符串进行压缩,但是发现似乎压缩过程就是向字符串中添加了一些0x00,体积反而大了……解压缩倒是正常的能够还原。代码如下:
#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_MAXIMUMtypedef 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[] = {0x8a,0x16,0x49,0x92,0x8f,0x80,0xa5,0xf6,0xac,0x22,0x19,0x6b,0x57,0xfd,0x8a,0x54,0xec,0x8a,0x40,0xe1,0xf4,0x7d,0x94,0x9c,0x02,0x88,0xdd,0xf1,0xe3,0x52,0x37,0xbf,0x72,0x6b,0xe2,0x67,0x97,0x00,0x51,0x6e,0x92,0x26,0x5b,0x89,0x37,0x7e,0xbc,0x8e,0x74,0x58,0xed,0x79,0x42,0x23,0x7f,0xe9,0x92,0xbe,0x7b,0xcf,0x60,0xb4,0x3c,0x1f,0xdc,0x7c,0xe2,0x15,0xd8,0xa9,0xd1,0xb4,0x99,0x3d,0xdc,0x59,0xc3,0xde,0x90,0xff,0x69,0x66,0x8b,0xe1,0x80,0x1f,0xf1,0x2d,0xdb,0xac,0x95,0x00,0xb3,0x3b,0x50,0x24,0x1d,0xfa,0x40,0xaa,0x81,0x23,0x66,0x01,0x70,0x12,0x17,0xeb,0x26,0x67,0x08,0x04,0xc0,0xed,0x2b,0x8b,0x0b,0xb9,0x15,0x7f,0xd7,0xc8,0xae,0xb4,0x13,0x38,0x6b,0x35,0x5a,0xd4,0x74,0xd5,0xdc,0xcd,0xcc,0xeb,0x95,0x1b,0x8d,0x3b,0x17,0xd3,0x79,0xb4,0x12,0x98,0xda,0x10,0x33,0xb9,0x11,0x94,0x9e,0x25,0x8c,0xd4,0xd2,0x4c,0x78,0x71,0x5c,0x46,0x1c,0x6e,0xb8,0xad,0x96,0x9c,0x9a,0x38,0x83,0x47,0x3a,0xf0,0xb4,0x66,0x4b,0xba,0x27,0xfc,0xce,0x8f,0x4d,0xe7,0x3c,0x82,0xfb,0x01,0xe2,0x58,0xd0,0x3b,0x04,0x75,0x8a,0xd2,0xc5,0x3e,0x86,0xe4,0xe5,0x51,0x5f,0x01,0x62,0xa2,0x9a,0xfe,0xd0,0x8b,0xe6,0x58,0x41,0x4a,0x37,0x93,0x76,0x9d,0x77,0x91,0xe9,0xb9,0xf3,0x70,0x37,0xf9,0x63,0x0f,0x69,0x38,0x10,0xd6,0xce,0xb1,0x22,0x8c,0x27,0xd8,0xc8,0x94};
char dst[512];
char buf[]={"[email protected]. This is a test string. Try to make it a little longer."};
char dst2[512];
HANDLE hDLL;
RtlCompressBuffer_Fn fcmp;
RtlDecompressBuffer_Fn fdcp;
RtlGetCompressionWorkSpaceSize_Fn fgcw;
DWORD dw, rc;
unsigned long xx;
void *tmpMem;
// register unsigned char i;
unsigned long 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( "%02X ", (BYTE) dst[i]);
printf( "\n--\n");
for (i = 0; i < sizeof(buf); i++)
buf[i] = 0; printf("Length of compressed is %d\n",dw); rc = (*fdcp)(CMP_FRM, buf, sizeof(buf), dst, sizeof(dst), &xx);
switch (rc)
{
case 0:
printf("decompression successful!\n");
break;
case 0xC000000D:
printf("invalid parameter!\n");
break;
case 0xC000025F:
printf("unsupported compression");
break;
case 0xC0000242:
printf("bad buffer\n");
break;
default:
printf("unknown return value\n");
}
printf("decompressed length is %lu\n",xx);
for (i = 0; i < sizeof(buf); i++)
printf( "%02X ", (BYTE) buf[i]);
printf( "\n");
}
else
printf("Get func addr failed!"); FreeLibrary(hDLL);
}
else
printf("LoadLibrary Failed!\n");
system("pause");
return 0;
}想请教一下,这样的“压缩”效果是否是正常的?压缩之后的数据有没有格式上的特征?