如何在Python中调用Linux系统调用PROCESS_VM_READV?

3
我正在尝试学习如何在Python中调用PROCESS_VM_READV。阅读手册后,我决定创建类似于他们示例的东西。
我已经使用root访问权限在终端中打开了Python3。然后导入和初始化所需的模块和变量。
import ctypes
libc = ctypes.CDLL('libc.so.6')
vm=libc.process_vm_readv

在这个例子中,有一个叫做 iovec 的结构体。所以,我需要在Python中重新创建它。
class iovec(ctypes.Structure):
    _fields_=[("iov_base",ctypes.c_void_p),("iov_len",ctypes.c_int)]

然后创建变量local和remote。
p1=ctypes.c_char_p(b"")
p1=ctypes.cast(p1,ctypes.c_void_p)
local=iovec(p1,10)
remote=iovec(0x00400000,20)  # Address of ELF header

最后,使用 KMines 的进程 ID 调用 PROCESS_VM_READV。

vm(2242,local,2,remote,1,0)

但是它返回-1,并且本地或远程的iov_base没有任何更改。我觉得我在这里犯了一个非常简单的错误,但无法确切地指出它。

非常感谢您的帮助,祝您拥有愉快的一天。

1个回答

5

可能已经晚了,但我能复制进程_vm_readv的例子在这里

我们需要传递一个有效的可读远程地址,为了测试目的,我编译了一个简单的hello world并使用gdb读取了一个有效的地址

(gdb) break main
Breakpoint 1 at 0x5a9: file hello.c, line 4.
(gdb) run
Starting program: /user/Desktop/hello
=> 0x800005a9 <main+25>:    sub    esp,0xc
   0x800005ac <main+28>:    lea    edx,[eax-0x19b0]
   0x800005b2 <main+34>:    push   edx
   0x800005b3 <main+35>:    mov    ebx,eax
   0x800005b5 <main+37>:    call   0x800003f0 <puts@plt>
   0x800005ba <main+42>:    add    esp,0x10
   0x800005bd <main+45>:    nop
   0x800005be <main+46>:    lea    esp,[ebp-0x8]
   0x800005c1 <main+49>:    pop    ecx
   0x800005c2 <main+50>:    pop    ebx
(gdb) x/20b 0x800005a9
0x800005a9 <main+25>:   0x83    0xec    0x0c    0x8d    0x90    0x50    0xe6    0xff
0x800005b1 <main+33>:   0xff    0x52    0x89    0xc3    0xe8    0x36    0xfe    0xff
0x800005b9 <main+41>:   0xff    0x83    0xc4    0x10

以下是用Python检索相同结果的代码。
from ctypes import *

class iovec(Structure):
    _fields_ = [("iov_base",c_void_p),("iov_len",c_size_t)]

local = (iovec*2)()             #create local iovec array
remote =  (iovec*1)()[0]        #create remote iovec
buf1 = (c_char*10)()
buf2 = (c_char*10)()
pid = 25117

local[0].iov_base = cast(byref(buf1),c_void_p)
local[0].iov_len = 10
local[1].iov_base = cast(byref(buf2),c_void_p)
local[1].iov_len = 10
remote.iov_base = c_void_p(0x800005a9)      #pass valid readable address
remote.iov_len = 20


libc = CDLL("libc.so.6")
vm = libc.process_vm_readv

vm.argtypes = [c_int, POINTER(iovec), c_ulong, POINTER(iovec), c_ulong, c_ulong]

nread = vm(pid,local,2,remote,1,0)

if nread != -1:
    bytes = "[+] "
    print "[+] received %s bytes" % (nread)
    for i in buf1: bytes += hex(ord(i)) + " "
    for i in buf2: bytes += hex(ord(i)) + " "
    print bytes 

输出

user@ubuntu:~/Desktop# python process_vm_readv.py
[+] received 20 bytes
[+] 0x83 0xec 0xc 0x8d 0x90 0x50 0xe6 0xff 0xff 0x52 0x89 0xc3 0xe8 0x36 0xfe 0xff 0xff 0x83 0xc4 0x10

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