mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-30 15:05:27 +00:00
401 lines
11 KiB
C#
401 lines
11 KiB
C#
|
// Decompiled with JetBrains decompiler
|
|||
|
// Type: Microsoft.InfoCards.BigInt
|
|||
|
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|
|||
|
// MVID: ADE0A079-11DB-4A46-8BDE-D2A592CA8DEA
|
|||
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Virus.Win32.Expiro.w-67b630ead60119692b9abbdfd8717c96904ef041127c2cae033c86b718eaa61e.exe
|
|||
|
|
|||
|
using Microsoft.InfoCards.Diagnostics;
|
|||
|
using System;
|
|||
|
|
|||
|
namespace Microsoft.InfoCards
|
|||
|
{
|
|||
|
internal sealed class BigInt
|
|||
|
{
|
|||
|
private const int m_maxbytes = 128;
|
|||
|
private const int m_base = 256;
|
|||
|
private byte[] m_elements;
|
|||
|
private int m_size;
|
|||
|
private static readonly char[] decValues = new char[10]
|
|||
|
{
|
|||
|
'0',
|
|||
|
'1',
|
|||
|
'2',
|
|||
|
'3',
|
|||
|
'4',
|
|||
|
'5',
|
|||
|
'6',
|
|||
|
'7',
|
|||
|
'8',
|
|||
|
'9'
|
|||
|
};
|
|||
|
|
|||
|
internal BigInt() => this.m_elements = new byte[128];
|
|||
|
|
|||
|
internal BigInt(byte[] b)
|
|||
|
{
|
|||
|
this.m_elements = new byte[128];
|
|||
|
Array.Copy((Array) b, (Array) this.m_elements, b.Length);
|
|||
|
this.m_size = b.Length;
|
|||
|
}
|
|||
|
|
|||
|
internal BigInt(byte b)
|
|||
|
{
|
|||
|
this.m_elements = new byte[128];
|
|||
|
this.SetDigit(0, b);
|
|||
|
}
|
|||
|
|
|||
|
internal int Size
|
|||
|
{
|
|||
|
get => this.m_size;
|
|||
|
set
|
|||
|
{
|
|||
|
this.m_size = value;
|
|||
|
if (value > 128)
|
|||
|
this.m_size = 128;
|
|||
|
if (value >= 0)
|
|||
|
return;
|
|||
|
this.m_size = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal byte GetDigit(int index) => index < 0 || index >= this.m_size ? (byte) 0 : this.m_elements[index];
|
|||
|
|
|||
|
internal void SetDigit(int index, byte digit)
|
|||
|
{
|
|||
|
if (index < 0 || index >= 128)
|
|||
|
return;
|
|||
|
this.m_elements[index] = digit;
|
|||
|
if (index >= this.m_size && digit != (byte) 0)
|
|||
|
this.m_size = index + 1;
|
|||
|
if (index != this.m_size - 1 || digit != (byte) 0)
|
|||
|
return;
|
|||
|
--this.m_size;
|
|||
|
}
|
|||
|
|
|||
|
internal void SetDigit(int index, byte digit, ref int size)
|
|||
|
{
|
|||
|
if (index < 0 || index >= 128)
|
|||
|
return;
|
|||
|
this.m_elements[index] = digit;
|
|||
|
if (index >= size && digit != (byte) 0)
|
|||
|
size = index + 1;
|
|||
|
if (index != size - 1 || digit != (byte) 0)
|
|||
|
return;
|
|||
|
--size;
|
|||
|
}
|
|||
|
|
|||
|
public static bool operator <(BigInt value1, BigInt value2)
|
|||
|
{
|
|||
|
if (value1 == (BigInt) null)
|
|||
|
return true;
|
|||
|
if (value2 == (BigInt) null)
|
|||
|
return false;
|
|||
|
int size1 = value1.Size;
|
|||
|
int size2 = value2.Size;
|
|||
|
if (size1 != size2)
|
|||
|
return size1 < size2;
|
|||
|
while (size1-- > 0)
|
|||
|
{
|
|||
|
if ((int) value1.m_elements[size1] != (int) value2.m_elements[size1])
|
|||
|
return (int) value1.m_elements[size1] < (int) value2.m_elements[size1];
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public static bool operator >(BigInt value1, BigInt value2)
|
|||
|
{
|
|||
|
if (value1 == (BigInt) null)
|
|||
|
return false;
|
|||
|
if (value2 == (BigInt) null)
|
|||
|
return true;
|
|||
|
int size1 = value1.Size;
|
|||
|
int size2 = value2.Size;
|
|||
|
if (size1 != size2)
|
|||
|
return size1 > size2;
|
|||
|
while (size1-- > 0)
|
|||
|
{
|
|||
|
if ((int) value1.m_elements[size1] != (int) value2.m_elements[size1])
|
|||
|
return (int) value1.m_elements[size1] > (int) value2.m_elements[size1];
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public static bool operator ==(BigInt value1, BigInt value2)
|
|||
|
{
|
|||
|
if ((object) value1 == null)
|
|||
|
return (object) value2 == null;
|
|||
|
if ((object) value2 == null)
|
|||
|
return (object) value1 == null;
|
|||
|
int size1 = value1.Size;
|
|||
|
int size2 = value2.Size;
|
|||
|
if (size1 != size2)
|
|||
|
return false;
|
|||
|
for (int index = 0; index < size1; ++index)
|
|||
|
{
|
|||
|
if ((int) value1.m_elements[index] != (int) value2.m_elements[index])
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public static bool operator !=(BigInt value1, BigInt value2) => !(value1 == value2);
|
|||
|
|
|||
|
public override bool Equals(object obj)
|
|||
|
{
|
|||
|
BigInt bigInt = obj as BigInt;
|
|||
|
return (BigInt) null != bigInt && bigInt == this;
|
|||
|
}
|
|||
|
|
|||
|
public override int GetHashCode()
|
|||
|
{
|
|||
|
int hashCode = 0;
|
|||
|
for (int index = 0; index < this.m_size; ++index)
|
|||
|
hashCode += (int) this.GetDigit(index);
|
|||
|
return hashCode;
|
|||
|
}
|
|||
|
|
|||
|
internal static void Add(BigInt a, byte b, ref BigInt c)
|
|||
|
{
|
|||
|
byte digit = b;
|
|||
|
int size1 = a.Size;
|
|||
|
int size2 = 0;
|
|||
|
for (int index = 0; index < size1; ++index)
|
|||
|
{
|
|||
|
int num = (int) a.GetDigit(index) + (int) digit;
|
|||
|
c.SetDigit(index, (byte) (num & (int) byte.MaxValue), ref size2);
|
|||
|
digit = (byte) (num >> 8 & (int) byte.MaxValue);
|
|||
|
}
|
|||
|
if (digit != (byte) 0)
|
|||
|
c.SetDigit(a.Size, digit, ref size2);
|
|||
|
c.Size = size2;
|
|||
|
}
|
|||
|
|
|||
|
internal static void Negate(ref BigInt a)
|
|||
|
{
|
|||
|
int size = 0;
|
|||
|
for (int index = 0; index < 128; ++index)
|
|||
|
a.SetDigit(index, (byte) ((uint) ~a.GetDigit(index) & (uint) byte.MaxValue), ref size);
|
|||
|
for (int index = 0; index < 128; ++index)
|
|||
|
{
|
|||
|
a.SetDigit(index, (byte) ((uint) a.GetDigit(index) + 1U), ref size);
|
|||
|
if (((int) a.GetDigit(index) & (int) byte.MaxValue) == 0)
|
|||
|
a.SetDigit(index, (byte) ((uint) a.GetDigit(index) & (uint) byte.MaxValue), ref size);
|
|||
|
else
|
|||
|
break;
|
|||
|
}
|
|||
|
a.Size = size;
|
|||
|
}
|
|||
|
|
|||
|
internal static void Subtract(BigInt a, BigInt b, ref BigInt c)
|
|||
|
{
|
|||
|
byte num1 = 0;
|
|||
|
if (a < b)
|
|||
|
{
|
|||
|
BigInt.Subtract(b, a, ref c);
|
|||
|
BigInt.Negate(ref c);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int size1 = a.Size;
|
|||
|
int size2 = 0;
|
|||
|
for (int index = 0; index < size1; ++index)
|
|||
|
{
|
|||
|
int num2 = (int) a.GetDigit(index) - (int) b.GetDigit(index) - (int) num1;
|
|||
|
num1 = (byte) 0;
|
|||
|
if (num2 < 0)
|
|||
|
{
|
|||
|
num2 += 256;
|
|||
|
num1 = (byte) 1;
|
|||
|
}
|
|||
|
c.SetDigit(index, (byte) (num2 & (int) byte.MaxValue), ref size2);
|
|||
|
}
|
|||
|
c.Size = size2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void Multiply(int b)
|
|||
|
{
|
|||
|
if (b == 0)
|
|||
|
{
|
|||
|
this.Clear();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int num1 = 0;
|
|||
|
int size1 = this.Size;
|
|||
|
int size2 = 0;
|
|||
|
for (int index = 0; index < size1; ++index)
|
|||
|
{
|
|||
|
int num2 = b * (int) this.GetDigit(index) + num1;
|
|||
|
num1 = num2 / 256;
|
|||
|
this.SetDigit(index, (byte) (num2 % 256), ref size2);
|
|||
|
}
|
|||
|
if (num1 != 0)
|
|||
|
{
|
|||
|
byte[] bytes = BitConverter.GetBytes(num1);
|
|||
|
for (int index = 0; index < bytes.Length; ++index)
|
|||
|
this.SetDigit(size1 + index, bytes[index], ref size2);
|
|||
|
}
|
|||
|
this.Size = size2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void Multiply(BigInt a, int b, ref BigInt c)
|
|||
|
{
|
|||
|
if (b == 0)
|
|||
|
{
|
|||
|
c.Clear();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int num1 = 0;
|
|||
|
int size1 = a.Size;
|
|||
|
int size2 = 0;
|
|||
|
for (int index = 0; index < size1; ++index)
|
|||
|
{
|
|||
|
int num2 = b * (int) a.GetDigit(index) + num1;
|
|||
|
num1 = num2 / 256;
|
|||
|
c.SetDigit(index, (byte) (num2 % 256), ref size2);
|
|||
|
}
|
|||
|
if (num1 != 0)
|
|||
|
{
|
|||
|
byte[] bytes = BitConverter.GetBytes(num1);
|
|||
|
for (int index = 0; index < bytes.Length; ++index)
|
|||
|
c.SetDigit(size1 + index, bytes[index], ref size2);
|
|||
|
}
|
|||
|
c.Size = size2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void Divide(int b)
|
|||
|
{
|
|||
|
int num1 = 0;
|
|||
|
int size1 = this.Size;
|
|||
|
int size2 = 0;
|
|||
|
while (size1-- > 0)
|
|||
|
{
|
|||
|
int num2 = 256 * num1 + (int) this.GetDigit(size1);
|
|||
|
num1 = num2 % b;
|
|||
|
this.SetDigit(size1, (byte) (num2 / b), ref size2);
|
|||
|
}
|
|||
|
this.Size = size2;
|
|||
|
}
|
|||
|
|
|||
|
internal static void Divide(
|
|||
|
BigInt numerator,
|
|||
|
BigInt denominator,
|
|||
|
ref BigInt quotient,
|
|||
|
ref BigInt remainder)
|
|||
|
{
|
|||
|
if (numerator < denominator)
|
|||
|
{
|
|||
|
quotient.Clear();
|
|||
|
remainder.CopyFrom(numerator);
|
|||
|
}
|
|||
|
else if (numerator == denominator)
|
|||
|
{
|
|||
|
quotient.Clear();
|
|||
|
quotient.SetDigit(0, (byte) 1);
|
|||
|
remainder.Clear();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
BigInt c1 = new BigInt();
|
|||
|
c1.CopyFrom(numerator);
|
|||
|
BigInt a = new BigInt();
|
|||
|
a.CopyFrom(denominator);
|
|||
|
uint num = 0;
|
|||
|
while (a.Size < c1.Size)
|
|||
|
{
|
|||
|
a.Multiply(256);
|
|||
|
++num;
|
|||
|
}
|
|||
|
if (a > c1)
|
|||
|
{
|
|||
|
a.Divide(256);
|
|||
|
--num;
|
|||
|
}
|
|||
|
BigInt c2 = new BigInt();
|
|||
|
quotient.Clear();
|
|||
|
for (int index = 0; (long) index <= (long) num; ++index)
|
|||
|
{
|
|||
|
int b = (c1.Size == a.Size ? (int) c1.GetDigit(c1.Size - 1) : 256 * (int) c1.GetDigit(c1.Size - 1) + (int) c1.GetDigit(c1.Size - 2)) / (int) a.GetDigit(a.Size - 1);
|
|||
|
if (b >= 256)
|
|||
|
b = (int) byte.MaxValue;
|
|||
|
BigInt.Multiply(a, b, ref c2);
|
|||
|
while (c2 > c1)
|
|||
|
{
|
|||
|
--b;
|
|||
|
BigInt.Multiply(a, b, ref c2);
|
|||
|
}
|
|||
|
quotient.Multiply(256);
|
|||
|
BigInt.Add(quotient, (byte) b, ref quotient);
|
|||
|
BigInt.Subtract(c1, c2, ref c1);
|
|||
|
a.Divide(256);
|
|||
|
}
|
|||
|
remainder.CopyFrom(c1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
internal void CopyFrom(BigInt a)
|
|||
|
{
|
|||
|
Array.Copy((Array) a.m_elements, (Array) this.m_elements, 128);
|
|||
|
this.m_size = a.m_size;
|
|||
|
}
|
|||
|
|
|||
|
internal bool IsZero()
|
|||
|
{
|
|||
|
for (int index = 0; index < this.m_size; ++index)
|
|||
|
{
|
|||
|
if (this.m_elements[index] != (byte) 0)
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
internal byte[] ToByteArray()
|
|||
|
{
|
|||
|
byte[] destinationArray = new byte[this.Size];
|
|||
|
Array.Copy((Array) this.m_elements, (Array) destinationArray, this.Size);
|
|||
|
return destinationArray;
|
|||
|
}
|
|||
|
|
|||
|
internal void Clear() => this.m_size = 0;
|
|||
|
|
|||
|
internal void FromDecimal(string decNum)
|
|||
|
{
|
|||
|
BigInt c1 = new BigInt();
|
|||
|
BigInt c2 = new BigInt();
|
|||
|
int length = decNum.Length;
|
|||
|
for (int index = 0; index < length; ++index)
|
|||
|
{
|
|||
|
if (decNum[index] > '9' || decNum[index] < '0')
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new FormatException());
|
|||
|
BigInt.Multiply(c1, 10, ref c2);
|
|||
|
BigInt.Add(c2, (byte) ((uint) decNum[index] - 48U), ref c1);
|
|||
|
}
|
|||
|
this.CopyFrom(c1);
|
|||
|
}
|
|||
|
|
|||
|
internal string ToDecimal()
|
|||
|
{
|
|||
|
BigInt denominator = new BigInt((byte) 10);
|
|||
|
BigInt numerator = new BigInt();
|
|||
|
BigInt quotient = new BigInt();
|
|||
|
BigInt remainder = new BigInt();
|
|||
|
numerator.CopyFrom(this);
|
|||
|
char[] chArray = new char[8 * this.m_size / 3];
|
|||
|
int length = 0;
|
|||
|
do
|
|||
|
{
|
|||
|
BigInt.Divide(numerator, denominator, ref quotient, ref remainder);
|
|||
|
chArray[length++] = BigInt.decValues[(int) remainder.m_elements[0]];
|
|||
|
numerator.CopyFrom(quotient);
|
|||
|
}
|
|||
|
while (!quotient.IsZero());
|
|||
|
Array.Reverse((Array) chArray, 0, length);
|
|||
|
return new string(chArray, 0, length);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|