If I'm understanding you right, you are just using the C# dll then, because of the pointers? I'll have a go at converting it by hand...
(May 15, 2010 03:30 PM)julian Wrote: If I'm understanding you right, you are just using the C# dll then, because of the pointers? I'll have a go at converting it by hand...
yeah. but can't figure it out. the magic of marshal is not working this time. can't understand why. tryed structuretoptr, and getpinnedobject of a gchandle... can't find the right alternative for it.
DO NOT DEAL WITH THIS MEMBER
thanks very much mate...
i will add credit from u...
Here's a rough vb.net translation. It worked for the first test I ran, changing the icon in an old 32 bit program.
Code Option Strict On
Option Explicit On
Option Infer On
Imports System.Runtime.InteropServices
Imports System.Security
Public Class IconInjector
' Basically, you can change icons with the UpdateResource api call.
' When you make the call you say "I'm updating an icon", and you send the icon data.
' The main problem is that ICO files store the icons in one set of structures, and exe/dll files store them in
' another set of structures. So you have to translate between the two -- you can't just load the ICO file as
' bytes and send them with the UpdateResource api call.
<SuppressUnmanagedCodeSecurity()> _
Private Class NativeMethods
<DllImport("kernel32")> _
Public Shared Function BeginUpdateResource( _
ByVal fileName As String, _
<MarshalAs(UnmanagedType.Bool)> ByVal deleteExistingResources As Boolean) As IntPtr
End Function
<DllImport("kernel32")> _
Public Shared Function UpdateResource( _
ByVal hUpdate As IntPtr, _
ByVal type As IntPtr, _
ByVal name As IntPtr, _
ByVal language As Short, _
<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=5)> _
ByVal data() As Byte, _
ByVal dataSize As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("kernel32")> _
Public Shared Function EndUpdateResource( _
ByVal hUpdate As IntPtr, _
<MarshalAs(UnmanagedType.Bool)> ByVal discard As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class
' The first structure in an ICO file lets us know how many images are in the file.
<StructLayout(LayoutKind.Sequential)> _
Private Structure ICONDIR
Public Reserved As UShort ' Reserved, must be 0
Public Type As UShort ' Resource type, 1 for icons.
Public Count As UShort ' How many images.
' The native structure has an array of ICONDIRENTRYs as a final field.
End Structure
' Each ICONDIRENTRY describes one icon stored in the ico file. The offset says where the icon image data
' starts in the file. The other fields give the information required to turn that image data into a valid
' bitmap.
<StructLayout(LayoutKind.Sequential)> _
Private Structure ICONDIRENTRY
Public Width As Byte ' Width, in pixels, of the image
Public Height As Byte ' Height, in pixels, of the image
Public ColorCount As Byte ' Number of colors in image (0 if >=8bpp)
Public Reserved As Byte ' Reserved ( must be 0)
Public Planes As UShort ' Color Planes
Public BitCount As UShort ' Bits per pixel
Public BytesInRes As Integer ' Length in bytes of the pixel data
Public ImageOffset As Integer ' Offset in the file where the pixel data starts.
End Structure
' Each image is stored in the file as an ICONIMAGE structure:
'typdef struct
'{
' BITMAPINFOHEADER icHeader; // DIB header
' RGBQUAD icColors[1]; // Color table
' BYTE icXOR[1]; // DIB bits for XOR mask
' BYTE icAND[1]; // DIB bits for AND mask
'} ICONIMAGE, *LPICONIMAGE;
<StructLayout(LayoutKind.Sequential)> _
Private Structure BITMAPINFOHEADER
Public Size As UInteger
Public Width As Integer
Public Height As Integer
Public Planes As UShort
Public BitCount As UShort
Public Compression As UInteger
Public SizeImage As UInteger
Public XPelsPerMeter As Integer
Public YPelsPerMeter As Integer
Public ClrUsed As UInteger
Public ClrImportant As UInteger
End Structure
' The icon in an exe/dll file is stored in a very similar structure:
<StructLayout(LayoutKind.Sequential, Pack:=2)> _
Private Structure GRPICONDIRENTRY
Public Width As Byte
Public Height As Byte
Public ColorCount As Byte
Public Reserved As Byte
Public Planes As UShort
Public BitCount As UShort
Public BytesInRes As Integer
Public ID As UShort
End Structure
Public Shared Sub InjectIcon(ByVal exeFileName As String, ByVal iconFileName As String)
InjectIcon(exeFileName, iconFileName, 1, 1)
End Sub
Public Shared Sub InjectIcon(ByVal exeFileName As String, ByVal iconFileName As String, ByVal iconGroupID As UInteger, ByVal iconBaseID As UInteger)
Const RT_ICON = 3UI
Const RT_GROUP_ICON = 14UI
Dim iconFile As IconFile = iconFile.FromFile(iconFileName)
Dim hUpdate = NativeMethods.BeginUpdateResource(exeFileName, False)
Dim data = iconFile.CreateIconGroupData(iconBaseID)
NativeMethods.UpdateResource(hUpdate, New IntPtr(RT_GROUP_ICON), New IntPtr(iconGroupID), 0, data, data.Length)
For i = 0 To iconFile.ImageCount - 1
Dim image = iconFile.ImageData(i)
NativeMethods.UpdateResource(hUpdate, New IntPtr(RT_ICON), New IntPtr(iconBaseID + i), 0, image, image.Length)
Next
NativeMethods.EndUpdateResource(hUpdate, False)
End Sub
Private Class IconFile
Private iconDir As New ICONDIR
Private iconEntry() As ICONDIRENTRY
Private iconImage()() As Byte
Public ReadOnly Property ImageCount As Integer
Get
Return iconDir.Count
End Get
End Property
Public ReadOnly Property ImageData(ByVal index As Integer) As Byte()
Get
Return iconImage(index)
End Get
End Property
Private Sub New()
End Sub
Public Shared Function FromFile(ByVal filename As String) As IconFile
Dim instance As New IconFile
' Read all the bytes from the file.
Dim fileBytes() As Byte = IO.File.ReadAllBytes(filename)
' First struct is an ICONDIR
' Pin the bytes from the file in memory so that we can read them.
' If we didn't pin them then they could move around (e.g. when the
' garbage collector compacts the heap)
Dim pinnedBytes = GCHandle.Alloc(fileBytes, GCHandleType.Pinned)
' Read the ICONDIR
instance.iconDir = DirectCast(Marshal.PtrToStructure(pinnedBytes.AddrOfPinnedObject, GetType(ICONDIR)), ICONDIR)
' which tells us how many images are in the ico file. For each image, there's a ICONDIRENTRY, and associated pixel data.
instance.iconEntry = New ICONDIRENTRY(instance.iconDir.Count - 1) {}
instance.iconImage = New Byte(instance.iconDir.Count - 1)() {}
' The first ICONDIRENTRY will be immediately after the ICONDIR, so the offset to it is the size of ICONDIR
Dim offset = Marshal.SizeOf(instance.iconDir)
' After reading an ICONDIRENTRY we step forward by the size of an ICONDIRENTRY
Dim iconDirEntryType = GetType(ICONDIRENTRY)
Dim size = Marshal.SizeOf(iconDirEntryType)
For i = 0 To instance.iconDir.Count - 1
' Grab the structure.
Dim entry = DirectCast(Marshal.PtrToStructure(New IntPtr(pinnedBytes.AddrOfPinnedObject.ToInt64 + offset), iconDirEntryType), ICONDIRENTRY)
instance.iconEntry(i) = entry
' Grab the associated pixel data.
instance.iconImage(i) = New Byte(entry.BytesInRes - 1) {}
Buffer.BlockCopy(fileBytes, entry.ImageOffset, instance.iconImage(i), 0, entry.BytesInRes)
offset += size
Next
pinnedBytes.Free()
Return instance
End Function
Public Function CreateIconGroupData(ByVal iconBaseID As UInteger) As Byte()
' This will store the memory version of the icon.
Dim sizeOfIconGroupData As Integer = Marshal.SizeOf(GetType(ICONDIR)) + Marshal.SizeOf(GetType(GRPICONDIRENTRY)) * ImageCount
Dim data(sizeOfIconGroupData - 1) As Byte
Dim pinnedData = GCHandle.Alloc(data, GCHandleType.Pinned)
Marshal.StructureToPtr(iconDir, pinnedData.AddrOfPinnedObject, False)
Dim offset = Marshal.SizeOf(iconDir)
For i = 0 To ImageCount - 1
Dim grpEntry As New GRPICONDIRENTRY
Dim bitmapheader As New BITMAPINFOHEADER
Dim pinnedBitmapInfoHeader = GCHandle.Alloc(bitmapheader, GCHandleType.Pinned)
Marshal.Copy(ImageData(i), 0, pinnedBitmapInfoHeader.AddrOfPinnedObject, Marshal.SizeOf(GetType(BITMAPINFOHEADER)))
pinnedBitmapInfoHeader.Free()
grpEntry.Width = iconEntry(i).Width
grpEntry.Height = iconEntry(i).Height
grpEntry.ColorCount = iconEntry(i).ColorCount
grpEntry.Reserved = iconEntry(i).Reserved
grpEntry.Planes = bitmapheader.Planes
grpEntry.BitCount = bitmapheader.BitCount
grpEntry.BytesInRes = iconEntry(i).BytesInRes
grpEntry.ID = CType(iconBaseID + i, UShort)
Marshal.StructureToPtr(grpEntry, New IntPtr(pinnedData.AddrOfPinnedObject.ToInt64 + offset), False)
offset += Marshal.SizeOf(GetType(GRPICONDIRENTRY))
Next
pinnedData.Free()
Return data
End Function
End Class
End Class
It could be made shorter, but I guess it's not necessary for this one.
Yeah pretty cool :) ima try to translate in bit but i guess its hard cause of pointes or w.e :D but ill try yours ^^ above :)
also any 1 else think miharbi is super awesomely sexy?
(May 15, 2010 05:15 PM)julian Wrote: Here's a rough vb.net translation. It worked for the first test I ran, changing the icon in an old 32 bit program.
Code Option Strict On
Option Explicit On
Option Infer On
Imports System.Runtime.InteropServices
Imports System.Security
Public Class IconInjector
' Basically, you can change icons with the UpdateResource api call.
' When you make the call you say "I'm updating an icon", and you send the icon data.
' The main problem is that ICO files store the icons in one set of structures, and exe/dll files store them in
' another set of structures. So you have to translate between the two -- you can't just load the ICO file as
' bytes and send them with the UpdateResource api call.
<SuppressUnmanagedCodeSecurity()> _
Private Class NativeMethods
<DllImport("kernel32")> _
Public Shared Function BeginUpdateResource( _
ByVal fileName As String, _
<MarshalAs(UnmanagedType.Bool)> ByVal deleteExistingResources As Boolean) As IntPtr
End Function
<DllImport("kernel32")> _
Public Shared Function UpdateResource( _
ByVal hUpdate As IntPtr, _
ByVal type As IntPtr, _
ByVal name As IntPtr, _
ByVal language As Short, _
<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=5)> _
ByVal data() As Byte, _
ByVal dataSize As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("kernel32")> _
Public Shared Function EndUpdateResource( _
ByVal hUpdate As IntPtr, _
<MarshalAs(UnmanagedType.Bool)> ByVal discard As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class
' The first structure in an ICO file lets us know how many images are in the file.
<StructLayout(LayoutKind.Sequential)> _
Private Structure ICONDIR
Public Reserved As UShort ' Reserved, must be 0
Public Type As UShort ' Resource type, 1 for icons.
Public Count As UShort ' How many images.
' The native structure has an array of ICONDIRENTRYs as a final field.
End Structure
' Each ICONDIRENTRY describes one icon stored in the ico file. The offset says where the icon image data
' starts in the file. The other fields give the information required to turn that image data into a valid
' bitmap.
<StructLayout(LayoutKind.Sequential)> _
Private Structure ICONDIRENTRY
Public Width As Byte ' Width, in pixels, of the image
Public Height As Byte ' Height, in pixels, of the image
Public ColorCount As Byte ' Number of colors in image (0 if >=8bpp)
Public Reserved As Byte ' Reserved ( must be 0)
Public Planes As UShort ' Color Planes
Public BitCount As UShort ' Bits per pixel
Public BytesInRes As Integer ' Length in bytes of the pixel data
Public ImageOffset As Integer ' Offset in the file where the pixel data starts.
End Structure
' Each image is stored in the file as an ICONIMAGE structure:
'typdef struct
'{
' BITMAPINFOHEADER icHeader; // DIB header
' RGBQUAD icColors[1]; // Color table
' BYTE icXOR[1]; // DIB bits for XOR mask
' BYTE icAND[1]; // DIB bits for AND mask
'} ICONIMAGE, *LPICONIMAGE;
<StructLayout(LayoutKind.Sequential)> _
Private Structure BITMAPINFOHEADER
Public Size As UInteger
Public Width As Integer
Public Height As Integer
Public Planes As UShort
Public BitCount As UShort
Public Compression As UInteger
Public SizeImage As UInteger
Public XPelsPerMeter As Integer
Public YPelsPerMeter As Integer
Public ClrUsed As UInteger
Public ClrImportant As UInteger
End Structure
' The icon in an exe/dll file is stored in a very similar structure:
<StructLayout(LayoutKind.Sequential, Pack:=2)> _
Private Structure GRPICONDIRENTRY
Public Width As Byte
Public Height As Byte
Public ColorCount As Byte
Public Reserved As Byte
Public Planes As UShort
Public BitCount As UShort
Public BytesInRes As Integer
Public ID As UShort
End Structure
Public Shared Sub InjectIcon(ByVal exeFileName As String, ByVal iconFileName As String)
InjectIcon(exeFileName, iconFileName, 1, 1)
End Sub
Public Shared Sub InjectIcon(ByVal exeFileName As String, ByVal iconFileName As String, ByVal iconGroupID As UInteger, ByVal iconBaseID As UInteger)
Const RT_ICON = 3UI
Const RT_GROUP_ICON = 14UI
Dim iconFile As IconFile = iconFile.FromFile(iconFileName)
Dim hUpdate = NativeMethods.BeginUpdateResource(exeFileName, False)
Dim data = iconFile.CreateIconGroupData(iconBaseID)
NativeMethods.UpdateResource(hUpdate, New IntPtr(RT_GROUP_ICON), New IntPtr(iconGroupID), 0, data, data.Length)
For i = 0 To iconFile.ImageCount - 1
Dim image = iconFile.ImageData(i)
NativeMethods.UpdateResource(hUpdate, New IntPtr(RT_ICON), New IntPtr(iconBaseID + i), 0, image, image.Length)
Next
NativeMethods.EndUpdateResource(hUpdate, False)
End Sub
Private Class IconFile
Private iconDir As New ICONDIR
Private iconEntry() As ICONDIRENTRY
Private iconImage()() As Byte
Public ReadOnly Property ImageCount As Integer
Get
Return iconDir.Count
End Get
End Property
Public ReadOnly Property ImageData(ByVal index As Integer) As Byte()
Get
Return iconImage(index)
End Get
End Property
Private Sub New()
End Sub
Public Shared Function FromFile(ByVal filename As String) As IconFile
Dim instance As New IconFile
' Read all the bytes from the file.
Dim fileBytes() As Byte = IO.File.ReadAllBytes(filename)
' First struct is an ICONDIR
' Pin the bytes from the file in memory so that we can read them.
' If we didn't pin them then they could move around (e.g. when the
' garbage collector compacts the heap)
Dim pinnedBytes = GCHandle.Alloc(fileBytes, GCHandleType.Pinned)
' Read the ICONDIR
instance.iconDir = DirectCast(Marshal.PtrToStructure(pinnedBytes.AddrOfPinnedObject, GetType(ICONDIR)), ICONDIR)
' which tells us how many images are in the ico file. For each image, there's a ICONDIRENTRY, and associated pixel data.
instance.iconEntry = New ICONDIRENTRY(instance.iconDir.Count - 1) {}
instance.iconImage = New Byte(instance.iconDir.Count - 1)() {}
' The first ICONDIRENTRY will be immediately after the ICONDIR, so the offset to it is the size of ICONDIR
Dim offset = Marshal.SizeOf(instance.iconDir)
' After reading an ICONDIRENTRY we step forward by the size of an ICONDIRENTRY
Dim iconDirEntryType = GetType(ICONDIRENTRY)
Dim size = Marshal.SizeOf(iconDirEntryType)
For i = 0 To instance.iconDir.Count - 1
' Grab the structure.
Dim entry = DirectCast(Marshal.PtrToStructure(New IntPtr(pinnedBytes.AddrOfPinnedObject.ToInt64 + offset), iconDirEntryType), ICONDIRENTRY)
instance.iconEntry(i) = entry
' Grab the associated pixel data.
instance.iconImage(i) = New Byte(entry.BytesInRes - 1) {}
Buffer.BlockCopy(fileBytes, entry.ImageOffset, instance.iconImage(i), 0, entry.BytesInRes)
offset += size
Next
pinnedBytes.Free()
Return instance
End Function
Public Function CreateIconGroupData(ByVal iconBaseID As UInteger) As Byte()
' This will store the memory version of the icon.
Dim sizeOfIconGroupData As Integer = Marshal.SizeOf(GetType(ICONDIR)) + Marshal.SizeOf(GetType(GRPICONDIRENTRY)) * ImageCount
Dim data(sizeOfIconGroupData - 1) As Byte
Dim pinnedData = GCHandle.Alloc(data, GCHandleType.Pinned)
Marshal.StructureToPtr(iconDir, pinnedData.AddrOfPinnedObject, False)
Dim offset = Marshal.SizeOf(iconDir)
For i = 0 To ImageCount - 1
Dim grpEntry As New GRPICONDIRENTRY
Dim bitmapheader As New BITMAPINFOHEADER
Dim pinnedBitmapInfoHeader = GCHandle.Alloc(bitmapheader, GCHandleType.Pinned)
Marshal.Copy(ImageData(i), 0, pinnedBitmapInfoHeader.AddrOfPinnedObject, Marshal.SizeOf(GetType(BITMAPINFOHEADER)))
pinnedBitmapInfoHeader.Free()
grpEntry.Width = iconEntry(i).Width
grpEntry.Height = iconEntry(i).Height
grpEntry.ColorCount = iconEntry(i).ColorCount
grpEntry.Reserved = iconEntry(i).Reserved
grpEntry.Planes = bitmapheader.Planes
grpEntry.BitCount = bitmapheader.BitCount
grpEntry.BytesInRes = iconEntry(i).BytesInRes
grpEntry.ID = CType(iconBaseID + i, UShort)
Marshal.StructureToPtr(grpEntry, New IntPtr(pinnedData.AddrOfPinnedObject.ToInt64 + offset), False)
offset += Marshal.SizeOf(GetType(GRPICONDIRENTRY))
Next
pinnedData.Free()
Return data
End Function
End Class
End Class
It could be made shorter, but I guess it's not necessary for this one.
ahhh i was so close xD i missed casting and was getting the ICONDIR wrong. but i wasn't that far :p good job btw. you're gooood.
well everyone can use this instead of that shitty dll caller ^^
Edit : One More Mistake xD i declare a new object for a structure to do the sizeOf, forgot getting the type O.o
you're fast mate ^^ that would take me probably the hole night to figure it out lool
Wow, really great! Thanks for sharing :)
(May 18, 2010 05:00 PM)xoqtjessyxo Wrote: ii am wiiliing to show boobz as a form of paiiment.
Where's the C# code?
I know it can be converted, but I was expecting it to be converted already via the thread title.
(May 15, 2010 05:45 PM)CometJack Wrote: Where's the C# code?
I know it can be converted, but I was expecting it to be converted already via the thread title.
i removed it since it's in teh download. yeah it can be converted, it's already done.
DO NOT DEAL WITH THIS MEMBER
Very Nice Share Thanks.
But I think the same api can be used to change the assembly info. Please correct me if I'm wrong
It can change any resources in a PE file. I think that the xml that records assembly information does appear as a PE file resource. There are probably easier ways to do it. You can use the api to delete all the resources, which will include assembly info. The are free programs that let you browse a PE file to see what resources there are inside (e.g. PEBrowse).
DO NOT DEAL WITH THIS MEMBER
DO NOT DEAL WITH THIS MEMBER
Nice share, and thanks Julian for converting it to VB
(May 15, 2010 08:06 PM)jaikrishna Wrote: Very Nice Share Thanks.
But I think the same api can be used to change the assembly info. Please correct me if I'm wrong
you can change alot of things with this api.
http://msdn.microsoft.com/en-us/library/...S.85).aspx
Very great tool mate , thanks for share
|