Python 内存修改器程序:代码注入和内存修改

本文介绍如何使用 Python 编写一个内存修改器程序,实现代码注入和内存修改功能。程序包括一个图形用户界面,用户可以输入目标进程 ID、内存地址、数据类型、新值和注入代码,并执行相应的操作。

程序代码

import sys
import ctypes
import tkinter as tk
from tkinter import messagebox, ttk
import mmap


class MemoryModifier:
    def __init__(self):
        if sys.platform.startswith('win32'):
            self.kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
            self.ntdll = ctypes.WinDLL('ntdll', use_last_error=True)
        else:
            raise NotImplementedError('Unsupported operating system')

    def open_process(self, pid):
        process_handle = self.kernel32.OpenProcess(0x1F0FFF, False, pid)
        if not process_handle:
            error_code = self.kernel32.GetLastError()
            raise OSError(error_code, 'Could not open process')
        return process_handle

    def read_memory(self, process_handle, address, data_type=ctypes.c_int):
        value = data_type()
        if not self.kernel32.ReadProcessMemory(process_handle, address, ctypes.byref(value), ctypes.sizeof(value), None):
            error_code = self.kernel32.GetLastError()
            self.kernel32.CloseHandle(process_handle)
            raise OSError(error_code, 'Could not read memory')
        return value.value

    def write_memory(self, process_handle, address, new_value):
        value = type(new_value)(new_value)
        if not self.kernel32.WriteProcessMemory(process_handle, address, ctypes.byref(value), ctypes.sizeof(value), None):
            error_code = self.kernel32.GetLastError()
            self.kernel32.CloseHandle(process_handle)
            raise OSError(error_code, 'Could not write memory')

    def inject_code(self, process_handle, code):
        # 在目标进程中分配内存
        allocation_address = self.kernel32.VirtualAllocEx(process_handle, 0, len(code), 0x1000 | 0x2000, 0x40)
        if not allocation_address:
            error_code = self.kernel32.GetLastError()
            self.kernel32.CloseHandle(process_handle)
            raise OSError(error_code, 'Could not allocate memory in target process')

        # 在目标进程中写入注入的代码
        if not self.kernel32.WriteProcessMemory(process_handle, allocation_address, code, len(code), 0):
            error_code = self.kernel32.GetLastError()
            self.kernel32.CloseHandle(process_handle)
            raise OSError(error_code, 'Could not write memory in target process')

        # 创建远程线程执行注入的代码
        thread_handle = self.kernel32.CreateRemoteThread(process_handle, None, 0, allocation_address, None, 0, None)
        if not thread_handle:
            error_code = self.kernel32.GetLastError()
            self.kernel32.CloseHandle(process_handle)
            raise OSError(error_code, 'Could not create remote thread in target process')

        # 等待远程线程执行完成
        if self.kernel32.WaitForSingleObject(thread_handle, -1) != 0:
            error_code = self.kernel32.GetLastError()
            self.kernel32.CloseHandle(thread_handle)
            self.kernel32.CloseHandle(process_handle)
            raise OSError(error_code, 'Could not wait for remote thread')

        # 关闭远程线程和进程句柄
        self.kernel32.CloseHandle(thread_handle)
        self.kernel32.CloseHandle(process_handle)


