CM-Huawei-P8-Development / device_gra_l09

Device tree
7 stars 16 forks source link

Huawei libgui reverse engineering #18

Closed Nexolight closed 7 years ago

Nexolight commented 7 years ago

The source of many app crashes is actually the Huawei libgui library in the way it's actually used within this rom.

The Huawei HWC does only work out of the box with the Huawei Surfaceflinger. However the Huawei Surfaceflinger depends on a few functions in the libgui library.

The first thing I want to try is to recreate those functions and inject or alter them in the CM libgui as it looks like the most simple (but quite dirty) solution. The long term goal would be eighter to do the same for the Surfaceflinger or even use a full featured opensource HWC.

We're talking about the version of the library included in the downloadlink within vendor6.0/~readme

Here's a reference; https://yurichev.com/mirrors/ARMv8-A_Architecture_Reference_Manual_(Issue_A.a).pdf Here's the CM libgui source: https://github.com/CyanogenMod/android_frameworks_native/tree/stable/cm-13.0-ZNH5Y/libs/gui


No1 - Missing

This is pseudocode from ida

__int64 __fastcall android::GLConsumer::getCurRefreshDirty(android::GLConsumer *this)
{
  android::GLConsumer *v1; // x19@1
  char *v2; // x20@1
  __int64 v3; // x21@1
  __int64 v4; // x19@1

  v1 = this;
  v2 = (char *)this + 1584;
  pthread_mutex_lock((char *)this + 1584);
  v3 = *((_QWORD *)v1 + 207);
  v4 = *((_QWORD *)v1 + 206);
  pthread_mutex_unlock(v2);
  return v4;
}

raw:

; Attributes: bp-based frame

; __int64 __fastcall android::GLConsumer::getCurRefreshDirty(android::GLConsumer *__hidden this)
EXPORT _ZNK7android10GLConsumer18getCurRefreshDirtyEv
_ZNK7android10GLConsumer18getCurRefreshDirtyEv

var_20= -0x20
var_10= -0x10
var_s0=  0

