首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在64位进程中使用Boyer-Moore算法

在64位进程中使用Boyer-Moore算法
EN

Stack Overflow用户
提问于 2017-06-01 18:36:31
回答 2查看 715关注 0票数 1

我正在制作一个类似于欺骗引擎的内存扫描应用程序,但是我想在c#中这样做,作为一个测试项目。所以,我使用了一个库,它使用https://github.com/Adversities/Cheatool,它使用Boyer。

进程检测是32位进程中的working..and,我可以找到像‘

608A DD 01 48 00 BC 88 01 04 02 00 01 44 D0 30 60 8C DD 01 46 AD 1 F 00 2A 12 10 00 00 29

如果我用Boyer方法找他们的话.

但由于某种原因,我无法在64位进程中找到它们。

如何更新dll库和我的应用程序中的方法以同时容纳64位进程?现在,我对c#非常陌生,就像做实验一样,我起草了一个测试应用程序:

测试应用程序代码:

代码语言:javascript
复制
   using System;
using System.Diagnostics;

using System.Linq;

using System.Threading.Tasks;
using System.Collections.Generic;
using System.Runtime.InteropServices;


using System.Threading;

namespace MemTester
{





    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Memory Addres Tester [?] (PID: ?)";

            //Console.Write("Process to open => ");
            //string process = Console.ReadLine();
            string process = " ";
            int ppid = 0;
            while (ppid == 0)
            {
                Console.Write("Process PID to open as int=> ");
                string ppid2 = Console.ReadLine();
                if ((ppid2 == "") || (ppid2 == null) || (ppid2.Length < 2))
                { ppid2 = "0"; }
                ppid = Convert.ToInt32(ppid2);
            }
            while (true)
            {
                Console.Write("Value to scan => ");
                string aob = Console.ReadLine();
                if (aob == "exit") break;

                MeMory(process, aob, ppid);
            }
        }
        public abstract class Manager
        {
            [DllImport("KERNEL32.DLL", SetLastError = true)]
            public static extern bool WriteProcessMemory(
                IntPtr process, IntPtr address, byte[] buffer, uint size, ref uint written);

            [DllImport("KERNEL32.DLL")]
            public static extern bool VirtualProtectEx(IntPtr process, IntPtr address,
                uint size, uint access, out uint oldProtect);

            [DllImport("KERNEL32.DLL")]
            public static extern int CloseHandle(IntPtr objectHandle);

            [DllImport("KERNEL32.DLL")]
            public static extern IntPtr OpenProcess(uint access, bool inheritHandler, uint processId);

            [Flags]
            public enum Protection
            {
                PEReadWrite = 0x40,
                PReadWrite = 0x04
            }

            [Flags]
            public enum Access
            {
                Synchronize = 0x100000,
                StandardRightsRequired = 0x000F0000,
                AllAccess = StandardRightsRequired | Synchronize | 0xFFFF
            }
        }
        public abstract class Reader
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct MEMORY_BASIC_INFORMATION
            {
                public IntPtr BaseAddress;
                public IntPtr AllocationBase;
                public uint AllocationProtect;
                public uint RegionSize;
                public uint State;
                public uint Protect;
                public uint Type;
            }

            [DllImport("KERNEL32.DLL")]
            public static extern int VirtualQueryEx(IntPtr hProcess,
                IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);

            [DllImport("KERNEL32.DLL", SetLastError = true)]
            public static extern bool ReadProcessMemory(
                IntPtr process, IntPtr address, byte[] buffer, uint size, ref uint read);

            public List<MEMORY_BASIC_INFORMATION> MemoryRegion = new List<MEMORY_BASIC_INFORMATION>();
        }
        public class BoyerMoore : Reader
        {
            private IntPtr _processHandle;

            public BoyerMoore(IntPtr processHandle)
            {
                _processHandle = processHandle;
            }

            private void MemInfo(bool unwritable)
            {
                IntPtr Addy = new IntPtr();

                while (true)
                {
                    MEMORY_BASIC_INFORMATION memInfo = new MEMORY_BASIC_INFORMATION();

                    int MemDump = VirtualQueryEx(_processHandle, Addy, out memInfo, Marshal.SizeOf(memInfo));

                    if (MemDump == 0) break;

                    if ((memInfo.State & 0x1000) != 0)
                    {
                        if (unwritable && (memInfo.Protect & 0xCC) != 0)
                            MemoryRegion.Add(memInfo);
                        else
                            MemoryRegion.Add(memInfo);
                    }

                    Addy = new IntPtr(memInfo.BaseAddress.ToInt32() + (int)memInfo.RegionSize);
                }
            }

            private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, byte[] pattern, ref List<IntPtr> addresses)
            {
                int offSet = 0;
                while ((offSet = Array.IndexOf(memoryBrick, pattern[0], offSet)) != -1)
                {
                    if (pattern.Length > 1)
                        for (int i = 1; i < pattern.Length; i++)
                        {
                            if (memoryBrick.Length <= offSet + pattern.Length
                                || pattern[i] != memoryBrick[offSet + i]) break;

                            if (i == pattern.Length - 1)
                                addresses.Add(new IntPtr((int)baseAddress + offSet));
                        }
                    else addresses.Add(new IntPtr((int)baseAddress + offSet));
                    offSet++;
                }
            }

            private void BoyerAlgo(IntPtr baseAddress, byte[] memoryBrick, string pattern, ref List<IntPtr> addresses)
            {
                int offSet = 0;
                string[] aob = pattern.Split(' ');
                List<int> bytesPos = new List<int>();

                for (int i = 0; i < aob.Length; i++)
                    if (aob[i] != "??")
                        bytesPos.Add(i);

                if (bytesPos.Count != 0)
                    while ((offSet = Array.IndexOf(memoryBrick, (byte)Convert.ToInt32(aob[bytesPos[0]], 16), offSet)) != -1)
                    {
                        if (bytesPos.Count > 1)
                            for (int i = 1; i < bytesPos.Count; i++)
                            {
                                if (memoryBrick.Length <= offSet + pattern.Length
                                    || (byte)Convert.ToInt32(aob[bytesPos[i]], 16)
                                    != memoryBrick[(offSet - bytesPos[0]) + bytesPos[i]]) break;

                                if (i == bytesPos.Count - 1)
                                    if (aob[0] == "??")
                                        addresses.Add(new IntPtr((int)baseAddress + (offSet - bytesPos[0])));
                                    else addresses.Add(new IntPtr((int)baseAddress + offSet));
                            }
                        else
                            addresses.Add(new IntPtr((int)baseAddress + (offSet - bytesPos[0])));
                        offSet++;
                    }
                else
                    for (int i = 0; i < memoryBrick.Length; i++)
                        addresses.Add(new IntPtr((int)baseAddress + i));
            }

            public CancellationTokenSource cancelToken { get; set; } = new CancellationTokenSource();

            public Task<IntPtr[]> AoByte(string pattern, bool unwritable = false)
            {
                if (!pattern.Contains("?"))
                {
                    byte[] buff = pattern.Split(' ').Select(by =>
                    (byte)Convert.ToInt32(by, 16)).ToArray();

                    return Task.Run(() => { return GeneralScan(buff, unwritable); }, cancelToken.Token);
                }
                else return Task.Run(() => { return WCScan(pattern, unwritable); }, cancelToken.Token);
            }


            private IntPtr[] GeneralScan(byte[] buff, bool unwritable)
            {
                MemInfo(unwritable);

                List<IntPtr> addresses = new List<IntPtr>();

                for (int i = 0; i < MemoryRegion.Count; i++)
                {
                    uint read = 0;
                    byte[] wholeMemory = new byte[MemoryRegion[i].RegionSize];

                    ReadProcessMemory(_processHandle, MemoryRegion[i].BaseAddress, wholeMemory,
                        MemoryRegion[i].RegionSize, ref read);

                    BoyerAlgo(MemoryRegion[i].BaseAddress, wholeMemory, buff, ref addresses);
                }
                return addresses.ToArray();
            }

            private IntPtr[] WCScan(string pattern, bool unwritable)
            {
                MemInfo(unwritable);

                List<IntPtr> addresses = new List<IntPtr>();

                for (int i = 0; i < MemoryRegion.Count; i++)
                {
                    uint read = 0;
                    byte[] wholeMemory = new byte[MemoryRegion[i].RegionSize];

                    ReadProcessMemory(_processHandle, MemoryRegion[i].BaseAddress, wholeMemory,
                        MemoryRegion[i].RegionSize, ref read);

                    BoyerAlgo(MemoryRegion[i].BaseAddress, wholeMemory, pattern, ref addresses);
                }
                return addresses.ToArray();
            }
        }

        public class MeMorybox : Manager
        {

            public BoyerMoore BoyerScan { get; set; }


            IntPtr _processHandle;

            public MeMorybox(Process process)
            {
                _processHandle = OpenProcess((uint)Access.AllAccess, false, (uint)process.Id);


                BoyerScan = new BoyerMoore(_processHandle);

            }



            ~MeMorybox()
            {
                CloseHandle(_processHandle);
            }

        }

        static void MeMory(string process, string aob, int ppid)
        {
            //Process[] processList = Process.GetProcessesByName(process);
            Process p = Process.GetProcessById(ppid); ;

            MeMorybox notepad = new MeMorybox(p);

            Console.WriteLine("Hex value of pid:"+p.Id.ToString("x8"));

            var addresses = notepad.BoyerScan.AoByte(aob).GetAwaiter().GetResult();

        Console.WriteLine(addresses.Length + " hits found for pid:"+ppid);

        Console.WriteLine();
    }
}

