MiSnapThunk

NTSTATUS __stdcall MiSnapThunk(
        PVOID DllBase,
        PVOID ImageBase,
        IMAGE_THUNK_DATA32 *NameThunk,
        IMAGE_THUNK_DATA32 *AddrThunk,
        IMAGE_IMPORT_BY_NAME *NameAddressOfData){
  unsigned __int64 v9; 
  unsigned __int64 v10; 
  __int64 v11; 
  IMAGE_IMPORT_BY_NAME *v12; 
  BYTE *Name; 
  char *v14; 
  __int64 Hint; 
  char *v16; 
  unsigned int v17; 
  __int64 v18; 
  BYTE *v19; 
  char *v20; 
  int v21; 
  int v22; 
  unsigned __int16 v23; 
  char *v24; 
  int v26; 
  int v27; 
  BYTE *v28; 
  int v29; 
  char *v30; 
  BYTE v31; 
  int v32; 
  __int16 v33; 
  unsigned __int16 v34; 
  PVOID *v35; 
  NTSTATUS v36; 
  UINT8 *v37; 
  __int64 v38; 
  IMAGE_IMPORT_BY_NAME *v39; 
  IMAGE_IMPORT_BY_NAME *v40; 
  PVOID v41; 
  ULONG Size[2]; 
  struct _STRING SourceString; 
  struct _UNICODE_STRING DestinationString; 
  Size[0] = 0;
  DestinationString = 0i64;
  SourceString = 0i64;
  LODWORD(v9) = RtlImageDirectoryEntryToData(DllBase, 1u, 0, (UINT64 *)Size);
  v10 = v9;
  if( !v9 )
    return -1073741213;
  v11 = *(_QWORD *)&NameThunk->u1.ForwarderString;
  v12 = NameAddressOfData;
  if( *(__int64 *)&NameThunk->u1.ForwarderString >= 0 )
  {
    if( !NameAddressOfData )
      v12 = (IMAGE_IMPORT_BY_NAME *)((char *)ImageBase + v11);
LABEL_5:
    Name = v12->Name;
    v14 = (char *)DllBase + *(unsigned int *)(v10 + 32);
    Hint = v12->Hint;
    v16 = (char *)DllBase + *(unsigned int *)(v10 + 36);
    v17 = *(_DWORD *)(v10 + 24);
    if( (unsigned int)Hint < v17 )
    {
      v18 = v12->Hint;
      v19 = v12->Name;
      v20 = (char *)((_BYTE *)DllBase + *(unsigned int *)&v14[4 * Hint] - Name);
      do
      {
        v21 = (unsigned __int8)v20[(_QWORD)v19];
        v22 = *v19 - v21;
        if( v22 )
          break;
        ++v19;
      }
      while( v21 );
      if( !v22 )
      {
        v23 = *(_WORD *)&v16[2 * v18];
        goto LABEL_11;
      }
    }
    v26 = 0;
    if( v17 )
    {
      v27 = v17 - 1;
      if( (int)(v17 - 1) >= 0 )
      {
        do
        {
          v28 = Name;
          v29 = (v26 + v27) >> 1;
          v30 = (char *)((_BYTE *)DllBase + *(unsigned int *)&v14[4 * v29] - Name);
          while( 1 )
          {
            v31 = *v28;
            if( *v28 != v30[(_QWORD)v28] )
              break;
            ++v28;
            if( !v31 )
            {
              v32 = 0;
              goto LABEL_21;
            }
          }
          v32 = *v28 < (unsigned int)v30[(_QWORD)v28] ? -1 : 1;
LABEL_21:
          if( v32 < 0 )
          {
            if( !v29 )
              return -1073741213;
            v27 = v29 - 1;
          }
          else
          {
            if( v32 <= 0 )
              break;
            v26 = v29 + 1;
          }
        }
        while( v27 >= v26 );
        if( v27 >= v26 )
        {
          v23 = *(_WORD *)&v16[2 * v29];
          goto LABEL_11;
        }
      }
    }
    return -1073741213;
  }
  if( NameAddressOfData )
    goto LABEL_5;
  v23 = v11 - *(_WORD *)(v10 + 16);
LABEL_11:
  if( (unsigned int)v23 >= *(_DWORD *)(v10 + 20) )
    return -1073741214;
  v24 = (char *)DllBase + *(unsigned int *)((char *)DllBase + 4 * v23 + *(unsigned int *)(v10 + 28));
  *(_QWORD *)&AddrThunk->u1.ForwarderString = v24;
  if( (unsigned __int64)v24 <= v10 || (unsigned __int64)v24 >= v10 + Size[0] )
    return 0;
  SourceString.Buffer = v24;
  strchr((UINT8 *)v24, 0x2Eu);
  v34 = 1 - (_WORD)v24 + v33;
  SourceString.Length = v34;
  SourceString.MaximumLength = v34;
  if( RtlAnsiStringToUnicodeString(&DestinationString, &SourceString, 1u) < 0 )
    return -1073741213;
  v35 = (PVOID *)PsLoadedModuleList;
  v36 = -1073741213;
  while( v35 != &PsLoadedModuleList )
  {
    if( RtlPrefixString((const _STRING *)&DestinationString, (const _STRING *)(v35 + 11), 1u) )
    {
      v37 = (UINT8 *)&v24[v34];
      v38 = -1i64;
      do
        ++v38;
      while( v37[v38] );
      LODWORD(v39) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
      v40 = v39;
      if( v39 )
      {
        memmove(v39->Name, v37, v38 + 1);
        v40->Hint = 0;
        v41 = v35[6];
        *(_QWORD *)Size = 0i64;
        v36 = MiSnapThunk(v41, ImageBase, (IMAGE_THUNK_DATA32 *)Size, (IMAGE_THUNK_DATA32 *)Size, v40);
        ExFreePoolWithTag(v40, 0);
        *(_QWORD *)&AddrThunk->u1.ForwarderString = *(_QWORD *)Size;
      }
      break;
    }
    v35 = (PVOID *)*v35;
  }
  RtlFreeAnsiString(&DestinationString);
  return v36;
}

Referenced by:

MiResolveImageReferences
MiSnapThunk