通过c#编辑内存地址

4

我希望编辑一个正在运行的应用程序(编辑内存地址),

在地址00498D45上,我想编辑其值。

当前值:

MOV BYTE PTR SS:[EBP-423],7

更新为:

更新后的值:

 MOV BYTE PTR SS:[EBP-423],8

我到目前为止得到的信息是这样的(在网上搜索了一下,这是我所得到的):
提前致谢!
using System.Runtime.InteropServices;

    [Flags]

        public enum ProcessAccessFlags : uint

{
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VMOperation = 0x00000008,
    VMRead = 0x00000010,
    VMWrite = 0x00000020,
    DupHandle = 0x00000040,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    Synchronize = 0x00100000
}

[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);

[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hProcess);

Process process = Process.GetProcessesByName("My Apps Name").FirstOrDefault();

public static bool WriteMemory(Process process, int address, long value, out int bytesWritten)
{
    IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

    byte[] val = BitConverter.GetBytes(value);

    bool worked = WriteProcessMemory(hProc, new IntPtr(address), val, (UInt32) val.LongLength, out bytesWritten);

    CloseHandle(hProc);

    return worked;
}

2
你有什么问题? - Yahia
3
你试图攻击哪个软件? - Federico Berasategui
嗨,我还没有尝试过,因为我不知道如何将我想要的更改嵌入到代码中,这就是为什么我问它是否可以使用正确的代码,并且如果可以,我应该如何放置它? - Dan272
1
@Evo510 为了能够执行像断点这样的操作,调试器必须注入代码(使用 int 3 来中断)。这里有一篇非常好的深入文章,解释了它是如何工作的细节。 - Scott Chamberlain
1
@Dan272 不,已经是这样的了,在 0x00498D45 + 6(假设是那个7的地址)处写入8。 - harold
显示剩余10条评论
2个回答

3

根据您的其他问题

WriteMemory(Process process,00498D45 , MOV BYTE PTR SS:[EBP-423],8)

有很多问题,我不知道从哪里开始。首先,这不是正确的C#语法。
  1. 你正在调用一个函数,但你在那里有一个类似于签名的Process。
  2. 00498D45在任何进制下都不是有效的常量。如果你的意思是十六进制(你可能是这样想的,因为你正在处理地址),那么和其他所有类C的语言一样,应该表示为0x00498D45。
  3. 这是ASCII码中的x86汇编代码(但它不在字符串中,你只是乱搞了)。你不能只是把ASCII汇编代码丢到另一个进程的地址空间中!
也许你应该在构建程序时深入了解编译和汇编过程以及CPU在执行程序时实际执行的内部操作。此外,我建议阅读你明显从某个地方引用的示例代码,并尝试理解它。学习正在发生的事情比请求帮助修复你拼凑在一起的东西要好得多。 </rant>
无论如何,在你汇编你的代码之后,它看起来像这样(重新反汇编):
C68559FEFFFF08    mov byte [ebp-0x1a7],0x8

这意味着您的指令实际上是字节串C6 85 59 FE FF FF 08。因此,这就是您需要写入目标应用程序的内容。

这是您正在尝试做的基础:

byte[] new_instr = new byte[] {0xC6, 0x85, 0x59, 0xFE, 0xFF, 0xFF, 0x08};
IntPtr target_addr = (IntPtr)0x00498D45;

int bytesWritten;
WriteProcessMemory(hProcess, target_addr, new_instr, (UInt32)new_instr.Length, out bytesWritten);

您复制并粘贴的WriteMemory内存函数在此处无法帮助您,问题在于它只能写入4个字节的long,但您需要写入7个字节。因此,您要么必须修改该函数以使用byte[]参数,要么自己解决。
我很钦佩您的雄心壮志,但您应该从更基础的地方开始。编写一些C#代码,以熟悉类C语言的编程。然后编写一些C代码,以熟悉当您不完美地进行操作时会导致崩溃的情况。然后尝试涉足汇编 - 可能会将小块嵌入您的C代码中。最终,您就准备好在其他运行进程的指令中进行操纵了。

写4个字节有什么问题吗?实际上只有1个字节会改变,对吧? - harold

2
您可以使用注入库,例如MemorySharp(我是作者)。所有这些功能都包装在一个方便的API中,集成了汇编器(FASM语法)。因此,这段代码可以实现您想要的功能:
using (var m = new MemorySharp(ApplicationFinder.FromProcessName("My App").First()))
{
    m.Assembly.Inject("MOV BYTE [EBP-423],8", new IntPtr(0x00498D45));
}

你的库似乎出了问题。当我尝试在一个可执行进程上使用你展示的代码(使用不同的指令和地址)时,我遇到了错误:“FASM 在汇编助记符时发生错误。错误代码:-118(无效表达式);错误行:3;错误偏移量:21”。你有任何想法为什么会发生这种情况吗? - FightRay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接