闪光过程的测试。firefox..<32位process> chrome..<64位process> url测试:https://apps.facebook.com/candycrushsoda 用作测试的字节数组:60? 它应该给出一个结果 在firefox--Flashplayerplugin中,它工作得很好, 在铬--包含模块pepflashplayer.dll的一个进程中,它>没有给出结果,因为铬是64位进程。 为了验证我使用欺骗引擎进行了双重检查,在这两种情况下都正确地找到了aob。

EN

回答 2

Stack Overflow用户

发布于 2017-06-08 14:48:15

我尝试了您的代码,对于我来说,当检查64位进程时,它在行上产生算术溢出:

代码语言:javascript
复制
      Addy = new IntPtr(memInfo.BaseAddress.ToInt32() + (int) memInfo.RegionSize);

(自己试试,打开Build /Advanced./检查算术.在项目设置中)

看起来,在查询64位进程时,VirtualQueryEx可能会用Int32.MaxValue()填充MEMORY_BASIC_INFORMATION.BaseAddress。

我认为,使其与32位和64位进程兼容的最简单方法是只针对64位架构,并相应地编写代码,如果您负担得起的话。我建议你尝试以下几种方法:

  1. 将项目的平台目标更改为x64
  2. 更新MEMORY_BASIC_INFORMATION,使其映射到结构的64位版本(备注中的底部版本),而不是另一个。https://msdn.microsoft.com/en-us/library/windows/desktop/aa366775(v=vs.85).aspx
  3. 在该更新之后,代码将使用64位算术,无论它使用的是BaseAddress还是RegionSize (例如,使它们成为IntPtr,使用.ToInt64()而不是.ToInt32())。
