设为首页 收藏本站
查看: 1112|回复: 0

C# 直接执行、调用本机代码、汇编代码 shell Native Code

[复制链接]

尚未签到

发表于 2015-4-28 11:36:13 | 显示全部楼层 |阅读模式
  本文讲述如何在 .net C# 中
坠入,执行调用本机代码、汇编代码 、shell Native Code

  谁说,.net 不能直接使用本机代码汇编;本文将讲述如何实现这一技术;
不多说了上代码:

刚才发布的那个版本修改时出了问题被我删除了又发了一次,抱歉了先


/*
   
    执行调用本机代码、汇编代码 shell Native Code

    解释
        本例中 IntPtr 其实是相当于 C 语言中的 (void *) 指向任何类型的指针,
            就是一个地址 32 位系统就是个 Int32,本例相当与一个函数指针

    核心技术流程
        变量:
            【本机代码字节数组】 byte[] codeBytes ; 一段加法本机代码
            【函数指针】 IntPtr handle ; 指向本机函数开始地址的变量
        流程:
            
        >> 给 【函数指针】划分非托管内存 ; 使用 Marshal.AllocHGlobal(codeBytes.Length)
                划分大小等同于本机代码字节总数    因为函数本身还不存在于内存中所以先开辟一块内存;
                以便放置函数。
               
        >> 将 【本机代码字节数组】中的字节写入 【函数指针】 ;
                Marshal.Copy(codeBytes,0,handle,codeBytes.Length);

        
        >> 使用 Marshal.GetDelegateForFunctionPointer 【函数指针】 强制转换为托管委托 DelegateAdd;
                因为这时 handle 内的字节数组已经是内存中的一段本机方法的代码
                handle 的“起始地址”就相当于一个“本机函数的入口地址”
                所以可以成功转换为对应的委托

        >> 调用 委托 ;

        >> 释放本机句柄;Marshal.FreeHGlobal(this._handle);

修改记录
    2008-5-11 8:07 曲滨
        >> 基本实现预期功能
        [!] 明天进行优化

    2008-5-12 15:54 曲滨
        [E] 优化完成
        [N] 加入 NativeCodeHelper 类便于使用
*/
namespace NShellNativeCode
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.IO;
    using System.Diagnostics;
    using System.Reflection;
   
    delegate int AddProc(int p1, int p2);
    class Program
    {
        

        static void Main(string[] args)
        {
            
            //一段加法函数本机代码;后面注释是给会 asm 看官看的
            //笔者本身也不是太明白汇编,简单的 10行8行的还可以
            
            byte[] codeBytes = {
                  0x8B, 0x44, 0x24, 0x08    // mov eax,[esp+08h]
                , 0x8B, 0x4C, 0x24, 0x04    // mov ecx,[esp+04h]
                , 0x03, 0xC1                // add    eax,ecx
                , 0xC3                        // ret
                };
                        
            /*
            上面的字节数组,就是下面函数的本机代码;
            int add(int x,int y) {
                return x+y;
            }
            
            */

            IntPtr handle = IntPtr.Zero;
            handle = Marshal.AllocHGlobal(codeBytes.Length);
            try
            {

                Marshal.Copy(codeBytes, 0, handle, codeBytes.Length);
                                
                AddProc add
                   = Marshal.GetDelegateForFunctionPointer(handle, typeof(AddProc)) as AddProc;
               
                int r = add(1976, 1);

                Console.WriteLine("本机代码返回:{0}", r);


            }
            finally
            {
                Marshal.FreeHGlobal(handle);
            }
            
            //本演示内包含的已经封装好的 本机字节代码,转换委托通用类
            //打开注释就可以用了;
            
            /*
            using (NativeCodeHelper helper = new NativeCodeHelper(codeBytes))
            {
                AddProc add = helper.ToDelegate();
                Type t =  add.Method.DeclaringType;
                int r = add(1976,1);
                Console.WriteLine("本机代码返回:{0}",r);
            }
            */
                    
            
            //Console.ReadLine();
        }   
            
        
    }

