#965: new hook function to support LZMA1/LZMA2 decompression for -m 11600 = 7-Zip

pull/986/head
philsmd 7 years ago
parent 5ea24d9bca
commit 6fe0173a79
No known key found for this signature in database
GPG Key ID: 4F25D016D9D6A8AF

@ -1359,26 +1359,17 @@ typedef struct
typedef struct
{
u32 user[16];
u32 ukey[8];
} cram_md5_t;
u32 hook_success;
} seven_zip_hook_t;
typedef struct
{
u32 iv_buf[4];
u32 iv_len;
u32 salt_buf[4];
u32 salt_len;
u32 crc;
u32 data_buf[96];
u32 data_len;
u32 unpack_size;
u32 user[16];
} seven_zip_t;
} cram_md5_t;
typedef struct
{

File diff suppressed because it is too large Load Diff

@ -5,6 +5,7 @@
##
- Added support for parsing 7-Zip hashes with LZMA/LZMA2 compression indicator set to a non-zero value
- Added support for decompressing LZMA1/LZMA2 data for -m 11600 = 7-Zip to validate the CRC
##
## Algorithms

@ -9,6 +9,7 @@
#include <stdio.h>
#include <errno.h>
int cpu_crc32 (hashcat_ctx_t *hashcat_ctx, const char *filename, u8 keytab[64]);
int cpu_crc32 (hashcat_ctx_t *hashcat_ctx, const char *filename, u8 keytab[64]);
u32 cpu_crc32_buffer (const u8 *buf, const size_t length);
#endif // _CPU_CRC32_H

@ -0,0 +1,18 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#ifndef _EXT_LZMA_H
#include "lzma_sdk/Alloc.h"
#include "lzma_sdk/LzmaDec.h"
#include "lzma_sdk/Lzma2Dec.h"
int hc_lzma1_decompress (const unsigned char *in, SizeT *in_len, unsigned char *out, SizeT *out_len, const char *props);
int hc_lzma2_decompress (const unsigned char *in, SizeT *in_len, unsigned char *out, SizeT *out_len, const char *props);
void *hc_lzma_alloc (void *p, size_t size);
void hc_lzma_free (void *p, void *address);
#endif // _EXT_LZMA_H

@ -753,7 +753,7 @@ typedef struct cram_md5
} cram_md5_t;
typedef struct seven_zip
typedef struct seven_zip_hook_salt
{
u32 iv_buf[4];
u32 iv_len;
@ -762,13 +762,26 @@ typedef struct seven_zip
u32 salt_len;
u32 crc;
u32 crc_len;
u32 data_buf[96];
u8 data_type;
u32 data_buf[2048];
u32 data_len;
u32 unpack_size;
} seven_zip_t;
char coder_attributes[5 + 1];
u8 coder_attributes_len;
u32 margin;
bool padding_check_full;
bool padding_check_fast;
int aes_len; // pre-computed length of the maximal (subset of) data we need for AES-CBC
} seven_zip_hook_salt_t;
typedef struct axcrypt_tmp
{
@ -784,6 +797,14 @@ typedef struct keepass_tmp
} keepass_tmp_t;
typedef struct seven_zip_hook
{
u32 ukey[8];
u32 hook_success;
} seven_zip_hook_t;
typedef struct struct_psafe2_hdr
{
u32 random[2];
@ -1066,8 +1087,8 @@ typedef enum display_len
DISPLAY_LEN_MAX_11400 = 6 + 512 + 1 + 512 + 1 + 116 + 1 + 116 + 1 + 246 + 1 + 245 + 1 + 246 + 1 + 245 + 1 + 50 + 1 + 50 + 1 + 50 + 1 + 50 + 1 + 3 + 1 + 32,
DISPLAY_LEN_MIN_11500 = 8 + 1 + 8,
DISPLAY_LEN_MAX_11500 = 8 + 1 + 8,
DISPLAY_LEN_MIN_11600 = 1 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 32 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 2,
DISPLAY_LEN_MAX_11600 = 1 + 2 + 1 + 1 + 1 + 2 + 1 + 1 + 1 + 64 + 1 + 1 + 1 + 32 + 1 + 10 + 1 + 3 + 1 + 3 + 1 + 768,
DISPLAY_LEN_MIN_11600 = 1 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 32 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 2,
DISPLAY_LEN_MAX_11600 = 1 + 2 + 1 + 1 + 1 + 2 + 1 + 1 + 1 + 64 + 1 + 1 + 1 + 32 + 1 + 10 + 1 + 4 + 1 + 4 + 1 + 16384+ /* only for compression: */ + 1 + 4 + 1 + 10,
DISPLAY_LEN_MIN_11700 = 64,
DISPLAY_LEN_MAX_11700 = 64,
DISPLAY_LEN_MIN_11800 = 128,
@ -1656,6 +1677,12 @@ int plaintext_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_bu
int sha1cx_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED const hashconfig_t *hashconfig);
int luks_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSED hashconfig_t *hashconfig, const int keyslot_idx);
/**
* hook functions
*/
void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, const u32 salt_pos, const u32 pws_cnt);
/**
* output functions
*/
@ -1675,7 +1702,7 @@ void hashconfig_destroy (hashcat_ctx_t *hashcat_ctx);
u32 hashconfig_get_kernel_threads (hashcat_ctx_t *hashcat_ctx, const hc_device_param_t *device_param);
u32 hashconfig_get_kernel_loops (hashcat_ctx_t *hashcat_ctx);
int hashconfig_general_defaults (hashcat_ctx_t *hashcat_ctx);
void hashconfig_benchmark_defaults (hashcat_ctx_t *hashcat_ctx, salt_t *salt, void *esalt);
void hashconfig_benchmark_defaults (hashcat_ctx_t *hashcat_ctx, salt_t *salt, void *esalt, void *hook_salt);
char *hashconfig_benchmark_mask (hashcat_ctx_t *hashcat_ctx);
#endif // _INTERFACE_H

