MiSnapThunk

NTSTATUS __stdcall MiSnapThunk(
        PVOID DllBase,
        PVOID ImageBase,
        _IMAGE_THUNK_DATA32 *NameThunk,
        _IMAGE_THUNK_DATA32 *AddrThunk,
        _IMAGE_IMPORT_BY_NAME *NameAddressOfData){
  char *v9; 
  __int64 v10; 
  _IMAGE_IMPORT_BY_NAME *v11; 
  CHAR *Name; 
  char *v13; 
  __int64 Hint; 
  char *v15; 
  unsigned int v16; 
  __int64 v17; 
  CHAR *v18; 
  char *v19; 
  int v20; 
  int v21; 
  unsigned __int16 v22; 
  char *v23; 
  int v25; 
  int v26; 
  CHAR *v27; 
  int v28; 
  char *v29; 
  CHAR v30; 
  int v31; 
  __int16 v32; 
  unsigned __int16 v33; 
  INT64 *v34; 
  NTSTATUS v35; 
  char *v36; 
  __int64 v37; 
  _IMAGE_IMPORT_BY_NAME *Pool; 
  _IMAGE_IMPORT_BY_NAME *v39; 
  void *v40; 
  UINT64 Size; 
  _STRING SourceString; 
  _UNICODE_STRING DestinationString; 

  LODWORD(Size) = 0;
  DestinationString = 0i64;
  SourceString = 0i64;
  v9 = (char *)RtlImageDirectoryEntryToData(DllBase, 1u, 0, &Size);
  if( !v9 )
    return -1073741213;
  v10 = *(_QWORD *)&NameThunk->u1.ForwarderString;
  v11 = NameAddressOfData;
  if( *(__int64 *)&NameThunk->u1.ForwarderString >= 0 )
  {
    if( !NameAddressOfData )
      v11 = (_IMAGE_IMPORT_BY_NAME *)((char *)ImageBase + v10);
LABEL_5:
    Name = v11->Name;
    v13 = (char *)DllBase + *((unsigned int *)v9 + 8);
    Hint = v11->Hint;
    v15 = (char *)DllBase + *((unsigned int *)v9 + 9);
    v16 = *((_DWORD *)v9 + 6);
    if( (unsigned int)Hint < v16 )
    {
      v17 = v11->Hint;
      v18 = v11->Name;
      v19 = (char *)((_BYTE *)DllBase + *(unsigned int *)&v13[4 * Hint] - Name);
      do
      {
        v20 = (unsigned __int8)v19[(_QWORD)v18];
        v21 = (unsigned __int8)*v18 - v20;
        if( v21 )
          break;
        ++v18;
      }
      while( v20 );
      if( !v21 )
      {
        v22 = *(_WORD *)&v15[2 * v17];
        goto LABEL_11;
      }
    }
    v25 = 0;
    if( v16 )
    {
      v26 = v16 - 1;
      if( (int)(v16 - 1) >= 0 )
      {
        do
        {
          v27 = Name;
          v28 = (v25 + v26) >> 1;
          v29 = (char *)((_BYTE *)DllBase + *(unsigned int *)&v13[4 * v28] - Name);
          while( 1 )
          {
            v30 = *v27;
            if( *v27 != v29[(_QWORD)v27] )
              break;
            ++v27;
            if( !v30 )
            {
              v31 = 0;
              goto LABEL_21;
            }
          }
          v31 = (unsigned __int8)*v27 < (unsigned int)v29[(_QWORD)v27] ? -1 : 1;
LABEL_21:
          if( v31 < 0 )
          {
            if( !v28 )
              return -1073741213;
            v26 = v28 - 1;
          }
          else
          {
            if( v31 <= 0 )
              break;
            v25 = v28 + 1;
          }
        }
        while( v26 >= v25 );
        if( v26 >= v25 )
        {
          v22 = *(_WORD *)&v15[2 * v28];
          goto LABEL_11;
        }
      }
    }
    return -1073741213;
  }
  if( NameAddressOfData )
    goto LABEL_5;
  v22 = v10 - *((_WORD *)v9 + 8);
LABEL_11:
  if( (unsigned int)v22 >= *((_DWORD *)v9 + 5) )
    return -1073741214;
  v23 = (char *)DllBase + *(unsigned int *)((char *)DllBase + 4 * v22 + *((unsigned int *)v9 + 7));
  *(_QWORD *)&AddrThunk->u1.ForwarderString = v23;
  if( v23 <= v9 || v23 >= &v9[(unsigned int)Size] )
    return 0;
  SourceString.Buffer = v23;
  strchr((UINT8 *)v23, 0x2Eu);
  v33 = 1 - (_WORD)v23 + v32;
  SourceString.Length = v33;
  SourceString.MaximumLength = v33;
  if( RtlAnsiStringToUnicodeString(&DestinationString, &SourceString, 1u) < 0 )
    return -1073741213;
  v34 = (INT64 *)PsLoadedModuleList;
  v35 = -1073741213;
  while( v34 != &PsLoadedModuleList )
  {
    if( RtlPrefixString(&DestinationString.Length, (INT64)(v34 + 11), 1) )
    {
      v36 = &v23[v33];
      v37 = -1i64;
      do
        ++v37;
      while( v36[v37] );
      Pool = (_IMAGE_IMPORT_BY_NAME *)MiAllocatePool(256i64, v37 + 5, 0x20206D4Dui64);
      v39 = Pool;
      if( Pool )
      {
        memmove(Pool->Name, v36, v37 + 1);
        v39->Hint = 0;
        v40 = (void *)v34[6];
        Size = 0i64;
        v35 = MiSnapThunk(v40, ImageBase, (_IMAGE_THUNK_DATA32 *)&Size, (_IMAGE_THUNK_DATA32 *)&Size, v39);
        ExFreePoolWithTag(v39, 0);
        *(_QWORD *)&AddrThunk->u1.ForwarderString = Size;
      }
      break;
    }
    v34 = (INT64 *)*v34;
  }
  RtlFreeAnsiString(&DestinationString);
  return v35;
}

Referenced by:

MiResolveImageReferences
MiSnapThunk