将.NET 4.0库注入非托管应用程序,clr.dll中无限循环
我正在尝试将 .net 库注入到托管应用程序中,但在使用 ollydbg 进行一些调试后它似乎不起作用,我发现它无限循环。如果我强行退出循环,一切都会正常。我已经创建了一个解决方法(请参阅下面的代码),但我怀疑这是否应该是这样!
循环从执行时开始: hr = pClrHost->Start();
注入器代码
static void Main(string[] args)
{
//Has to be 32Bit app, not sure why yet, x86 should work in x64 apps
Process np = Process.GetProcessesByName("notepad")[0];
string dllpath = @"c:\Loader.dll";
string corepath = string.Format("{0}\\{1}", Environment.GetFolderPath(Environment.SpecialFolder.System), "mscoree.dll");
if (!File.Exists(corepath))
{
//No .NET
}
//Open Process for write access
IntPtr PID = OpenProcess(PROCESS_ALL_ACCESS, false, np.Id);
//Allocate memory
IntPtr addr = (IntPtr)VirtualAllocEx(PID, IntPtr.Zero, (uint)dllpath.Length + 1, 0x1000, 4);
if (addr == IntPtr.Zero)
{
//return false;
}
//Write DLL path into process memory
int wrote = WriteProcessMemory(PID, addr, System.Text.Encoding.ASCII.GetBytes(dllpath), (uint)dllpath.Length +1, IntPtr.Zero);
IntPtr hRemoteThread = IntPtr.Zero;
uint temp;
//Start new thread @ LoadLibraryA with path to library as parameter
hRemoteThread = CreateRemoteThread(PID, IntPtr.Zero, 0, (IntPtr)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"), addr, 0, out temp);
if (hRemoteThread == IntPtr.Zero)
{
//return false;
}
System.Threading.Thread.Sleep(1000);
//**WORK AROUND**
//Force loop to exit, Will cause the messagebox to show up
wrote = WriteProcessMemory(PID, (IntPtr)0x6D8EC91A, new byte[1]{ 0xEB}, (uint)1, IntPtr.Zero);
//Clean up
VirtualFreeEx(PID, addr, (uint)dllpath.Length + 1, FreeType.Release);
//return true;
}
C++ .Net 加载器代码
#pragma comment(lib,"MSCorEE.lib")
#include <mscoree.h>
#include <metahost.h>
ICLRRuntimeHost* pClrHost = NULL;
int WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
{
// Get the policy object, so we can determine which runtime to use.
ICLRMetaHostPolicy* pMetaHostPolicy = NULL;
HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy);
if (FAILED(hr))
{
MessageBox(NULL, L"Could not create a ICLRMetaHostPolicy object!", L"Injection - Error", MB_OK);
return 1;
}
ICLRRuntimeInfo* pRuntimeInfo = NULL;
// Get the runtime info object. Allow the assembly to tell US what runtime to use.
DWORD pcchVersion = 0;
DWORD dwConfigFlags = 0;
hr = pMetaHostPolicy->GetRequestedRuntime(METAHOST_POLICY_HIGHCOMPAT,
L"C:\\Test.dll", NULL,
NULL, &pcchVersion,
NULL, NULL, &dwConfigFlags,
IID_ICLRRuntimeInfo,
(LPVOID*)&pRuntimeInfo);
if (FAILED(hr))
{
MessageBox(NULL, L"Could not create an ICLRRuntimeInfo object.", L"Injection - Error", MB_OK);
return 1;
}
// Allow the runtime to load .NET 2.0 mixed-mode libraries. (This covers 2.0-3.5 SP1)
hr = pRuntimeInfo->BindAsLegacyV2Runtime();
if (FAILED(hr))
{
MessageBox(NULL, L"Could not bind as legacy v2 runtime.", L"Injection - Error", MB_OK);
return 1;
}
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pClrHost);
if (FAILED(hr))
{
MessageBox(NULL, L"Could not get an instance of ICLRRuntimeHost!", L"Injection - Error", MB_OK);
return 1;
}
hr = pClrHost->Start();
if (FAILED(hr))
{
MessageBox(NULL, L"Failed to start the CLR!", L"Injection - Error", MB_OK);
return 1;
}
DWORD dwRet = 0;
// Execute the Main func in the domain manager, this will block indefinitely.
// (Hence why we're in our own thread!)
hr = pClrHost->ExecuteInDefaultAppDomain(
L"C:\\Test.dll", // Executable path
L"Test.bc",
L"InjectedMain",
L"Hello World!",
&dwRet);
if (FAILED(hr))
{
MessageBox(NULL, L"Failed to execute in the default app domain!", L"Injection - Error", MB_OK);
return 1;
}
}
break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH: break;
}
//FreeLibraryAndExitThread(hInstance, 0);
return true;
}
.Net 测试代码
public class bc
{
public static int InjectedMain(string args)
{
try
{
MessageBox.Show(args);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
return 0;
}
}
调试器中所述循环的图像
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案:
删除DllMain,它有限制。
将代码移至导出函数。加载库然后调用导出的函数。
Solution:
Remove DllMain, It has restrictions.
Move code to exported function. Load the library then call the exported function.
不确定,因为您描述的场景至少可以说是“某种程度上不寻常”,但我怀疑解决方案位于以下可能性/选项中:
SetDefaultStartupFlags
STARTUP_DISABLE_COMMITTHREADSTACK
对我来说看起来非常有希望,因为循环似乎对堆栈和线程做了一些事情...Not sure since the scenario you describe is to say the least "somehow unusual" but I suspect the solution lies somewhere in the following possibilities/options:
SetDefaultStartupFlags
STARTUP_DISABLE_COMMITTHREADSTACK
looks very promising to me since the loop seems to do something with stacks and threads...