Advertisement
mrfearless

CDCompressMem / CDDecompressMem

Jan 24th, 2024
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 12.53 KB | Source Code | 0 0
  1. ;------------------------------------------------------------------------------
  2. ; CDCompressMem - Compress data in memory with one of the Cabinet compression
  3. ; algorithms. Stores a header signature at the first dword indicating the
  4. ; compression algorithm used to compress the data.
  5. ;
  6. ; Returns: pointer to Compressed data if succesful or NULL otherwise.
  7. ; User should free memory when no longer required with call to GlobalFree
  8. ; Variable pointed to by lpdwCompressedDataLength will contain the size of the
  9. ; compressed data or 0 if a failure occured.
  10. ;------------------------------------------------------------------------------
  11. CDCompressMem PROC USES EBX lpUncompressedData:DWORD, dwUncompressedDataLength:DWORD, dwCompressionAlgorithm:DWORD, lpdwCompressedDataLength:DWORD
  12.     LOCAL CompressorHandle:DWORD
  13.     LOCAL CompressedBuffer:DWORD
  14.     LOCAL CompressedBufferSize:DWORD
  15.     LOCAL CompressedDataSize:DWORD
  16.     LOCAL CompressionAlgorithm:DWORD
  17.     LOCAL pData:DWORD
  18.    
  19.     IFDEF DEBUG32
  20.     PrintText 'CDCompressMem'
  21.     ;PrintDec lpUncompressedData
  22.     ;PrintDec dwUncompressedDataLength
  23.     ENDIF
  24.    
  25.     .IF lpUncompressedData == NULL || dwUncompressedDataLength == 0
  26.         IFDEF DEBUG32
  27.         PrintText 'CDCompressMem lpUncompressedData == NULL || dwUncompressedDataLength == 0'
  28.         ENDIF
  29.         .IF lpdwCompressedDataLength != 0
  30.             mov ebx, lpdwCompressedDataLength
  31.             mov eax, 0
  32.             mov [ebx], eax
  33.         .ENDIF
  34.         mov eax, NULL
  35.         ret
  36.     .ENDIF
  37.    
  38.     mov eax, dwCompressionAlgorithm
  39.     .IF eax != COMPRESS_ALGORITHM_MSZIP && eax != COMPRESS_ALGORITHM_XPRESS && eax != COMPRESS_ALGORITHM_XPRESS_HUFF && eax != COMPRESS_ALGORITHM_LZMS
  40.         IFDEF DEBUG32
  41.         PrintText 'CDCompressMem dwCompressionAlgorithm Not Valid'
  42.         ENDIF
  43.         .IF lpdwCompressedDataLength != 0
  44.             mov ebx, lpdwCompressedDataLength
  45.             mov eax, 0
  46.             mov [ebx], eax
  47.         .ENDIF
  48.         mov eax, NULL
  49.         ret
  50.     .ENDIF
  51.    
  52.     ;--------------------------------------------------------------------------
  53.     ; Create compressor
  54.     ;--------------------------------------------------------------------------
  55.     Invoke CreateCompressor, dwCompressionAlgorithm, NULL, Addr CompressorHandle
  56.     .IF eax == FALSE
  57.         IFDEF DEBUG32
  58.         PrintText 'CDCompressMem CreateCompressor Failed'
  59.         ENDIF
  60.         .IF lpdwCompressedDataLength != 0
  61.             mov ebx, lpdwCompressedDataLength
  62.             mov eax, 0
  63.             mov [ebx], eax
  64.         .ENDIF
  65.         mov eax, NULL
  66.         ret
  67.     .ENDIF
  68.    
  69.     ;--------------------------------------------------------------------------
  70.     ; Get size required first
  71.     ;--------------------------------------------------------------------------
  72.     Invoke Compress, CompressorHandle, lpUncompressedData, dwUncompressedDataLength, NULL, 0, Addr CompressedBufferSize
  73.     .IF eax == FALSE
  74.         Invoke GetLastError
  75.         .IF eax == ERROR_INSUFFICIENT_BUFFER
  76.            
  77.         .ELSE
  78.             IFDEF DEBUG32
  79.             PrintText 'CDCompressMem Compress Get Size Failed'
  80.             ENDIF
  81.             .IF CompressorHandle != 0
  82.                 Invoke CloseCompressor, CompressorHandle
  83.             .ENDIF
  84.             .IF lpdwCompressedDataLength != 0
  85.                 mov ebx, lpdwCompressedDataLength
  86.                 mov eax, 0
  87.                 mov [ebx], eax
  88.             .ENDIF
  89.             mov eax, NULL
  90.             ret
  91.         .ENDIF
  92.     .ENDIF
  93.    
  94.     ;--------------------------------------------------------------------------
  95.     ; Alloc buffer required
  96.     ;--------------------------------------------------------------------------
  97.     ;PrintDec CompressedBufferSize
  98.     mov eax, CompressedBufferSize
  99.     add eax, SIZEOF DWORD ; room for header signature
  100.     Invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, eax
  101.     .IF eax == NULL
  102.         IFDEF DEBUG32
  103.         PrintText 'CDCompressMem GlobalAlloc Failed'
  104.         ENDIF
  105.         .IF CompressorHandle != 0
  106.             Invoke CloseCompressor, CompressorHandle
  107.         .ENDIF
  108.         .IF lpdwCompressedDataLength != 0
  109.             mov ebx, lpdwCompressedDataLength
  110.             mov eax, 0
  111.             mov [ebx], eax
  112.         .ENDIF
  113.         mov eax, NULL
  114.         ret
  115.     .ENDIF
  116.     mov CompressedBuffer, eax
  117.     mov pData, eax
  118.     add pData, SIZEOF DWORD ; skip past header signature
  119.    
  120.     ;--------------------------------------------------------------------------
  121.     ; Add header signature
  122.     ;--------------------------------------------------------------------------
  123.     mov ebx, CompressedBuffer
  124.     mov eax, dwCompressionAlgorithm
  125.     .IF eax == COMPRESS_ALGORITHM_MSZIP
  126.         mov eax, HEADER_MSZIP
  127.         mov [ebx], eax
  128.     .ELSEIF eax == COMPRESS_ALGORITHM_XPRESS
  129.         mov eax, HEADER_XPRESS
  130.         mov [ebx], eax
  131.     .ELSEIF eax == COMPRESS_ALGORITHM_XPRESS_HUFF
  132.         mov eax, HEADER_HUFF
  133.         mov [ebx], eax
  134.     .ELSEIF eax == COMPRESS_ALGORITHM_LZMS
  135.         mov eax, HEADER_LZMS
  136.         mov [ebx], eax
  137.     .ENDIF
  138.    
  139.     ;--------------------------------------------------------------------------
  140.     ; Do actual compression now
  141.     ;--------------------------------------------------------------------------
  142.     Invoke Compress, CompressorHandle, lpUncompressedData, dwUncompressedDataLength, pData, CompressedBufferSize, Addr CompressedDataSize
  143.     .IF eax == FALSE
  144.         IFDEF DEBUG32
  145.         PrintText 'CDCompressMem Compress Failed'
  146.         ENDIF
  147.         .IF CompressedBuffer != 0
  148.             Invoke GlobalFree, CompressedBuffer
  149.         .ENDIF
  150.         .IF CompressorHandle != 0
  151.             Invoke CloseCompressor, CompressorHandle
  152.         .ENDIF
  153.         .IF lpdwCompressedDataLength != 0
  154.             mov ebx, lpdwCompressedDataLength
  155.             mov eax, 0
  156.             mov [ebx], eax
  157.         .ENDIF
  158.         mov eax, NULL
  159.         ret
  160.     .ENDIF
  161.    
  162.     ;--------------------------------------------------------------------------
  163.     ; Cleanup
  164.     ;--------------------------------------------------------------------------
  165.     .IF CompressorHandle != 0
  166.         Invoke CloseCompressor, CompressorHandle
  167.     .ENDIF
  168.    
  169.     .IF lpdwCompressedDataLength != 0
  170.         mov ebx, lpdwCompressedDataLength
  171.         mov eax, CompressedDataSize
  172.         add eax, SIZEOF DWORD ; to account for compression header we add
  173.         mov [ebx], eax
  174.     .ENDIF
  175.    
  176.     mov eax, CompressedBuffer
  177.     ret
  178. CDCompressMem ENDP
  179.  
  180. ;------------------------------------------------------------------------------
  181. ; CDDecompressMem - Decompress memory that was previously compressed with one
  182. ; of the Cabinet compression algorithms. Checks for header signature first to
  183. ; verify that there is a compressed data and what algorithm to use.
  184. ;
  185. ; Returns: pointer to decompressed data if succesful or NULL otherwise.
  186. ; User should free memory when no longer required with call to GlobalFree
  187. ;------------------------------------------------------------------------------
  188. CDDecompressMem PROC USES EBX lpCompressedData:DWORD, dwCompressedDataLength:DWORD
  189.     LOCAL DecompressorHandle:DWORD
  190.     LOCAL DecompressedBuffer:DWORD
  191.     LOCAL DecompressedBufferSize:DWORD
  192.     LOCAL DecompressedDataSize:DWORD
  193.     LOCAL DecompressionAlgorithm:DWORD
  194.     LOCAL pData:DWORD
  195.     LOCAL nDataLength:DWORD
  196.    
  197.     IFDEF DEBUG32
  198.     PrintText 'CDDecompressMem'
  199.     ENDIF
  200.    
  201.     .IF lpCompressedData == NULL || dwCompressedDataLength == 0
  202.         mov eax, NULL
  203.         ret
  204.     .ENDIF
  205.    
  206.     ;--------------------------------------------------------------------------
  207.     ; Check for header signature and adjust pointer and length
  208.     ;--------------------------------------------------------------------------
  209.     mov ebx, lpCompressedData
  210.     mov eax, [ebx]
  211.     .IF eax == HEADER_MSZIP || eax == HEADER_XPRESS || eax == HEADER_HUFF || eax == HEADER_LZMS
  212.         .IF eax == HEADER_MSZIP
  213.             mov DecompressionAlgorithm, COMPRESS_ALGORITHM_MSZIP
  214.         .ELSEIF eax == HEADER_XPRESS
  215.             mov DecompressionAlgorithm, COMPRESS_ALGORITHM_XPRESS
  216.         .ELSEIF eax == HEADER_HUFF
  217.             mov DecompressionAlgorithm, COMPRESS_ALGORITHM_XPRESS_HUFF
  218.         .ELSEIF eax == HEADER_LZMS
  219.             mov DecompressionAlgorithm, COMPRESS_ALGORITHM_LZMS
  220.         .ENDIF
  221.     .ELSE
  222.         mov eax, NULL
  223.         ret
  224.     .ENDIF
  225.     mov eax, lpCompressedData
  226.     add eax, 4 ; skip past header signature
  227.     mov pData, eax
  228.    
  229.     mov eax, dwCompressedDataLength
  230.     sub eax, 4 ; we need 4 less coz of signature
  231.     .IF sdword ptr eax < 0 ; check size again
  232.         mov eax, NULL
  233.         ret
  234.     .ENDIF
  235.     mov nDataLength, eax
  236.    
  237.     ;--------------------------------------------------------------------------
  238.     ; Create decompressor
  239.     ;--------------------------------------------------------------------------
  240.     Invoke CreateDecompressor, DecompressionAlgorithm, NULL, Addr DecompressorHandle
  241.     .IF eax == FALSE
  242.         IFDEF DEBUG32
  243.         PrintText 'CDDecompressMem CreateDecompressor Failed'
  244.         ENDIF
  245.         mov eax, FALSE
  246.         ret
  247.     .ENDIF
  248.    
  249.     ;--------------------------------------------------------------------------
  250.     ; Get size required
  251.     ;--------------------------------------------------------------------------
  252.     Invoke Decompress, DecompressorHandle, pData, nDataLength, NULL, 0, Addr DecompressedBufferSize
  253.     .IF eax == FALSE
  254.         Invoke GetLastError
  255.         .IF eax == ERROR_INSUFFICIENT_BUFFER
  256.             ;
  257.         .ELSE
  258.             IFDEF DEBUG32
  259.             PrintText 'CDDecompressMem Decompress Get Size Failed'
  260.             ENDIF
  261.             .IF DecompressorHandle != 0
  262.                 Invoke CloseDecompressor, DecompressorHandle
  263.             .ENDIF
  264.             mov eax, NULL
  265.             ret
  266.         .ENDIF
  267.     .ENDIF
  268.    
  269.     ;--------------------------------------------------------------------------
  270.     ; Alloc buffer required
  271.     ;--------------------------------------------------------------------------
  272.     mov eax, DecompressedBufferSize
  273.     add eax, 4 ; we add four extra to give us 4 null bytes in case compressed
  274.     ; data is an ansi or unicode string or something that requires null endings
  275.     Invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, eax ;DecompressedBufferSize
  276.     .IF eax == NULL
  277.         IFDEF DEBUG32
  278.         PrintText 'CDDecompressMem GlobalAlloc Failed'
  279.         ENDIF
  280.         .IF DecompressorHandle != 0
  281.             Invoke CloseDecompressor, DecompressorHandle
  282.         .ENDIF
  283.         mov eax, NULL
  284.         ret
  285.     .ENDIF
  286.     mov DecompressedBuffer, eax
  287.    
  288.     ;--------------------------------------------------------------------------
  289.     ; Do the actual decompression now
  290.     ;--------------------------------------------------------------------------
  291.     Invoke Decompress, DecompressorHandle, pData, nDataLength, DecompressedBuffer, DecompressedBufferSize, Addr DecompressedDataSize
  292.     .IF eax == FALSE
  293.         IFDEF DEBUG32
  294.         PrintText 'CDDecompressMem Decompress Failed'
  295.         ENDIF
  296.         Invoke GetLastError
  297.         .IF eax == ERROR_BAD_COMPRESSION_BUFFER
  298.             IFDEF DEBUG32
  299.             PrintText 'CDDecompressMem Decompress Failed ERROR_BAD_COMPRESSION_BUFFER'
  300.             ENDIF
  301.         .ELSEIF eax == ERROR_INSUFFICIENT_BUFFER
  302.             IFDEF DEBUG32
  303.             PrintText 'CDDecompressMem Decompress Failed ERROR_INSUFFICIENT_BUFFER'
  304.             PrintDec DecompressedBufferSize
  305.             PrintDec nDataLength
  306.             PrintDec DecompressedBuffer
  307.             PrintDec pData
  308.             ENDIF
  309.         .ELSEIF eax == ERROR_FUNCTION_FAILED
  310.             IFDEF DEBUG32
  311.             PrintText 'CDDecompressMem Decompress Failed ERROR_FUNCTION_FAILED'
  312.             ENDIF
  313.         .ELSEIF eax == ERROR_INVALID_HANDLE
  314.             IFDEF DEBUG32
  315.             PrintText 'CDDecompressMem Decompress Failed ERROR_INVALID_HANDLE'
  316.             ENDIF
  317.         .ENDIF
  318.         .IF DecompressedBuffer != 0
  319.             Invoke GlobalFree, DecompressedBuffer
  320.         .ENDIF
  321.         .IF DecompressorHandle != 0
  322.             Invoke CloseDecompressor, DecompressorHandle
  323.         .ENDIF
  324.         mov eax, NULL
  325.         ret
  326.     .ENDIF
  327.    
  328.     ;--------------------------------------------------------------------------
  329.     ; Cleanup and return pointer to decompressed data
  330.     ;--------------------------------------------------------------------------
  331.     .IF DecompressorHandle != 0
  332.         Invoke CloseDecompressor, DecompressorHandle
  333.     .ENDIF
  334.    
  335.     mov eax, DecompressedBuffer
  336.     ret
  337. CDDecompressMem ENDP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement