Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import socket, struct
- class TCPGecko:
- def __init__(self, *args):
- self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
- self.s.connect((str(args[0]), 7331)) #IP, 1337 reversed, Cafiine uses 7332+
- def readmem(self, address, length): #Number of bytes
- if length == 0: raise BaseException("Reading memory requires a length (# of bytes)")
- if not self.validrange(address, length): raise BaseException("Address range not valid")
- if not self.validaccess(address, length, "read"): raise BaseException("Cannot read from address")
- ret = ""
- if length > 0x400:
- print("Length is greater than 0x400 bytes, need to read in chunks")
- print("Start address: " + hexstr0(address))
- for i in range(length / 0x400): #Number of blocks, ignores extra
- self.s.send(b"\x04") #cmd_readmem
- request = struct.pack(">II", address, address + 0x400)
- self.s.send(request)
- status = self.s.recv(1)
- if status == "\xbd": ret += self.s.recv(0x400)
- elif status == "\xb0": ret += "\x00" * 0x400
- else: raise BaseException("Something went terribly wrong")
- address += 0x400;length -= 0x400
- print("Current address: " + hexstr0(address))
- if length != 0: #Now read the last little bit
- self.s.send(b"\x04")
- request = struct.pack(">II", address, address + length)
- self.s.send(request)
- status = self.s.recv(1)
- if status == "\xbd": ret += self.s.recv(length)
- elif status == "\xb0": ret += "\x00" * length
- else: raise BaseException("Something went terribly wrong")
- print("Finished!")
- else:
- self.s.send(b"\x04")
- request = struct.pack(">II", address, address + length)
- self.s.send(request)
- status = self.s.recv(1)
- if status == "\xbd": ret += self.s.recv(length)
- elif status == "\xb0": ret += "\x00" * length
- else: raise BaseException("Something went terribly wrong")
- return ret
- def get_symbol(self, rplname, symname, data = 0): #Don't need to specify data
- self.s.send(b"\x71") #cmd_getsymbol
- request = struct.pack(">II", 8, 8 + len(rplname) + 1) #Pointers
- request += rplname.encode("UTF-8") + b"\x00"
- request += symname.encode("UTF-8") + b"\x00"
- size = struct.pack(">B", len(request))
- data = struct.pack(">B", data)
- self.s.send(size) #Read this many bytes
- self.s.send(request) #Get this symbol
- self.s.send(data) #Is it data?
- address = self.s.recv(4)
- return ExportedSymbol(address, self, rplname, symname)
- def call(self, address, *args):
- arguments = list(args)
- if len(arguments) > 8: #Use the big call function
- while len(arguments) != 16:
- arguments.append(0)
- self.s.send(b"\x72")
- address = struct.unpack(">I", address)[0]
- request = struct.pack(">I16I", address, *arguments)
- self.s.send(request)
- reply = self.s.recv(8)
- return struct.unpack(">I", reply[:4])[0]
- else: #Use the normal one that dNet client uses
- while len(arguments) != 8:
- arguments.append(0)
- self.s.send(b"\x70")
- address = struct.unpack(">I", address)[0]
- request = struct.pack(">I8I", address, *arguments)
- self.s.send(request)
- reply = self.s.recv(8)
- return struct.unpack(">I", reply[:4])[0]
- def validrange(self, address, length):
- if 0x01000000 <= address and address + length <= 0x01800000: return True
- elif 0x0E000000 <= address and address + length <= 0x10000000: return True #Depends on game
- elif 0x10000000 <= address and address + length <= 0x4B000000: return True #Doesn't quite go to 5
- elif 0xE0000000 <= address and address + length <= 0xE4000000: return True
- elif 0xE8000000 <= address and address + length <= 0xEA000000: return True
- elif 0xF4000000 <= address and address + length <= 0xF6000000: return True
- elif 0xF6000000 <= address and address + length <= 0xF6800000: return True
- elif 0xF8000000 <= address and address + length <= 0xFB000000: return True
- elif 0xFB000000 <= address and address + length <= 0xFB800000: return True
- elif 0xFFFE0000 <= address and address + length <= 0xFFFFFFFF: return True
- else: return False
- def validaccess(self, address, length, access):
- if 0x01000000 <= address and address + length <= 0x01800000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0x0E000000 <= address and address + length <= 0x10000000: #Depends on game, may be EG 0x0E3
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0x10000000 <= address and address + length <= 0x4B000000:
- if access.lower() == "read": return True
- if access.lower() == "write": return True
- elif 0xE0000000 <= address and address + length <= 0xE4000000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0xE8000000 <= address and address + length <= 0xEA000000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0xF4000000 <= address and address + length <= 0xF6000000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0xF6000000 <= address and address + length <= 0xF6800000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0xF8000000 <= address and address + length <= 0xFB000000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0xFB000000 <= address and address + length <= 0xFB800000:
- if access.lower() == "read": return True
- if access.lower() == "write": return False
- elif 0xFFFE0000 <= address and address + length <= 0xFFFFFFFF:
- if access.lower() == "read": return True
- if access.lower() == "write": return True
- else: return False
- def hexstr0(data): #0xFFFFFFFF, uppercase hex string
- return "0x" + hex(data).lstrip("0x").rstrip("L").zfill(8).upper()
- class ExportedSymbol(object):
- def __init__(self, address, rpc=None, rplname=None, symname=None):
- self.address = address
- self.rpc = rpc
- self.rplname = rplname
- self.symname = symname
- print(symname + " address: " + hexstr0(struct.unpack(">I", address)[0]))
- def __call__(self, *args):
- return self.rpc.call(self.address, *args) #Pass in arguments, run address
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement