本帖最后由 wangjia184 于 2009-08-11 21:36:57 编辑

解决方案 »

  1.   

    .NET虚拟机有自己的内存管理方式,不同于Win32原生代码。.NET 有专门的加壳软件和混淆器。
      

  2.   

    .Net PE还是属于 Windows PE,是在Windows PE的基础上通过IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR这个数据目录进行了扩展,本质上还是Windows PE
    只是说运行的时候是MSIL通过虚拟机执行,而不是Intel 机器码.Net PE文件同样引入了mscoree.dll,这是一个非托管DLL,既然它能够导入一个非托管dll,为什么不能导入2个呢??
      

  3.   

    .Net PE 本身就是一个壳了
      

  4.   

    相同和不同是相对的,不是绝对的。我说的不同是.NET虚拟机有自己的内存管理方式。
    要绝对地说来,DOS程序和Win32程序也是相同的。Win32程序包括一个DOS头,只不过多了PE节而已。
      

  5.   

    我查过了,
    PE Optinal Header的 EntryOfAddress指向 一条jmp指令
    这条jmp指令对于 .Net exe 文件是跳转到 mscoree.dll的 _CorExeMain, 
    对于 .Net dll文件时跳转到 mscoree.dll的 _CorDllMain 也就是说 mscoree.dll 负责初始化.Net runtime。只要能够拦截到现在我已经完成了IL指令的加密,我需要HOOK到 mscoree.dll 的一些运行时函数来定制.Net Runtime。
    现在的问题是:为什么修改导入表后.Net PE文件就损坏了,而普通Win32 PE文件正常?
      

  6.   


    怎么加壳IL指令我都已经解决了,我只是修改.Net Runtime的一些行为而不是自己完全写一个.Net Runtime.  .Net PE文件既然属于Windows PE,就应该能够修改导入表,在.Net Runtime初始化时加入自己的行为。
      

  7.   


    我的问题不是挂钩,不过我看了你的文章,我的方式和你不同,是HOOK  Profiler的COM接口来实现
    当JIT对MethodBody的 IL代码即时编译时进行修改
    可以对任何Method进行修改
    我现在需要找到一种方法进入到目标的进程空间去修改 Runtime的行为
    要防止程序被内存Dump后还能正常运行,基本上就是自己的一套保护机制
    因为一般ASP.Net编译出来的是DLL,所以不考虑任何外在的进入方式,比如配置环境变量做Profiler都不好
    想直接在.Net PE文件上做文章.Net PE其实就是普通的PE文件,在入口点后跳到了 mscoree.dll去进行虚拟机的初始化,以及执行。
    奇怪的是,加入一个自己的dll到导入表就初始化失败,而且尝试在mscoree.dll中间加一层Proxy也不可以
      

  8.   

    终于有点眉目了,Windows PE Loader 在调用LdrpInitializeProcess 的时候返回失败
    .text:7C835534 loc_7C835534:
    .text:7C835534 mov     dword ptr [esi+0A0h], offset _LdrpLoaderLock
    .text:7C83553E mov     _LdrpInLdrInit, 1
    .text:7C835545 mov     eax, offset _RtlpCalloutEntryList
    .text:7C83554A mov     dword_7C88A3EC, eax
    .text:7C83554F mov     _RtlpCalloutEntryList, eax
    .text:7C835554 mov     eax, offset _RtlpCallbackEntryList
    .text:7C835559 mov     dword_7C88AA14, eax
    .text:7C83555E mov     _RtlpCallbackEntryList, eax
    .text:7C835563 mov     [ebp+ms_exc.disabled], ebx
    .text:7C835566 push    [ebp+arg_4]
    .text:7C835569 push    [ebp+arg_0]
    .text:7C83556C call    LdrpInitializeProcess(x,x)
    .text:7C835571 mov     edi, eax
    .text:7C835573 mov     [ebp+var_1C], edi
    .text:7C835576 cmp     edi, ebx
    .text:7C835578 jl      loc_7C84A512继续跟踪进入 LdrpInitializeProcess, 发现LdrpCorValidateImage失败.text:7C83F48E lea     esi, [ebx+8]
    .text:7C83F491 mov     eax, [esi]
    .text:7C83F493 mov     [ebp+var_88], eax
    .text:7C83F499 mov     eax, _LdrpImageEntry
    .text:7C83F49E push    dword ptr [eax+28h]
    .text:7C83F4A1 push    esi
    .text:7C83F4A2 call    LdrpCorValidateImage(x,x)
    .text:7C83F4A7 test    eax, eax
    .text:7C83F4A9 jl      loc_7C837059
    再深入,发现此时LdrLoadDll开始加载 mscoree.dll,然后 LdrGetProcedureAddress 获取_CorValidateImage, _CorValidateImage调用失败.text:7C83F98A loc_7C83F98A:
    .text:7C83F98A push    [ebp+var_118]
    .text:7C83F990 push    [ebp+var_114]
    .text:7C83F996 call    _CorValidateImage
    .text:7C83F99C mov     esi, eax
    .text:7C83F99E cmp     esi, ebx
    .text:7C83F9A0 jl      loc_7C83F4MSDN上说 _CorValidateImage的作用是2个:
    1. 重定位进程基址
    2. 验证看来还是mscoree.dll在搞鬼