none
大家来看看我这代码哪错了 RRS feed

  • 问题

  • private void Immit(string url, int Id)
            {
                IntPtr NewAdd = new IntPtr();
                int leng = url.Length + 1;
                IntPtr proceHandle = new IntPtr();
                try
                {
                    proceHandle = ApiFunction.OpenProcess(0x1F0FFF, false, Id);//进程句柄
                    //从目标分配空间
                    NewAdd = ApiFunction.VirtualAllocEx(proceHandle, (IntPtr)null, leng, MEMMessage.MEM_COMMIT, PAGEinfo.PAGE_READWRITE);
    
                    if (NewAdd == (IntPtr)0)
                    {
                        throw new Exception("分配空间失败");
                    }
                    //复制DLL到指定空间
                    bool isok = ApiFunction.WriteProcessMemory(proceHandle, NewAdd, url, leng, 0);
                    if (!isok)
                    {
                        throw new Exception("复制DLL到指定空间失败");
                    }
                    //得到LoadLibraryA函数地址
                    IntPtr add = ApiFunction.GetProcAddress(ApiFunction.GetModuleHandle("kernel32.dll"), "LoadLibraryA");
                    if (add == (IntPtr)0)
                    {
                        throw new Exception("取LoadLibraryA函数地址失败");
                    }
                    //创建远程线程
                    IntPtr result = ApiFunction.CreateRemoteThread(proceHandle, 0, 0, add,NewAdd, 0, null);
                    if (result == (IntPtr)0)
                    {
                        throw new Exception("创建远程线程失败");
                    }
                    
                    ApiFunction.WaitForSingleObject(result, 0xFFFFFFFF);
                  //关键在这,上面已经把DLL注入到目标进程了。
                    
                Assembly assembly = Assembly.LoadFile(url);
                IntPtr MethodAdd = new IntPtr();
                Type[] tp = assembly.GetTypes();
                for (int i = 0; i < tp.Length; i++)
                {
                    MethodInfo[] mf = tp[i].GetMethods();
                    for (int j = 0; j < mf.Length; j++)
                    {
                        string n = mf[j].Name;
                        if (n == "tt")//这里我DLL里面有个tt方法
                        {
                            RuntimeMethodHandle rmh = mf[i].MethodHandle;
                            MethodAdd = rmh.Value;//得到方法句柄
                            //在目标进程运行方法
                           result = ApiFunction.CreateRemoteThread(proceHandle, 0, 0, MethodAdd ,(IntPtr)0, 0, null);
                            break;
                        }
                    }
                }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示");
                }
                finally
                {
                    ApiFunction.VirtualFreeEx(proceHandle, NewAdd, leng, MEMMessage.MEM_DECOMMIT);
                    ApiFunction.CloseHandle(proceHandle);
                }
    
            }
    
    运行之后,目标进程提示错误,程序崩溃。
    2009年11月2日 6:15

答案

  • 就我所知,这是不支持的在.NET的程序中,

    这种行为必须具有原生DLL导出到另一个进程中注入需要一个有效的,一致的函数本身调入。这种现象需要一个DLL导出的。NET Framework不支持DLL导出。托管代码没有一个一致的价值函数指针的概念,因为这些函数指针是动态建置的Proxy。
    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年11月6日 3:48
    版主

全部回复

  • 你好!
         请问具体抛出什么异常?
    周雪峰
    2009年11月2日 9:20
    版主
  • 异常是目标程序提示错误内存地址不能为read,崩溃
    2009年11月2日 15:09
  • 这种错误一般比较难判断,一般是和非托管代码交互的时候容易发生类似的问题,你检查一些传递给非托管代码的参数类型!
    周雪峰
    2009年11月2日 16:46
    版主
  • 那你觉得我上面的那个思路正确吗?
    2009年11月3日 2:24
  • WriteProcessMemory copies the data from the specified buffer in the current process to the address range of the specified process. Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call the function. Typically but not always, the process with address space that is being written to is being debugged.

    The entire area to be written to must be accessible, and if it is not accessible, the function fails.

    估计你对目标进程没有相应的权限。

    如果有需求,请调用AdjustTokenPrivileges 或者CreateRestrictedToken去修改目标进程的权限。
    希望这个文章能帮助你。http://blog.csdn.net/cigogo/archive/2009/04/29/4136590.aspx


    月下听禅风疾,篁中论道水湍
    2009年11月4日 4:59
  • 我已经把自身进程权限提升为"SeDebugPrivilege"了
    2009年11月4日 6:17
  • 你还要设置目标进程的权限,因为你是注入目标进程的。
    月下听禅风疾,篁中论道水湍
    2009年11月4日 8:57
  • 那能不能说下,要对目标进程设置那种权限呢?
    2009年11月4日 13:54
  • WriteProcessMemory copies the data from the specified buffer in the current process to the address range of the specified process. Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call the function. Typically but not always, the process with address space that is being written to is being debugged.



    Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call the function
    月下听禅风疾,篁中论道水湍
    2009年11月4日 14:01
  • 哦 是这个权限啊!  我已经设置为PROCESS_ALL_ACCESS了
    2009年11月5日 1:46
  • 你好,

    看你的代码,你是做DLL注入,你好像是在要执行托管的代码在另外一个进程中,这个一般都是使用Native C++来做的,因为托管的代码都要一个运行时环境,不建议这样做。你最好看一下 chapter21 DLL Injection and API Hooking of  Windows Via C/C++在这种情况使用C++来实现这个功能。

    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年11月5日 6:46
    版主
  • 恩  没错  我就是想做这个。至于托管的代码都要一个运行时环境,我把它注入到.NET的程序里不是就可以了吗。现在问题的关键是,我想注入用C#写的dll。因为C#写的dll没有DllMain,所以我就用反射的方式找到方法句柄,让远程进程执行。不知道可行不,我上面的代码已经实现了,但是没成功。

    2009年11月5日 7:01
  • 就我所知,这是不支持的在.NET的程序中,

    这种行为必须具有原生DLL导出到另一个进程中注入需要一个有效的,一致的函数本身调入。这种现象需要一个DLL导出的。NET Framework不支持DLL导出。托管代码没有一个一致的价值函数指针的概念,因为这些函数指针是动态建置的Proxy。
    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年11月6日 3:48
    版主