mirror of
https://github.com/reswitched/Mephisto.git
synced 2024-05-11 01:04:53 -04:00
210 lines
5.6 KiB
Python
210 lines
5.6 KiB
Python
from socket import *
|
|
from struct import pack, unpack
|
|
import math, sys
|
|
|
|
def dump(data):
|
|
data = map(ord, data)
|
|
fmt = '%%0%ix |' % (int(math.log(len(data), 16)) + 1)
|
|
for i in xrange(0, len(data), 16):
|
|
print fmt % i,
|
|
ascii = ''
|
|
for j in xrange(16):
|
|
if i + j < len(data):
|
|
print '%02x' % data[i + j],
|
|
if 0x20 <= data[i+j] <= 0x7E:
|
|
ascii += chr(data[i+j])
|
|
else:
|
|
ascii += '.'
|
|
else:
|
|
print ' ',
|
|
ascii += ' '
|
|
if j == 7:
|
|
print '',
|
|
ascii += ' '
|
|
print '|', ascii
|
|
|
|
def hexify(obj, name, pname=None):
|
|
def sub(v):
|
|
if isinstance(v, list) or isinstance(v, tuple):
|
|
return '[%s]' % ', '.join(map(sub, v))
|
|
elif isinstance(v, str):
|
|
return 'buf<0x%x>' % len(v)
|
|
else:
|
|
return '0x%x' % v
|
|
|
|
pname = name if pname is None else pname
|
|
value = getattr(obj, pname)
|
|
if len(value) == 0:
|
|
return ''
|
|
|
|
return ', %s=%s' % (name, sub(value))
|
|
|
|
class IPCMessage(object):
|
|
def __init__(self, cmdId=0, client=None):
|
|
self.client = client
|
|
|
|
self.type = -1
|
|
self.cmdId = cmdId
|
|
self.request = False
|
|
|
|
self.pid = -1
|
|
self.dataBuffer = []
|
|
|
|
self.aDescriptors = []
|
|
self.bDescriptors = []
|
|
self.cDescriptors = []
|
|
self.xDescriptors = []
|
|
|
|
self.copiedHandles = []
|
|
self.movedHandles = []
|
|
|
|
def setType(self, type):
|
|
self.type = type
|
|
return self
|
|
def hasPID(self, pid=0xDEAD):
|
|
self.pid = pid
|
|
return self
|
|
def data(self, *args):
|
|
self.dataBuffer += list(args)
|
|
return self
|
|
def aDescriptor(self, data, perms):
|
|
self.aDescriptors.append((data, perms))
|
|
return self
|
|
def bDescriptor(self, data, perms):
|
|
self.bDescriptors.append((data, perms))
|
|
return self
|
|
def cDescriptor(self, data):
|
|
self.cDescriptors.append(data)
|
|
return self
|
|
def xDescriptor(self, data, counter):
|
|
self.xDescriptors.append((data, counter))
|
|
return self
|
|
def copyHandle(self, handle):
|
|
self.copiedHandles.append(handle)
|
|
return self
|
|
def moveHandle(self, handle):
|
|
self.movedHandles.append(handle)
|
|
return self
|
|
|
|
def sendTo(self, handle):
|
|
return self.client.sendMsg(handle, self)
|
|
|
|
def __repr__(self):
|
|
return '%s(%s%s%s%s%s%s%s%s%s)' % (
|
|
self.__class__.__name__,
|
|
'cmdId=%i' % self.cmdId,
|
|
', type=%i' % self.type if self.type != 0 else '',
|
|
hexify(self, 'data', 'dataBuffer'),
|
|
hexify(self, 'aDescriptors'),
|
|
hexify(self, 'bDescriptors'),
|
|
hexify(self, 'cDescriptors'),
|
|
hexify(self, 'xDescriptors'),
|
|
hexify(self, 'copiedHandles'),
|
|
hexify(self, 'movedHandles'),
|
|
)
|
|
|
|
class Client(object):
|
|
def __init__(self, host='127.0.0.1'):
|
|
self.sock = socket(AF_INET, SOCK_STREAM)
|
|
self.sock.connect((host, 31337))
|
|
|
|
self.autoHandles = {}
|
|
|
|
def getService(self, name):
|
|
if name not in self.autoHandles:
|
|
print 'Getting service', name
|
|
self.writeint(0)
|
|
self.writedata(name)
|
|
self.autoHandles[name] = self.readint()
|
|
return self.autoHandles[name]
|
|
|
|
def closeHandle(self, handle):
|
|
print 'Closing handle %x' % handle
|
|
self.writeint(1)
|
|
self.writeint(handle)
|
|
|
|
def ipcMsg(self, cmdId):
|
|
return IPCMessage(cmdId, client=self)
|
|
|
|
def sendMsg(self, nameOrHandle, msg):
|
|
if isinstance(nameOrHandle, str) or isinstance(nameOrHandle, unicode):
|
|
handle = self.getService(nameOrHandle)
|
|
name = nameOrHandle
|
|
else:
|
|
handle = nameOrHandle
|
|
name = None
|
|
|
|
self.writeint(2)
|
|
self.writeint(4 if msg.type == -1 else msg.type)
|
|
self.writeint(len(msg.dataBuffer) + 1)
|
|
map(self.writeint, [msg.cmdId] + list(msg.dataBuffer))
|
|
self.writeint(msg.pid)
|
|
self.writeint(len(msg.copiedHandles))
|
|
map(self.writeint, msg.copiedHandles)
|
|
self.writeint(len(msg.movedHandles))
|
|
map(self.writeint, msg.movedHandles)
|
|
self.writeint(len(msg.aDescriptors))
|
|
[(self.writedata(y), self.writeint(z)) for y, z in msg.aDescriptors]
|
|
self.writeint(len(msg.bDescriptors))
|
|
[(self.writedata(y), self.writeint(z)) for y, z in msg.bDescriptors]
|
|
self.writeint(len(msg.cDescriptors))
|
|
[self.writedata(y) for y in msg.cDescriptors]
|
|
self.writeint(len(msg.xDescriptors))
|
|
[(self.writedata(y), self.writeint(z)) for y, z in msg.xDescriptors]
|
|
self.writeint(handle)
|
|
|
|
error_code = self.readint()
|
|
if error_code != 0:
|
|
if error_code == 0xf601 and name is not None:
|
|
del self.autoHandles[name]
|
|
return error_code, None
|
|
|
|
data = [self.readint() for i in xrange(self.readint(0))]
|
|
copy = [self.readint() for i in xrange(self.readint(0))]
|
|
move = [self.readint() for i in xrange(self.readint(0))]
|
|
a = [(self.readdata(), self.readint()) for i in xrange(self.readint(0))]
|
|
b = [(self.readdata(), self.readint()) for i in xrange(self.readint(0))]
|
|
c = [self.readdata() for i in xrange(self.readint(0))]
|
|
x = [(self.readdata(), self.readint()) for i in xrange(self.readint(0))]
|
|
request_type = self.readint()
|
|
|
|
if request_type is None:
|
|
return None
|
|
|
|
msg = IPCMessage(data[0])
|
|
msg.setType(request_type)
|
|
msg.data(*data[1:])
|
|
map(msg.copyHandle, copy)
|
|
map(msg.moveHandle, move)
|
|
map(lambda v: msg.aDescriptor(*v), a)
|
|
map(lambda v: msg.bDescriptor(*v), b)
|
|
map(lambda v: msg.cDescriptor(v), c)
|
|
map(lambda v: msg.xDescriptor(*v), x)
|
|
msg.data = msg.dataBuffer
|
|
return 0, msg
|
|
|
|
def readint(self, default=None):
|
|
data = self.sock.recv(8)
|
|
if len(data) != 8:
|
|
return default
|
|
return unpack('<Q', data)[0]
|
|
def readdata(self, default=None):
|
|
size = self.readint()
|
|
if size is None:
|
|
return default
|
|
odata = ''
|
|
while len(odata) != size:
|
|
data = self.sock.recv(size - len(odata))
|
|
if len(data) == 0:
|
|
return None
|
|
odata += data
|
|
return odata
|
|
def writeint(self, v):
|
|
self.sock.send(pack('<Q', v & 0xFFFFFFFFFFFFFFFF))
|
|
def writedata(self, v):
|
|
self.writeint(len(v))
|
|
if isinstance(v, str) or isinstance(v, unicode):
|
|
self.sock.send(v)
|
|
else:
|
|
self.sock.send(''.join(map(chr, v)))
|