票数 2
EN

Stack Overflow用户

发布于 2017-06-09 19:39:58

Right..so首先我必须在任何cpu上使用build,然后取消选中“偏好32位”。

代码语言:javascript
复制
public class MeMorybox : Manager
        {

            public BoyerMoore BoyerScan { get; set; }


            IntPtr _processHandle;

            public MeMorybox(Process process)
            {
                _processHandle = OpenProcess((uint)Access.AllAccess, false, (uint)process.Id);


                BoyerScan = new BoyerMoore(_processHandle);

            }

更新如下:

代码语言:javascript
复制
 UIntPtr _processHandle;

        public MeMorybox(Process process)
        {
            _processHandle = OpenProcess((uint)Access.AllAccess, false, (uint)process.Id);


            BoyerScan = new BoyerMoore(_processHandle);

        }

我更新了内存基本信息.:

代码语言:javascript
复制
 public struct _MEMORY_BASIC_INFORMATION64
    {
        public ulong BaseAddress;
        public ulong AllocationBase;
        public int AllocationProtect;
        public int __alignment1;
        public ulong RegionSize;
        public int State;
        public int Protect;
        public int Type;
        public int __alignment2;
    }

并通过代码更新了在_MEMORY_BASIC_INFORMATION中应用的更改以及对## UIntPtr ##的过程处理更改。

还更新了:

代码语言:javascript
复制
[DllImport("KERNEL32.DLL")]
        public static extern int VirtualQueryEx(UIntPtr hProcess,
            UIntPtr lpAddress, out _MEMORY_BASIC_INFORMATION64 lpBuffer, int dwLength);

        [DllImport("KERNEL32.DLL", SetLastError = true)]
        public static extern bool ReadProcessMemory(
            UIntPtr process, ulong address, byte[] buffer, ulong size, ref uint read);

        public List<_MEMORY_BASIC_INFORMATION64> MemoryRegion = new List<_MEMORY_BASIC_INFORMATION64>();

        [DllImport("KERNEL32.DLL", SetLastError = true)]
        public static extern bool WriteProcessMemory(
            UIntPtr process, ulong address, byte[] buffer, uint size, ref uint written);

        [DllImport("KERNEL32.DLL")]
        public static extern bool VirtualProtectEx(UIntPtr process, ulong address,
            uint size, uint access, out uint oldProtect);

        [DllImport("KERNEL32.DLL")]
        public static extern int CloseHandle(UIntPtr objectHandle);

        [DllImport("KERNEL32.DLL")]
        public static extern UIntPtr OpenProcess(uint access, bool inheritHandler, uint processId);

        [Flags]
        public enum Protection
        {
            PEReadWrite = 0x40,
            PReadWrite = 0x04
        }

        [Flags]
        public enum Access
        {
            Synchronize = 0x100000,
            StandardRightsRequired = 0x000F0000,
            AllAccess = StandardRightsRequired | Synchronize | 0xFFFF
        }

    so, now, compiled for any cpu, it finds adreses corectly for 32 bit and 64 bit proceses
    many thanks to:
    @Dirk
    and
    @Loonquawl
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44314769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档