CLR在文件访问

时间:2016-11-16 21:50:56

标签: c# .net clr code-injection appdomain

我借助CLR(启动.NET 4.0.30319)将托管类库注入非托管进程[将单人游戏变为多人游戏]。

ICLRMetaHost *pMetaHost;
ICLRRuntimeInfo *pRuntimeInfo;
ICLRRuntimeHost *pClrRuntimeHost;
DWORD result;

CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo);
pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pClrRuntimeHost);
pClrRuntimeHost->Start();

// execute the method "Int32 Program.Main(String arg)"
pClrRuntimeHost->ExecuteInDefaultAppDomain(L"UnmanagedAssembly.dll", L"Program", L"Main", L"Argument", &result);

要从目标进程调用我自己的非托管方法,我使用了以下方法:

HRESULT ExecuteInDefaultAppDomain (
[in] LPCWSTR pwzAssemblyPath,
[in] LPCWSTR pwzTypeName, 
[in] LPCWSTR pwzMethodName,
[in] LPCWSTR pwzArgument,
[out] DWORD *pReturnValue
);

https://msdn.microsoft.com/en-gb/library/ms164411(v=vs.110).aspx
哪个工作正常,但由于它只接受字符串作为参数我试图用这个方法做同样的事情,这似乎更方便:

HRESULT ExecuteInAppDomain(
[in] DWORD AppDomainId, 
[in] FExecuteInDomainCallback pCallback, 
[in] void* cookie
);

https://msdn.microsoft.com/de-de/library/ms164410(v=vs.110).aspx
我使用第一个方法使用的相同AppDomain,调用我的.NET回调,并且cookie参数传输正常。 但是,如果我尝试访问由ExecuteInAppDomain启动的托管回调中的文件,请执行此操作。

File.Create("wat.txt");

流程直接崩溃,没有例外。使用“ExecuteInDefaultAppDomain”-Method我没有遇到这个问题。调试崩溃转储为我提供了以下信息:

>   KERNELBASE.dll!_RaiseException@16()
[Transition from managed to native] 
mscorlib.dll!Microsoft.Win32.Win32Native.SafeCreateFile(string lpFileName, int dwDesiredAccess, System.IO.FileShare dwShareMode, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES securityAttrs, System.IO.FileMode dwCreationDisposition, int dwFlagsAndAttributes, System.IntPtr hTemplateFile)
mscorlib.dll!System.IO.FileStream.Init(string path, System.IO.FileMode mode, System.IO.FileAccess access = ReadWrite, int rights, bool useRights = false, System.IO.FileShare share, int bufferSize = 4096, System.IO.FileOptions options, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES secAttrs, string msgPath = "wat.txt", bool bFromProxy, bool useLongPath, bool checkHost)
mscorlib.dll!System.IO.FileStream.FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize)
mscorlib.dll!System.IO.File.Create(string path)


  Error module name:    KERNELBASE.dll
  Error module version: 6.3.9600.18202
  Exception code:   e0434352
  Exception offset: 00015b68

互联网上没有任何内容可以帮助解决这个KernelBase错误,但似乎它只是一个症状。是否缺少某些权限? 我有点无奈该做什么。显然“ExecuteInDefaultAppDomain”的做法与“ExecuteInAppDomain”不同,尽管我使用两种方法调用相同的AppDomain,这两种方法都是具有不受限制权限的默认AppDomain。

此外,如果我使用pinvoke

[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi, SetLastError=true)]
public static extern IntPtr fopen(String filename, String mode);

在我的托管代码中读/写文件,它工作得很好。

编辑:

什么在起作用:

Managed Code:
pClrRuntimeHost->ExecuteInDefaultAppDomain(L"D:/UnmanagedLib.dll", L"Unmanaged.Program", L"Main", L"Argument", &result);

Unmanaged Code:
namespace Unmanaged
{
    public static class Program
    {
        public static int Main(string message)
        {
            File.Create("D:\\test.txt");
            AnotherClass.CreateFile();
            return 0;
        }
    }

    public static class AnotherClass
    {
        public static void CreateFile()
        {
            File.Create("D:\\test2.txt");
        }
    }
}

Managed Code:
pClrRuntimeHost->ExecuteInDefaultAppDomain(L"D:/UnmanagedLib.dll", L"Unmanaged.Program", L"Main", L"Argument", &result);
pClrRuntimeHost->ExecuteInAppDomain(1, (ExecuteInAppDomainCallback)result, (void*)1234);

Unmanaged Code:
namespace Unmanaged
{
    public static class Program
    {
        public delegate void Callback(int arg);

        public static int Main(string message)
        {
            return Marshal.GetFunctionPointerForDelegate((Callback)MyCallback).ToInt32();
        }

        public static void MyCallback(int argument)
        {
            File.Create("D:\\test.txt");
        }
    }
}

什么不起作用:

Managed Code:
pClrRuntimeHost->ExecuteInDefaultAppDomain(L"D:/UnmanagedLib.dll", L"Unmanaged.Program", L"Main", L"Argument", &result);
pClrRuntimeHost->ExecuteInAppDomain(1, (ExecuteInAppDomainCallback)result, (void*)1234);

Unmanaged Code:
namespace Unmanaged
{
    public static class Program
    {
        public delegate void Callback(int arg);

        public static int Main(string message)
        {
            return Marshal.GetFunctionPointerForDelegate((Callback)MyCallback).ToInt32();
        }

        public static void MyCallback(int argument)
        {
            AnotherClass.CreateFile();
        }
    }

    public static class AnotherClass
    {
        public static void CreateFile()
        {
            File.Create("D:\\test.txt"); // crashes here
        }
    }
}

Managed Code:
pClrRuntimeHost->ExecuteInDefaultAppDomain(L"D:/UnmanagedLib.dll", L"Unmanaged.Program", L"Main", L"Argument", &result);
pClrRuntimeHost->ExecuteInAppDomain(1, (ExecuteInAppDomainCallback)result, (void*)1234);

Unmanaged Code:
namespace Unmanaged
{
    public static class Program
    {
        public delegate void Callback(int arg);

        public static int Main(string message)
        {
            return Marshal.GetFunctionPointerForDelegate((Callback)AnotherClass.MyCallback).ToInt32();
        }
    }

    public static class AnotherClass
    {
        public static void MyCallback(int argument)
        {
            File.Create("D:\\test.txt"); // crashes here
        }
    }
}

0 个答案:

没有答案