C#如何从进程中检索代码然后运行它?
Posted
技术标签:
【中文标题】C#如何从进程中检索代码然后运行它?【英文标题】:C# How to retrieve code from a process and then run it? 【发布时间】:2016-09-19 05:14:22 【问题描述】:由于进程是计算机程序的一个实例,并且包含程序代码及其当前活动,因此我尝试了以下操作:
解析我的进程并检索一个字节数组。 执行这些字节。我的问题是我同时检索程序代码及其当前活动,而我只对第一部分感兴趣。
这是我检索进程“foo”字节的方法:
public static byte[] retrieveProcessBytes(String processName)
Process process = ApplicationFinder.FromProcessName(processName).First();
var sharp = new MemorySharp(process);
List<byte> bytes = new List<byte>();
IntPtr ptr = IntPtr.Zero;
try
while (true)
bytes.Add(sharp.Read<byte>(ptr, 1)[0]);
ptr = IntPtr.Add(ptr, 1);
catch (Exception e)
Console.Write("Exception caught : " + e);
return bytes.ToArray();
这是我尝试执行它的方式:
byte[] bytes = retrieveProcessBytes("foo");
Assembly asm = Assembly.Load(bytes);
Object[] Args = new Object[0];
asm.EntryPoint.Invoke(null, Args);
它给了我以下错误:
在 mscorlib.dll 中发生了“System.BadImageFormatException”类型的未处理异常
同时,如果我从“foo.exe”程序中检索字节并执行它们,如下所示,它可以工作。
Byte[] bytes = File.ReadAllBytes(pathToFooExe);
Assembly asm = Assembly.Load(bytes);
我从进程中检索到的字节数组比我从“foo.exe”文件中检索到的要大得多。因为我想我也检索了当前的流程活动。
我怎样才能只检索我的流程的代码部分?
它是从 IntPtr.Zero 还是之后开始?我什么时候停下来?
任何帮助将不胜感激,在此先感谢。
【问题讨论】:
这是一种非常简单的查看方式。但是你不能像这样从一个正在运行的进程中提取程序。首先,内存不是线性块,其次,进程的内存中还有其他加载的模块(程序集/DLL等),第三,EXE文件没有1:1加载到内存中。有关 EXE 文件格式以及如何将其加载到内存中的更多详细信息,请查看this out。 你这次行动的目标是什么?可能有更好的解决方案来实现您想要的。 我想比较我的进程中的代码是否与exe文件中的代码相同。如果程序在运行时通常会有所不同,例如具有 DRM 或保护的程序。 在你自己的进程中还是在另一个进程中?在任何情况下,您都可以专门检查代码部分和/或数据部分,并将它们与 EXE 文件中的相应部分进行比较(再次查看我在上面发布的文件格式的链接)。但请注意,可能会有第三方软件,例如防病毒软件在运行时修补您的代码(例如,COMODO 会/这样做过,我过去因此遇到过问题)。 【参考方案1】:如果您阅读了有关 Assembly.Load 函数的信息,您会发现您使用不当。仅仅因为它允许一个字节数组作为输入并不意味着你正在给它一个正确的字节数组。
Assembly.Load(Byte[])
使用基于通用对象文件格式 (COFF) 的图像加载程序集,该图像包含已发出的程序集。程序集被加载到调用者的应用程序域中。
COFF file format
这显然不是你正在做的事情。基本上,你正在做的事情是做不到的。 CherryDT 在他的 cmets 中也给了你很好的理由。
【讨论】:
以上是关于C#如何从进程中检索代码然后运行它?的主要内容,如果未能解决你的问题,请参考以下文章