none
AccessVioalationException & Assembly Load & Assembly file name RRS feed

  • Question

  • Hi,

    I have an AccessVioalationException, which always happens when I run my application in the installation directory. As I cannot regenerate the problem under Visual Studio debug directory, I cannot debug it. When I receive the exception the application terminates immediately so there is no chance to connect a debugger.

    Most strange thing is that I only see this problem in the release directory with the original executable name. If I change the name of the executable or if I install it to another directory, the problem suddenly disappears. I couldn't find a relation between executable's file name (or path)  and AccessVioalationException.

    Maybe you guys have at least some idea about what is happening. Here are the details.

    - The application consists of two parts, Launcher and the main executable, encrpyted in a binary file.
    - Launcher decodes the main file and loads it as a raw assembly by using Assembly.Load(byte[]) and than invokes the Main()
    - Assembly names of Launcher and the main executable are the same, they are generated from the same source tree and use the same strong key.
    - The problem happens, when the application performs a P/Invoke operation, where it gets the icons associated to the file types

    The following is how I get the Icons using P/Invoke:


     public struct SHFileInfo
    {
            public IntPtr hIcon;
            public IntPtr iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }


    public class Shell
    {

            [DllImport("shell32.dll", EntryPoint = "SHGetFileInfo", CharSet = CharSet.Auto)]
            public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFileInfo psfi, uint cbSizeFileInfo, SHGFIFlags uFlags);

            public static Icon GetIcon(string path, IconSize size, bool copy)
            {
                SHFileInfo shinfo = new SHFileInfo();
                IntPtr hSuccess = GetIcon(path, size, ref shinfo);
                if(hSuccess != IntPtr.Zero){
                    Icon icon;
                    if(copy){
                        icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();
                        Win32.DestroyIcon(shinfo.hIcon);
                        shinfo.
                    }else{
                        icon = Icon.FromHandle(shinfo.hIcon);
                    }
                    return icon;
                }else{
                    return null;
                }
            }
           
            public static IntPtr GetIcon(string path, IconSize size, ref SHFileInfo shinfo){
                SHGFIFlags flags;
     
                if(size == IconSize.Small){
                    flags = SHGFIFlags.SmallIcon | SHGFIFlags.Icon;
                }else{
                    flags = SHGFIFlags.LargeIcon | SHGFIFlags.Icon;
                }
                return SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags);
            }

    }

            Icon GetFileIcon(string path)
            {
                //SHFileInfo fi = new SHFileInfo();
                //IntPtr iconPtr =
                return Shell.GetIcon(path, IconSize.Large, true);
                //return System.Drawing.Icon.FromHandle(fi.hIcon);
            }



    Thanks in advance,

    Onur



    Friday, February 6, 2009 1:15 PM

All replies

  • The 2nd member of SHFileInfo is an int, not IntPtr.  SHGetFileInfo() doesn't return an IntPtr.  You'll leak when you ever pass copy=false.  There is no loading context for the main assembly since you loaded it with Load(byte[]), there'll be trouble when that main assembly has dependent assemblies.  That has a casual link to your problem with the installation directory.

    Do weigh the cost of creating a maintenance headache against the unlikely odds of anybody ever actually disassembling your code.  .NET obfuscators are a dime a dozen.

    Hans Passant.
    Friday, February 6, 2009 2:53 PM
    Moderator
  • Hi Nobugz,

    Thanks for the info. I am going to fix the errors and try again.

    Neither the main assembly nor the launcher don't have dependent assemblies. They are compiled using command line compiler as single assemblies. I use the same assembly name for both launcher and the main app. And as they are from the same sourcebase and namespace they both have objects with the same names. Do you think it may cause any problems?

    I am already using an Obfuscator. Encryption is the secondary protection :) Of course I know that there is no uncrackable code. I am just trying to make things more complex for hackers.

    Regards,

    Onur
    Friday, February 6, 2009 3:54 PM
  • Onur Okyay said:

    just trying to make things more complex for hackers.

    I'll try to not follow-up on that comment, it would be too easy.  No assemblies should be loaded from disk, other than .NET's.  Verify with fuslogvw.exe

    Hans Passant.
    Friday, February 6, 2009 6:04 PM
    Moderator

  • Hi,

    You're right about the hacking issue :|.

    I checked fusion log. There are no binding errors. I also run the exe in CLR Debugger. But this time the exception I got was ExecutionEngineException. I couldn't load pdb file  for the the main module symbols, that I load by using Assembly.Load(). Debugger complains that the PDB file is incompatible, although it is. The CLR debugger cannot step into the loaded module from the launcher at the point of invocation.

    By the way the problem disappears when I compile the main module with debugging enabled. But I don't know whether this is a random case or not, like the path problem above.

    If we forget all the stuff above for a moment;

    - What should I care when loading another exe by using Assembly.Load(byte[])?
    - Is there any precautions that we should take when doing P/Invoke inside the loaded assembly.

    So as you see I am stuck.  Any suggestions are appreciated.

    Thanks,

    Onur
    Monday, February 9, 2009 3:15 PM