mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-23 20:05:26 +00:00
337 lines
14 KiB
C#
337 lines
14 KiB
C#
|
// Decompiled with JetBrains decompiler
|
|||
|
// Type: Microsoft.InfoCards.IndexedDataBuffer
|
|||
|
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|
|||
|
// MVID: ADE0A079-11DB-4A46-8BDE-D2A592CA8DEA
|
|||
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00001-msil\Virus.Win32.Expiro.w-1f15ee7e9f7da02b6bfb4c5a5e6484eb9fa71b82d3699c54bcc7a31794b4a66d.exe
|
|||
|
|
|||
|
using Microsoft.InfoCards.Diagnostics;
|
|||
|
using System;
|
|||
|
using System.IO;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace Microsoft.InfoCards
|
|||
|
{
|
|||
|
internal class IndexedDataBuffer
|
|||
|
{
|
|||
|
private byte[] m_buffer;
|
|||
|
private byte[] m_masterIndex;
|
|||
|
private FreeIndexList m_freeList;
|
|||
|
private int m_dataLength;
|
|||
|
private bool m_isOpen;
|
|||
|
private DataSource m_owner;
|
|||
|
|
|||
|
public unsafe IndexedDataBuffer(
|
|||
|
byte[] masterIndex,
|
|||
|
byte[] buffer,
|
|||
|
int dataLength,
|
|||
|
DataSource owner)
|
|||
|
{
|
|||
|
if (masterIndex == null || masterIndex.Length == 0)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (masterIndex), SR.GetString("StoreIndexedDataBufferNullOrEmptyMasterIndexBuffer"));
|
|||
|
if (buffer == null || buffer.Length == 0)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (buffer), SR.GetString("StoreIndexedDataBufferNullOrEmptyDataIndexBuffer"));
|
|||
|
if (dataLength < 0 || dataLength > buffer.Length)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (dataLength), (object) dataLength, SR.GetString("StoreIndexDataBufferDataLengthOutOfRange")));
|
|||
|
this.m_owner = owner;
|
|||
|
this.m_masterIndex = masterIndex;
|
|||
|
this.m_buffer = buffer;
|
|||
|
this.m_dataLength = dataLength;
|
|||
|
this.m_freeList = new FreeIndexList(20);
|
|||
|
fixed (byte* numPtr = &this.m_masterIndex[0])
|
|||
|
{
|
|||
|
for (int index = 1; index < this.m_masterIndex.Length / 4; ++index)
|
|||
|
{
|
|||
|
if (((int*) numPtr)[index] <= 0)
|
|||
|
this.m_freeList.Put(index);
|
|||
|
}
|
|||
|
}
|
|||
|
this.m_isOpen = true;
|
|||
|
}
|
|||
|
|
|||
|
public byte[] Index
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
return this.m_masterIndex;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public byte[] Data
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
return this.m_buffer;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public int DataLength
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
return this.m_dataLength;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Close()
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
this.Clear();
|
|||
|
this.m_buffer = (byte[]) null;
|
|||
|
this.m_masterIndex = (byte[]) null;
|
|||
|
this.m_isOpen = false;
|
|||
|
}
|
|||
|
|
|||
|
public unsafe DataRow CreateDataRow(int id)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
fixed (byte* pHeader = &this.m_buffer[this.GetOffset(ref id)])
|
|||
|
return DataRow.Create((EncryptedObjectHeader*) pHeader, this.m_owner);
|
|||
|
}
|
|||
|
|
|||
|
public unsafe void CopyIVFromObject(int id, byte[] iv, int index)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (iv == null || iv.Length == 0)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (iv));
|
|||
|
if (index < 0 || index > this.DataLength - iv.Length)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (index), (object) index, SR.GetString("StoreIndexDataBufferIndexOutOfRange")));
|
|||
|
if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
int offset = this.GetOffset(ref id);
|
|||
|
InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset.");
|
|||
|
fixed (byte* numPtr = &this.m_buffer[offset])
|
|||
|
Marshal.Copy(new IntPtr((void*) &((EncryptedObjectHeader*) numPtr)->IV), iv, 0, iv.Length);
|
|||
|
}
|
|||
|
|
|||
|
public Stream GetStreamForObjectData(int id)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
int offset = this.GetOffset(ref id);
|
|||
|
InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset.");
|
|||
|
int objectDataSize = this.GetObjectDataSize(offset);
|
|||
|
InfoCardTrace.Assert(objectDataSize <= this.m_buffer.Length - offset, "The length the stored object is invalid");
|
|||
|
return (Stream) new MemoryStream(this.m_buffer, offset + sizeof (EncryptedObjectHeader), objectDataSize, false, false);
|
|||
|
}
|
|||
|
|
|||
|
public void RemoveObject(int id)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
int offset = this.GetOffset(ref id);
|
|||
|
InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset.");
|
|||
|
this.RemoveFromMasterIndex(id);
|
|||
|
this.EnsureSpaceForData(offset, 0);
|
|||
|
}
|
|||
|
|
|||
|
public unsafe int WriteObject(
|
|||
|
int id,
|
|||
|
byte[] iv,
|
|||
|
byte[] data,
|
|||
|
int objectType,
|
|||
|
long lastChange,
|
|||
|
GlobalId globalId)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (iv == null || iv.Length == 0)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (iv));
|
|||
|
if (data == null || data.Length == 0)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (iv));
|
|||
|
if (id > this.m_masterIndex.Length / 4)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
int offset = id <= 0 || !this.m_freeList.Contains(id) ? this.GetOffset(ref id) : throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset.");
|
|||
|
this.EnsureSpaceForData(offset, data.Length);
|
|||
|
fixed (byte* numPtr1 = &this.m_buffer[offset])
|
|||
|
{
|
|||
|
byte* numPtr2 = (byte*) ((EncryptedObjectHeader*) numPtr1 + 1);
|
|||
|
((EncryptedObjectHeader*) numPtr1)->LastChange = lastChange;
|
|||
|
((EncryptedObjectHeader*) numPtr1)->DataSize = data.Length;
|
|||
|
((EncryptedObjectHeader*) numPtr1)->ObjectType = objectType;
|
|||
|
((EncryptedObjectHeader*) numPtr1)->LocalId = id;
|
|||
|
((EncryptedObjectHeader*) numPtr1)->GlobalId = globalId;
|
|||
|
InfoCardTrace.Assert(iv.Length <= 32, "IV Length is invalid");
|
|||
|
Marshal.Copy(iv, 0, new IntPtr((void*) &((EncryptedObjectHeader*) numPtr1)->IV), iv.Length);
|
|||
|
Marshal.Copy(data, 0, new IntPtr((void*) numPtr2), data.Length);
|
|||
|
}
|
|||
|
return id;
|
|||
|
}
|
|||
|
|
|||
|
private unsafe int GetObjectDataSize(int offset)
|
|||
|
{
|
|||
|
fixed (byte* numPtr = &this.m_buffer[offset])
|
|||
|
return ((EncryptedObjectHeader*) numPtr)->DataSize;
|
|||
|
}
|
|||
|
|
|||
|
private void Clear()
|
|||
|
{
|
|||
|
Array.Clear((Array) this.m_buffer, 0, this.m_dataLength);
|
|||
|
Array.Clear((Array) this.m_masterIndex, 0, this.m_masterIndex.Length);
|
|||
|
this.m_dataLength = 0;
|
|||
|
}
|
|||
|
|
|||
|
private unsafe int EnsureSpaceForData(int offset, int dataSize)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert((uint) offset <= (uint) this.m_dataLength, "offset specified is outside the range of the data buffer");
|
|||
|
InfoCardTrace.Assert(dataSize >= 0, "The requested data size must be greater than or equal to 0");
|
|||
|
int num1 = 0;
|
|||
|
if (dataSize != 0)
|
|||
|
num1 = dataSize + sizeof (EncryptedObjectHeader);
|
|||
|
if (num1 % 8 != 0)
|
|||
|
num1 += 8 - num1 % 8;
|
|||
|
int num2;
|
|||
|
if (offset == this.m_dataLength)
|
|||
|
{
|
|||
|
num2 = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
fixed (byte* numPtr = &this.m_buffer[offset])
|
|||
|
{
|
|||
|
num2 = ((EncryptedObjectHeader*) numPtr)->DataSize + sizeof (EncryptedObjectHeader);
|
|||
|
if (num2 % 8 != 0)
|
|||
|
num2 += 8 - num2 % 8;
|
|||
|
}
|
|||
|
}
|
|||
|
InfoCardTrace.Assert(num2 <= this.m_dataLength, "currentSize can not be more ");
|
|||
|
if (num2 == num1)
|
|||
|
return num1;
|
|||
|
int num3 = offset + num2;
|
|||
|
int diff = num1 - num2;
|
|||
|
int num4 = num3 + diff;
|
|||
|
if (diff > 0 && this.m_dataLength + diff >= this.m_buffer.Length)
|
|||
|
this.GrowBuffer(this.m_dataLength + diff);
|
|||
|
InfoCardTrace.Assert((uint) num3 <= (uint) this.m_buffer.Length && num3 >= offset, "NextIndex value is corrupt when attempting to ensure space for object");
|
|||
|
InfoCardTrace.Assert((uint) num4 <= (uint) this.m_buffer.Length, "NextNewIndex value is corrupt when attempting to ensure space for object");
|
|||
|
if (this.m_dataLength != num3)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(this.m_dataLength - num3 > 0, "NextIndex data is corrupt when attempting to ensure space for object in middle of content.");
|
|||
|
Array.Copy((Array) this.m_buffer, num3, (Array) this.m_buffer, num4, this.m_dataLength - num3);
|
|||
|
this.m_dataLength += diff;
|
|||
|
InfoCardTrace.Assert(this.m_dataLength >= 0, "DataLength has been corrupted.");
|
|||
|
if (diff < 0)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(this.m_dataLength <= this.m_buffer.Length, "DataLength is larger than allocated buffer.");
|
|||
|
Array.Clear((Array) this.m_buffer, this.m_dataLength, Math.Abs(diff));
|
|||
|
}
|
|||
|
this.UpdateMasterIndex(Math.Min(num3, num4), diff);
|
|||
|
}
|
|||
|
else
|
|||
|
this.m_dataLength += diff;
|
|||
|
InfoCardTrace.Assert(this.m_dataLength <= this.m_buffer.Length, "DataLength is larger than allocated buffer.");
|
|||
|
return num1;
|
|||
|
}
|
|||
|
|
|||
|
private void GrowMasterIndex()
|
|||
|
{
|
|||
|
int num1 = this.m_masterIndex.Length / 4;
|
|||
|
int increaseByPercent = Utility.CalculateIncreaseByPercent(this.m_masterIndex.Length, 4, 5);
|
|||
|
InfoCardTrace.Assert(increaseByPercent > this.m_masterIndex.Length, "NewSize must be greater than old size to grow master index buffer");
|
|||
|
byte[] destinationArray = new byte[increaseByPercent];
|
|||
|
Array.Copy((Array) this.m_masterIndex, 0, (Array) destinationArray, 0, this.m_masterIndex.Length);
|
|||
|
Array.Clear((Array) this.m_masterIndex, 0, this.m_masterIndex.Length);
|
|||
|
this.m_masterIndex = destinationArray;
|
|||
|
int num2 = this.m_masterIndex.Length / 4;
|
|||
|
for (int index = num1 + 1; index < num2; ++index)
|
|||
|
this.m_freeList.Put(index);
|
|||
|
}
|
|||
|
|
|||
|
private void GrowBuffer(int spaceRequired)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(spaceRequired >= this.m_buffer.Length, "RequireSpace must be greater than old size to grow data buffer");
|
|||
|
int num = spaceRequired;
|
|||
|
int length = num + num / 20;
|
|||
|
InfoCardTrace.Assert(length >= spaceRequired, "NewLength must be greater than required space to grow data buffer");
|
|||
|
byte[] destinationArray = new byte[length];
|
|||
|
Array.Copy((Array) this.m_buffer, 0, (Array) destinationArray, 0, this.m_buffer.Length);
|
|||
|
Array.Clear((Array) this.m_buffer, 0, this.m_buffer.Length);
|
|||
|
this.m_buffer = destinationArray;
|
|||
|
InfoCardTrace.Assert(this.m_dataLength <= this.m_buffer.Length, "DataLength Corrupt or buffer growth failed.");
|
|||
|
}
|
|||
|
|
|||
|
private unsafe int GetOffset(ref int id)
|
|||
|
{
|
|||
|
if (id <= 0)
|
|||
|
{
|
|||
|
if (this.m_dataLength <= 0)
|
|||
|
this.m_dataLength = 8;
|
|||
|
int dataLength = this.m_dataLength;
|
|||
|
id = this.GetNextLocalId(dataLength);
|
|||
|
return dataLength;
|
|||
|
}
|
|||
|
fixed (byte* numPtr = &this.m_masterIndex[0])
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(((int*) numPtr)[id] >= 0, "Master Index offset value is invalid");
|
|||
|
return ((int*) numPtr)[id];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void RemoveFromMasterIndex(int id)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(id > 0, "LocalId is invalid");
|
|||
|
fixed (byte* numPtr = &this.m_masterIndex[0])
|
|||
|
{
|
|||
|
*(int*) (numPtr + ((IntPtr) id * 4).ToInt64()) = 0;
|
|||
|
this.m_freeList.Put(id);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void UpdateMasterIndex(int offset, int diff)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(offset > 0, "Offset is invalid");
|
|||
|
InfoCardTrace.Assert(diff != 0, "Difference is invalid");
|
|||
|
int num = this.m_masterIndex.Length / 4;
|
|||
|
fixed (byte* numPtr1 = &this.m_masterIndex[0])
|
|||
|
{
|
|||
|
for (int index = 1; index < num; ++index)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert((int*) numPtr1 + index - (int*) numPtr1 <= (long) this.m_masterIndex.Length, "Pointer has walked past the end of the allocated buffer.");
|
|||
|
if (((int*) numPtr1)[index] > 0 && ((int*) numPtr1)[index] >= offset)
|
|||
|
{
|
|||
|
int* numPtr2 = (int*) numPtr1 + index;
|
|||
|
*numPtr2 = *numPtr2 + diff;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe int GetNextLocalId(int offset)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(offset >= 0, "The offset can not be negative.");
|
|||
|
int next = this.m_freeList.GetNext();
|
|||
|
if (next > 0)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(null != this.m_masterIndex, "m_masterIndex must not be null by now");
|
|||
|
InfoCardTrace.Assert(this.m_masterIndex.Length > 0, "m_masterIndex must not be empty.");
|
|||
|
fixed (byte* numPtr = &this.m_masterIndex[0])
|
|||
|
{
|
|||
|
*(int*) (numPtr + ((IntPtr) next * 4).ToInt64()) = offset;
|
|||
|
return next;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int nextLocalId = this.m_masterIndex.Length / 4;
|
|||
|
this.GrowMasterIndex();
|
|||
|
InfoCardTrace.Assert(this.m_masterIndex.Length / 4 > nextLocalId && nextLocalId > 0, "Calculated count is corrupt or invalid.");
|
|||
|
fixed (byte* numPtr = &this.m_masterIndex[0])
|
|||
|
*(int*) (numPtr + ((IntPtr) nextLocalId * 4).ToInt64()) = offset;
|
|||
|
return nextLocalId;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void ThrowIfNotOpen()
|
|||
|
{
|
|||
|
if (!this.m_isOpen)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ObjectDisposedException(nameof (IndexedDataBuffer)));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|