STP             X22, X21, [SP,#-0x10+var_20]!
STP             X20, X19, [SP,#0x20+var_10]
STP             X29, X30, [SP,#0x20+var_s0]
ADD             X29, SP, #0x20
MOV             X19, X0
ADD             X20, X19, #0x630
MOV             X0, X20
BL              .pthread_mutex_lock
LDR             X21, [X19,#0x678]
LDR             X19, [X19,#0x670]
MOV             X0, X20
BL              .pthread_mutex_unlock
MOV             X0, X19
MOV             X1, X21
LDP             X29, X30, [SP,#0x20+var_s0]
LDP             X20, X19, [SP,#0x20+var_10]
LDP             X22, X21, [SP+0x20+var_20],#0x30
RET
; End of function android::GLConsumer::getCurRefreshDirty(void)

This is the pseudocode from the subfunction which does that call - there's only one in libsurfaceflinger.so.

__int64 __usercall sub_2C16C@<X0>(__int64 a1@<X0>, _BYTE *a2@<X1>, android::Region *a3@<X8>)
{
  _BYTE *v3; // x21@1
  __int64 v4; // x20@1
  unsigned __int8 *v5; // x27@1
  unsigned int v6; // w9@1
  android::Region *v7; // x19@1
  unsigned int *v8; // x8@5
  unsigned int v9; // w9@6
  __int64 v10; // x22@8
  unsigned int *v11; // x8@9
  unsigned int v12; // w9@10
  __int64 v13; // x8@11
  unsigned int *v14; // x8@12
  unsigned int v15; // w9@13
  unsigned int v16; // w9@13
  unsigned int *v17; // x8@18
  unsigned int v18; // w9@19
  unsigned int v19; // w9@19
  unsigned int *v20; // x8@25
  unsigned int v21; // w9@26
  unsigned int v22; // w21@28
  unsigned int v23; // w22@28
  signed __int64 v24; // x20@28
  char *v25; // x0@32
  int v26; // w0@35
  android::RefBase *v27; // x8@35
  int v28; // w28@35
  signed __int64 v29; // x25@37
  unsigned int v30; // w24@37
  __int64 v31; // x0@38
  int v32; // w8@38
  unsigned int *v33; // x28@40
  signed __int64 v34; // x25@40
  __int64 v35; // x24@40
  int v36; // w0@40
  _BYTE *v37; // x24@42
  __int64 v38; // x26@43
  __int64 v39; // x24@43
  android::VectorImpl *v40; // x27@43
  unsigned int v41; // w8@45
  unsigned int v42; // w8@48
  unsigned int v43; // off@54
  signed int v44; // w8@60
  android::RefBase *v45; // x25@63
  android::RefBase *v46; // x0@65
  unsigned __int64 v47; // x0@72
  int v48; // w26@72
  unsigned __int64 v49; // x1@72
  int v50; // w25@72
  signed __int64 v51; // x22@72
  signed __int64 v52; // x28@72
  int v53; // w27@72
  int v54; // w0@72
  int v55; // w8@83
  bool v56; // w8@85
  unsigned int v57; // w21@89
  unsigned int v58; // w22@89
  unsigned __int64 v59; // x22@94
  __int64 v60; // x1@94
  unsigned __int64 v61; // x21@94
  char v62; // w0@94
  signed __int64 v63; // x6@94
  signed __int64 v64; // x4@94
  __int64 v65; // x5@100
  int v66; // ST10_4@100
  __int64 result; // x0@105
  unsigned int v68; // w8@105
  void *v69; // [xsp+20h] [xbp-180h]@43
  int v70; // [xsp+2Ch] [xbp-174h]@38
  char v71; // [xsp+38h] [xbp-168h]@99
  unsigned __int64 v72; // [xsp+60h] [xbp-140h]@94
  __int64 v73; // [xsp+68h] [xbp-138h]@94
  int v74; // [xsp+78h] [xbp-128h]@93
  int v75; // [xsp+7Ch] [xbp-124h]@93
  unsigned int v76; // [xsp+80h] [xbp-120h]@93
  unsigned int v77; // [xsp+84h] [xbp-11Ch]@93
  int v78; // [xsp+88h] [xbp-118h]@37
  __int64 v79; // [xsp+90h] [xbp-110h]@100
  __int64 v80; // [xsp+98h] [xbp-108h]@100
  android::RefBase *v81; // [xsp+B0h] [xbp-F0h]@63
  void *v82; // [xsp+B8h] [xbp-E8h]@40
  __int64 v83; // [xsp+C0h] [xbp-E0h]@40
  __int64 v84; // [xsp+C8h] [xbp-D8h]@40
  _BYTE *v85; // [xsp+D0h] [xbp-D0h]@40
  bool v86; // [xsp+D8h] [xbp-C8h]@40
  android::RefBase *v87; // [xsp+E0h] [xbp-C0h]@35
  char v88; // [xsp+E8h] [xbp-B8h]@33
  __int64 v89; // [xsp+F0h] [xbp-B0h]@100
  __int64 v90; // [xsp+F8h] [xbp-A8h]@100
  int v91; // [xsp+110h] [xbp-90h]@32
  int v92; // [xsp+114h] [xbp-8Ch]@32
  unsigned int v93; // [xsp+118h] [xbp-88h]@32
  unsigned int v94; // [xsp+11Ch] [xbp-84h]@32
  char v95; // [xsp+120h] [xbp-80h]@32
  __int64 v96; // [xsp+148h] [xbp-58h]@8

  v3 = a2;
  v4 = a1;
  v5 = 0LL;
  v6 = __ldar(0LL);
  v7 = a3;
  if ( !(v6 & 1) )
    ((void (*)(void))atrace_setup)();
  if ( MEMORY[0] & 2 )
    atrace_begin_body("latchBuffer");
  v8 = (unsigned int *)(v4 + 608);
  do
  {
    v9 = __ldaxr(v8);
    if ( v9 != 1 )
    {
      android::Region::Region((android::Region *)&v88);
      if ( *(_DWORD *)(v4 + 604) < 1 || *(_BYTE *)(v4 + 5865) )
      {
LABEL_103:
        android::Region::Region(v7, (const android::Region *)&v88);
LABEL_104:
        v25 = &v88;
        goto LABEL_105;
      }
      v26 = (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v4 + 48LL))(v4);
      v27 = *(android::RefBase **)(v4 + 5824);
      v28 = v26;
      v87 = v27;
      if ( v27 )
        android::RefBase::incStrong(v27, &v87);
      v78 = 0;
      v29 = v4 + 232;
      v30 = (*(__int64 (**)(void))(**(_QWORD **)(v4 + 200) + 96LL))();
      if ( v30 )
      {
        v70 = v28;
        v31 = strerror(-v30);
        __android_log_print(
          5LL,
          "SurfaceFlinger",
          "%s: Error %s (%d) while querying window sticky transform.",
          "getProducerStickyTransform",
          v31,
          v30);
        v32 = 0;
      }
      else
      {
        v70 = v28;
        v32 = v78;
      }
      v33 = (unsigned int *)(v4 + 604);
      v82 = &unk_73690;
      v83 = v4 + 416;
      v84 = v29;
      v85 = v3;
      v86 = v32 != 0;
      v34 = v4 + 6084;
      pthread_mutex_lock(v4 + 6084);
      v35 = *(_QWORD *)(v4 + 6216);
      pthread_mutex_unlock(v4 + 6084);
      v36 = sub_3F0C4(*(_QWORD *)(v4 + 192), &v82, *(_QWORD *)(v4 + 184) + 6024LL, v35);
      if ( v36 == -2147483640 )
      {
        pthread_mutex_lock(v34);
        android::VectorImpl::removeItemsAt((android::VectorImpl *)(v4 + 6176), 0LL, 1uLL);
        do
          v42 = __ldxr(v33);
        while ( __stlxr(v42 - 1, v33) );
        android::Region::Region(v7, (const android::Region *)&v88);
        pthread_mutex_unlock(v34);
LABEL_57:
        if ( v87 )
          android::RefBase::decStrong(v87, &v87);
        goto LABEL_104;
      }
      if ( v36 )
      {
        if ( v36 == 3 )
        {
          sub_32540(*(_QWORD *)(v4 + 184));
LABEL_56:
          android::Region::Region(v7, (const android::Region *)&v88);
          goto LABEL_57;
        }
        v37 = (_BYTE *)(v4 + 6224);
      }
      else
      {
        v37 = (_BYTE *)(v4 + 6224);
        if ( !*(_BYTE *)(v4 + 6224) )
        {
          v69 = (void *)(v4 + 5824);
          v38 = android::GLConsumer::getFrameNumber(*(android::GLConsumer **)(v4 + 192));
          pthread_mutex_lock(v34);
          v39 = *(_QWORD *)(*(_QWORD *)(v4 + 6184) + 72LL);
          v40 = (android::VectorImpl *)(v4 + 6176);
          while ( 1 )
          {
            android::VectorImpl::removeItemsAt(v40, 0LL, 1uLL);
            if ( v39 == v38 )
              break;
            do
              v41 = __ldxr(v33);
            while ( __stlxr(v41 - 1, v33) );
            v39 = *(_QWORD *)(*(_QWORD *)(v4 + 6184) + 72LL);
          }
          pthread_mutex_unlock(v34);
          v5 = 0LL;
          do
            v44 = __ldxr(v33);
          while ( __stlxr(v44 - 1, v33) );
          if ( v44 >= 2 )
            sub_32540(*(_QWORD *)(v4 + 184));
          android::GLConsumer::getCurrentBuffer(*(android::GLConsumer **)(v4 + 192));
          v45 = v81;
          if ( v81 )
            android::RefBase::incStrong(v81, v69);
          v46 = *(android::RefBase **)v69;
          if ( *(_QWORD *)v69 )
            android::RefBase::decStrong(v46, v69);
          *(_QWORD *)v69 = v45;
          if ( v81 )
          {
            android::RefBase::decStrong(v81, &v81);
            v45 = *(android::RefBase **)v69;
          }
          if ( v45 )
          {
            *(_BYTE *)(v4 + 5865) = 1;
            *(_BYTE *)(v4 + 5866) = 1;
            if ( !v87 )
              *v3 = 1;
            v47 = android::GLConsumer::getCurrentCrop(*(android::GLConsumer **)(v4 + 192));
            v48 = v47;
            v50 = v49;
            v51 = (v49 >> 32) & 0xFFFFFFFF;
            v52 = (v47 >> 32) & 0xFFFFFFFF;
            v53 = android::GLConsumer::getCurrentTransform(*(android::GLConsumer **)(v4 + 192));
            v54 = android::GLConsumer::getCurrentScalingMode(*(android::GLConsumer **)(v4 + 192));
            if ( v48 != *(_DWORD *)(v4 + 5840)
              || (_DWORD)v52 != *(_DWORD *)(v4 + 5844)
              || v50 != *(_DWORD *)(v4 + 5848)
              || (_DWORD)v51 != *(_DWORD *)(v4 + 5852)
              || v53 != *(_DWORD *)(v4 + 5856)
              || v54 != *(_DWORD *)(v4 + 5860) )
            {
              *(_DWORD *)(v4 + 5840) = v48;
              *(_DWORD *)(v4 + 5844) = v52;
              *(_DWORD *)(v4 + 5848) = v50;
              *(_DWORD *)(v4 + 5852) = v51;
              *(_DWORD *)(v4 + 5856) = v53;
              *(_DWORD *)(v4 + 5860) = v54;
              *v3 = 1;
            }
            v5 = 0LL;
            if ( v87
              && (*(_DWORD *)(*(_QWORD *)v69 + 72LL) != *((_DWORD *)v87 + 18)
               || *(_DWORD *)(*(_QWORD *)v69 + 76LL) != *((_DWORD *)v87 + 19)) )
            {
              *v3 = 1;
            }
            v55 = *(_DWORD *)(*(_QWORD *)v69 + 84LL);
            v56 = (v55 & 0xFFFFFF00) == 256 || (v55 | 4) != 5;
            *(_BYTE *)(v4 + 5864) = v56;
            if ( (v70 ^ (unsigned int)(*(__int64 (__fastcall **)(__int64, __int64))(*(_QWORD *)v4 + 48LL))(v4, v4 + 416)) & 1 )
              *v3 = 1;
            v57 = *(_DWORD *)(v4 + 416);
            v58 = *(_DWORD *)(v4 + 420);
            if ( v57 & 0x80000000 )
            {
              __android_log_print(5LL, "Rect", "Width %u too large for Rect class, clamping", v57);
              v57 = 0x7FFFFFFF;
            }
            if ( v58 & 0x80000000 )
            {
              __android_log_print(5LL, "Rect", "Height %u too large for Rect class, clamping", v58);
              v58 = 0x7FFFFFFF;
            }
            v74 = 0;
            v75 = 0;
            v76 = v57;
            v77 = v58;
            android::Region::Region((android::Region *)&v78, (const android::Rect *)&v74);
            if ( sub_3A064(*(_QWORD *)(v4 + 184)) & 1 )
            {
              v59 = android::GLConsumer::getCurRefreshDirty(*(android::GLConsumer **)(v4 + 192));
              v61 = v60;
              v72 = v59;
              v73 = v60;
              v62 = sub_3A10C(*(_QWORD *)(v4 + 184));
              v63 = (v61 >> 32) & 0xFFFFFFFF;
              v64 = (v59 >> 32) & 0xFFFFFFFF;
              if ( v62 & 1 )
              {
                __android_log_print(
                  3LL,
                  "SurfaceFlinger",
                  "@@@latchBuffer-refreshDirty=[%d, %d, %d, %d]-w:%d, h:%d",
                  (unsigned int)v59);
                LODWORD(v63) = HIDWORD(v73);
                LODWORD(v61) = v73;
                LODWORD(v64) = HIDWORD(v72);
                LODWORD(v59) = v72;
              }
              if ( (signed int)v61 > (signed int)v59 && (signed int)v63 > (signed int)v64 )
                android::Region::set((android::Region *)&v78, (const android::Rect *)&v72);
            }
            sub_4013C(v4 + 480, &v78);
            android::Region::operator=(&v88, &v71);
            android::Region::~Region((android::Region *)&v71);
            if ( sub_3A10C(*(_QWORD *)(v4 + 184)) & 1 )
            {
              v65 = (unsigned int)(*(_DWORD *)(v89 + 16 * v90 - 8) - *(_DWORD *)(v89 + 16 * v90 - 16));
              v66 = *(_DWORD *)(v79 + 16 * v80 - 4) - *(_DWORD *)(v79 + 16 * v80 - 12);
              __android_log_print(
                3LL,
                "SurfaceFlinger",
                "@@@latchBuffer-outDirty=[%d, %d, w:%d, h:%d], dirtyRegion=[%d, %d, w:%d, h:%d]");
            }
            android::Region::~Region((android::Region *)&v78);
            if ( v87 )
              android::RefBase::decStrong(v87, &v87);
            goto LABEL_103;
          }
          goto LABEL_56;
        }
      }
      pthread_mutex_lock(v34);
      android::VectorImpl::clear((android::VectorImpl *)(v4 + 6176));
      do
        v43 = __ldxr(v33);
      while ( __stlxr(0, v33) );
      pthread_mutex_unlock(v34);
      *v37 = 1;
      goto LABEL_56;
    }
  }
  while ( __stxr(0, v8) );
  sub_3F434(*(_QWORD *)(v4 + 192));
  v10 = v96;
  if ( v96 )
  {
    v11 = (unsigned int *)(v96 + 8);
    do
      v12 = __ldxr(v11);
    while ( __stlxr(v12 + 1, v11) );
  }
  v13 = *(_QWORD *)(v4 + 5832);
  if ( v13 )
  {
    v14 = (unsigned int *)(v13 + 8);
    do
    {
      v15 = __ldxr(v14);
      v16 = v15 - 1;
    }
    while ( __stlxr(v16, v14) );
    if ( !v16 && v14 != (unsigned int *)8 )
      (*(void (**)(void))(*((_QWORD *)v14 - 1) + 8LL))();
  }
  *(_QWORD *)(v4 + 5832) = v10;
  if ( v96 )
  {
    v17 = (unsigned int *)(v96 + 8);
    do
    {
      v18 = __ldxr(v17);
      v19 = v18 - 1;
    }
    while ( __stlxr(v19, v17) );
    if ( !v19 && v17 != (unsigned int *)8 )
      (*(void (**)(void))(*((_QWORD *)v17 - 1) + 8LL))();
    v10 = *(_QWORD *)(v4 + 5832);
  }
  if ( v10 )
  {
    v20 = (unsigned int *)(v4 + 600);
    do
      v21 = __ldxr(v20);
    while ( __stlxr(v21 | 1, v20) );
    sub_30928(*(_QWORD *)(v4 + 184), 2LL);
  }
  *v3 = 1;
  v22 = *(_DWORD *)(v4 + 416);
  v23 = *(_DWORD *)(v4 + 420);
  v24 = v4 + 480;
  if ( v22 & 0x80000000 )
  {
    __android_log_print(5LL, "Rect", "Width %u too large for Rect class, clamping", v22);
    v22 = 0x7FFFFFFF;
  }
  if ( v23 & 0x80000000 )
  {
    __android_log_print(5LL, "Rect", "Height %u too large for Rect class, clamping", v23);
    v23 = 0x7FFFFFFF;
  }
  v91 = 0;
  v92 = 0;
  v93 = v22;
  v94 = v23;
  android::Region::Region((android::Region *)&v95, (const android::Rect *)&v91);
  sub_4013C(v24, &v95);
  v25 = &v95;
LABEL_105:
  result = android::Region::~Region((android::Region *)v25);
  v68 = __ldar(v5);
  if ( !(v68 & 1) )
    result = atrace_setup(result);
  if ( MEMORY[0] & 2 )
  {
    v88 = 69;
    result = write(MEMORY[0], &v88, 1LL);
  }
  return result;
}
Nexolight commented 7 years ago

obsolete