在内存中搜索特定值C#(Xbox 360)
编辑:我想我有一个可能的解决方案的实际搜索值的想法。通过确保用户输入以0结尾,问题应该得到解决。这将涉及从uint中减去最后一个数字(我不知道如何得到,除非我使用转换为字符串,修剪结束回到uint方法,这很难看,但我想它可以工作),然后减去它。如果有人对如何做到这一点有任何建议,请帮助我 我一直在开发一个程序,在Xbox360上搜索内存中的特定值,如果你熟悉的话,它类似于“作弊引擎”。我已经了解了基本情况,但我遇到了一个问题。我搜索内存的方法取决于在与您的值一致的地址开始搜索。如果这对您来说没有意义,下面是代码:在内存中搜索特定值C#(Xbox 360),c#,search,memory,byte,xbox360,C#,Search,Memory,Byte,Xbox360,编辑:我想我有一个可能的解决方案的实际搜索值的想法。通过确保用户输入以0结尾,问题应该得到解决。这将涉及从uint中减去最后一个数字(我不知道如何得到,除非我使用转换为字符串,修剪结束回到uint方法,这很难看,但我想它可以工作),然后减去它。如果有人对如何做到这一点有任何建议,请帮助我 我一直在开发一个程序,在Xbox360上搜索内存中的特定值,如果你熟悉的话,它类似于“作弊引擎”。我已经了解了基本情况,但我遇到了一个问题。我搜索内存的方法取决于在与您的值一致的地址开始搜索。如果这对您来说没有
private void searchInt32(int Value, uint Address, uint BytesToSearch)
{
for (uint i = 0; i <= BytesToSearch; i+=4)
{
int recoveredMem = XboxSupport.littleEndtoInt(XboxSupport.GetMem(Address + i, 4), 0);
//Recover Memory (As Bytes) and convert to integer from address (incremented based on for loop)
if (recoveredMem == Value) //Check if recovered mem = search value
{
writeToFile(Address + i, Convert.ToString(Value)); //If recovered mem = search value, write to a text file
}
siStatus.Caption = String.Format("Searching Bytes {0} out of {1}...", i, BytesToSearch); //Update status caption
}
}
与其将内存转储到磁盘并读取每次迭代,不如将目标进程的内存分块扫描,然后封送数据以利用指针算法的效率
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace MemoryScan {
internal class Program {
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
private static unsafe void Main(string[] args) {
Process process = Process.GetProcessesByName("notepad")[0]; //example target process
int search = 100; //search value
int segment = 0x10000; //avoid the large object heap (> 84k)
int range = 0x7FFFFFFF - segment; ; //32-bit example
int bytesRead;
List<int> addresses = new List<int>();
DateTime start = DateTime.Now;
for (int i = 0; i < range; i += segment) {
byte[] buffer = new byte[segment];
if (!ReadProcessMemory(process.Handle, new IntPtr(i), buffer, segment, out bytesRead)) {
continue;
}
IntPtr data = Marshal.AllocHGlobal(bytesRead);
Marshal.Copy(buffer, 0, data, bytesRead);
for (int j = 0; j < bytesRead; j++) {
int current = *(int*)(data + j);
if (current == search) {
addresses.Add(i + j);
}
}
Marshal.FreeHGlobal(data);
}
Console.WriteLine("Duration: {0} seconds", (DateTime.Now - start).TotalSeconds);
Console.WriteLine("Found: {0}", addresses.Count);
Console.ReadLine();
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Runtime.InteropServices;
名称空间内存扫描{
内部课程计划{
[DllImport(“kernel32.dll”,SetLastError=true)]
私有静态外部bool ReadProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,[Out]byte[]lpBuffer,int dwSize,Out int lpNumberOfBytesRead);
私有静态不安全void Main(字符串[]args){
Process Process=Process.getProcessByName(“记事本”)[0];//目标进程示例
int search=100;//搜索值
int segment=0x10000;//避免大对象堆(>84k)
int range=0x7fffff-segment;;//32位示例
int字节读取;
列表地址=新列表();
DateTime start=DateTime.Now;
对于(int i=0;i
测试结果
持续时间:1.142秒电话:3204 创建泛型类以简化类型封送,如下所示:
public static class MarshalHelper
{
public unsafe static T Read<T>(IntPtr address)
{
object value;
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Int16:
value = *(short*)address;
break;
case TypeCode.Int32:
value = *(int*)address;
break;
case TypeCode.Int64:
value = *(long*)address;
break;
default:
throw new ArgumentOutOfRangeException();
}
return (T)value;
}
}
公共静态类MarshallHelper
{
公共不安全静态T读(IntPtr地址)
{
目标价值;
开关(Type.GetTypeCode(typeof(T)))
{
case TypeCode.Int16:
值=*(短*)地址;
打破
case TypeCode.Int32:
值=*(int*)地址;
打破
case TypeCode.Int64:
值=*(长*)地址;
打破
违约:
抛出新ArgumentOutOfRangeException();
}
返回(T)值;
}
}
不完全相关,但为了整洁起见,我将把i+=4放在for循环中,以避免所有那些*4s和/4I我不确定是否要转发此类原因,但您似乎已经对这里的性能失去了所有希望:byte[]data=XboxSupport.GetMem(地址,BytesToSearch)代码>在内存中和一点点大小的块中完成这一切要好得多。。。您应该能够通过重新排列输入值(可能不止一次)而不是重新排列正在搜索的数据来找到输入值…@WeylandYutani Done,谢谢you@ebyrob我不完全明白你的意思。GetMem函数从我指定的地址恢复“BytesToSearch”指定的字节数。我想你指的是我发布的第二个,在我看来,这不是有效的,甚至不是好的代码。遗憾的是,我没有选择在不首先恢复控制台内存的情况下查看控制台内存,但是我假设按照我的第一个方法的思路,某些内容将接近您所指的内容?至于重新安排的部分,你能给我举个例子吗?谢谢。是的,你的第一个例子做了更好的扫描。它一次在1个4字节的块中查找匹配项,而不是查找可能是多MB甚至GB的匹配项。如果我在内存中执行,我可能会从一个8k(8192字节)块开始,然后通过调用.GetMem()
来搜索它。一旦它起作用了,我就会上下改变块大小,看看它是否重要。最后,考虑到整数输入,我会考虑更快的搜索每一个8K块的方法。(在无限数据长度中搜索固定位字符串是一个无限加速的解决方案空间,或者我被告知)问题是我没有搜索一个可以在计算机上找到的进程,否则这段代码会非常好。遗憾的是,目前还没有一种方法可以扫描Xbox 360上运行的进程内存,至少我目前知道of@NoviceProgrammer等等,XboxSupport.GetMem()
是一个不存在的虚构函数吗?PS-使用位运算。清除n中的最低阶位n=n | 0xFFFFFFFE
@ebyrob是的,这是我创建的函数。那么什么是位运算呢?这只是将最低值设为0还是将其完全删除?您不能真正“删除”一点。它会将最低位(0x1)设置为0。实际上,这应该是一个&
而不是一个|
@ebyrob,如果它是1,那么它只会将最低位设置为0,尽管正确吗?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace MemoryScan {
internal class Program {
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
private static unsafe void Main(string[] args) {
Process process = Process.GetProcessesByName("notepad")[0]; //example target process
int search = 100; //search value
int segment = 0x10000; //avoid the large object heap (> 84k)
int range = 0x7FFFFFFF - segment; ; //32-bit example
int bytesRead;
List<int> addresses = new List<int>();
DateTime start = DateTime.Now;
for (int i = 0; i < range; i += segment) {
byte[] buffer = new byte[segment];
if (!ReadProcessMemory(process.Handle, new IntPtr(i), buffer, segment, out bytesRead)) {
continue;
}
IntPtr data = Marshal.AllocHGlobal(bytesRead);
Marshal.Copy(buffer, 0, data, bytesRead);
for (int j = 0; j < bytesRead; j++) {
int current = *(int*)(data + j);
if (current == search) {
addresses.Add(i + j);
}
}
Marshal.FreeHGlobal(data);
}
Console.WriteLine("Duration: {0} seconds", (DateTime.Now - start).TotalSeconds);
Console.WriteLine("Found: {0}", addresses.Count);
Console.ReadLine();
}
}
}
public static class MarshalHelper
{
public unsafe static T Read<T>(IntPtr address)
{
object value;
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Int16:
value = *(short*)address;
break;
case TypeCode.Int32:
value = *(int*)address;
break;
case TypeCode.Int64:
value = *(long*)address;
break;
default:
throw new ArgumentOutOfRangeException();
}
return (T)value;
}
}