@ -0,0 +1,256 @@
/* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#ifdef _WIN32
/* #include <windows.h> */
#endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned WRes;
#else
typedef int WRes;
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_NO_INLINE
#define MY_CDECL
#define MY_FAST_CALL
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct
{
SRes (*Look)(void *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ILookInStream;
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
size_t pos;
size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
EXTERN_C_END
#endif

@ -0,0 +1,37 @@
/* Alloc.h -- Memory allocation functions
2015-02-21 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
void *MyAlloc(size_t size);
void MyFree(void *address);
#ifdef _WIN32
void SetLargePageSize(void);
void *MidAlloc(size_t size);
void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
#else
#define MidAlloc(size) MyAlloc(size)
#define MidFree(address) MyFree(address)
#define BigAlloc(size) MyAlloc(size)
#define BigFree(address) MyFree(address)
#endif
extern ISzAlloc g_Alloc;
extern ISzAlloc g_BigAlloc;
EXTERN_C_END
#endif

@ -0,0 +1,32 @@
/* Compiler.h
2015-08-02 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
#ifdef _MSC_VER
#ifdef UNDER_CE
#define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
#endif
#if _MSC_VER >= 1300
#pragma warning(disable : 4996) // This function or variable may be unsafe
#else
#pragma warning(disable : 4511) // copy constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif

@ -0,0 +1,80 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2015-05-13 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
#include "LzmaDec.h"
EXTERN_C_BEGIN
/* ---------- State Interface ---------- */
typedef struct
{
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
unsigned state;
Byte control;
Bool needInitDic;
Bool needInitState;
Bool needInitProp;
} CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
void Lzma2Dec_Init(CLzma2Dec *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
SZ_ERROR_DATA - Data error
*/
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
EXTERN_C_END
#endif

@ -0,0 +1,229 @@
/* LzmaDec.h -- LZMA Decoder
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
#ifdef _LZMA_PROB32
#define CLzmaProb UInt32
#else
#define CLzmaProb UInt16
#endif
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
CLzmaProps prop;
CLzmaProb *probs;
Byte *dic;
const Byte *buf;
UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize;
UInt32 processedPos;
UInt32 checkDicSize;
unsigned state;
UInt32 reps[4];
unsigned remainLen;
int needFlush;
int needInitState;
UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Constr()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
EXTERN_C_END
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
#endif

@ -0,0 +1,10 @@
/* Precomp.h -- StdAfx
2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "Compiler.h"
/* #include "7zTypes.h" */
#endif

@ -365,6 +365,7 @@ typedef enum opts_type
OPTS_TYPE_HOOK12 = (1 << 26),
OPTS_TYPE_HOOK23 = (1 << 27),
OPTS_TYPE_BINARY_HASHFILE = (1 << 28),
OPTS_TYPE_HOOK_SALT = (1 << 29),
} opts_type_t;
@ -674,6 +675,8 @@ typedef struct hashinfo
user_t *user;
char *orighash;
void *hook_salt; // additional salt info only used by the hook (host)
} hashinfo_t;
typedef struct hash

@ -117,7 +117,7 @@ PRODUCTION := 0
## General compiler and linker options
##
CFLAGS += -pipe -std=c99 -Iinclude/ -IOpenCL/
CFLAGS += -pipe -std=c99 -Iinclude/ -Iinclude/lzma_sdk/ -IOpenCL/
CFLAGS += -Wno-format-zero-length
ifeq ($(PRODUCTION),0)
@ -274,7 +274,7 @@ include $(CRT_GLOB_INCLUDE_FOLDER)/win_file_globbing.mk
## Objects
##
OBJS_ALL := affinity autotune benchmark bitmap bitops combinator common convert cpt cpu_aes cpu_crc32 cpu_des cpu_md4 cpu_md5 cpu_sha1 cpu_sha256 debugfile dictstat dispatch dynloader event ext_ADL ext_nvapi ext_nvml ext_OpenCL ext_sysfs ext_xnvctrl filehandling folder hashcat hashes hlfmt hwmon induct interface locking logfile loopback memory monitor mpsp opencl outfile_check outfile potfile restore rp rp_cpu rp_kernel_on_cpu shared status stdout straight terminal thread timer tuningdb usage user_options weak_hash wordlist
OBJS_ALL := affinity autotune benchmark bitmap bitops combinator common convert cpt cpu_aes cpu_crc32 cpu_des cpu_md4 cpu_md5 cpu_sha1 cpu_sha256 debugfile dictstat dispatch dynloader event ext_ADL ext_nvapi ext_nvml ext_OpenCL ext_sysfs ext_xnvctrl ext_lzma lzma_sdk/Alloc lzma_sdk/Lzma2Dec lzma_sdk/LzmaDec filehandling folder hashcat hashes hlfmt hwmon induct interface locking logfile loopback memory monitor mpsp opencl outfile_check outfile potfile restore rp rp_cpu rp_kernel_on_cpu shared status stdout straight terminal thread timer tuningdb usage user_options weak_hash wordlist
NATIVE_OBJS :=
NATIVE_SHARED_OBJS := $(foreach OBJ,$(OBJS_ALL),obj/$(OBJ).NATIVE.SHARED.o)
@ -300,7 +300,7 @@ WIN_64_OBJS := $(foreach OBJ,$(OBJS_ALL),obj/$(OBJ).WIN.64.o) $(CRT_
default: $(HASHCAT_FRONTEND)
clean:
$(RM) -f obj/*.o *.bin *.exe *.so *.dll *.restore *.out *.pot *.log hashcat hashcat_shared core
$(RM) -f obj/*.o obj/lzma_sdk/*.o *.bin *.exe *.so *.dll *.restore *.out *.pot *.log hashcat hashcat_shared core
$(RM) -rf *.induct
$(RM) -rf *.outfiles
$(RM) -rf *.dSYM

@ -77,6 +77,18 @@ static const u32 crc32tab[256] =
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
u32 cpu_crc32_buffer (const u8 *buf, const size_t length)
{
u32 crc = ~0u;
for (size_t pos = 0; pos < length; pos++)
{
crc = crc32tab[(crc ^ buf[pos]) & 0xff] ^ (crc >> 8);
}
return crc ^ 0xffffffff;;
}
int cpu_crc32 (hashcat_ctx_t *hashcat_ctx, const char *filename, u8 keytab[64])
{
u32 crc = ~0u;

@ -0,0 +1,44 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#include "common.h"
#include "types.h"
#include "memory.h"
#include "event.h"
#include "ext_lzma.h"
void *hc_lzma_alloc (MAYBE_UNUSED void *p, size_t size)
{
return hcmalloc (size);
}
void hc_lzma_free (MAYBE_UNUSED void *p, void *address)
{
hcfree (address);
}
int hc_lzma1_decompress (const unsigned char *in, SizeT *in_len, unsigned char *out, SizeT *out_len, const char *props)
{
ISzAlloc hc_lzma_mem_alloc = {hc_lzma_alloc, hc_lzma_free};
ELzmaStatus status;
// parameters to LzmaDecode (): unsigned char *dest, size_t *destLen, const unsigned char *src,
// size_t *srcLen, const unsigned char *props, size_t propsSize, ELzmaFinishMode finishMode, ELzmaStatus status, ISzAlloc *alloc
return LzmaDecode (out, out_len, in, in_len, (Byte *) props, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &hc_lzma_mem_alloc);
}
int hc_lzma2_decompress (const unsigned char *in, SizeT *in_len, unsigned char *out, SizeT *out_len, const char *props)
{
ISzAlloc hc_lzma_mem_alloc = {hc_lzma_alloc, hc_lzma_free};
ELzmaStatus status;
// parameters to Lzma2Decode (): unsigned char *dest, size_t *destLen, const unsigned char *src,
// size_t *srcLen, const unsigned char props, ELzmaFinishMode finishMode, ELzmaStatus status, ISzAlloc *alloc
return Lzma2Decode (out, out_len, in, in_len, (Byte) props[0], LZMA_FINISH_ANY, &status, &hc_lzma_mem_alloc);
}

@ -570,7 +570,7 @@ int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx)
digests_buf = (void *) hccalloc (hashes_avail, hashconfig->dgst_size);
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY))
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT))
{
u32 hash_pos;
@ -585,9 +585,20 @@ int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx)
hash_info->user = (user_t*) hcmalloc (sizeof (user_t));
}
if (user_options->benchmark == true)
if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY)
{
hash_info->orighash = (char *) hcmalloc (256);
if (user_options->benchmark == false)
{
hash_info->orighash = (char *) hcmalloc (256);
}
}
if (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT)
{
if (hashconfig->hash_mode == 11600)
{
hash_info->hook_salt = (seven_zip_hook_salt_t *) hcmalloc (sizeof (seven_zip_hook_salt_t));
}
}
}
}
@ -638,7 +649,7 @@ int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx)
if (user_options->benchmark == true)
{
hashconfig_benchmark_defaults (hashcat_ctx, hashes_buf[0].salt, hashes_buf[0].esalt);
hashconfig_benchmark_defaults (hashcat_ctx, hashes_buf[0].salt, hashes_buf[0].esalt, hashes_buf[0].hash_info->hook_salt);
hashes->hashfile = "-";
@ -688,6 +699,16 @@ int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx)
hash_info_tmp->orighash = hcstrdup (hash_buf);
}
if (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT)
{
hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info;
if (hashconfig->hash_mode == 11600)
{
hash_info_tmp->hook_salt = hash_info_tmp->hook_salt;
}
}
if (hashconfig->is_salted)
{
memset (hashes_buf[0].salt, 0, sizeof (salt_t));
@ -926,6 +947,16 @@ int hashes_init_stage1 (hashcat_ctx_t *hashcat_ctx)
hash_info_tmp->orighash = hcstrdup (hash_buf);
}
if (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT)
{
hashinfo_t *hash_info_tmp = hashes_buf[hashes_cnt].hash_info;
if (hashconfig->hash_mode == 11600)
{
hash_info_tmp->hook_salt = hash_info_tmp->hook_salt;
}
}
if (hashconfig->is_salted)
{
memset (hashes_buf[hashes_cnt].salt, 0, sizeof (salt_t));
@ -1119,21 +1150,9 @@ int hashes_init_stage2 (hashcat_ctx_t *hashcat_ctx)
hashinfo_t **hash_info = NULL;
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY))
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT))
{
hash_info = (hashinfo_t **) hccalloc (hashes_cnt, sizeof (hashinfo_t *));
if (user_options->username == true)
{
u32 user_pos;
for (user_pos = 0; user_pos < hashes_cnt; user_pos++)
{
hash_info[user_pos] = (hashinfo_t *) hcmalloc (sizeof (hashinfo_t));
hash_info[user_pos]->user = (user_t *) hcmalloc (sizeof (user_t));
}
}
}
u32 *salts_shown = (u32 *) hccalloc (digests_cnt, sizeof (u32));
@ -1173,7 +1192,7 @@ int hashes_init_stage2 (hashcat_ctx_t *hashcat_ctx)
hashes_buf[0].digest = digests_buf_new_ptr;
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY))
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT))
{
hash_info[0] = hashes_buf[0].hash_info;
}
@ -1226,7 +1245,7 @@ int hashes_init_stage2 (hashcat_ctx_t *hashcat_ctx)
hashes_buf[hashes_pos].digest = digests_buf_new_ptr;
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY))
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT))
{
hash_info[hashes_pos] = hashes_buf[hashes_pos].hash_info;
}
@ -1391,7 +1410,9 @@ int hashes_init_stage4 (hashcat_ctx_t *hashcat_ctx)
void hashes_destroy (hashcat_ctx_t *hashcat_ctx)
{
hashes_t *hashes = hashcat_ctx->hashes;
hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
user_options_t *user_options = hashcat_ctx->user_options;
hashes_t *hashes = hashcat_ctx->hashes;
hcfree (hashes->digests_buf);
hcfree (hashes->digests_shown);
@ -1402,6 +1423,27 @@ void hashes_destroy (hashcat_ctx_t *hashcat_ctx)
hcfree (hashes->esalts_buf);
if ((user_options->username == true) || (hashconfig->opts_type & OPTS_TYPE_HASH_COPY) || (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT))
{
for (u32 hash_pos = 0; hash_pos < hashes->hashes_cnt; hash_pos++)
{
if (user_options->username == true)
{
hcfree (hashes->hash_info[hash_pos]->user);
}
if (hashconfig->opts_type & OPTS_TYPE_HASH_COPY)
{
hcfree (hashes->hash_info[hash_pos]->orighash);
}
if (hashconfig->opts_type & OPTS_TYPE_HOOK_SALT)
{
hcfree (hashes->hash_info[hash_pos]->hook_salt);
}
}
}
hcfree (hashes->hash_info);
hcfree (hashes->out_buf);

@ -18,6 +18,7 @@
#include "cpu_sha1.h"
#include "cpu_sha256.h"
#include "interface.h"
#include "ext_lzma.h"
static const char OPTI_STR_ZERO_BYTE[] = "Zero-Byte";
static const char OPTI_STR_PRECOMPUTE_INIT[] = "Precompute-Init";
@ -11059,19 +11060,19 @@ int seven_zip_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_
salt_t *salt = hash_buf->salt;
seven_zip_t *seven_zip = (seven_zip_t *) hash_buf->esalt;
seven_zip_hook_salt_t *seven_zip = (seven_zip_hook_salt_t *) hash_buf->hash_info->hook_salt;
/**
* parse line
*/
u8 *lzma_buf_pos = input_buf + 4;
u8 *data_type_pos = input_buf + 4;
u8 *NumCyclesPower_pos = (u8 *) strchr ((const char *) lzma_buf_pos, '$');
u8 *NumCyclesPower_pos = (u8 *) strchr ((const char *) data_type_pos, '$');
if (NumCyclesPower_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
u32 lzma_buf_len = NumCyclesPower_pos - lzma_buf_pos;
u32 data_type_len = NumCyclesPower_pos - data_type_pos;
NumCyclesPower_pos++;
@ -11139,33 +11140,109 @@ int seven_zip_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_
data_buf_pos++;
u32 data_buf_len = input_len - 1 - 2 - 1 - lzma_buf_len - 1 - NumCyclesPower_len - 1 - salt_len_len - 1 - salt_buf_len - 1 - iv_len_len - 1 - iv_buf_len - 1 - crc_buf_len - 1 - data_len_len - 1 - unpack_size_len - 1;
// fields only used when data was compressed:
u8 *crc_len_pos = (u8 *) strchr ((const char *) data_buf_pos, '$');
u32 crc_len_len = 0;
u8 *coder_attributes_pos = 0;
u32 coder_attributes_len = 0;
u32 data_buf_len = 0;
if (crc_len_pos != NULL)
{
data_buf_len = crc_len_pos - data_buf_pos;
crc_len_pos++;
coder_attributes_pos = (u8 *) strchr ((const char *) crc_len_pos, '$');
if (coder_attributes_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
crc_len_len = coder_attributes_pos - crc_len_pos;
coder_attributes_pos++;
}
else
{
data_buf_len = input_len - 1 - 2 - 1 - data_type_len - 1 - NumCyclesPower_len - 1 - salt_len_len - 1 - salt_buf_len - 1 - iv_len_len - 1 - iv_buf_len - 1 - crc_buf_len - 1 - data_len_len - 1 - unpack_size_len - 1;
}
const u32 iter = atoll ((const char *) NumCyclesPower_pos);
const u32 crc = atoll ((const char *) crc_buf_pos);
const u32 lzma_buf = atoll ((const char *) lzma_buf_pos);
const u32 data_type = atoll ((const char *) data_type_pos);
const u32 salt_len = atoll ((const char *) salt_len_pos);
const u32 iv_len = atoll ((const char *) iv_len_pos);
const u32 unpack_size = atoll ((const char *) unpack_size_pos);
const u32 data_len = atoll ((const char *) data_len_pos);
// if neither uncompressed nor truncated, then we need the length for crc and coder attributes
u32 crc_len = 0;
bool is_compressed = ((data_type != 0) && (data_type != 0x80));
if (is_compressed == true)
{
if (crc_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
coder_attributes_len = input_len - 1 - 2 - 1 - data_type_len - 1 - NumCyclesPower_len - 1 - salt_len_len - 1 - salt_buf_len - 1 - iv_len_len - 1 - iv_buf_len - 1 - crc_buf_len - 1 - data_len_len - 1 - unpack_size_len - 1 - data_buf_len - 1 - crc_len_len - 1;
crc_len = atoll ((const char *) crc_len_pos);
}
/**
* verify some data
*/
if (lzma_buf > 2) return (PARSER_SALT_VALUE);
if (data_type > 2)
{
// 0x80 is special case and means "truncated"
if (data_type != 0x80) return (PARSER_SALT_VALUE);
// if 0x80 (truncated), we always should have a data_len of exactly 16
if (data_len != 16) return (PARSER_SALT_VALUE);
}
if (salt_len != 0) return (PARSER_SALT_VALUE);
if ((data_len * 2) != data_buf_len) return (PARSER_SALT_VALUE);
if (data_len > 384) return (PARSER_SALT_VALUE);
if (data_len > 8192) return (PARSER_SALT_VALUE);
if (unpack_size > data_len) return (PARSER_SALT_VALUE);
if (is_compressed == true)
{
if (crc_len_len > 5) return (PARSER_SALT_VALUE);
if (coder_attributes_len > 10) return (PARSER_SALT_VALUE);
if ((coder_attributes_len % 2) != 0) return (PARSER_SALT_VALUE);
// we should be more strict about the needed attribute_len:
if (data_type == 1) // LZMA1
{
if ((coder_attributes_len / 2) != 5) return (PARSER_SALT_VALUE);
}
else if (data_type == 2) // LZMA2
{
if ((coder_attributes_len / 2) != 1) return (PARSER_SALT_VALUE);
}
}
/**
* store data
*/
seven_zip->data_type = data_type;
if (is_valid_hex_string (iv_buf_pos, 32) == false) return (PARSER_SALT_ENCODING);
seven_zip->iv_buf[0] = hex_to_u32 ((const u8 *) &iv_buf_pos[ 0]);
@ -11173,10 +11250,10 @@ int seven_zip_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_
seven_zip->iv_buf[2] = hex_to_u32 ((const u8 *) &iv_buf_pos[16]);
seven_zip->iv_buf[3] = hex_to_u32 ((const u8 *) &iv_buf_pos[24]);
seven_zip->iv_buf[0] = byte_swap_32 (seven_zip->iv_buf[0]);
seven_zip->iv_buf[1] = byte_swap_32 (seven_zip->iv_buf[1]);
seven_zip->iv_buf[2] = byte_swap_32 (seven_zip->iv_buf[2]);
seven_zip->iv_buf[3] = byte_swap_32 (seven_zip->iv_buf[3]);
seven_zip->iv_buf[0] = seven_zip->iv_buf[0];
seven_zip->iv_buf[1] = seven_zip->iv_buf[1];
seven_zip->iv_buf[2] = seven_zip->iv_buf[2];
seven_zip->iv_buf[3] = seven_zip->iv_buf[3];
seven_zip->iv_len = iv_len;
@ -11197,6 +11274,67 @@ int seven_zip_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_
seven_zip->unpack_size = unpack_size;
seven_zip->crc_len = crc_len;
memset (seven_zip->coder_attributes, 0, sizeof (seven_zip->coder_attributes));
seven_zip->coder_attributes_len = 0;
if (is_compressed == 1)
{
if (is_valid_hex_string (coder_attributes_pos, coder_attributes_len) == false) return (PARSER_SALT_ENCODING);
for (u32 i = 0, j = 0; j < coder_attributes_len; i += 1, j += 2)
{
seven_zip->coder_attributes[i] = hex_to_u8 ((const u8 *) &coder_attributes_pos[j]);
seven_zip->coder_attributes_len++;
}
}
// normally: crc_len <= unpacksize <= packsize (== data_len)
u32 aes_len = data_len;
if (crc_len != 0) // it is 0 only in case of uncompressed data or truncated data
{
// in theory we could just use crc_len, but sometimes (very rare) the compressed data
// is larger than the original data! (because of some additional bytes from lzma/headers)
// the +0.5 is used to round up (just to be sure we don't truncate)
if (data_type == 1) // LZMA1 uses more bytes
{
aes_len = 32.5f + (float) crc_len * 1.05f; // +5% max (only for small random inputs)
}
else if (data_type == 2) // LZMA2 is more clever (e.g. uncompressed chunks)
{
aes_len = 4.5f + (float) crc_len * 1.01f; // +1% max (only for small random inputs)
}
// just make sure we never go beyond the data_len limit itself
aes_len = MIN (aes_len, data_len);
}
seven_zip->aes_len = aes_len;
const u32 margin = data_len - unpack_size;
seven_zip->margin = margin;
seven_zip->padding_check_fast = (margin > 0) && (data_len >= 32);
if ((margin > 0) && (data_len < 32))
{
if ((data_len - aes_len) <= 16) // we need the same amount of AES BLOCKS (should always be true)!
{
seven_zip->padding_check_full = true; // determine if AES-CBC padding attack is possible
}
}
else
{
seven_zip->padding_check_full = false;
}
// real salt
salt->salt_buf[0] = seven_zip->data_buf[0];
@ -11206,7 +11344,7 @@ int seven_zip_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_
salt->salt_len = 16;
salt->salt_sign[0] = lzma_buf;
salt->salt_sign[0] = data_type;
salt->salt_iter = 1u << iter;
@ -13385,6 +13523,344 @@ int luks_parse_hash (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAYBE_UNUSE
return (PARSER_OK);
}
/**
* hook functions
*/
void seven_zip_hook_func (hc_device_param_t *device_param, hashes_t *hashes, const u32 salt_pos, const u32 pws_cnt)
{
seven_zip_hook_t *hook_items = (seven_zip_hook_t *) device_param->hooks_buf;
salt_t *salts_buf = hashes->salts_buf;
salt_t salt = salts_buf[salt_pos];
hashinfo_t *hash_info = hashes->hash_info[salt.digests_offset];
seven_zip_hook_salt_t *seven_zip = (seven_zip_hook_salt_t *) hash_info->hook_salt;
u8 data_type = seven_zip->data_type;
u32 *data_buf = seven_zip->data_buf;
u32 data_len = seven_zip->data_len;
u32 unpack_size = seven_zip->unpack_size;
u32 margin = seven_zip->margin;
// can we use the padding attack:
u32 padding_check_fast = seven_zip->padding_check_fast;
u32 padding_check_full = seven_zip->padding_check_full;
for (u32 pw_pos = 0; pw_pos < pws_cnt; pw_pos++)
{
// this hook data needs to be updated (the "hook_success" variable):
seven_zip_hook_t *hook_item = &hook_items[pw_pos];
const u8 *ukey = (const u8 *) hook_item->ukey;
// init AES
AES_KEY aes_key;
AES_set_decrypt_key (ukey, 256, &aes_key);
AES_KEY aes_key_copied;
memcpy (&aes_key_copied, &aes_key, sizeof (AES_KEY));
if (padding_check_fast == true) // use part of the data as initialization vector
{
u8 *data_buf_ptr = (u8 *) data_buf;
u32 data_tmp_buf[8];
memcpy (&data_tmp_buf, data_buf_ptr + data_len - 32, 32);
u32 data[4];
data[0] = data_tmp_buf[4];
data[1] = data_tmp_buf[5];
data[2] = data_tmp_buf[6];
data[3] = data_tmp_buf[7];
u32 out[4];
AES_decrypt (&aes_key, (u8*) data, (u8*) out);
out[0] ^= data_tmp_buf[0];
out[1] ^= data_tmp_buf[1];
out[2] ^= data_tmp_buf[2];
out[3] ^= data_tmp_buf[3];
switch (margin)
{
case 15: out[0] &= 0xffffff00;
break;
case 14: out[0] &= 0xffff0000;
break;
case 13: out[0] &= 0xff000000;
break;
case 12: out[0] = 0;
break;
case 11: out[0] = 0;
out[1] &= 0xffffff00;
break;
case 10: out[0] = 0;
out[1] &= 0xffff0000;
break;
case 9: out[0] = 0;
out[1] &= 0xff000000;
break;
case 8: out[0] = 0;
out[1] = 0;
break;
case 7: out[0] = 0;
out[1] = 0;
out[2] &= 0xffffff00;
break;
case 6: out[0] = 0;
out[1] = 0;
out[2] &= 0xffff0000;
break;
case 5: out[0] = 0;
out[1] = 0;
out[2] &= 0xff000000;
break;
case 4: out[0] = 0;
out[1] = 0;
out[2] = 0;
break;
case 3: out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] &= 0xffffff00;
break;
case 2: out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] &= 0xffff0000;
break;
case 1: out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] &= 0xff000000;
break;
}
if ((out[0] != 0) || (out[1] != 0) || (out[2] != 0) || (out[3] != 0))
{
hook_item->hook_success = 0;
continue;
}
}
// if the previous check was okay, we need to do some more staff to eliminate some possible false positives
int aes_len = seven_zip->aes_len;
u32 data[4];
u32 out [4];
u32 iv [4];
iv[0] = seven_zip->iv_buf[0];
iv[1] = seven_zip->iv_buf[1];
iv[2] = seven_zip->iv_buf[2];
iv[3] = seven_zip->iv_buf[3];
u32 out_full[2048];
// if aes_len > 16 we need to loop
int i = 0;
int j = 0;
for (i = 0, j = 0; i < aes_len - 16; i += 16, j += 4)
{
data[0] = data_buf[j + 0];
data[1] = data_buf[j + 1];
data[2] = data_buf[j + 2];
data[3] = data_buf[j + 3];
AES_decrypt (&aes_key_copied, (u8*) data, (u8*) out);
out[0] ^= iv[0];
out[1] ^= iv[1];
out[2] ^= iv[2];
out[3] ^= iv[3];
iv[0] = data[0];
iv[1] = data[1];
iv[2] = data[2];
iv[3] = data[3];
out_full[j + 0] = out[0];
out_full[j + 1] = out[1];
out_full[j + 2] = out[2];
out_full[j + 3] = out[3];
}
// we need to run it at least once:
data[0] = data_buf[j + 0];
data[1] = data_buf[j + 1];
data[2] = data_buf[j + 2];
data[3] = data_buf[j + 3];
AES_decrypt (&aes_key_copied, (u8*) data, (u8*) out);
out[0] ^= iv[0];
out[1] ^= iv[1];
out[2] ^= iv[2];
out[3] ^= iv[3];
out_full[j + 0] = out[0];
out_full[j + 1] = out[1];
out_full[j + 2] = out[2];
out_full[j + 3] = out[3];
if (padding_check_full == true)
{
// do the check if margin > 0 but data_len < 32
switch (margin)
{
case 15: out[0] &= 0xffffff00;
break;
case 14: out[0] &= 0xffff0000;
break;
case 13: out[0] &= 0xff000000;
break;
case 12: out[0] = 0;
break;
case 11: out[0] = 0;
out[1] &= 0xffffff00;
break;
case 10: out[0] = 0;
out[1] &= 0xffff0000;
break;
case 9: out[0] = 0;
out[1] &= 0xff000000;
break;
case 8: out[0] = 0;
out[1] = 0;
break;
case 7: out[0] = 0;
out[1] = 0;
out[2] &= 0xffffff00;
break;
case 6: out[0] = 0;
out[1] = 0;
out[2] &= 0xffff0000;
break;
case 5: out[0] = 0;
out[1] = 0;
out[2] &= 0xff000000;
break;
case 4: out[0] = 0;
out[1] = 0;
out[2] = 0;
break;
case 3: out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] &= 0xffffff00;
break;
case 2: out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] &= 0xffff0000;
break;
case 1: out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] &= 0xff000000;
break;
}
if ((out[0] != 0) || (out[1] != 0) || (out[2] != 0) || (out[3] != 0))
{
hook_item->hook_success = 0;
continue;
}
}
if (data_type == 0x80) // truncated
{
// we can't do a full CRC check since data in this case is truncated
// could lead to a higher number of false positives in very rare cases
hook_item->hook_success = 1;
continue;
}
/*
* check the CRC32 "hash"
*/
u32 seven_zip_crc = seven_zip->crc;
u32 crc;
if (data_type == 0) // uncompressed
{
crc = cpu_crc32_buffer ((u8 *) out_full, unpack_size);
}
else
{
u32 crc_len = seven_zip->crc_len;
char *coder_attributes = seven_zip->coder_attributes;
// input buffers and length
u8 *compressed_data = (u8 *) out_full;
SizeT compressed_data_len = aes_len;
// output buffers and length
unsigned char *decompressed_data;
decompressed_data = (unsigned char *) hcmalloc (crc_len);
SizeT decompressed_data_len = crc_len;
int ret;
if (data_type == 1) // LZMA1
{
ret = hc_lzma1_decompress (compressed_data, &compressed_data_len, decompressed_data, &decompressed_data_len, coder_attributes);
}
else // we only support LZMA2 in addition to LZMA1
{
ret = hc_lzma2_decompress (compressed_data, &compressed_data_len, decompressed_data, &decompressed_data_len, coder_attributes);
}
if (ret != SZ_OK)
{
hook_item->hook_success = 0;
hcfree (decompressed_data);
continue;
}
crc = cpu_crc32_buffer (decompressed_data, crc_len);
hcfree (decompressed_data);
}
if (crc == seven_zip_crc)
{
hook_item->hook_success = 1;
}
else
{
hook_item->hook_success = 0;
}
}
}
/**
* output
*/
@ -15934,9 +16410,11 @@ int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const size_t out_le
}
else if (hash_mode == 11600)
{
seven_zip_t *seven_zips = (seven_zip_t *) esalts_buf;
u32 digest_idx = salt.digests_offset + digest_pos;
hashinfo_t **hashinfo_ptr = hash_info;
seven_zip_t *seven_zip = &seven_zips[salt_pos];
seven_zip_hook_salt_t *seven_zip = (seven_zip_hook_salt_t *) hashinfo_ptr[digest_idx]->hook_salt;
const u32 data_len = seven_zip->data_len;
@ -15946,11 +16424,20 @@ int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const size_t out_le
{
const u8 *ptr = (const u8 *) seven_zip->data_buf;
sprintf (data_buf + j, "%02x", ptr[i]);
snprintf (data_buf + j, (data_len * 2) + 1 - j, "%02x", ptr[i]);
}
u32 salt_iter = salt.salt_iter;
u32 iv[4];
iv[0] = byte_swap_32 (seven_zip->iv_buf[0]);
iv[1] = byte_swap_32 (seven_zip->iv_buf[1]);
iv[2] = byte_swap_32 (seven_zip->iv_buf[2]);
iv[3] = byte_swap_32 (seven_zip->iv_buf[3]);
u32 iv_len = seven_zip->iv_len;
u32 cost = 0; // the log2 () of salt_iter
while (salt_iter >>= 1)
@ -15964,16 +16451,37 @@ int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const size_t out_le
cost,
seven_zip->salt_len,
(char *) seven_zip->salt_buf,
seven_zip->iv_len,
seven_zip->iv_buf[0],
seven_zip->iv_buf[1],
seven_zip->iv_buf[2],
seven_zip->iv_buf[3],
iv_len,
iv[0],
iv[1],
iv[2],
iv[3],
seven_zip->crc,
seven_zip->data_len,
seven_zip->unpack_size,
data_buf);
if (seven_zip->data_type > 0)
{
if (seven_zip->data_type != 0x80) // 0x80 would be a special case: means truncated
{
u32 bytes_written = strlen (out_buf);
snprintf (out_buf + bytes_written, out_len - bytes_written - 1, "$%i$", seven_zip->crc_len);
bytes_written = strlen (out_buf);
const u8 *ptr = (const u8 *) seven_zip->coder_attributes;
for (u32 i = 0, j = 0; i < seven_zip->coder_attributes_len; i += 1, j += 2)
{
snprintf (out_buf + bytes_written, out_len - bytes_written - 1, "%02x", ptr[i]);
bytes_written += 2;
}
}
}
hcfree (data_buf);
}
else if (hash_mode == 11700)
@ -19823,7 +20331,8 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
hashconfig->salt_type = SALT_TYPE_EMBEDDED;
hashconfig->attack_exec = ATTACK_EXEC_OUTSIDE_KERNEL;
hashconfig->opts_type = OPTS_TYPE_PT_GENERATE_LE
| OPTS_TYPE_PT_NEVERCRACK;
| OPTS_TYPE_HOOK23
| OPTS_TYPE_HOOK_SALT;
hashconfig->kern_type = KERN_TYPE_SEVEN_ZIP;
hashconfig->dgst_size = DGST_SIZE_4_4; // originally DGST_SIZE_4_2
hashconfig->parse_func = seven_zip_parse_hash;
@ -20628,7 +21137,6 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
case 10900: hashconfig->esalt_size = sizeof (pbkdf2_sha256_t); break;
case 11300: hashconfig->esalt_size = sizeof (bitcoin_wallet_t); break;
case 11400: hashconfig->esalt_size = sizeof (sip_t); break;
case 11600: hashconfig->esalt_size = sizeof (seven_zip_t); break;
case 11900: hashconfig->esalt_size = sizeof (pbkdf2_md5_t); break;
case 12000: hashconfig->esalt_size = sizeof (pbkdf2_sha1_t); break;
case 12100: hashconfig->esalt_size = sizeof (pbkdf2_sha512_t); break;
@ -20754,6 +21262,7 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
switch (hashconfig->hash_mode)
{
case 11600: hashconfig->hook_size = sizeof (seven_zip_hook_t); break;
};
// pw_min
@ -20976,7 +21485,7 @@ int hashconfig_general_defaults (hashcat_ctx_t *hashcat_ctx)
return 0;
}
void hashconfig_benchmark_defaults (hashcat_ctx_t *hashcat_ctx, salt_t *salt, void *esalt)
void hashconfig_benchmark_defaults (hashcat_ctx_t *hashcat_ctx, salt_t *salt, void *esalt, void *hook_salt)
{
hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
@ -21109,10 +21618,6 @@ void hashconfig_benchmark_defaults (hashcat_ctx_t *hashcat_ctx, salt_t *salt, vo
((pdf_t *) esalt)->o_len = 127;
((pdf_t *) esalt)->u_len = 127;
break;
case 11600: ((seven_zip_t *) esalt)->iv_len = 16;
((seven_zip_t *) esalt)->data_len = 112;
((seven_zip_t *) esalt)->unpack_size = 112;
break;
case 13400: ((keepass_t *) esalt)->version = 2;
break;
case 13500: ((pstoken_t *) esalt)->salt_len = 113;
@ -21126,8 +21631,19 @@ void hashconfig_benchmark_defaults (hashcat_ctx_t *hashcat_ctx, salt_t *salt, vo
((luks_t *) esalt)->cipher_mode = HC_LUKS_CIPHER_MODE_XTS_PLAIN;
break;
}
// special hook salt handling
switch (hashconfig->hash_mode)
{
case 11600: ((seven_zip_hook_salt_t *) hook_salt)->iv_len = 16;
((seven_zip_hook_salt_t *) hook_salt)->data_len = 112;
((seven_zip_hook_salt_t *) hook_salt)->unpack_size = 112;
break;
}
}
// set default iterations
switch (hashconfig->hash_mode)

@ -0,0 +1,136 @@
/* Alloc.c -- Memory allocation functions
2015-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdlib.h>
#include "Alloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountMid = 0;
int g_allocCountBig = 0;
#endif
void *MyAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
{
void *p = malloc(size);
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
return p;
}
#else
return malloc(size);
#endif
}
void MyFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
#endif
free(address);
}
#ifdef _WIN32
void *MidAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
#endif
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
}
void MidFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
#endif
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#ifndef MEM_LARGE_PAGES
#undef _7ZIP_LARGE_PAGES
#endif
#ifdef _7ZIP_LARGE_PAGES
SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
#endif
void SetLargePageSize()
{
#ifdef _7ZIP_LARGE_PAGES
SIZE_T size = 0;
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
if (largePageMinimum == 0)
return;
size = largePageMinimum();
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
#endif
}
void *BigAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
#endif
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
{
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
if (res != 0)
return res;
}
#endif
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
}
void BigFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
#endif
if (address == 0)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#endif
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };

@ -0,0 +1,378 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
#include "Precomp.h"
#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif
#include <string.h>
#include "Lzma2Dec.h"
/*
00000000 - EOS
00000001 U U - Uncompressed Reset Dic
00000010 U U - Uncompressed No Reset
100uuuuu U U P P - LZMA no reset
101uuuuu U U P P - LZMA reset state
110uuuuu U U P P S - LZMA reset state + new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
u, U - Unpack Size
P - Pack Size
S - Props
*/
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
typedef enum
{
LZMA2_STATE_CONTROL,
LZMA2_STATE_UNPACK0,
LZMA2_STATE_UNPACK1,
LZMA2_STATE_PACK0,
LZMA2_STATE_PACK1,
LZMA2_STATE_PROP,
LZMA2_STATE_DATA,
LZMA2_STATE_DATA_CONT,
LZMA2_STATE_FINISHED,
LZMA2_STATE_ERROR
} ELzma2State;
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
{
UInt32 dicSize;
if (prop > 40)
return SZ_ERROR_UNSUPPORTED;
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
props[0] = (Byte)LZMA2_LCLP_MAX;
props[1] = (Byte)(dicSize);
props[2] = (Byte)(dicSize >> 8);
props[3] = (Byte)(dicSize >> 16);
props[4] = (Byte)(dicSize >> 24);
return SZ_OK;
}
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
{
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
{
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
void Lzma2Dec_Init(CLzma2Dec *p)
{
p->state = LZMA2_STATE_CONTROL;
p->needInitDic = True;
p->needInitState = True;
p->needInitProp = True;
LzmaDec_Init(&p->decoder);
}
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{
switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->control = b;
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", (unsigned)b));
if (p->control == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if ((p->control & 0x7F) > 2)
return LZMA2_STATE_ERROR;
p->unpackSize = 0;
}
else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP:
{
unsigned lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = b / 5;
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc;
p->decoder.prop.lp = lp;
p->needInitProp = False;
return LZMA2_STATE_DATA;
}
}
return LZMA2_STATE_ERROR;
}
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
{
memcpy(p->dic + p->dicPos, src, size);
p->dicPos += size;
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
p->checkDicSize = p->prop.dicSize;
p->processedPos += (UInt32)size;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
*srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED)
{
SizeT dicPos = p->decoder.dicPos;
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
continue;
}
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur)
{
destSizeCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->state == LZMA2_STATE_DATA)
{
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
if (srcSizeCur > destSizeCur)
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
SizeT outSizeProcessed;
SRes res;
if (p->state == LZMA2_STATE_DATA)
{
unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT;
}
if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur;
outSizeProcessed = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outSizeProcessed;
RINOK(res);
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res;
if (srcSizeCur == 0 && outSizeProcessed == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0
|| p->packSize != 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->state = LZMA2_STATE_CONTROL;
}
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0;
for (;;)
{
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos)
{
outSizeCur = p->decoder.dicBufSize;
curFinishMode = LZMA_FINISH_ANY;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
}
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur;
*srcLen += srcSizeCur;
outSizeCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
}
}
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{
CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
Lzma2Dec_Construct(&p);
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest;
p.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&p);
*srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc);
return res;
}

File diff suppressed because it is too large Load Diff

@ -1111,7 +1111,7 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param,
}
else
{
CL_rc = run_kernel (hashcat_ctx, device_param, KERN_RUN_3,pws_cnt, true, fast_iteration);
CL_rc = run_kernel (hashcat_ctx, device_param, KERN_RUN_3, pws_cnt, true, fast_iteration);
if (CL_rc == -1) return -1;
}
@ -1214,7 +1214,19 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param,
if (CL_rc == -1) return -1;
// do something with data
/*
* The following section depends on the hash mode
*/
switch (hashconfig->hash_mode)
{
// for 7z we only need device_param->hooks_buf, but other hooks could use any info from device_param. All of them should/must update hooks_buf
case 11600: seven_zip_hook_func (device_param, hashes, salt_pos, pws_cnt); break;
}
/*
* END of hash mode specific hook operations
*/
CL_rc = hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->command_queue, device_param->d_hooks, CL_TRUE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL);

Loading…
Cancel
Save