/*
    结束语
        已知问题
            1)在操作系统打开 DEP 保护的情况下,这类代码会不灵;
                我没有测试,有兴趣的可以试验一下,估计是不会好用的;
            
            2)如果要在 本机代码 中调用 Win API 函数,因为在不同系统不同版本中
                Win API 的地址是不同的;
                要有一些编写 shell code 能力于黑客技术关系密切这里不做详细描述
   
        本文技术的适用范围
            >> 遗留系统,C/C++ 的某些算法、尤其汇编形式的是如果懒的改成.net 可以直接吧二进制copy
                出来直接调用、不过需要C/VC、反汇编、汇编有点了解要不没法Copy;

            >> 有些代码不想被反编译,给破解者增加些破解难度、郁闷有可能会改你代码的人
                实用性有多少看官自己感觉吧,因为技术这东西是相对的
                如果你的程序中到处都是这类代码是很难维护的,就是熟悉汇编的人
                这种东西多了也很郁闷的、本机代码远比汇编难看的多  

            >> 忽悠小朋友
                把我的代码直接copy倒你的项目里,一点都不改,要算int加法的时候都这么用
                如果有小朋友看见一定会感觉你很 Cool
        
        重要声明:
            这种本机代码方式如果应用倒真实项目中一定要项目负责人的同意的情况下,否则出现
        任何人事问题,或刑事问题与本文作者无关;
            如
                >> 在真实项目中使用本文技术,在代码中坠入逻辑炸弹者;
                >> 在真实项目中使用本文技术,拒不上缴本机字节代码对应的源代码者;
                >> 在真实项目或共享软件中,捆绑病毒代码者;
        
*/

    ///
    /// 用于将本机代码 byte 数组转换为 .net 委托
    ///
    ///
    /// 实现了 IDisposable 使用了非托管资源 使用时不要忘记释放
    ///
    public class NativeCodeHelper:IDisposable
    {
        
        private bool _disposed = false;
        private byte[] _codeBytes = {};
        private IntPtr _handle = IntPtr.Zero;
        
        public NativeCodeHelper(byte[] codeBytes)
        {
             this._codeBytes =  codeBytes;
        }
        
        ///
        /// 把byte数字转换为本机类型的指针 主要处理 this._handle
        ///
        private void CreateHandle()
        {
            if (_handle == IntPtr.Zero)
            {
                _handle = Marshal.AllocHGlobal( this._codeBytes.Length);
                Marshal.Copy(_codeBytes, 0, _handle, _codeBytes.Length);
            }        
        }
        ///
        /// 转换为指定的委托
        ///
        ///
        ///
        public T ToDelegate() where T:class
        {
            this.CreateHandle();
            
            //把指针转换为 委托方法
            T result = Marshal.GetDelegateForFunctionPointer(_handle, typeof(T)) as T;            
            
            return result;

        }
        
        #region IDisposable 成员
        
        ~NativeCodeHelper()
        {
            Dispose(false);
        }
        
        public void Dispose()
        {
            Dispose(true);        
            GC.SuppressFinalize(this);

        }

        
        
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                //给调用者忘记 Dispose 释放的提示
                MethodBase mb = System.Reflection.MethodBase.GetCurrentMethod();
                Type t = mb.DeclaringType;
               
                Trace.WriteLine("not Dispose"
                , "" + t + "." + mb );
            }
            
            
            if (!this._disposed)
            {
                if (disposing)
                {
                    //释放.net 需要 Dispose 的对象                    
                }

                Marshal.FreeHGlobal(this._handle);
                _handle = IntPtr.Zero;
            }
            _disposed = true;
        }        

        #endregion
    }
}

end cnblogs 2008-5-11
程序为命令行程序,
最终输出结果:
    本机代码返回:1977

本文代码下载  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-61534-1-1.html 上篇帖子: shell截取字符串的方法 下篇帖子: shell 中的 eval
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表