KiOpComputeLinearAddress

INT64 __fastcall KiOpComputeLinearAddress(INT64 a1, INT64 *a2){
  _ETHREAD *CurrentThread; 
  INT64 v3; 
  INT64 v5; 
  char v6; 
  KPCR *Pcr; 
  __int16 v8; 
  _ETHREAD *v10; 
  _ETHREAD *v11; 
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v3 = a1;
  v5 = *a2;
  v6 = *(_BYTE *)(a1 + 81);
  _BitScanForward((unsigned int *)&a1, *(_DWORD *)(a1 + 48));
  Pcr = 0i64;
  v8 = *(_WORD *)(*(unsigned int *)&KiOpSegmentOffsetTable[2 * a1] + *(_QWORD *)(v3 + 24));
  if( 1 << a1 == 32 )
  {
    if( v6 )
    {
      Pcr = (KPCR *)*((_QWORD *)CurrentThread + 190);
      if( !Pcr )
      {
        v10 = (_ETHREAD *)KeGetCurrentThread();
        if( (*((_DWORD *)v10 + 29) & 0x400) != 0 || *((_BYTE *)v10 + 586) == 1 )
          Pcr = 0i64;
        else
          Pcr = (KPCR *)*((_QWORD *)v10 + 30);
      }
    }
    else
    {
      Pcr = KeGetPcr();
    }
    goto LABEL_4;
  }
  if( 1 << a1 == 16 )
  {
    Pcr = (KPCR *)*((_QWORD *)CurrentThread + 189);
    if( !Pcr )
    {
      v11 = (_ETHREAD *)KeGetCurrentThread();
      if( (*((_DWORD *)v11 + 29) & 0x400) != 0 || *((_BYTE *)v11 + 586) == 1 )
        Pcr = 0i64;
      else
        Pcr = (KPCR *)*((_QWORD *)v11 + 30);
      if( Pcr )
        Pcr = (KPCR *)((char *)Pcr + 0x2000);
    }
    goto LABEL_4;
  }
  if( v6 != 1 || !*(_BYTE *)(v3 + 58) || ((v8 - 35) & 0xFFE7) == 0 && v8 != 59 )
  {
LABEL_4:
    *a2 = (INT64)Pcr + v5;
    return 0i64;
  }
  *a2 = 0x7FFFFFFF0000i64;
  return 3221225477i64;
}

Referenced by:

KiOpRetrieveRegMemAddress