Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I tried to create a small C# app to modify the embedded manifest so it wouldn't request admin privileges. This is the solution I finally came up with, making a bunch of Win32 calls to extract the manifest and replace an existing manifest. It's already long enough, so I omitted the part where I actually modify the manifest (just some basic XML operations).</p> <p>There are two static methods here: <strong>LoadManifestResource</strong>, which loads the string representation of the embedded manifest of an executable and <strong>SaveManifestResource</strong>, which saves the string representation of a manifest resource in the specified executable, overwriting the old one.</p> <p>This is a quick and dirty solution which worked just fine for me, but might very well not work in every case.</p> <pre><code>public static class Library { [DllImport("kernel32.dll")] static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll")] static extern IntPtr FindResource(IntPtr hModule, int lpName, int lpType); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo); [DllImport("kernel32.dll")] static extern IntPtr LockResource(IntPtr hResData); [DllImport("Kernel32.dll", EntryPoint = "SizeofResource", SetLastError = true)] private static extern uint SizeofResource(IntPtr hModule, IntPtr hResource); [System.Flags] enum LoadLibraryFlags : uint { DONT_RESOLVE_DLL_REFERENCES = 0x00000001, LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010, LOAD_LIBRARY_AS_DATAFILE = 0x00000002, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040, LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020, LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 } public static unsafe string LoadManifestResource(string fileName) { // load library to retrieve manifest from var libraryHandle = LoadLibraryEx(fileName, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE); if (libraryHandle.ToInt32() == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't load library"); } try { // find manifest var resource = FindResource(libraryHandle, 1, 24); if (resource.ToInt32() == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't find manifest resource"); } // load manifest var loadedManifest = LoadResource(libraryHandle, resource); if (loadedManifest.ToInt32() == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't load manifest resource"); } // lock manifest var lockedManifest = LockResource(loadedManifest); if (lockedManifest.ToInt32() == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "couldn't lock manifest resource"); } // calculate size of manifest, copy to byte array and convert to string int manifestSize = (int)SizeofResource(libraryHandle, resource); byte[] data = new byte[manifestSize]; Marshal.Copy(lockedManifest, data, 0, manifestSize); var manifest = Encoding.UTF8.GetString(data); return manifest; } finally { FreeLibrary(libraryHandle); } } [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources); [DllImport("kernel32.dll", SetLastError = true)] static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData); [DllImport("kernel32.dll", SetLastError = true)] static extern bool UpdateResource(IntPtr hUpdate, int lpType, int lpName, ushort wLanguage, IntPtr lpData, uint cbData); [DllImport("kernel32.dll", SetLastError = true)] static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard); public static unsafe void SaveManifestResource(string file, string manifest) { var hUpdate = BeginUpdateResource(file, false); byte[] bytes = Encoding.UTF8.GetBytes(manifest); IntPtr ptr = Marshal.AllocHGlobal(bytes.Length); try { Marshal.Copy(bytes, 0, ptr, bytes.Length); if (!UpdateResource(hUpdate, 24, 1, 0, ptr, (uint)bytes.Length)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (!EndUpdateResource(hUpdate, false)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { Marshal.FreeHGlobal(ptr); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload