为什么ctypes的WriteProcessMemory()失败?

0 投票
1 回答
2332 浏览
提问于 2025-04-15 17:15

我一直在尝试让这个函数正常工作,但一直没有成功。

def write_memory(self, address, data):
    PROCESS_ALL_ACCESS = 0x001F0FFF
    count = c_ulong(0)
    length = len(data)
    c_data = c_char_p(data[count.value:])
    null = c_int(0)
    windll.kernel32.SetLastError(10000)
    if not windll.kernel32.WriteProcessMemory(self.h_process, address, c_data, length, byref(count)):
        print "Failed to write memory."
        print  "Error Code: ", windll.kernel32.GetLastError()
    else:
        return True

GetLastError() 返回的是 87 (0x57),这表示参数无效。这个函数我直接从《Gray Hat Python》这本书里抄的,不知道我哪里出错了。ReadProcessMemory() 函数运行得很好,返回的值也正确。

我现在随便选了一个地址,0x00050000,然后传入数据像是 "\x61",在读取这个地址前后都没有变化。

我觉得这可能是个简单的错误,提前谢谢你的帮助。Nav。


你说得对,这确实是个权限问题。但我还是搞不清楚我在找什么。这里是我的启动进程的代码:

class SECURITY_ATTRIBUTES(Structure):
    _fields_ = [("Length", DWORD),
                ("SecDescriptor", LPVOID),
                ("InheritHandle", BOOL)]

def launch(self, path_to_exe):
    CREATE_NEW_CONSOLE = 0x0000010

    startupinfo = STARTUPINFO()
    process_information = PROCESS_INFORMATION()
    security_attributes = SECURITY_ATTRIBUTES()

    startupinfo.dwFlags = 0x1
    startupinfo.wShowWindow = 0x0


    startupinfo.cb = sizeof(startupinfo)
    security_attributes.Length = sizeof(security_attributes)
    security_attributes.SecDescriptior = None
    security_attributes.InheritHandle = True



    if windll.kernel32.CreateProcessA(path_to_exe,
                               None,
                               byref(security_attributes),
                               byref(security_attributes),
                               True,
                               CREATE_NEW_CONSOLE,
                               None,
                               None,
                               byref(startupinfo),
                               byref(process_information)):

        self.pid = process_information.dwProcessId
    else:
        print "Couldnt launch: %d" %path_to_exe
        print windll.kernel32.GetLastError()

我需要用不同的方式创建这个进程吗?在 SecDescriptor 结构里我应该放什么?MSDN 上关于 DACL 和 ACE 的内容让我有点困惑,没什么帮助。谢谢你们到现在为止的所有帮助。

PS - 只是个想法,调试器或者其他程序是怎么不创建进程却能修改内存的呢?

1 个回答

0

这个调用看起来没有什么明显的问题。很可能是地址0x00050000那里没有任何页面,或者那里有的页面是不能写的。

你可以试着用VirtualQuery去检查一下你想写入的那些字节,看看它们是不是可以写的。大多数随机地址都是不能写的。

撰写回答