mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
f2ac1ece55
add
354 lines
13 KiB
C#
354 lines
13 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: SevenZip.Compression.LZMA.Decoder
|
|
// Assembly: P4CTEMP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
// MVID: 7BE4E538-8555-4C2E-974B-99E556F5462C
|
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Trojan-Ransom.Win32.Gimemo.ayt-624a52079bf1703bcd3bcc9d2d3716b6126fd05655e25289d19142f9aae02eb5.exe
|
|
|
|
using SevenZip.Compression.LZ;
|
|
using SevenZip.Compression.RangeCoder;
|
|
using System;
|
|
using System.IO;
|
|
|
|
namespace SevenZip.Compression.LZMA
|
|
{
|
|
public class Decoder : ICoder, ISetDecoderProperties
|
|
{
|
|
private OutWindow m_OutWindow = new OutWindow();
|
|
private SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
|
|
private BitDecoder[] m_IsMatchDecoders = new BitDecoder[new IntPtr(192)];
|
|
private BitDecoder[] m_IsRepDecoders = new BitDecoder[new IntPtr(12)];
|
|
private BitDecoder[] m_IsRepG0Decoders = new BitDecoder[new IntPtr(12)];
|
|
private BitDecoder[] m_IsRepG1Decoders = new BitDecoder[new IntPtr(12)];
|
|
private BitDecoder[] m_IsRepG2Decoders = new BitDecoder[new IntPtr(12)];
|
|
private BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[new IntPtr(192)];
|
|
private BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[new IntPtr(4)];
|
|
private BitDecoder[] m_PosDecoders = new BitDecoder[new IntPtr(114)];
|
|
private BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(4);
|
|
private Decoder.LenDecoder m_LenDecoder = new Decoder.LenDecoder();
|
|
private Decoder.LenDecoder m_RepLenDecoder = new Decoder.LenDecoder();
|
|
private Decoder.LiteralDecoder m_LiteralDecoder = new Decoder.LiteralDecoder();
|
|
private uint m_DictionarySize;
|
|
private uint m_DictionarySizeCheck;
|
|
private uint m_PosStateMask;
|
|
private bool _solid;
|
|
|
|
public Decoder()
|
|
{
|
|
this.m_DictionarySize = uint.MaxValue;
|
|
for (int index = 0; index < 4; ++index)
|
|
this.m_PosSlotDecoder[index] = new BitTreeDecoder(6);
|
|
}
|
|
|
|
private void SetDictionarySize(uint dictionarySize)
|
|
{
|
|
if ((int) this.m_DictionarySize == (int) dictionarySize)
|
|
return;
|
|
this.m_DictionarySize = dictionarySize;
|
|
this.m_DictionarySizeCheck = Math.Max(this.m_DictionarySize, 1U);
|
|
this.m_OutWindow.Create(Math.Max(this.m_DictionarySizeCheck, 4096U));
|
|
}
|
|
|
|
private void SetLiteralProperties(int lp, int lc)
|
|
{
|
|
if (lp > 8)
|
|
throw new InvalidParamException();
|
|
if (lc > 8)
|
|
throw new InvalidParamException();
|
|
this.m_LiteralDecoder.Create(lp, lc);
|
|
}
|
|
|
|
private void SetPosBitsProperties(int pb)
|
|
{
|
|
if (pb > 4)
|
|
throw new InvalidParamException();
|
|
uint numPosStates = (uint) (1 << pb);
|
|
this.m_LenDecoder.Create(numPosStates);
|
|
this.m_RepLenDecoder.Create(numPosStates);
|
|
this.m_PosStateMask = numPosStates - 1U;
|
|
}
|
|
|
|
private void Init(Stream inStream, Stream outStream)
|
|
{
|
|
this.m_RangeDecoder.Init(inStream);
|
|
this.m_OutWindow.Init(outStream, this._solid);
|
|
for (uint index1 = 0; index1 < 12U; ++index1)
|
|
{
|
|
for (uint index2 = 0; index2 <= this.m_PosStateMask; ++index2)
|
|
{
|
|
uint index3 = (index1 << 4) + index2;
|
|
this.m_IsMatchDecoders[(IntPtr) index3].Init();
|
|
this.m_IsRep0LongDecoders[(IntPtr) index3].Init();
|
|
}
|
|
this.m_IsRepDecoders[(IntPtr) index1].Init();
|
|
this.m_IsRepG0Decoders[(IntPtr) index1].Init();
|
|
this.m_IsRepG1Decoders[(IntPtr) index1].Init();
|
|
this.m_IsRepG2Decoders[(IntPtr) index1].Init();
|
|
}
|
|
this.m_LiteralDecoder.Init();
|
|
for (uint index = 0; index < 4U; ++index)
|
|
this.m_PosSlotDecoder[(IntPtr) index].Init();
|
|
for (uint index = 0; index < 114U; ++index)
|
|
this.m_PosDecoders[(IntPtr) index].Init();
|
|
this.m_LenDecoder.Init();
|
|
this.m_RepLenDecoder.Init();
|
|
this.m_PosAlignDecoder.Init();
|
|
}
|
|
|
|
public void Code(
|
|
Stream inStream,
|
|
Stream outStream,
|
|
long inSize,
|
|
long outSize,
|
|
ICodeProgress progress)
|
|
{
|
|
this.Init(inStream, outStream);
|
|
Base.State state = new Base.State();
|
|
state.Init();
|
|
uint distance = 0;
|
|
uint num1 = 0;
|
|
uint num2 = 0;
|
|
uint num3 = 0;
|
|
ulong pos = 0;
|
|
ulong num4 = (ulong) outSize;
|
|
if (pos < num4)
|
|
{
|
|
if (this.m_IsMatchDecoders[(IntPtr) (state.Index << 4)].Decode(this.m_RangeDecoder) != 0U)
|
|
throw new DataErrorException();
|
|
state.UpdateChar();
|
|
this.m_OutWindow.PutByte(this.m_LiteralDecoder.DecodeNormal(this.m_RangeDecoder, 0U, (byte) 0));
|
|
++pos;
|
|
}
|
|
while (pos < num4)
|
|
{
|
|
uint posState = (uint) pos & this.m_PosStateMask;
|
|
if (this.m_IsMatchDecoders[(IntPtr) ((state.Index << 4) + posState)].Decode(this.m_RangeDecoder) == 0U)
|
|
{
|
|
byte prevByte = this.m_OutWindow.GetByte(0U);
|
|
this.m_OutWindow.PutByte(state.IsCharState() ? this.m_LiteralDecoder.DecodeNormal(this.m_RangeDecoder, (uint) pos, prevByte) : this.m_LiteralDecoder.DecodeWithMatchByte(this.m_RangeDecoder, (uint) pos, prevByte, this.m_OutWindow.GetByte(distance)));
|
|
state.UpdateChar();
|
|
++pos;
|
|
}
|
|
else
|
|
{
|
|
uint len;
|
|
if (this.m_IsRepDecoders[(IntPtr) state.Index].Decode(this.m_RangeDecoder) == 1U)
|
|
{
|
|
if (this.m_IsRepG0Decoders[(IntPtr) state.Index].Decode(this.m_RangeDecoder) == 0U)
|
|
{
|
|
if (this.m_IsRep0LongDecoders[(IntPtr) ((state.Index << 4) + posState)].Decode(this.m_RangeDecoder) == 0U)
|
|
{
|
|
state.UpdateShortRep();
|
|
this.m_OutWindow.PutByte(this.m_OutWindow.GetByte(distance));
|
|
++pos;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint num5;
|
|
if (this.m_IsRepG1Decoders[(IntPtr) state.Index].Decode(this.m_RangeDecoder) == 0U)
|
|
{
|
|
num5 = num1;
|
|
}
|
|
else
|
|
{
|
|
if (this.m_IsRepG2Decoders[(IntPtr) state.Index].Decode(this.m_RangeDecoder) == 0U)
|
|
{
|
|
num5 = num2;
|
|
}
|
|
else
|
|
{
|
|
num5 = num3;
|
|
num3 = num2;
|
|
}
|
|
num2 = num1;
|
|
}
|
|
num1 = distance;
|
|
distance = num5;
|
|
}
|
|
len = this.m_RepLenDecoder.Decode(this.m_RangeDecoder, posState) + 2U;
|
|
state.UpdateRep();
|
|
}
|
|
else
|
|
{
|
|
num3 = num2;
|
|
num2 = num1;
|
|
num1 = distance;
|
|
len = 2U + this.m_LenDecoder.Decode(this.m_RangeDecoder, posState);
|
|
state.UpdateMatch();
|
|
uint num6 = this.m_PosSlotDecoder[(IntPtr) Base.GetLenToPosState(len)].Decode(this.m_RangeDecoder);
|
|
if (num6 >= 4U)
|
|
{
|
|
int NumBitLevels = (int) (num6 >> 1) - 1;
|
|
uint num7 = (uint) ((2 | (int) num6 & 1) << NumBitLevels);
|
|
distance = num6 >= 14U ? num7 + (this.m_RangeDecoder.DecodeDirectBits(NumBitLevels - 4) << 4) + this.m_PosAlignDecoder.ReverseDecode(this.m_RangeDecoder) : num7 + BitTreeDecoder.ReverseDecode(this.m_PosDecoders, (uint) ((int) num7 - (int) num6 - 1), this.m_RangeDecoder, NumBitLevels);
|
|
}
|
|
else
|
|
distance = num6;
|
|
}
|
|
if ((ulong) distance >= (ulong) this.m_OutWindow.TrainSize + pos || distance >= this.m_DictionarySizeCheck)
|
|
{
|
|
if (distance != uint.MaxValue)
|
|
throw new DataErrorException();
|
|
break;
|
|
}
|
|
this.m_OutWindow.CopyBlock(distance, len);
|
|
pos += (ulong) len;
|
|
}
|
|
}
|
|
this.m_OutWindow.Flush();
|
|
this.m_OutWindow.ReleaseStream();
|
|
this.m_RangeDecoder.ReleaseStream();
|
|
}
|
|
|
|
public void SetDecoderProperties(byte[] properties)
|
|
{
|
|
if (properties.Length < 5)
|
|
throw new InvalidParamException();
|
|
int lc = (int) properties[0] % 9;
|
|
int num = (int) properties[0] / 9;
|
|
int lp = num % 5;
|
|
int pb = num / 5;
|
|
if (pb > 4)
|
|
throw new InvalidParamException();
|
|
uint dictionarySize = 0;
|
|
for (int index = 0; index < 4; ++index)
|
|
dictionarySize += (uint) properties[1 + index] << index * 8;
|
|
this.SetDictionarySize(dictionarySize);
|
|
this.SetLiteralProperties(lp, lc);
|
|
this.SetPosBitsProperties(pb);
|
|
}
|
|
|
|
public bool Train(Stream stream)
|
|
{
|
|
this._solid = true;
|
|
return this.m_OutWindow.Train(stream);
|
|
}
|
|
|
|
private class LenDecoder
|
|
{
|
|
private BitDecoder m_Choice = new BitDecoder();
|
|
private BitDecoder m_Choice2 = new BitDecoder();
|
|
private BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[new IntPtr(16)];
|
|
private BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[new IntPtr(16)];
|
|
private BitTreeDecoder m_HighCoder = new BitTreeDecoder(8);
|
|
private uint m_NumPosStates;
|
|
|
|
public void Create(uint numPosStates)
|
|
{
|
|
for (uint numPosStates1 = this.m_NumPosStates; numPosStates1 < numPosStates; ++numPosStates1)
|
|
{
|
|
this.m_LowCoder[(IntPtr) numPosStates1] = new BitTreeDecoder(3);
|
|
this.m_MidCoder[(IntPtr) numPosStates1] = new BitTreeDecoder(3);
|
|
}
|
|
this.m_NumPosStates = numPosStates;
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
this.m_Choice.Init();
|
|
for (uint index = 0; index < this.m_NumPosStates; ++index)
|
|
{
|
|
this.m_LowCoder[(IntPtr) index].Init();
|
|
this.m_MidCoder[(IntPtr) index].Init();
|
|
}
|
|
this.m_Choice2.Init();
|
|
this.m_HighCoder.Init();
|
|
}
|
|
|
|
public uint Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, uint posState)
|
|
{
|
|
if (this.m_Choice.Decode(rangeDecoder) == 0U)
|
|
return this.m_LowCoder[(IntPtr) posState].Decode(rangeDecoder);
|
|
uint num = 8;
|
|
return this.m_Choice2.Decode(rangeDecoder) != 0U ? num + 8U + this.m_HighCoder.Decode(rangeDecoder) : num + this.m_MidCoder[(IntPtr) posState].Decode(rangeDecoder);
|
|
}
|
|
}
|
|
|
|
private class LiteralDecoder
|
|
{
|
|
private Decoder.LiteralDecoder.Decoder2[] m_Coders;
|
|
private int m_NumPrevBits;
|
|
private int m_NumPosBits;
|
|
private uint m_PosMask;
|
|
|
|
public void Create(int numPosBits, int numPrevBits)
|
|
{
|
|
if (this.m_Coders != null && this.m_NumPrevBits == numPrevBits && this.m_NumPosBits == numPosBits)
|
|
return;
|
|
this.m_NumPosBits = numPosBits;
|
|
this.m_PosMask = (uint) ((1 << numPosBits) - 1);
|
|
this.m_NumPrevBits = numPrevBits;
|
|
uint length = (uint) (1 << this.m_NumPrevBits + this.m_NumPosBits);
|
|
this.m_Coders = new Decoder.LiteralDecoder.Decoder2[(IntPtr) length];
|
|
for (uint index = 0; index < length; ++index)
|
|
this.m_Coders[(IntPtr) index].Create();
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
uint num = (uint) (1 << this.m_NumPrevBits + this.m_NumPosBits);
|
|
for (uint index = 0; index < num; ++index)
|
|
this.m_Coders[(IntPtr) index].Init();
|
|
}
|
|
|
|
private uint GetState(uint pos, byte prevByte) => (uint) ((((int) pos & (int) this.m_PosMask) << this.m_NumPrevBits) + ((int) prevByte >> 8 - this.m_NumPrevBits));
|
|
|
|
public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte) => this.m_Coders[(IntPtr) this.GetState(pos, prevByte)].DecodeNormal(rangeDecoder);
|
|
|
|
public byte DecodeWithMatchByte(
|
|
SevenZip.Compression.RangeCoder.Decoder rangeDecoder,
|
|
uint pos,
|
|
byte prevByte,
|
|
byte matchByte)
|
|
{
|
|
return this.m_Coders[(IntPtr) this.GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte);
|
|
}
|
|
|
|
private struct Decoder2
|
|
{
|
|
private BitDecoder[] m_Decoders;
|
|
|
|
public void Create() => this.m_Decoders = new BitDecoder[768];
|
|
|
|
public void Init()
|
|
{
|
|
for (int index = 0; index < 768; ++index)
|
|
this.m_Decoders[index].Init();
|
|
}
|
|
|
|
public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder)
|
|
{
|
|
uint index = 1;
|
|
do
|
|
{
|
|
index = index << 1 | this.m_Decoders[(IntPtr) index].Decode(rangeDecoder);
|
|
}
|
|
while (index < 256U);
|
|
return (byte) index;
|
|
}
|
|
|
|
public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte)
|
|
{
|
|
uint index = 1;
|
|
do
|
|
{
|
|
uint num1 = (uint) ((int) matchByte >> 7 & 1);
|
|
matchByte <<= 1;
|
|
uint num2 = this.m_Decoders[(IntPtr) ((uint) (1 + (int) num1 << 8) + index)].Decode(rangeDecoder);
|
|
index = index << 1 | num2;
|
|
if ((int) num1 != (int) num2)
|
|
{
|
|
while (index < 256U)
|
|
index = index << 1 | this.m_Decoders[(IntPtr) index].Decode(rangeDecoder);
|
|
break;
|
|
}
|
|
}
|
|
while (index < 256U);
|
|
return (byte) index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|