MalwareSourceCode/MSIL/Virus/Win32/E/Virus.Win32.Expiro.w-1f15ee7e9f7da02b6bfb4c5a5e6484eb9fa71b82d3699c54bcc7a31794b4a66d/Microsoft/InfoCards/IndexedDataBuffer.cs
2022-08-18 06:28:56 -05:00

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)));
}
}
}