牛骨文教育服务平台(让学习变的简单)
博文笔记

写了一个内存地址特征码搜索工具

创建时间:2013-04-26 投稿人: 浏览次数:128

实现了

1.搜索汇编上的地址

2.搜索匹配特征的内存地址

3.搜索到的地址再做+法计算,还没做读取内存指针,是直接16进制加法

4.支持通配符(就是用正则表达式来做的)

现在还不是很完善,因为一边学一边做,总觉得欠缺了啥,一些地方还得优化,先上图,过几天放源码


搜索界面:



搜索结果图:搜索运用了线程同时处理,用时单位是毫秒


生成规则界面:




这一版本的操作类:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;

    public class Scan
    {
        /// <summary>
        /// 所有需要扫描的列表
        /// </summary>
        private List<ScanCode> _scode;
        public List<ScanCode> scode
        {
            get { return this._scode; }
            set { this._scode = value; }
        }
        /// <summary>
        /// 打开文件的byte[]数组
        /// </summary>
        private byte[] _fileBytes;
        public byte[] fileBytes
        {
            get { return this._fileBytes; }
        }
        /// <summary>
        /// 打开文件的16进制全字符串
        /// </summary>
        private string _fileHex;
        public string fileHex
        {
            get { return this._fileHex; }
        }
        /// <summary>
        /// 文件流的起始十六进制
        /// </summary>
        private int _beginHex;
        public int beginHex
        {
            get { return this._beginHex; }
            set { this._beginHex = value; }
        }
        /// <summary>
        /// 文件缓冲区大小
        /// </summary>
        private int _bufferSize;
        public int bufferSize
        {
            get { return this._beginHex; }
            set { this._beginHex = value; }
        }
        /// <summary>
        /// 当前扫描线程数
        /// </summary>
        private int _threadCount;
        public int threadCount
        {
            get { return this._threadCount; }
            set { this._threadCount = value; }
        }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="filePath">打开应用程序文件</param>
        /// <param name="beginHex">应用程序起始地址</param>
        public Scan(string filePath, int beginHex)
        {
            this._beginHex = beginHex;
            this._scode = new List<ScanCode>();
            //打开文件
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                int fsLength = (int)fs.Length;
                //读取文件的byte[] 耗时约 1000ms 内
                fs.Seek(0, SeekOrigin.Begin);
                this._fileBytes = new byte[fsLength];
                fs.Read(this._fileBytes, 0, fsLength);
                //通过byte[]转成string的16进制 耗时约 7M = 20s
                fs.Seek(0, SeekOrigin.Begin);
                int atIndex;
                List<string> tmpHex = new List<string>();
                atIndex = fs.ReadByte();
                while (atIndex != -1)
                {
                    tmpHex.Add(string.Format("{0:X2} ", atIndex));
                    atIndex = fs.ReadByte();
                }
                this._fileHex = string.Join("", tmpHex).Replace(" ", "");
                this._bufferSize = 4096;
            }
        }

        /// <summary>
        /// 启动扫描
        /// </summary>
        public void Start()
        {
            this.threadCount = 0;
            foreach (ScanCode c in this.scode)
            {
                //取自定义的开始位置和结束位置中的16进制//
                if (c.start < 0 || c.end < c.start)
                    c.hexString = this._fileHex;
                else
                    c.hexString = this._fileHex.Substring(c.start - this._beginHex, c.end - c.start);
                c.callback = CallBack;
                c.beginhex = this._beginHex;
                c.buffersize = this._bufferSize;
                Thread t = new Thread(new ThreadStart(c.Scan));
                t.Start();
                threadCount++;
            }
        }

        //线程回调方法
        private void CallBack()
        {
            threadCount--;
        }
    }

    public class ScanCode
    {

        public delegate void CallBackDelegate();

        #region 属性
        /// <summary>
        /// 名称
        /// </summary>
        [DisplayNameAttribute("名称"), CategoryAttribute("重要属性"), ReadOnlyAttribute(false), DescriptionAttribute("便于您识别的名称命名")]
        public string name { get; set; }
        /// <summary>
        /// 实际变量
        /// </summary>
        [DisplayNameAttribute("变量名"), CategoryAttribute("重要属性"), DescriptionAttribute("最终格式化的变量名称")]
        public string variable { get; set; }
        /// <summary>
        /// 输入的特征码
        /// </summary>
        [DisplayNameAttribute("特征码"), CategoryAttribute("重要属性"), DescriptionAttribute("特征码,通配符请用*号代替")]
        public string code { get; set; }
        /// <summary>
        /// 用于搜索的特征码
        /// </summary>
        [BrowsableAttribute(false)]
        public string scancode { get { return formatCode(this.code).ToUpper(); } }
        /// <summary>
        /// 代表程序的内存起始位
        /// </summary>
        [BrowsableAttribute(false)]
        public int beginhex { get; set; }
        /// <summary>
        /// 代码程序的内存缓冲区
        /// </summary>
        [BrowsableAttribute(false)]
        public int buffersize { get; set; }
        /// <summary>
        /// 扫描开始值 16进制
        /// </summary>
        [DisplayNameAttribute("A扫描开始段"), CategoryAttribute("地址设置"), DescriptionAttribute("代表程序从您设置的地址开始扫描")]
        [TypeConverter(typeof(HexConverter))]
        public int start { get; set; }
        /// <summary>
        /// 扫描结束值 16进制
        /// </summary>
        [DisplayNameAttribute("B扫描结束段"), CategoryAttribute("地址设置"), DescriptionAttribute("代表程序开始扫描到您设置的地址结束")]
        [TypeConverter(typeof(HexConverter))]
        public int end { get; set; }
        /// <summary>
        /// 返回值
        /// </summary>
        ///[BrowsableAttribute(false)]
        [DisplayNameAttribute("结果值"), DescriptionAttribute("制作时候不需要填写")]
        public string value { get; set; }
        /// <summary>
        /// 说明
        /// </summary>
        [DisplayNameAttribute("说明"), CategoryAttribute("其他"), DescriptionAttribute("简要说明或备注,也作为注释的功能")]
        public string explain { get; set; }
        /// <summary>
        /// 偏移量
        /// </summary>
        [DisplayNameAttribute("附加属性"), CategoryAttribute("附加"), DescriptionAttribute("一些附加的应用属性")]
        [TypeConverterAttribute(typeof(ScanAdditionConverter))]
        public ScanAddition append { get; set; }
        /// <summary>
        /// 扫描用时
        /// </summary>
        [DisplayNameAttribute("扫描用时"), DescriptionAttribute("制作时候不需要填写")]
        public int time { get; set; }
        /// <summary>
        /// 扫描类型
        /// </summary>
        [DisplayNameAttribute("扫描方式"), CategoryAttribute("重要属性"), DefaultValue(typeof(ScanType), "Address"), DescriptionAttribute("这个特征码所要扫描的地址类型")]
        public ScanType type { get; set; }
        /// <summary>
        /// 是否可用
        /// </summary>
        [DisplayNameAttribute("是否生效"), CategoryAttribute("其他"), DefaultValue(true), DescriptionAttribute("失效时不会被载入扫描列队")]
        public bool status { get; set; }
        /// <summary>
        /// 搜索段
        /// </summary>
        [BrowsableAttribute(false)]
        public string hexString { get; set; }
        /// <summary>
        /// 搜索结果匹配项
        /// </summary>
        [DisplayNameAttribute("匹配总数"), DescriptionAttribute("制作时候不需要填写")]
        public int matchCount { get; set; }
        /// <summary>
        /// 线程结束回调
        /// </summary>
        [BrowsableAttribute(false)]
        public CallBackDelegate callback { get; set; }

        #endregion

        #region 方法
        /// <summary>
        /// 格式化特征码中的*号为正则表达式的符号
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private string formatCode(string value)
        {
            string r = "";
            int index = 0;
            for (int i = 0; i < value.Length; i++)
            {
                if (value[i] != "*")
                {
                    if (index > 0)
                    {
                        r += "(.{" + index.ToString() + "})";
                        index = 0;
                    }
                    r += value[i];
                }
                else
                    index++;
            }
            return r;
        }
        /// <summary>
        /// 简易的16进制2/2翻转
        /// </summary>
        /// <param name="value"></param>
        /// <param name="bit"></param>
        /// <returns></returns>
        private string turnHex(string value, int bit)
        {
            string r = "";
            int sbit = value.Length;
            while (sbit > 0)
            {
                r += value.Substring(sbit - bit, bit);
                sbit = sbit - bit;
            }
            return r;
        }
        #endregion

        public ScanCode()
        { }

        public ScanCode(string c)
        {
            string[] t = c.Split("|");
            name = t[0].TrimStart("/");
            variable = t[1];
            code = t[2];
            start = Convert.ToInt32(t[3], 16);
            end = Convert.ToInt32(t[4], 16);
            type = (ScanType)Convert.ToInt32(t[5]);
            append = new ScanAddition(t[6]);
            explain = t[7];
            status = c.StartsWith("//") ? false : true;
        }

        public override string ToString()
        {
            return string.Format("{0}{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}",
                status ? "" : "//",
                name,
                variable,
                code,
                string.Format("{0:X2}", start),
                string.Format("{0:X2}", end),
                (int)type,
                append.ToString(),
                explain);
        }

        public void Scan()
        {
            Stopwatch cl = new Stopwatch();
            cl.Start();
            Regex rx = new Regex(this.scancode);
            MatchCollection matches = rx.Matches(this.hexString);
            this.matchCount = matches.Count;
            //string.Format("找到 {0} 匹配项:
", matches.Count);
            int m = 1;
            foreach (Match match in matches)
            {
                //string.Format("
匹配项 {0} 的详情:
", m.ToString());
                GroupCollection groups = match.Groups;
                int i = 0;
                foreach (Group v in groups)
                {
                    //string.Format("值{2}: {0} 位于坐标 {1}
", v.Value, v.Index, i.ToString());
                    switch (this.type)
                    {
                        case ScanType.Address:
                            if (m == this.append.matchItem && i == this.append.matchPoint)
                                this.value = turnHex(v.Value, 2).TrimStart("0");
                            break;
                        case ScanType.Call:
                            if (m == this.append.matchItem && i == 0)
                            {
                                if (this.append.OffsetPosition == ScanOffset.Up)
                                    this.value = (this.beginhex + (this.start - this.beginhex) + v.Index - this.buffersize - 1 + this.append.OffsetQTY).ToString("X2");
                                else
                                    this.value = (this.beginhex + (this.start - this.beginhex) + v.Index + v.Length - this.buffersize - 1 + this.append.OffsetQTY).ToString("X2");
                            }
                            break;
                        case ScanType.Calculate:
                            if (m == this.append.matchItem && i == this.append.matchPoint)
                                this.value = (Convert.ToInt32(turnHex(v.Value, 2), 16) + this.append.CalcPointer).ToString("X2");
                            break;
                    }
                    i++;
                }
                m++;
            }
            cl.Stop();
            this.time = Convert.ToInt32(cl.ElapsedMilliseconds);
            CallBackDelegate cb = this.callback as CallBackDelegate;
            cb();
        }
    }

    public class ScanAddition
    {
        #region 属性
        [DisplayNameAttribute("匹配项"), DescriptionAttribute("地址和CALL的共用参数,意思:取结果集中的第几个匹配项"), DefaultValue(1)]
        public int matchItem { get; set; }
        [DisplayNameAttribute("匹配位"), DescriptionAttribute("地址的参数,意思:取结果中的第几个通配符得出的结果,0为完全结果"), DefaultValue(1)]
        public int matchPoint { get; set; }
        [DisplayNameAttribute("偏移位"), DescriptionAttribute("CALL的参数,意思:从结果的地址上方还是下方开始计算偏移量"), DefaultValue(typeof(ScanOffset), "Up")]
        public ScanOffset OffsetPosition { get; set; }
        [DisplayNameAttribute("偏移量"), DescriptionAttribute("CALL的参数,意思:取值做最后的偏移量地址,16进制,整数"), DefaultValue(0)]
        [TypeConverter(typeof(HexConverter))]
        public int OffsetQTY { get; set; }
        [DisplayNameAttribute("计算指针"), DescriptionAttribute("组合的参数,意思:Address + this.value"), DefaultValue(0)]
        [TypeConverter(typeof(HexConverter))]
        public int CalcPointer { get; set; }
        #endregion
        public ScanAddition() { OffsetPosition = ScanOffset.Up; matchPoint = 1; matchItem = 1; }
        public ScanAddition(string value)
        {
            OffsetPosition = ScanOffset.Up; matchPoint = 1; matchItem = 1;
            string[] arr = value.Split("~");
            if (arr.Length == 5)
            {
                matchItem = Convert.ToInt32(arr[0]);
                matchPoint = Convert.ToInt32(arr[1]);
                OffsetPosition = (ScanOffset)Convert.ToInt32(arr[2]);
                OffsetQTY = Convert.ToInt32(arr[3], 16);
                CalcPointer = Convert.ToInt32(arr[4], 16);
            }
        }

        public override string ToString()
        {
            return string.Format("{0}~{1}~{2}~{3}~{4}", matchItem.ToString(), matchPoint.ToString(), (int)OffsetPosition, string.Format("{0:X2}", OffsetQTY), string.Format("{0:X2}", CalcPointer));
        }
    }

    /// <summary>
    /// 扫描附加属性转换器
    /// </summary>
    public class ScanAdditionConverter : ExpandableObjectConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context,
                                   System.Type destinationType)
        {
            if (destinationType == typeof(ScanAddition))
                return true;
            return base.CanConvertTo(context, destinationType);
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
    object value, System.Type destinationType)
        {
            if (destinationType == typeof(System.String) &&
                 value is ScanAddition)
            {
                ScanAddition so = (ScanAddition)value;
                return "";
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
        public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                try
                {
                    string s = (string)value;
                }
                catch
                {
                    throw new ArgumentException(
                        "无法将“" + (string)value +
                                           "”转换为 ScanAddition 类型");
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
    }

    /// <summary>
    /// 扫描类型枚举
    /// </summary>
    public enum ScanType
    {
        [DescriptionAttribute("地址")]
        Address = 1,
        [DescriptionAttribute("CALL")]
        Call = 2,
        [DescriptionAttribute("计算")]
        Calculate = 3,
    }

    /// <summary>
    /// CALL扫描结果取值方式
    /// </summary>
    public enum ScanOffset
    {
        Up = 1,
        Down = 2,
    }

    /// <summary>
    /// 16进制属性值转换器
    /// </summary>
    public class HexConverter : Int32Converter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (!string.IsNullOrWhiteSpace(value.ToString()))
                return GetInt(value);
            return base.ConvertFrom(context, culture, value);
        }


        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (!string.IsNullOrWhiteSpace(value.ToString()))
                return string.Format("{0:X2}", value);
            return base.ConvertTo(context, culture, value, destinationType);
        }

        public static int GetInt(object value)
        {
            return Convert.ToInt32(value.ToString(), 16);
        }
    }


小弟不才,如果更好的优化方案,请大虾们批评指证。

源码包和DEMO届时再放!

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。