class MemoryEditorGUI:
    def __init__(self, root):
        self.root = root
        self.root.title('内存编辑器')
        self.root.geometry('400x300')

        self.process_id_label = tk.Label(self.root, text='进程ID:')
        self.process_id_label.pack()
        self.process_id_entry = tk.Entry(self.root)
        self.process_id_entry.pack()

        self.memory_address_label = tk.Label(self.root, text='内存地址:')
        self.memory_address_label.pack()
        self.memory_address_entry = tk.Entry(self.root)
        self.memory_address_entry.pack()

        self.data_type_label = tk.Label(self.root, text='数据类型:')
        self.data_type_label.pack()
        self.data_type_combobox = ttk.Combobox(self.root, values=['int', 'float', 'str'], state='readonly')
        self.data_type_combobox.current(0)
        self.data_type_combobox.pack()

        self.new_value_label = tk.Label(self.root, text='新值:')
        self.new_value_label.pack()
        self.new_value_entry = tk.Entry(self.root)
        self.new_value_entry.pack()

        self.inject_code_label = tk.Label(self.root, text='注入代码:')
        self.inject_code_label.pack()
        self.inject_code_text = tk.Text(self.root)
        self.inject_code_text.pack()

        self.get_button = tk.Button(self.root, text='读取', command=self.get_memory_data)
        self.get_button.pack()

        self.modify_button = tk.Button(self.root, text='修改', command=self.modify_memory_data)
        self.modify_button.pack()

        self.inject_button = tk.Button(self.root, text='注入代码', command=self.inject_code)
        self.inject_button.pack()

        self.modifier = MemoryModifier()

    def get_memory_data(self):
        pid = int(self.process_id_entry.get())
        address = int(self.memory_address_entry.get(), 16)
        data_type = self.data_type_combobox.get()

        try:
            process_handle = self.modifier.open_process(pid)

            if data_type == 'int':
                value = self.modifier.read_memory(process_handle, address, ctypes.c_int)
            elif data_type == 'float':
                value = self.modifier.read_memory(process_handle, address, ctypes.c_float)
            else:
                value = self.modifier.read_memory(process_handle, address, ctypes.c_char_p)

            messagebox.showinfo('读取结果', str(value))
        except OSError as e:
            messagebox.showerror('错误', str(e))

        kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
        kernel32.CloseHandle(process_handle)

    def modify_memory_data(self):
        pid = int(self.process_id_entry.get())
        address = int(self.memory_address_entry.get(), 16)
        data_type = self.data_type_combobox.get()
        new_value = self.new_value_entry.get()

        try:
            process_handle = self.modifier.open_process(pid)

            if data_type == 'int':
                self.modifier.write_memory(process_handle, address, int(new_value))
            elif data_type == 'float':
                self.modifier.write_memory(process_handle, address, float(new_value))
            else:
                self.modifier.write_memory(process_handle, address, new_value.encode())

            messagebox.showinfo('成功', '内存值已修改')
        except OSError as e:
            messagebox.showerror('错误', str(e))

        kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
        kernel32.CloseHandle(process_handle)

    def inject_code(self):
        pid = int(self.process_id_entry.get())
        code = self.inject_code_text.get('1.0', 'end-1c').encode()

        try:
            process_handle = self.modifier.open_process(pid)
            self.modifier.inject_code(process_handle, code)
            messagebox.showinfo('成功', '代码已成功注入')
        except OSError as e:
            messagebox.showerror('错误', str(e))

        kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
        kernel32.CloseHandle(process_handle)


class GameDataModifierGUI:
    def __init__(self, root):
        self.root = root
        self.root.title('游戏数据修改器')
        self.root.geometry('400x300')

        self.shared_memory = None

        self.data_label = tk.Label(self.root, text='游戏数据:')
        self.data_label.pack()
        self.data_entry = tk.Entry(self.root)
        self.data_entry.pack()

        self.modify_button = tk.Button(self.root, text='修改游戏数据', command=self.modify_game_data)
        self.modify_button.pack()

        self.create_shared_memory()

    def create_shared_memory(self):
        self.shared_memory = mmap.mmap(-1, 1024, 'SharedMemory')
        self.shared_memory.write(b'')

    def modify_game_data(self):
        data = self.data_entry.get().encode()
        self.shared_memory.seek(0)
        self.shared_memory.write(data)

        messagebox.showinfo('成功', '游戏数据已修改')


def main():
    # 创建主窗口
    window = tk.Tk()

    # 创建内存编辑器界面
    memory_editor_gui = MemoryEditorGUI(window)

    # 创建游戏数据修改器界面
    game_data_modifier_gui = GameDataModifierGUI(window)

    # 运行主循环
    window.mainloop()


if __name__ == '__main__':
    main()

使用说明

  1. 运行程序,在“进程ID”输入框中输入目标进程的进程ID。
  2. 在“内存地址”输入框中输入要修改的内存地址(十六进制)。
  3. 在“数据类型”下拉框中选择要修改的数据类型(int、float、str)。
  4. 在“新值”输入框中输入要写入的新值。
  5. 可选:在“注入代码”文本框中输入要注入的代码,点击“注入代码”按钮进行代码注入。
  6. 点击“修改”按钮,程序将尝试打开目标进程并修改指定内存地址的值。

注意

  • 确保你有足够的权限来打开和修改目标进程的内存。
  • 修改其他进程的内存可能会对目标进程的稳定性和安全性产生影响,请谨慎操作。
  • 本程序仅供学习和研究使用,请勿用于任何非法目的。

原文地址: https://www.cveoy.top/t/topic/pHIj 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录