openyou / emokit

Open source driver for accessing raw data from the Emotiv EPOC EEG headset
http://www.openyou.org
Other
521 stars 235 forks source link

Deciphering the functions. #256

Open warrenarea opened 7 years ago

warrenarea commented 7 years ago

So it occurs to me that trying to locate the get_level and decryption functions, based on where the rjindael code is... is pretty much a lost cause, because the rjindael is just mixed in with a bunch of other encryption functions, and they could be doing all sorts of other processes in between actually utilizing the data acquired.

So I think I'm getting a little closer, by first looking at "Imports" or Symbols, which are basically the function names.

What I want to focus on at this point, is "sure thing" code and recognizable code segments, because there is a ton of code, and we don't want to waste our time on false positives and confusing ourselves.

I think I'll break the code up into sections, to make it easier to edit later.

If you want to comment on an item, reference its function name. (for clarity)

warrenarea commented 7 years ago

Object Explorer : DataAcqThread

_DWORD *__thiscall sub_14DD040(_DWORD *this, int a2, int a3, int a4, int a5, int a6, char *Source, char a8, char a9)
{
  _DWORD *v9; // edi@1
  void *v10; // ST18_4@1
  int v11; // edx@1
  int v13; // [sp+0h] [bp-1Ch]@0
  int v14; // [sp+4h] [bp-18h]@0
  int v15; // [sp+8h] [bp-14h]@0

  v9 = this;
  v10 = this;
  sub_14E2890(Source, a8, a9);
  *v9 = &off_16AB094;
  v9[94] = Xtime_get_ticks(v13, v14, v15, v10);
  v9[95] = v11;
  v9[96] = *(_DWORD *)a6;
  v9[97] = *(_DWORD *)(a6 + 4);
  v9[98] = a2;
  v9[99] = 0;
  v9[100] = 0;
  v9[99] = sub_138CCC0(v9 + 99);
  v9[101] = a3;
  v9[102] = a4;
  v9[103] = 0;
  v9[104] = 0;
  v9[105] = 0;
  v9[106] = 0;
  v9[107] = a5;
  v9[108] = 0;
  v9[109] = 0;
  v9[108] = sub_138CCC0(v9 + 108);
  v9[111] = 0;
  v9[112] = 0;
  v9[113] = 0;
  v9[112] = sub_14DD940(v9 + 112);
  v9[114] = 0;
  v9[115] = 0;
  v9[114] = sub_14DD940(v9 + 114);
  v9[116] = 0;
  v9[117] = 0;
  v9[116] = sub_14DD940(v9 + 116);
  v9[118] = 0;
  v9[119] = 0;
  v9[118] = sub_14DD940(v9 + 118);
  v9[120] = 0;
  v9[121] = 0;
  v9[120] = sub_140A580(v9 + 120);
  v9[122] = 0;
  v9[123] = 0;
  v9[122] = sub_138CCC0(v9 + 122);
  v9[124] = 0;
  v9[125] = 0;
  v9[124] = sub_138CCC0(v9 + 124);
  v9[126] = 0;
  v9[127] = 0;
  v9[126] = sub_138CCC0(v9 + 126);
  return v9;
}

Comments: Looks like sensor_bit values we're seeing here.

minifiredragon commented 7 years ago

I would agree, this is what I found as well while running EPOC+

warrenarea commented 7 years ago

Object Explorer : CognitiveDetectionG2_Clamshell

signed int __thiscall sub_8670310(void *this, int a2, int a3)
{
  void *v3; // ebx@1
  int v4; // edi@23
  int v15; // eax@41
  int v16; // eax@41
  unsigned int v17; // esi@41
  int v18; // ecx@42
  signed int v19; // edi@45
  signed int v20; // ebx@47
  signed int v21; // eax@47
  int v22; // eax@49
  bool v23; // zf@49
  signed int v24; // eax@51
  int v25; // eax@55
  unsigned int v26; // esi@65
  int v27; // ecx@66
  signed int v28; // eax@68
  int v29; // eax@70
  bool v30; // zf@70
  signed int v31; // eax@72
  int v32; // eax@76
  int v33; // esi@76
  int v34; // eax@85
  int v35; // eax@85
  int v36; // esi@85
  int v37; // eax@85
  int v38; // ST3C_4@85
  unsigned int v39; // esi@99
  int v40; // ecx@100
  signed int v41; // eax@102
  int v42; // eax@104
  unsigned int v43; // esi@109
  int v44; // ecx@110
  signed int v45; // eax@112
  int v46; // eax@114
  unsigned int v47; // esi@119
  int v48; // eax@123
  char v52; // [sp+0h] [bp-70h]@0
  void *v53; // [sp+10h] [bp-60h]@1
  unsigned int v55; // [sp+18h] [bp-58h]@55
  int v57; // [sp+28h] [bp-48h]@41
  unsigned int v58; // [sp+2Ch] [bp-44h]@55
  int v59; // [sp+2Ch] [bp-44h]@76
  int v60; // [sp+30h] [bp-40h]@85
  void *Src; // [sp+48h] [bp-28h]@1
  int v62; // [sp+58h] [bp-18h]@1
  unsigned int v63; // [sp+5Ch] [bp-14h]@1
  int v64; // [sp+6Ch] [bp-4h]@1

  v3 = this;
  v53 = this;
  v64 = 0;
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "34bd287fcda21853efba287688db0c4d", 0x20u);
  LOBYTE(v64) = 1;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "1b67a98380453cedca92592b3428a418", 0x20u);
  LOBYTE(v64) = 2;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "2f862bcdcbeffd69eb4a6f84c0f1e69b", 0x20u);
  LOBYTE(v64) = 3;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "077ad045a661aa9be650f87a291716c3", 0x20u);
  LOBYTE(v64) = 4;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "563f77be9797afaed87a515a37302163", 0x20u);
  LOBYTE(v64) = 5;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "600e25844e2cd2ac247acef85582a262", 0x20u);
  LOBYTE(v64) = 6;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "9de38cf5529d7eb1b4caade47f3c594c", 0x20u);
  LOBYTE(v64) = 7;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "1e0fa5d1bedb54db63f18862dcd6538d", 0x20u);
  LOBYTE(v64) = 8;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "b07766e96df0e9a01737ab61f60503d5", 0x20u);
  LOBYTE(v64) = 9;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "aa07a0cd4f6f544b8bf34c0be604da7f", 0x20u);
  LOBYTE(v64) = 10;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "824180e25489bf4935865cc05377f606", 0x20u);
  LOBYTE(v64) = 11;
  sub_853E2F0(&Src);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  v4 = a2;
  if ( !(unsigned __int8)(*(int (__thiscall **)(void *))(*(_DWORD *)v3 + 48))(v3) )
    v3 = v53;
  v15 = (*(int (__thiscall **)(void *))(*(_DWORD *)v3 + 84))(v3);
  v16 = sub_86E7710(v15);
  v17 = *(_DWORD *)(a2 + 16);
  v57 = v16;
  if ( *(_DWORD *)(a2 + 20) < 0x10u )
    v18 = a2;
  else
    v18 = *(_DWORD *)a2;
  v20 = 32;
  v21 = 32;
  if ( v17 < 0x20 )
    v21 = *(_DWORD *)(a2 + 16);
  v22 = sub_8519A70(v18, "2f862bcdcbeffd69eb4a6f84c0f1e69b", v21);
  v23 = v22 == 0;
  if ( !v22 )
  {
    if ( v17 >= 0x20 )
      v24 = v17 != 32;
    else
      v24 = -1;
    v23 = v24 == 0;
  }
  if ( !v23 )
    goto LABEL_138;
  v55 = sub_86E6260(a3);
  v63 = 15;
  v62 = 0;
  LOBYTE(Src) = 0;
  sub_850C1E0((int)&Src, "207990f83c61d088201133343f06b299", 0x20u);
  LOBYTE(v64) = 12;
  v25 = (*(int (__stdcall **)(int *))(*(_DWORD *)v57 + 4))((int *)&Src);
  v58 = sub_86E6260(v25);
  LOBYTE(v64) = 0;
  if ( v63 >= 0x10 )
    operator delete(Src);
  if ( v55 & 0xFFFFC001 )
  {
    if ( dword_8949F54 <= 2 )
      sub_86E5C20(2, "CognitivDetectionG2: parameterSanityCheck failed. Invalid active action(s).", v52);
    return 774;
  }
  if ( ((v55
       + ((v55 - ((v55 >> 1) & 0x77777777) - ((v55 >> 2) & 0x33333333) - ((v55 >> 3) & 0x11111111)) >> 4)
       - ((v55 >> 1) & 0x77777777)
       - ((v55 >> 2) & 0x33333333)
       - ((v55 >> 3) & 0x11111111)) & 0xF0F0F0F)
     % 0xFF > v58 )
  {
    if ( dword_8949F54 <= 2 )
      sub_86E5C20(2, "CognitivDetectionG2: parameterSanityCheck failed. Max active actions reached.", v52);
    v19 = 775;
  }
  else
  {
LABEL_138:
    v26 = *(_DWORD *)(a2 + 16);
    if ( *(_DWORD *)(a2 + 20) < 0x10u )
      v27 = a2;
    else
      v27 = *(_DWORD *)a2;
    v28 = 32;
    if ( v26 < 0x20 )
      v28 = *(_DWORD *)(a2 + 16);
    v29 = sub_8519A70(v27, "1b67a98380453cedca92592b3428a418", v28);
    v30 = v29 == 0;
    if ( !v29 )
    {
      if ( v26 >= 0x20 )
        v31 = v26 != 32;
      else
        v31 = -1;
      v30 = v31 == 0;
    }
    if ( v30 )
    {
      v59 = sub_86E6260(a3);
      v63 = 15;
      v62 = 0;
      LOBYTE(Src) = 0;
      sub_850C1E0((int)&Src, "1b67a98380453cedca92592b3428a418", 0x20u);
      LOBYTE(v64) = 13;
      v32 = (*(int (__stdcall **)(void **))(*(_DWORD *)v57 + 4))(&Src);
      v33 = sub_86E6260(v32);
      LOBYTE(v64) = 0;
      if ( v63 >= 0x10 )
        operator delete(Src);
      switch ( v59 )
      {
        case 0:
          if ( v33 != 1 )
            goto LABEL_99;
          if ( dword_8949F54 > 2 )
            goto LABEL_95;
          sub_86E5C20(
            2,
            "%s %s",
            (unsigned int)"CognitivDetectionG2: parameterSanityCheck failed. Unexpected training control flag:");
          return 773;
        case 1:
          if ( v33 == 1 )
          {
            if ( dword_8949F54 > 2 )
            {
LABEL_95:
              v19 = 773;
            }
            else
            {
              sub_86E5C20(
                2,
                "%s %s",
                (unsigned int)"CognitivDetectionG2: parameterSanityCheck failed. Unexpected training control flag:");
              v19 = 773;
            }
          }
          else
          {
            sub_850B460((int)&Src, "2f862bcdcbeffd69eb4a6f84c0f1e69b");
            LOBYTE(v64) = 14;
            v34 = (*(int (__stdcall **)(void **))(*(_DWORD *)v57 + 4))(&Src);
            v35 = sub_86E6260(v34);
            LOBYTE(v64) = 0;
            v36 = v35 | 1;
            sub_850B5D0(&Src);
            sub_850B460((int)&v60, "34bd287fcda21853efba287688db0c4d");
            LOBYTE(v64) = 15;
            v37 = (*(int (__stdcall **)(int *))(*(_DWORD *)v57 + 4))(&v60);
            v38 = sub_86E6260(v37);
            LOBYTE(v64) = 0;
            sub_850B5D0(&v60);
            if ( v38 & v36 )
              goto LABEL_99;
            if ( dword_8949F54 <= 2 )
              sub_86E5C20(
                2,
                "%s %d",
                (unsigned int)"CognitivDetectionG2: parameterSanityCheck failed. Unexpected training action:");
            v19 = 772;
          }
          break;
        case 2:
        case 3:
          if ( v33 == 1 )
            goto LABEL_99;
          if ( dword_8949F54 > 2 )
            goto LABEL_95;
          sub_86E5C20(
            2,
            "%s %s",
            (unsigned int)"CognitivDetectionG2: parameterSanityCheck failed. Unexpected training control flag:");
          return 773;
        case 4:
          if ( !v33 )
            goto LABEL_99;
          if ( dword_8949F54 <= 2 )
            sub_86E5C20(
              2,
              "%s %s",
              (unsigned int)"CognitivDetectionG2: parameterSanityCheck failed. Unexpected training control flag:");
          goto LABEL_95;
        case 5:
          goto LABEL_99;
        default:
          if ( dword_8949F54 <= 2 )
            sub_86E5C20(2, "CognitivDetectionG2: parameterSanityCheck failed. Unknown training control parameter.", v52);
          return 773;
      }
    }
    else
    {
LABEL_99:
      v39 = *(_DWORD *)(a2 + 16);
      if ( *(_DWORD *)(a2 + 20) < 0x10u )
        v40 = a2;
      else
        v40 = *(_DWORD *)a2;
      v41 = 32;
      if ( v39 < 0x20 )
        v41 = *(_DWORD *)(a2 + 16);
      v42 = sub_8519A70(v40, "98ec7f4c8199a7096deb25f48034a60c", v41);
      if ( v42 || v39 < 0x20 || (LOBYTE(v42) = v39 != 32, v42) || (unsigned int)sub_86E6260(a3) <= 1 )
      {
        v43 = *(_DWORD *)(a2 + 16);
        if ( *(_DWORD *)(a2 + 20) < 0x10u )
          v44 = a2;
        else
          v44 = *(_DWORD *)a2;
        v45 = 32;
        if ( v43 < 0x20 )
          v45 = *(_DWORD *)(a2 + 16);
        v46 = sub_8519A70(v44, "bf67cdf1c3362bbe1846a77ea067483e", v45);
        if ( v46 || v43 < 0x20 || (LOBYTE(v46) = v43 != 32, v46) || sub_86E6260(a3) >= 0 )
        {
          v47 = *(_DWORD *)(a2 + 16);
          if ( *(_DWORD *)(a2 + 20) >= 0x10u )
            v4 = *(_DWORD *)a2;
          if ( v47 < 0x20 )
            v20 = *(_DWORD *)(a2 + 16);
          v48 = sub_8519A70(v4, "824180e25489bf4935865cc05377f606", v20);
          if ( v48 || v47 < 0x20 || (LOBYTE(v48) = v47 != 32, v48) )
          {
            v19 = 0;
          }
          else if ( (*(int (**)(void))(*(_DWORD *)v53 + 20))() )
          {
            v19 = 1;
          }
          else
          {
            v19 = 2304;
          }
        }
        else
        {
          v19 = 769;
        }
      }
      else
      {
        v19 = 770;
      }
    }
  }
  return v19;
}

Comment: Though I don't think its entirely relevant, it has some interesting features, and shows a small piece of the core code.

minifiredragon commented 7 years ago

I think that code is what is used to draw the graphs. It repeats in the loop x number of times equal to i think 500ms as it looks like it prints half a second to the display.

warrenarea commented 7 years ago

its a little more slow going than i thought, still looking for that function that explains it all. think i'm pretty close though.... seen a few functions that look pretty promising.

double checking them though. I decided I might take another approach, and went back to looking at the "old" v2.0 Emotiv Control Panel.

Figured it might be easier to pin point it there, and then go back to the new one.

Though I am noticing some key differences, kind of like some of the functions were renamed, and modularized and the code a bit more organized in the Xavier version. So although I might be able to pin point the general structure of the old version, the functions will likely be slightly re-arranged.

warrenarea commented 7 years ago

Signal Quality

int __thiscall sub_13CA090(void *this)
{
  void *v1; // edi@1
  signed __int32 v2; // edx@1
  QString *v3; // ebx@1
  signed int v4; // esi@1
  int v5; // eax@1
  int v6; // edx@2
  int v7; // edx@2
  int v8; // edx@3
  const struct QString *v9; // eax@12
  const struct QString *v10; // eax@12
  char *v11; // ecx@12
  const struct QString *v12; // eax@13
  const struct QString *v13; // eax@13
  const struct QString *v14; // eax@14
  const struct QString *v15; // eax@14
  const struct QString *v16; // eax@15
  const struct QString *v17; // eax@15
  const struct QString *v18; // eax@16
  const struct QString *v19; // eax@16
  const struct QString *v20; // eax@17
  const struct QString *v21; // eax@17
  const char *v22; // ecx@18
  QString *v23; // ecx@18
  QString *v25; // [sp-4h] [bp-5Ch]@18
  const char *v26; // [sp+0h] [bp-58h]@3
  char v27; // [sp+14h] [bp-44h]@17
  char v28; // [sp+18h] [bp-40h]@17
  char v29; // [sp+1Ch] [bp-3Ch]@16
  char v30; // [sp+20h] [bp-38h]@16
  char v31; // [sp+24h] [bp-34h]@15
  char v32; // [sp+28h] [bp-30h]@15
  char v33; // [sp+2Ch] [bp-2Ch]@14
  char v34; // [sp+30h] [bp-28h]@14
  char v35; // [sp+34h] [bp-24h]@13
  char v36; // [sp+38h] [bp-20h]@13
  char v37; // [sp+3Ch] [bp-1Ch]@12
  char v38; // [sp+40h] [bp-18h]@12
  int v39; // [sp+44h] [bp-14h]@1
  int v40; // [sp+48h] [bp-10h]@1
  int v41; // [sp+54h] [bp-4h]@1

  v1 = this;
  v39 = QString::shared_null;
  v2 = _InterlockedExchangeAdd(QString::shared_null, 1u);
  v41 = 0;
  v40 = QString::shared_null;
  _InterlockedExchangeAdd(QString::shared_null, 1u);
  LOBYTE(v41) = 1;
  v3 = (this + 64);
  v4 = 0;
  v5 = this + 60;
  do
  {
    QString::operator=(v5, v2, "image:url(:/Resources/Sensorsignal/");
    QString::operator=(v3, v6, "image:url(:/Resources/Sensorsignal/");
    switch ( v4 )
    {
      case 0:
        QString::operator=(&v39, v7, "F3");
        v26 = "sF3";
        goto LABEL_8;
      case 1:
        QString::operator=(&v39, v7, "F4");
        v26 = "sF4";
        goto LABEL_8;
      case 2:
        QString::operator=(&v39, v7, "T7");
        v26 = "sT7";
        goto LABEL_8;
      case 3:
        QString::operator=(&v39, v7, "T8");
        v26 = "sT8";
        goto LABEL_8;
      case 4:
        QString::operator=(&v39, v7, "Pz");
        v26 = &off_1624340;
LABEL_8:
        QString::operator=(&v40, v8, v26);
        break;
      default:
        break;
    }
    QString::append((v1 + 60), &v39);
    QString::append(v3, &v40);
    if ( !*(v1 + 28) )
      *(v1 + v4 + 10) = 0;
    switch ( *(v1 + v4 + 10) )
    {
      case 0:
        v9 = QString::fromAscii(&v38, "Black.png);", -1);
        LOBYTE(v41) = 2;
        QString::append((v1 + 60), v9);
        LOBYTE(v41) = 1;
        QString::~QString(&v38);
        v10 = QString::fromAscii(&v37, "Black.png);", -1);
        LOBYTE(v41) = 3;
        QString::append(v3, v10);
        v11 = &v37;
        break;
      case 1:
        v12 = QString::fromAscii(&v36, "Red.png);", -1);
        LOBYTE(v41) = 4;
        QString::append((v1 + 60), v12);
        LOBYTE(v41) = 1;
        QString::~QString(&v36);
        v13 = QString::fromAscii(&v35, "Red.png);", -1);
        LOBYTE(v41) = 5;
        QString::append(v3, v13);
        v11 = &v35;
        break;
      case 2:
        v14 = QString::fromAscii(&v34, "Orange.png);", -1);
        LOBYTE(v41) = 6;
        QString::append((v1 + 60), v14);
        LOBYTE(v41) = 1;
        QString::~QString(&v34);
        v15 = QString::fromAscii(&v33, "Red.png);", -1);
        LOBYTE(v41) = 7;
        QString::append(v3, v15);
        v11 = &v33;
        break;
      case 3:
        v16 = QString::fromAscii(&v32, "Orange.png);", -1);
        LOBYTE(v41) = 8;
        QString::append((v1 + 60), v16);
        LOBYTE(v41) = 1;
        QString::~QString(&v32);
        v17 = QString::fromAscii(&v31, "Orange.png);", -1);
        LOBYTE(v41) = 9;
        QString::append(v3, v17);
        v11 = &v31;
        break;
      case 4:
        v18 = QString::fromAscii(&v30, "Green.png);", -1);
        LOBYTE(v41) = 10;
        QString::append((v1 + 60), v18);
        LOBYTE(v41) = 1;
        QString::~QString(&v30);
        v19 = QString::fromAscii(&v29, "Green.png);", -1);
        LOBYTE(v41) = 11;
        QString::append(v3, v19);
        v11 = &v29;
        break;
      default:
        v20 = QString::fromAscii(&v28, "Black.png);", -1);
        LOBYTE(v41) = 12;
        QString::append((v1 + 60), v20);
        LOBYTE(v41) = 1;
        QString::~QString(&v28);
        v21 = QString::fromAscii(&v27, "Black.png);", -1);
        LOBYTE(v41) = 13;
        QString::append(v3, v21);
        v11 = &v27;
        break;
    }
    LOBYTE(v41) = 1;
    QString::~QString(v11);
    v26 = v22;
    v25 = v3;
    QString::QString(&v26);
    sub_13C9BD0(v4, v25);
    v25 = v23;
    QString::QString(&v25);
    sub_13C9B30(v4++, v25);
    v5 = v1 + 60;
  }
  while ( v4 < 5 );
  LOBYTE(v41) = 0;
  QString::~QString(&v40);
  v41 = -1;
  return QString::~QString(&v39);
}
warrenarea commented 7 years ago

Some sort of main thread. Could be useful in seeing what order the functions are initiated. Might look further into the "data acquisition" function.

int __cdecl sub_13E41C0(int a1, int a2, void *a3)
{
  void **v4; // eax@6
  void *v5; // eax@9
  int v6; // ebx@9
  int v7; // ecx@15
  int v8; // eax@17
  int v9; // ecx@19
  int v10; // eax@21
  int v11; // ecx@24
  char *v12; // eax@30
  int v13; // esi@32
  int v14; // eax@35
  int v15; // eax@52
  int v16; // eax@53
  void *v17; // eax@54
  int v18; // ecx@55
  int v19; // eax@58
  void *v20; // eax@62
  int *v21; // esi@63
  int v22; // ecx@66
  int v23; // eax@68
  int v24; // edx@68
  int v25; // eax@68
  int v26; // edx@68
  char v27; // al@68
  int v28; // eax@69
  int v29; // edx@69
  int v30; // eax@71
  int v31; // edx@71
  int v32; // eax@73
  int v33; // edx@73
  int v34; // eax@75
  int v35; // edx@75
  int v36; // eax@76
  int v37; // edx@76
  char v38; // al@76
  int v39; // eax@77
  int v40; // edx@77
  int v41; // eax@79
  int v42; // edx@79
  int v43; // eax@81
  int v44; // edx@81
  int v45; // eax@83
  int v46; // edx@83
  int v47; // eax@87
  int v48; // edx@87
  int v49; // eax@88
  int v50; // edx@88
  void *v51; // eax@88
  int v52; // ecx@89
  char v53; // [sp+14h] [bp-BCh]@19
  __int128 v54; // [sp+18h] [bp-B8h]@19
  int v55; // [sp+28h] [bp-A8h]@19
  char v56; // [sp+2Ch] [bp-A4h]@15
  void *v57; // [sp+30h] [bp-A0h]@15
  int v58; // [sp+34h] [bp-9Ch]@15
  __int128 v59; // [sp+38h] [bp-98h]@15
  int v60; // [sp+48h] [bp-88h]@1
  char v61; // [sp+58h] [bp-78h]@4
  char **v62; // [sp+5Ch] [bp-74h]@30
  char v63; // [sp+64h] [bp-6Ch]@28
  char v64; // [sp+65h] [bp-6Bh]@29
  char v65; // [sp+69h] [bp-67h]@68
  char v66; // [sp+6Ch] [bp-64h]@66
  void *v67; // [sp+90h] [bp-40h]@18
  int v68; // [sp+94h] [bp-3Ch]@7
  void **v69; // [sp+98h] [bp-38h]@6
  void *v70; // [sp+9Ch] [bp-34h]@23
  void *v71[2]; // [sp+A0h] [bp-30h]@1
  int v72; // [sp+B4h] [bp-1Ch]@4
  unsigned int v73; // [sp+B8h] [bp-18h]@4
  int *v74; // [sp+C0h] [bp-10h]@1
  int v75; // [sp+CCh] [bp-4h]@1

  v74 = &v60;
  v71[0] = a3;
  v75 = 0;
  if ( !a1 && !sub_13EED30(a2) )
    return a1 + 2;
  sub_14A8950(&v61);
  LOBYTE(v75) = 1;
  v73 = 15;
  v72 = 0;
  LOBYTE(v71[1]) = 0;
  sub_136C1E0(&v71[1], "edk.cfg", 7u);
  LOBYTE(v75) = 2;
  sub_14A99B0(&v71[1]);
  LOBYTE(v75) = 1;
  if ( v73 >= 0x10 )
    operator delete(v71[1]);
  v4 = operator new(0x10u);
  v69 = v4;
  LOBYTE(v75) = 3;
  if ( v4 )
    v68 = sub_154B840(v4);
  else
    v68 = 0;
  LOBYTE(v75) = 1;
  v5 = operator new(0x28u);
  v6 = v5;
  if ( v5 )
  {
    *(v5 + 8) = xmmword_16BDE30;
    *v5 = &off_16BCEB4;
    *(v5 + 6) = 0;
    *(v5 + 7) = 0;
    *(v5 + 8) = 0;
  }
  else
  {
    v6 = 0;
  }
  if ( a1 != 1 )
  {
    if ( a1 == 2 )
    {
      v70 = operator new(0x300u);
      LOBYTE(v75) = 7;
      if ( v70 )
        v11 = sub_13DF780(2, 0);
      else
        v11 = 0;
      LOBYTE(v75) = 1;
      dword_17D348C = v11;
      if ( v11 )
        (*(*v6 + 72))(v6, v11);
      goto LABEL_62;
    }
    if ( !v63 || !v64 )
    {
      if ( DWORD2(xmmword_17A8708) == 2 )
      {
        if ( (DWORD1(xmmword_17A8708) - 2) > 2 )
        {
          if ( dword_17A9F54 <= 3 )
          {
            DWORD3(v59) = DWORD1(xmmword_17A8708);
            sub_1545C20(3, "%s [%d]", "EE_EngineConnect : unknown board type");
          }
        }
        else if ( xmmword_17A8708 == 2 )
        {
          v70 = operator new(0x88u);
          LOBYTE(v75) = 8;
          if ( v70 )
          {
            v15 = sub_13E03B0(xmmword_16BDE20, *(&xmmword_16BDE20 + 1));
            LOBYTE(v75) = 1;
            (*(*v6 + 72))(v6, v15);
          }
          else
          {
            v16 = *v6;
            LOBYTE(v75) = 1;
            (*(v16 + 72))(v6, 0);
          }
        }
        else
        {
          v17 = operator new(0x40u);
          if ( v17 )
            v18 = sub_13E1610(v17, xmmword_16BDE20, *(&xmmword_16BDE20 + 1));
          else
            v18 = 0;
          (*(*v6 + 72))(v6, v18);
          if ( operator new(0x38u) )
          {
            v19 = sub_13E15B0(xmmword_16BDE20, *(&xmmword_16BDE20 + 1));
            (*(*v6 + 72))(v6, v19);
          }
          else
          {
            (*(*v6 + 72))(v6, 0);
          }
        }
      }
      goto LABEL_62;
    }
    v12 = *v62;
    for ( v71[0] = *v62; ; v12 = v71[0] )
    {
      while ( 1 )
      {
        if ( v12 == v62 )
          goto LABEL_62;
        v13 = (v12 + 40);
        v69 = 0;
        if ( *(v12 + 14) )
          break;
LABEL_47:
        sub_13F7DA0(v71);
        v12 = v71[0];
      }
      if ( dword_17A9F54 <= 0 )
      {
        if ( *(v12 + 15) < 0x10u )
          v14 = (v12 + 40);
        else
          v14 = *v13;
        DWORD3(v59) = v14;
        sub_1545C20(0, "%s [%s] ...", "EE_EngineConnect : Loading file");
      }
      if ( !sub_149C590(v13, v68, &v69) )
      {
        if ( dword_17A9F54 <= 0 )
        {
          if ( *(v13 + 20) >= 0x10u )
            v13 = *v13;
          DWORD3(v59) = v13;
          sub_1545C20(0, "%s [%s]", "EE_EngineConnect : Error loading profile ");
        }
        goto LABEL_47;
      }
      if ( dword_17A9F54 > 0 )
        goto LABEL_47;
      if ( *(v13 + 20) >= 0x10u )
        v13 = *v13;
      *(&v59 + 1) = __PAIR__("has been loaded.", v13);
      sub_1545C20(0, "%s [%s] %s", "EE_EngineConnect : Profile ");
      sub_13F7DA0(v71);
    }
  }
  if ( byte_17A86B8 )
  {
    v69 = operator new(0x3D8u);
    LOBYTE(v75) = 4;
    if ( v69 )
    {
      *(&v59 + 1) = 15i64;
      DWORD1(v59) = 0;
      v56 = 0;
      sub_136C0C0(&v56, v71[0], 0, 0xFFFFFFFF);
      v7 = sub_13DF3A0(
             a2,
             1,
             xmmword_16BDE30,
             *(&xmmword_16BDE30 + 1),
             0,
             *&v56,
             v57,
             v58,
             v59,
             SDWORD1(v59),
             SDWORD2(v59),
             SDWORD3(v59));
    }
    else
    {
      v7 = 0;
    }
    dword_17D3488 = v7;
    v8 = *v6;
    DWORD3(v59) = v7;
    LOBYTE(v75) = 1;
    (*(v8 + 72))(v6, v7);
  }
  else
  {
    v67 = operator new(0x300u);
    LOBYTE(v75) = 5;
    if ( v67 )
    {
      v69 = &v57;
      sub_136B460(&v57, Memory);
      *&v56 = 0;
      LOBYTE(v75) = 6;
      v55 = 15;
      DWORD3(v54) = 0;
      v53 = 0;
      sub_136C0C0(&v53, v71[0], 0, 0xFFFFFFFF);
      LOBYTE(v75) = 5;
      v9 = sub_13DF080(
             a2,
             0,
             1,
             xmmword_16BDE30,
             *(&xmmword_16BDE30 + 1),
             0,
             *&v53,
             v54,
             SDWORD1(v54),
             SDWORD2(v54),
             SDWORD3(v54),
             v55,
             *&v56,
             v57,
             v58,
             v59,
             SDWORD1(v59),
             SDWORD2(v59),
             SDWORD3(v59));
    }
    else
    {
      v9 = 0;
    }
    dword_17D3490 = v9;
    v10 = *v6;
    DWORD3(v59) = v9;
    LOBYTE(v75) = 1;
    (*(v10 + 72))(v6, v9);
  }
LABEL_62:
  sub_149E320();
  v20 = operator new(0x88u);
  v70 = v20;
  LOBYTE(v75) = 9;
  if ( v20 )
    v21 = sub_14ACA30(v20);
  else
    v21 = 0;
  LOBYTE(v75) = 1;
  v70 = operator new(0x28u);
  LOBYTE(v75) = 10;
  if ( v70 )
  {
    v22 = sub_14ABD40(v21, &v66);
    v71[0] = v22;
  }
  else
  {
    v22 = 0;
    v71[0] = 0;
  }
  *(v22 + 25) = v65;
  LOBYTE(v75) = 1;
  v23 = sub_149D5A0("DataAcquisitionDetection");
  v24 = *v21;
  DWORD3(v59) = v23;
  (*(v24 + 100))(v21, v23);
  v25 = sub_149D5A0("FFTDataDetection");
  v26 = *v21;
  DWORD3(v59) = v25;
  (*(v26 + 100))(v21, v25);
  v27 = dword_17A8618;
  if ( dword_17A8618 & 1 )
  {
    v28 = sub_149D5A0("BlinkWinkG3Detection");
    v29 = *v21;
    DWORD3(v59) = v28;
    (*(v29 + 100))(v21, v28);
    v27 = dword_17A8618;
  }
  if ( v27 & 2 )
  {
    v30 = sub_149D5A0("NTExpressivDetection");
    v31 = *v21;
    DWORD3(v59) = v30;
    (*(v31 + 100))(v21, v30);
    v27 = dword_17A8618;
  }
  if ( v27 & 4 )
  {
    v32 = sub_149D5A0("HorizontalEyeDetection");
    v33 = *v21;
    DWORD3(v59) = v32;
    (*(v33 + 100))(v21, v32);
    v27 = dword_17A8618;
  }
  if ( v27 & 8 )
  {
    v34 = sub_149D5A0("ExciteIntegrateDetection");
    v35 = *v21;
    DWORD3(v59) = v34;
    (*(v35 + 100))(v21, v34);
  }
  v36 = sub_149D5A0("SignalQualityDetection");
  v37 = *v21;
  DWORD3(v59) = v36;
  (*(v37 + 100))(v21, v36);
  v38 = dword_17A8618;
  if ( dword_17A8618 & 0x200 )
  {
    v39 = sub_149D5A0("CognitivDetectionG2");
    v40 = *v21;
    DWORD3(v59) = v39;
    (*(v40 + 100))(v21, v39);
    v38 = dword_17A8618;
  }
  if ( v38 & 0x10 )
  {
    v41 = sub_149D5A0("EngagementBoredomDetection");
    v42 = *v21;
    DWORD3(v59) = v41;
    (*(v42 + 100))(v21, v41);
    v38 = dword_17A8618;
  }
  if ( v38 & 0x20 )
  {
    v43 = sub_149D5A0("MeditationDetection");
    v44 = *v21;
    DWORD3(v59) = v43;
    (*(v44 + 100))(v21, v43);
    v38 = dword_17A8618;
  }
  if ( v38 & 0x40 )
  {
    v45 = sub_149D5A0("ValenceDetection");
    v46 = *v21;
    DWORD3(v59) = v45;
    (*(v46 + 100))(v21, v45);
    v38 = dword_17A8618;
  }
  if ( xmmword_17A8708 != 3 && xmmword_17A8708 != 4 && v38 < 0 )
  {
    v47 = sub_149D5A0("FrustrationDetection");
    v48 = *v21;
    DWORD3(v59) = v47;
    (*(v48 + 100))(v21, v47);
  }
  v49 = sub_149D5A0("BatteryDetection");
  v50 = *v21;
  DWORD3(v59) = v49;
  (*(v50 + 100))(v21, v49);
  v51 = operator new(0xE10u);
  v70 = v51;
  LOBYTE(v75) = 11;
  if ( v51 )
    v52 = sub_14A2360(v51, v6, v68, v71[0]);
  else
    v52 = 0;
  LOBYTE(v75) = 1;
  dword_17D3494 = v52;
  if ( dword_17D3488 )
  {
    sub_14A75D0(dword_17D3488);
    v52 = dword_17D3494;
  }
  (*(*v52 + 64))();
  LOBYTE(v75) = 0;
  sub_14A9220(&v61);
  return 0;
}
warrenarea commented 7 years ago

Signal Quality for Insight.

Not entirely sure how useful this will be. Probably more to this function.

int __thiscall sub_140A460(QWidget **this, QObject *a2)
{
  QWidget **v2; // edi@1
  bool v3; // bl@1
  const struct QString *v4; // eax@2
  const struct QString *v5; // eax@3
  _DWORD *v6; // esi@3
  const struct QString *v7; // eax@6
  QObject *v8; // ecx@6
  QWidget *v9; // ecx@6
  const struct QString *v10; // eax@6
  QWidget *v11; // ecx@6
  int v12; // eax@7
  const struct QString *v13; // eax@9
  QObject *v14; // ecx@9
  QWidget *v15; // ecx@9
  const struct QString *v16; // eax@9
  QWidget *v17; // ecx@9
  int v18; // eax@10
  const struct QString *v19; // eax@12
  QObject *v20; // ecx@12
  QWidget *v21; // ecx@12
  const struct QString *v22; // eax@12
  QWidget *v23; // ecx@12
  int v24; // eax@13
  const struct QString *v25; // eax@15
  QObject *v26; // ecx@15
  QWidget *v27; // ecx@15
  const struct QString *v28; // eax@15
  QWidget *v29; // ecx@15
  int v30; // eax@16
  const struct QString *v31; // eax@18
  QObject *v32; // ecx@18
  QWidget *v33; // ecx@18
  const struct QString *v34; // eax@18
  QWidget *v35; // ecx@18
  int v36; // eax@19
  const struct QString *v37; // eax@21
  QObject *v38; // ecx@21
  QWidget *v39; // ecx@21
  const struct QString *v40; // eax@21
  QWidget *v41; // ecx@21
  int v42; // eax@22
  const struct QString *v43; // eax@24
  QObject *v44; // ecx@24
  QWidget *v45; // ecx@24
  const struct QString *v46; // eax@24
  QWidget *v47; // ecx@24
  int v48; // eax@25
  const struct QString *v49; // eax@27
  QObject *v50; // ecx@27
  QWidget *v51; // ecx@27
  const struct QString *v52; // eax@27
  QWidget *v53; // ecx@27
  int v54; // eax@28
  const struct QString *v55; // eax@30
  QObject *v56; // ecx@30
  QWidget *v57; // ecx@30
  const struct QString *v58; // eax@30
  QWidget *v59; // ecx@30
  int v60; // eax@31
  const struct QString *v61; // eax@33
  QObject *v62; // ecx@33
  QWidget *v63; // ecx@33
  const struct QString *v64; // eax@33
  QWidget *v65; // ecx@33
  int v66; // eax@34
  const struct QString *v67; // eax@36
  QObject *v68; // ecx@36
  QWidget *v69; // ecx@36
  const struct QString *v70; // eax@36
  QWidget *v71; // ecx@36
  int v72; // eax@37
  const struct QString *v73; // eax@39
  QObject *v74; // ecx@39
  QWidget *v75; // ecx@39
  const struct QString *v76; // eax@39
  QWidget *v77; // ecx@39
  int v78; // eax@40
  const struct QString *v79; // eax@42
  QObject *v80; // ecx@42
  QWidget *v81; // ecx@42
  const struct QString *v82; // eax@42
  QWidget *v83; // ecx@42
  char v85; // [sp+10h] [bp-28h]@9
  _DWORD *v86; // [sp+18h] [bp-20h]@3
  __int128 v87; // [sp+1Ch] [bp-1Ch]@1
  int v88; // [sp+34h] [bp-4h]@2

  v2 = this;
  v3 = *(*QObject::objectName(a2, &v87 + 12) + 8) == 0;
  QString::~QString((&v87 + 12));
  if ( v3 )
  {
    v4 = QString::fromUtf8(&v87 + 12, "SignalQualityInsight", -1);
    v88 = 0;
    QObject::setObjectName(a2, v4);
    v88 = -1;
    QString::~QString((&v87 + 12));
  }
  *(&v87 + 1) = 987842478280i64;
  QWidget::resize(a2, (&v87 + 8));
  v5 = QString::fromUtf8(&v87 + 12, "background-image: none;", -1);
  v88 = 1;
  QWidget::setStyleSheet(a2, v5);
  v88 = -1;
  QString::~QString((&v87 + 12));
  v6 = operator new(0x14u);
  v86 = v6;
  v88 = 2;
  if ( v6 )
  {
    QWidget::QWidget(a2, 0);
    *v6 = &off_165CFAC;
    v6[2] = &off_165D078;
  }
  else
  {
    v6 = 0;
  }
  v88 = -1;
  *v2 = v6;
  v7 = QString::fromUtf8(&v87 + 12, "s_sensorCQ", -1);
  v8 = *v2;
  v88 = 3;
  QObject::setObjectName(v8, v7);
  v88 = -1;
  QString::~QString((&v87 + 12));
  v9 = *v2;
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664640));
  QWidget::setGeometry(v9, &v87);
  v10 = QString::fromUtf8(&v87 + 12, "image:url(:/image/image/Sensorsignal/sheadsignal.png);", -1);
  v11 = *v2;
  v88 = 4;
  QWidget::setStyleSheet(v11, v10);
  v88 = -1;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  v88 = 5;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(*v2, 0);
    v12 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v12 + 8) = &off_1659268;
  }
  else
  {
    v12 = 0;
  }
  v2[1] = v12;
  v88 = -1;
  v13 = QString::fromUtf8(&v87 + 12, "sF3", -1);
  v14 = v2[1];
  v88 = 6;
  QObject::setObjectName(v14, v13);
  v88 = -1;
  QString::~QString((&v87 + 12));
  v15 = v2[1];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664600));
  QWidget::setGeometry(v15, &v87);
  QFont::QFont(&v85);
  v88 = 7;
  QFont::setPointSize(&v85, 9);
  QFont::setWeight(&v85, 75);
  QFont::setWeight(&v85, 75);
  QWidget::setFont(v2[1], &v85);
  v16 = QString::fromUtf8(&v87 + 12, "\nbackground-image: url(:/Resources/SetUpWidget/Sensorsignal/sF3Black.png);", -1);
  v17 = v2[1];
  LOBYTE(v88) = 8;
  QWidget::setStyleSheet(v17, v16);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 9;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(*v2, 0);
    v18 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v18 + 8) = &off_1659268;
  }
  else
  {
    v18 = 0;
  }
  v2[2] = v18;
  LOBYTE(v88) = 7;
  v19 = QString::fromUtf8(&v87 + 12, "sF4", -1);
  v20 = v2[2];
  LOBYTE(v88) = 10;
  QObject::setObjectName(v20, v19);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v21 = v2[2];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664610));
  QWidget::setGeometry(v21, &v87);
  QWidget::setFont(v2[2], &v85);
  v22 = QString::fromUtf8(&v87 + 12, "image: url(:/Resources/SetUpWidget/Sensorsignal/sF4Black.png);", -1);
  v23 = v2[2];
  LOBYTE(v88) = 11;
  QWidget::setStyleSheet(v23, v22);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 12;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(*v2, 0);
    v24 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v24 + 8) = &off_1659268;
  }
  else
  {
    v24 = 0;
  }
  v2[3] = v24;
  LOBYTE(v88) = 7;
  v25 = QString::fromUtf8(&v87 + 12, "sT7", -1);
  v26 = v2[3];
  LOBYTE(v88) = 13;
  QObject::setObjectName(v26, v25);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v27 = v2[3];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664620));
  QWidget::setGeometry(v27, &v87);
  QWidget::setFont(v2[3], &v85);
  v28 = QString::fromUtf8(&v87 + 12, "image: url(:/Resources/SetUpWidget/Sensorsignal/sT7Black.png);", -1);
  v29 = v2[3];
  LOBYTE(v88) = 14;
  QWidget::setStyleSheet(v29, v28);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 15;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(*v2, 0);
    v30 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v30 + 8) = &off_1659268;
  }
  else
  {
    v30 = 0;
  }
  v2[4] = v30;
  LOBYTE(v88) = 7;
  v31 = QString::fromUtf8(&v87 + 12, "sT8", -1);
  v32 = v2[4];
  LOBYTE(v88) = 16;
  QObject::setObjectName(v32, v31);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v33 = v2[4];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664630));
  QWidget::setGeometry(v33, &v87);
  QWidget::setFont(v2[4], &v85);
  v34 = QString::fromUtf8(&v87 + 12, "image: url(:/Resources/SetUpWidget/Sensorsignal/sT8Black.png);", -1);
  v35 = v2[4];
  LOBYTE(v88) = 17;
  QWidget::setStyleSheet(v35, v34);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 18;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(*v2, 0);
    v36 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v36 + 8) = &off_1659268;
  }
  else
  {
    v36 = 0;
  }
  v2[5] = v36;
  LOBYTE(v88) = 7;
  v37 = QString::fromUtf8(&v87 + 12, &off_1664340, -1);
  v38 = v2[5];
  LOBYTE(v88) = 19;
  QObject::setObjectName(v38, v37);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v39 = v2[5];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664650));
  QWidget::setGeometry(v39, &v87);
  QWidget::setFont(v2[5], &v85);
  v40 = QString::fromUtf8(&v87 + 12, "image: url(:/Resources/SetUpWidget/Sensorsignal/sPzBlack.png);", -1);
  v41 = v2[5];
  LOBYTE(v88) = 20;
  QWidget::setStyleSheet(v41, v40);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 21;
  if ( DWORD3(v87) )
  {
    QWidget::QWidget(a2, 0);
    v42 = DWORD3(v87);
    *DWORD3(v87) = &off_165CFAC;
    *(v42 + 8) = &off_165D078;
  }
  else
  {
    v42 = 0;
  }
  v2[6] = v42;
  LOBYTE(v88) = 7;
  v43 = QString::fromUtf8(&v87 + 12, "sensorCQ", -1);
  v44 = v2[6];
  LOBYTE(v88) = 22;
  QObject::setObjectName(v44, v43);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v45 = v2[6];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_16646C0));
  QWidget::setGeometry(v45, &v87);
  v46 = QString::fromUtf8(&v87 + 12, "image:url(:/Resources/SetUpWidget/Sensorsignal/headsignal.png);", -1);
  v47 = v2[6];
  LOBYTE(v88) = 23;
  QWidget::setStyleSheet(v47, v46);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 24;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(v2[6], 0);
    v48 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v48 + 8) = &off_1659268;
  }
  else
  {
    v48 = 0;
  }
  v2[7] = v48;
  LOBYTE(v88) = 7;
  v49 = QString::fromUtf8(&v87 + 12, "sensorF3", -1);
  v50 = v2[7];
  LOBYTE(v88) = 25;
  QObject::setObjectName(v50, v49);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v51 = v2[7];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664660));
  QWidget::setGeometry(v51, &v87);
  v52 = QString::fromUtf8(&v87 + 12, "image:url(:/Resources/Sensorsignal/F3Black.png);", -1);
  v53 = v2[7];
  LOBYTE(v88) = 26;
  QWidget::setStyleSheet(v53, v52);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 27;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(v2[6], 0);
    v54 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v54 + 8) = &off_1659268;
  }
  else
  {
    v54 = 0;
  }
  v2[8] = v54;
  LOBYTE(v88) = 7;
  v55 = QString::fromUtf8(&v87 + 12, "sensorT7", -1);
  v56 = v2[8];
  LOBYTE(v88) = 28;
  QObject::setObjectName(v56, v55);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v57 = v2[8];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664690));
  QWidget::setGeometry(v57, &v87);
  v58 = QString::fromUtf8(&v87 + 12, "image:url(:/Resources/Sensorsignal/T7Black.png);", -1);
  v59 = v2[8];
  LOBYTE(v88) = 29;
  QWidget::setStyleSheet(v59, v58);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 30;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(v2[6], 0);
    v60 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v60 + 8) = &off_1659268;
  }
  else
  {
    v60 = 0;
  }
  v2[9] = v60;
  LOBYTE(v88) = 7;
  v61 = QString::fromUtf8(&v87 + 12, "sensorT8", -1);
  v62 = v2[9];
  LOBYTE(v88) = 31;
  QObject::setObjectName(v62, v61);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v63 = v2[9];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_16646A0));
  QWidget::setGeometry(v63, &v87);
  v64 = QString::fromUtf8(&v87 + 12, "image:url(:/Resources/Sensorsignal/T8Black.png);", -1);
  v65 = v2[9];
  LOBYTE(v88) = 32;
  QWidget::setStyleSheet(v65, v64);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 33;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(v2[6], 0);
    v66 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v66 + 8) = &off_1659268;
  }
  else
  {
    v66 = 0;
  }
  v2[10] = v66;
  LOBYTE(v88) = 7;
  v67 = QString::fromUtf8(&v87 + 12, "sensorF4", -1);
  v68 = v2[10];
  LOBYTE(v88) = 34;
  QObject::setObjectName(v68, v67);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v69 = v2[10];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664670));
  QWidget::setGeometry(v69, &v87);
  v70 = QString::fromUtf8(&v87 + 12, "image:url(:/Resources/Sensorsignal/F4Black.png);", -1);
  v71 = v2[10];
  LOBYTE(v88) = 35;
  QWidget::setStyleSheet(v71, v70);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 36;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(v2[6], 0);
    v72 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v72 + 8) = &off_1659268;
  }
  else
  {
    v72 = 0;
  }
  v2[11] = v72;
  LOBYTE(v88) = 7;
  v73 = QString::fromUtf8(&v87 + 12, "sensorPz", -1);
  v74 = v2[11];
  LOBYTE(v88) = 37;
  QObject::setObjectName(v74, v73);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v75 = v2[11];
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_16646B0));
  QWidget::setGeometry(v75, &v87);
  v76 = QString::fromUtf8(&v87 + 12, "image:url(:/Resources/Sensorsignal/PzBlack.png);", -1);
  v77 = v2[11];
  LOBYTE(v88) = 38;
  QWidget::setStyleSheet(v77, v76);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  DWORD3(v87) = operator new(0x14u);
  LOBYTE(v88) = 39;
  if ( DWORD3(v87) )
  {
    QLabel::QLabel(v2[6], 0);
    v78 = DWORD3(v87);
    *DWORD3(v87) = &off_165919C;
    *(v78 + 8) = &off_1659268;
  }
  else
  {
    v78 = 0;
  }
  v2[12] = v78;
  LOBYTE(v88) = 7;
  v79 = QString::fromUtf8(&v87 + 12, "sensorCMS", -1);
  v80 = v2[12];
  LOBYTE(v88) = 40;
  QObject::setObjectName(v80, v79);
  LOBYTE(v88) = 7;
  QString::~QString((&v87 + 12));
  v81 = v2[12];
  DWORD2(v87) = &v87;
  _mm_storeu_si128(&v87, _mm_load_si128(&xmmword_1664680));
  QWidget::setGeometry(v81, DWORD2(v87));
  v82 = QString::fromUtf8(&v86, "image:url(:/Resources/Sensorsignal/fr3.png);", -1);
  v83 = v2[12];
  LOBYTE(v88) = 41;
  QWidget::setStyleSheet(v83, v82);
  LOBYTE(v88) = 7;
  QString::~QString(&v86);
  QWidget::raise(v2[7]);
  QWidget::raise(v2[10]);
  QWidget::raise(v2[11]);
  QWidget::raise(v2[8]);
  QWidget::raise(v2[9]);
  QWidget::raise(v2[12]);
  QWidget::raise(v2[6]);
  QWidget::raise(*v2);
  sub_1409E00(a2);
  QMetaObject::connectSlotsByName(a2);
  v88 = -1;
  return QFont::~QFont(&v85);
}
warrenarea commented 7 years ago

void __thiscall sub_1498E80(int *this, int a2)
{
  int *v2; // ebx@1
  int v3; // ecx@1
  int v4; // ST14_4@1
  int v5; // eax@1
  int v6; // esi@1
  int v7; // edi@1
  signed int v8; // ebx@1
  signed int v9; // esi@2
  int v10; // esi@8
  char v11; // [sp+10h] [bp-2Ch]@1
  void *v12; // [sp+18h] [bp-24h]@9
  char v13; // [sp+1Ch] [bp-20h]@1
  int v14; // [sp+20h] [bp-1Ch]@1
  void *v15; // [sp+24h] [bp-18h]@7
  int v16; // [sp+28h] [bp-14h]@1
  int *v17; // [sp+2Ch] [bp-10h]@1
  int v18; // [sp+38h] [bp-4h]@1
  int v19; // [sp+44h] [bp+8h]@1

  v2 = this;
  v17 = this;
  sub_1304FC0(&v13, a2, 0, 0, 0, *(_DWORD *)(a2 + 4) - 1);
  v3 = *(_DWORD *)a2;
  v4 = *(_DWORD *)(a2 + 4) - 1;
  v18 = 0;
  sub_1304FC0(&v11, a2, 1, v3 - 1, 0, v4);
  v5 = *v2;
  v6 = v14;
  LOBYTE(v18) = 1;
  v16 = v14;
  v19 = (*(int (__thiscall **)(int *))(v5 + 84))(v2);
  v7 = 0;
  v8 = sub_14C7540(v19);
  if ( v6 > 0 )
  {
    do
    {
      v9 = 128;
      sub_14C76A0(v19);
      if ( sub_14C76A0(v19) == 2 )
      {
        if ( v8 == 128 )
        {
          v9 = 127;
        }
        else if ( v8 == 256 )
        {
          v9 = 255;
        }
      }
      sub_1307C40(0, v7);
      if ( (signed int)floor(*((double *)v15 + v7)) != v9 )
      {
        sub_1307C40(0, v7);
        v10 = (signed int)floor(*((double *)v15 + v7)) % (v8 / 2);
        if ( v10 < 14 )
        {
          sub_1307C40(0, v7);
          *(_QWORD *)&v17[2 * v10 + 20] = *((_QWORD *)v12 + v7);
        }
      }
      ++v7;
    }
    while ( v7 < v16 );
  }
  if ( v12 )
    operator delete[](v12);
  if ( v15 )
    operator delete[](v15);
}

This function is interesting, because i noticed it Floor's one of the values (brings it to integer) and then it performs a % division? the v8 was 128 which divided by 2, would then be 64.

obviously this would be some sort of binary math... this function looked promising because... when I set up a breakpoint, I got it to display just a segment of the data, before breaking. so could be getting closer. Though looking at the code alone, might be tough... without seeing what numbers are actually passing through the variables.... I can hover over some of them while its running and get results... but it can be a little slow going since some of the results are in hex, while others are in integers.

warrenarea commented 7 years ago

Also found the function for when the USB dongle is removed, but that's not entirely helpful here.

Emotiv Dongle Plus function, not helpful either, think that's just more HID functions.

Data Acquisition, really thought there would be something to that one, and it does have some unique data structures, but nothing really jumping out.... these decompilations are sort of helpful, but can still be confusing without some context.

ghost commented 7 years ago

v8 in that function could be the counter.

ghost commented 7 years ago
def quality(reference_class):
  offset? = (this + 64);
  sensor = 0;
  offset_2? = this + 60;
  for sensor in range(0, 5):
    if ( !*(reference_class.current_sensor_value + 28) )
    # if sensor value not positive after + 28 set lowest level.
     quality_value = reference_class.current_sensor_value + sensor + 10 = 0;
    switch (quality_value) 
         0:  Nothing,
         1: Worst,
         2: Bad,
         3: Better,
         4: Good
  # do_something_with_sensor_maybe_set_the_string(v4, v25);
  # v25 = v23;
  # QString::QString(&v25);
  # increment_current_sensor_and_or_something_else(v4++, v25);
ghost commented 7 years ago

sub_1307C40 <--- this function is important

ghost commented 7 years ago

sub_14C76A0 <-- this one too

ghost commented 7 years ago
void __thiscall sub_1498E80(int *this, int a2/length)
{
  int *v2; // ebx@1
  int v3; // ecx@1
  int v4; // ST14_4@1
  int v5; // eax@1
  int v6; // esi@1
  int v7; // edi@1
  signed int v8; // ebx@1
  signed int max_value; // esi@2
  int v10; // esi@8
  char v11; // [sp+10h] [bp-2Ch]@1
  void *v12; // [sp+18h] [bp-24h]@9 <--- interesting location
  char v13; // [sp+1Ch] [bp-20h]@1 <---
  int v14; // [sp+20h] [bp-1Ch]@1 ? What is this
  void *v15; // [sp+24h] [bp-18h]@7
  int v16; // [sp+28h] [bp-14h]@1
  int *v17; // [sp+2Ch] [bp-10h]@1
  int v18; // [sp+38h] [bp-4h]@1
  int v19; // [sp+44h] [bp+8h]@1

   v2 = this;
   v17 = this;
   sub_1304FC0(&v13, a2, 0, 0, 0, *(_DWORD *)(a2 + 4) - 1); <-- get character value at bytes/bits? assign to v13?
   v3_bytes = *(_DWORD *)length; <- length of bytes or initial value?
   v4_bytes = *(_DWORD *)(length + 4) - 1; <- length of bytes or initial value?
   v18 = 0;
   sub_1304FC0(&v11, length, 1, v3_bytes - 1, 0, v4_bytes); <-- get character value at bytes/bits? assign to v11?
    v5 = *v2;
    value_size = v14;
   LOBYTE(v18) = 1; ? Unused?
   max_size = v14; Max Bytes/Bits
    v19 = (*(int (__thiscall **)(int *))(v5 + 84))(v2);  ? call this function with 84 added to the first parameter and length is obviously not length then.
    current_bit/byte = 0;
    v8 = sub_14C7540(v19); # Detect speed/battery/extra precision/counter? headset version/mode?
    if ( value_size > 0 )
   {
        do
       {
       max_value = 128;  Max value
       sub_14C76A0(v19); Detect number of bytes?
       if ( sub_14C76A0(v19) == 2 ) 
       {
             if ( v8 == 128 )
             {
                 max_value = 127; # Max Value
             }
             else if ( v8 == 256 )
            {
                 max_value = 255; #  Max Value
            }
      }
  sub_1307C40(0, current_bit); <-- shift?
  # v15 == current value?
  if ( (signed int)floor(*((double *)v15 + current_bit)) != v9 ) # If current_value != max value or battery?
  {
    sub_1307C40(0, current_bit); <-- shift?
    v10 = (signed int)floor(*((double *)v15 + current_bit)) % --> (v8 / 2); <-- precision? 64 or 128 always maybe?
    if ( v10 < 14 ) # 14 is an interesting number old headset logic? some sensor, gyros? quality?
    {
         sub_1307C40(0, current_bit); <-- shift?
         *(_QWORD *)&v17[2 * v10 + 20] = *((_QWORD *)v12 + current_bit);
          Set some bytes to something plus the current bit?

        }
     }
     ++current_bit;
   }
    while ( current_bit < max_size );
  }
ghost commented 7 years ago

There definitely appears to be some juiciness in this function: sub_149D5A0

would like to see that.

CaptainSmileyXL commented 7 years ago

Is there anywhere I can see a few lines of raw output from the pure eeg program (even if they are screenshots)? There are references in some of the other threads to it's output and the values, I was just hoping I could see some as I play with the output of the various read functions from the Control Panel. And I apologize ahead of time if I have missed a post where this has already been addressed!!!

ghost commented 7 years ago

@drneuronerd https://github.com/openyou/emokit/files/923013/0002-0002-14.04.17-17.43.31.txt https://github.com/openyou/emokit/files/903185/emotiv_slight_edit.txt

warrenarea commented 7 years ago

Terrific news bill... it looks like i've discovered the function for Epoc Plus, that handles evaluating data quality.

warrenarea commented 7 years ago
int __thiscall sub_300260(int this, char a2, char a3, int a4)
{
  int v4; // edi@1
  _DWORD *v5; // eax@2
  _DWORD *v6; // eax@2
  int v7; // esi@2
  int v9; // eax@3
  int v10; // ecx@3
  unsigned int v11; // esi@3
  unsigned int v12; // eax@5
  int *v13; // ecx@10
  signed int v14; // esi@11
  _DWORD *v15; // eax@14
  int *v16; // edi@15
  _DWORD *v17; // eax@16
  int v18; // ebx@16
  int v19; // esi@17

  v4 = this;
  if ( *sub_2FD670((this + 504), &a3) )
  {
    v5 = sub_2FD670((v4 + 504), &a3);
    --*v5;
    v6 = sub_2FD670((v4 + 488), &a3);
    v7 = a4;
    *v6 = a4;
    *sub_2FD670((v4 + 496), &a3) = v7;
    return 0;
  }
  v9 = sub_2FD700(&a3);
  v10 = v9;
  v11 = *(v9 + 16);
  if ( *(v9 + 20) >= 0x10u )
  {
    v10 = *v9;
  }
  v12 = 8;
  if ( v11 < 8 )
  {
    v12 = v11;
  }
  if ( sub_159A70(v10, "EPOCPLUS", v12) || v11 < 8 || v11 != 8 )
  {
    v14 = 129;
  }
  else
  {
    v13 = (v4 + 472);
    if ( !a2 )
    {
      sub_2FD820(v13, &a3);
      v15 = sub_2FD820((v4 + 472), &a3);
      v14 = floor(round(
                    COERCE_UNSIGNED_INT64(*(*v15 + 8) * 0.03125),
                    COERCE_UNSIGNED_INT64(*(*v15 + 8) * 0.03125) >> 32) * 32.0);
      goto LABEL_15;
    }
    v14 = 256;
    if ( **sub_2FD820(v13, &a3) <= 128.0 )
    {
      v14 = 128;
    }
  }
  if ( a2 )
  {
    v16 = (v4 + 488);
    goto LABEL_16;
  }
LABEL_15:
  v16 = (v4 + 496);
LABEL_16:
  v17 = sub_2FD670(v16, &a3);
  v18 = a4;
  if ( a4 == *v17 )
  {
    v19 = -1;
  }
  else if ( v18 <= *sub_2FD670(v16, &a3) )
  {
    v19 = v18 + v14 - *sub_2FD670(v16, &a3) - 1;
  }
  else
  {
    v19 = v18 - *sub_2FD670(v16, &a3) - 1;
  }
  *sub_2FD670(v16, &a3) = v18;
  return v19;
}
warrenarea commented 7 years ago

I found this little nugget nested below some "data ACQ thread" in a double precision float.

its obviously some math dealing with Epoc Plus microvoltage, because its multiplaying by 0.03125 (i.e .031)

which is a little confusing now that i think about it, because they have been saying that the microvoltage is .13 not .31

warrenarea commented 7 years ago

there is even more math i believe that you will find useful... in the "data Acq thread"

warrenarea commented 7 years ago

what would be really helpful.... is if Minifiredragon could put a breakpoint in there... and look for the values being returned.

warrenarea commented 7 years ago

Data Acquisition Thread:


1. 
2. int *__thiscall sub_2FE5C0(_DWORD **this)
3. {
4.   _DWORD **v1; // ebx@1
5.   __m128d v2; // xmm0@1
6.   void (__stdcall ***v3)(_DWORD); // eax@2
7.   void (__thiscall ***v4)(_DWORD, _DWORD); // esi@2
8.   int v5; // eax@3
9.   int *result; // eax@4
10.   int *v7; // esi@4
11.   int v8; // eax@6
12.   int v9; // edi@19
13.   _DWORD *v10; // esi@19
14.   int v11; // eax@19
15.   _DWORD *v12; // ecx@22
16.   _DWORD *v13; // ecx@23
17.   _DWORD *v14; // ecx@23
18.   _DWORD *v15; // edx@23
19.   int *v16; // esi@23
20.   int v17; // ecx@25
21.   signed int v18; // edi@25
22.   int v19; // edx@27
23.   unsigned int v20; // ecx@28
24.   size_t v21; // ecx@29
25.   int v22; // edx@38
26.   unsigned int v23; // ecx@39
27.   unsigned int v24; // ecx@40
28.   int *v25; // edx@48
29.   int v26; // edi@50
30.   int v27; // edx@52
31.   unsigned int v28; // ecx@53
32.   size_t v29; // ecx@54
33.   int v30; // edx@63
34.   unsigned int v31; // ecx@64
35.   unsigned int v32; // ecx@65
36.   char *v33; // edx@73
37.   int v34; // edi@75
38.   int v35; // edx@77
39.   unsigned int v36; // ecx@78
40.   size_t v37; // ecx@79
41.   int v38; // edx@88
42.   unsigned int v39; // ecx@89
43.   unsigned int v40; // ecx@90
44.   void *v41; // eax@98
45.   char v42; // al@99
46.   _DWORD *v43; // ecx@101
47.   _DWORD *v44; // eax@101
48.   size_t v45; // edi@101
49.   void *v46; // eax@102
50.   void *v47; // esi@102
51.   size_t v48; // esi@106
52.   size_t *v49; // ecx@106
53.   size_t v50; // eax@107
54.   __int64 v51; // rax@115
55.   signed int v52; // eax@115
56.   signed int v53; // edi@115
57.   int v54; // edx@115
58.   int v55; // esi@115
59.   _DWORD **v56; // esi@115
60.   void *v57; // ebx@115
61.   int *v58; // ecx@115
62.   void *v59; // edi@115
63.   int v60; // eax@115
64.   double *v61; // esi@115
65.   _DWORD **v62; // ecx@115
66.   void *v63; // eax@122
67.   char v64; // si@123
68.   void (__stdcall ***v65)(_DWORD); // esi@131
69.   void *v66; // eax@134
70.   void *v67; // edi@134
71.   void *v68; // eax@137
72.   void *v69; // edi@137
73.   size_t v70; // eax@140
74.   int (*v71)(void); // edi@140
75.   __int64 v72; // rax@140
76.   int v73; // edi@142
77.   int v74; // eax@142
78.   void *v75; // eax@143
79.   char v76; // al@144
80.   _DWORD *v77; // ecx@146
81.   _DWORD *v78; // edx@146
82.   int v79; // eax@147
83.   _DWORD *v80; // ecx@148
84.   void *v81; // eax@150
85.   size_t v82; // edi@150
86.   unsigned int v83; // edi@153
87.   void *v85; // eax@164
88.   void *v86; // edi@164
89.   void *v87; // eax@167
90.   void *v88; // edi@167
91.   void *v89; // eax@170
92.   void *v90; // edi@170
93.   _DWORD *v91; // ecx@173
94.   __int64 v92; // rax@173
95.   int v93; // eax@173
96.   int v94; // edx@173
97.   unsigned int v95; // edi@173
98.   signed int v96; // eax@177
99.   _DWORD *v97; // eax@180
100.   __int128 v98; // xmm0@180
101.   double **v100; // eax@182
102.   _DWORD *v101; // eax@182
103.   int v102; // eax@183
104.   int *v103; // ecx@183
105.   double **v104; // eax@185
106.   double **v105; // eax@185
107.   double **v106; // eax@187
108.   _DWORD *v107; // eax@187
109.   int v108; // eax@191
110.   size_t v109; // edi@192
111.   void *v111; // eax@195
112.   double *v112; // edx@203
113.   int v113; // eax@204
114.   int v114; // ecx@204
115.   void *v115; // eax@204
116.   size_t v116; // eax@205
117.   int v117; // edx@207
118.   int v118; // eax@207
119.   _DWORD *v119; // ecx@209
120.   int v120; // eax@211
121.   size_t v121; // edi@213
122.   char *headsetType; // ecx@215
123.   unsigned int v123; // edi@215
124.   unsigned int v124; // edx@217
125.   const char *v125; // edi@220
126.   unsigned int v126; // edx@220
127.   bool v127; // cf@224
128.   unsigned __int8 v128; // al@226
129.   unsigned __int8 v129; // al@228
130.   unsigned __int8 v130; // al@230
131.   int v131; // eax@231
132.   bool v132; // zf@233
133.   signed int v133; // eax@236
134.   void *v134; // eax@240
135.   void *v135; // eax@244
136.   char v136; // al@245
137.   _DWORD *v137; // ecx@247
138.   int v138; // eax@247
139.   int v139; // ecx@247
140.   size_t *v140; // eax@247
141.   void **v141; // edi@247
142.   size_t v142; // ecx@248
143.   void *v143; // eax@248
144.   void *v144; // eax@254
145.   void *v145; // edi@254
146.   std::_Container_base0 *v146; // ecx@268
147.   double **v147; // eax@269
148.   char v148; // al@270
149.   _DWORD *v149; // ecx@272
150.   void (__stdcall **v150)(_DWORD); // eax@278
151.   void (__stdcall **j)(_DWORD); // eax@279
152.   void (__stdcall **i)(_DWORD); // eax@282
153.   int *v153; // eax@286
154.   int v154; // edi@286
155.   void *v155; // eax@290
156.   char v156; // al@291
157.   _DWORD *v157; // ecx@293
158.   int v158; // [sp+0h] [bp-1ECh]@1
159.   char v159; // [sp+10h] [bp-1DCh]@247
160.   void *v160; // [sp+18h] [bp-1D4h]@251
161.   char v161; // [sp+1Ch] [bp-1D0h]@290
162.   int v162; // [sp+20h] [bp-1CCh]@290
163.   int v163; // [sp+28h] [bp-1C4h]@290
164.   int v164; // [sp+30h] [bp-1BCh]@290
165.   char v165; // [sp+34h] [bp-1B8h]@290
166.   int v166; // [sp+38h] [bp-1B4h]@290
167.   char v167; // [sp+3Ch] [bp-1B0h]@19
168.   char v168; // [sp+40h] [bp-1ACh]@290
169.   void *v169; // [sp+44h] [bp-1A8h]@290
170.   int v170; // [sp+48h] [bp-1A4h]@290
171.   void *v171; // [sp+4Ch] [bp-1A0h]@290
172.   int v172; // [sp+50h] [bp-19Ch]@290
173.   _DWORD *v173; // [sp+54h] [bp-198h]@290
174.   _DWORD *v174; // [sp+58h] [bp-194h]@290
175.   _DWORD *v175; // [sp+5Ch] [bp-190h]@290
176.   _DWORD *v176; // [sp+60h] [bp-18Ch]@290
177.   void *v177; // [sp+64h] [bp-188h]@290
178.   int v178; // [sp+68h] [bp-184h]@290
179.   void *v179; // [sp+6Ch] [bp-180h]@290
180.   int v180; // [sp+70h] [bp-17Ch]@290
181.   char v181; // [sp+74h] [bp-178h]@150
182.   void *v182; // [sp+7Ch] [bp-170h]@162
183.   int v183; // [sp+80h] [bp-16Ch]@209
184.   void *v184; // [sp+84h] [bp-168h]@115
185.   int v185; // [sp+88h] [bp-164h]@115
186.   int v186; // [sp+8Ch] [bp-160h]@115
187.   int v187; // [sp+90h] [bp-15Ch]@23
188.   void *v188; // [sp+94h] [bp-158h]@115
189.   int v189; // [sp+98h] [bp-154h]@115
190.   int v190; // [sp+9Ch] [bp-150h]@115
191.   int v191; // [sp+A0h] [bp-14Ch]@173
192.   void *v192; // [sp+A4h] [bp-148h]@115
193.   int v193; // [sp+A8h] [bp-144h]@115
194.   int v194; // [sp+ACh] [bp-140h]@115
195.   int v195; // [sp+B0h] [bp-13Ch]@23
196.   int v196; // [sp+B4h] [bp-138h]@23
197.   int v197; // [sp+B8h] [bp-134h]@23
198.   int v198; // [sp+BCh] [bp-130h]@23
199.   int v199; // [sp+C0h] [bp-12Ch]@23
200.   int v200; // [sp+C4h] [bp-128h]@209
201.   int v201; // [sp+C8h] [bp-124h]@209
202.   int v202; // [sp+CCh] [bp-120h]@209
203.   unsigned int v203; // [sp+D0h] [bp-11Ch]@170
204.   int v204; // [sp+D4h] [bp-118h]@170
205.   void *v205; // [sp+D8h] [bp-114h]@173
206.   void *v206; // [sp+DCh] [bp-110h]@180
207.   int v207; // [sp+E0h] [bp-10Ch]@188
208.   int v208; // [sp+E4h] [bp-108h]@188
209.   int v209; // [sp+E8h] [bp-104h]@141
210.   int v210; // [sp+ECh] [bp-100h]@209
211.   unsigned int v211; // [sp+F0h] [bp-FCh]@164
212.   int v212; // [sp+F4h] [bp-F8h]@164
213.   void *v213; // [sp+F8h] [bp-F4h]@167
214.   int v214; // [sp+FCh] [bp-F0h]@209
215.   unsigned int v215; // [sp+100h] [bp-ECh]@167
216.   int v216; // [sp+104h] [bp-E8h]@167
217.   void *v217; // [sp+108h] [bp-E4h]@170
218.   _DWORD **v218; // [sp+10Ch] [bp-E0h]@1
219.   int v219; // [sp+110h] [bp-DCh]@23
220.   int v220; // [sp+114h] [bp-D8h]@150
221.   int v221; // [sp+118h] [bp-D4h]@150
222.   size_t v222; // [sp+11Ch] [bp-D0h]@153
223.   double v223; // [sp+120h] [bp-CCh]@140
224.   double v224; // [sp+128h] [bp-C4h]@1
225.   int v225; // [sp+130h] [bp-BCh]@48
226.   int v226; // [sp+134h] [bp-B8h]@73
227.   int v227; // [sp+138h] [bp-B4h]@23
228.   double v228; // [sp+13Ch] [bp-B0h]@1
229.   void *v229; // [sp+144h] [bp-A8h]@209
230.   _BYTE *v230; // [sp+148h] [bp-A4h]@209
231.   int v231; // [sp+14Ch] [bp-A0h]@209
232.   _DWORD **v232; // [sp+150h] [bp-9Ch]@1
233.   double v233; // [sp+154h] [bp-98h]@115
234.   unsigned int Dst; // [sp+15Ch] [bp-90h]@137
235.   int v235; // [sp+160h] [bp-8Ch]@137
236.   void *v236; // [sp+164h] [bp-88h]@140
237.   int v237; // [sp+168h] [bp-84h]@164
238.   void (__stdcall ***v238)(_DWORD); // [sp+16Ch] [bp-80h]@2
239.   double *v239; // [sp+170h] [bp-7Ch]@167
240.   unsigned int v240; // [sp+174h] [bp-78h]@134
241.   int v241; // [sp+178h] [bp-74h]@134
242.   void *Src; // [sp+17Ch] [bp-70h]@137
243.   double v243; // [sp+180h] [bp-6Ch]@184
244.   size_t v244; // [sp+184h] [bp-68h]@98
245.   int v245; // [sp+188h] [bp-64h]@21
246.   size_t Size; // [sp+18Ch] [bp-60h]@28
247.   void *v247; // [sp+190h] [bp-5Ch]@22
248.   unsigned int v248; // [sp+194h] [bp-58h]@22
249.   int v249; // [sp+198h] [bp-54h]@22
250.   size_t v250; // [sp+19Ch] [bp-50h]@150
251.   size_t v251; // [sp+1A0h] [bp-4Ch]@150
252.   size_t v252; // [sp+1A4h] [bp-48h]@140
253.   void *v253; // [sp+1A8h] [bp-44h]@125
254.   int v254; // [sp+1B8h] [bp-34h]@125
255.   unsigned int v255; // [sp+1BCh] [bp-30h]@125
256.   void *v256; // [sp+1C0h] [bp-2Ch]@23
257.   int v257; // [sp+1D0h] [bp-1Ch]@23
258.   unsigned int v258; // [sp+1D4h] [bp-18h]@23
259.   int *v259; // [sp+1DCh] [bp-10h]@1
260.   int v260; // [sp+1E8h] [bp-4h]@22
261. 
262.   v259 = &v158;
263.   v1 = this;
264.   v232 = this;
265.   v224 = *&qword_3F9A30;
266.   v2 = 0i64;
267.   v218 = this;
268.   v228 = 0.0;
269. LABEL_2:
270.   while ( 1 )
271.   {
272.     v3 = sub_3023D0((v1 + 79), 0);
273.     v4 = v3;
274.     v238 = v3;
275.     if ( v3 )
276.     {
277.       break;
278.     }
279. LABEL_20:
280.     if ( v1[103] < (*(*v1[98] + 4))() )
281.     {
282.       do
283.       {
284.         (*(*v1[98] + 8))(&v245);
285.         if ( v245 == -1 )
286.         {
287.           break;
288.         }
289.         v247 = 0;
290.         v248 = 0;
291.         v249 = 0;
292.         v12 = v1[98];
293.         v260 = 0;
294.         if ( (*(*v12 + 28))(v245, &v247) )
295.         {
296.           goto LABEL_122;
297.         }
298.         (*(*v1[98] + 20))(v245, &v196);
299.         v258 = 15;
300.         v257 = 0;
301.         LOBYTE(v256) = 0;
302.         v13 = v1[98];
303.         LOBYTE(v260) = 3;
304.         (*(*v13 + 32))(v245, &v256);
305.         v14 = v1[98];
306.         v219 = 0;
307.         (*(*v14 + 60))(v245, &v219);
308.         (*(*v1[98] + 40))(v245, &v198);
309.         (*(*v1[98] + 44))(v245, &v199);
310.         (*(*v1[98] + 48))(v245, &v187);
311.         (*(*v1[98] + 52))(v245, &v195);
312.         (*(*v1[98] + 56))(v245, &v197);
313.         v15 = v248;
314.         v16 = v247;
315.         v227 = 53;
316.         if ( &v227 >= v248 || v247 > &v227 )
317.         {
318.           v17 = v249;
319.           if ( v248 == v249 && ((v249 - v248) >> 2) < 1 )
320.           {
321.             v22 = (v248 - v247) >> 2;
322.             if ( (0x3FFFFFFF - v22) < 1 )
323.             {
324.               goto LABEL_121;
325.             }
326.             v23 = (v249 - v247) >> 2;
327.             if ( 0x3FFFFFFF - (v23 >> 1) >= v23 )
328.             {
329.               v24 = (v23 >> 1) + v23;
330.             }
331.             else
332.             {
333.               v24 = 0;
334.             }
335.             if ( v24 < v22 + 1 )
336.             {
337.               v24 = v22 + 1;
338.             }
339.             sub_277E90(v24);
340.             v17 = v249;
341.             v15 = v248;
342.             v16 = v247;
343.           }
344.           if ( v15 )
345.           {
346.             *v15 = 53;
347.             goto LABEL_47;
348.           }
349.         }
350.         else
351.         {
352.           v17 = v249;
353.           v18 = (&v227 - v247) >> 2;
354.           if ( v248 == v249 && ((v249 - v248) >> 2) < 1 )
355.           {
356.             v19 = (v248 - v247) >> 2;
357.             if ( (0x3FFFFFFF - v19) < 1 )
358.             {
359.               goto LABEL_121;
360.             }
361.             v20 = (v249 - v247) >> 2;
362.             Size = v19 + 1;
363.             if ( 0x3FFFFFFF - (v20 >> 1) >= v20 )
364.             {
365.               v21 = (v20 >> 1) + v20;
366.             }
367.             else
368.             {
369.               v21 = 0;
370.             }
371.             if ( v21 < Size )
372.             {
373.               v21 = Size;
374.             }
375.             sub_277E90(v21);
376.             v17 = v249;
377.             v15 = v248;
378.             v16 = v247;
379.           }
380.           if ( v15 )
381.           {
382.             *v15 = v16[v18];
383. LABEL_47:
384.             v17 = v249;
385.             v16 = v247;
386.             v15 = v248;
387.             goto LABEL_48;
388.           }
389.         }
390. LABEL_48:
391.         v25 = v15 + 1;
392.         v225 = 54;
393.         v248 = v25;
394.         if ( &v225 >= v25 || v16 > &v225 )
395.         {
396.           if ( v25 == v17 && ((v17 - v25) >> 2) < 1 )
397.           {
398.             v30 = v25 - v16;
399.             if ( (0x3FFFFFFF - v30) < 1 )
400.             {
401.               goto LABEL_121;
402.             }
403.             v31 = (v17 - v16) >> 2;
404.             if ( 0x3FFFFFFF - (v31 >> 1) >= v31 )
405.             {
406.               v32 = (v31 >> 1) + v31;
407.             }
408.             else
409.             {
410.               v32 = 0;
411.             }
412.             if ( v32 < v30 + 1 )
413.             {
414.               v32 = v30 + 1;
415.             }
416.             sub_277E90(v32);
417.             v17 = v249;
418.             v25 = v248;
419.             v16 = v247;
420.           }
421.           if ( v25 )
422.           {
423.             *v25 = 54;
424.             goto LABEL_72;
425.           }
426.         }
427.         else
428.         {
429.           v26 = &v225 - v16;
430.           if ( v25 == v17 && ((v17 - v25) >> 2) < 1 )
431.           {
432.             v27 = v25 - v16;
433.             if ( (0x3FFFFFFF - v27) < 1 )
434.             {
435.               goto LABEL_121;
436.             }
437.             v28 = (v17 - v16) >> 2;
438.             Size = v27 + 1;
439.             if ( 0x3FFFFFFF - (v28 >> 1) >= v28 )
440.             {
441.               v29 = (v28 >> 1) + v28;
442.             }
443.             else
444.             {
445.               v29 = 0;
446.             }
447.             if ( v29 < Size )
448.             {
449.               v29 = Size;
450.             }
451.             sub_277E90(v29);
452.             v17 = v249;
453.             v25 = v248;
454.             v16 = v247;
455.           }
456.           if ( v25 )
457.           {
458.             *v25 = v16[v26];
459. LABEL_72:
460.             v17 = v249;
461.             v16 = v247;
462.             v25 = v248;
463.             goto LABEL_73;
464.           }
465.         }
466. LABEL_73:
467.         v33 = (v25 + 1);
468.         v226 = 55;
469.         v248 = v33;
470.         if ( &v226 >= v33 || v16 > &v226 )
471.         {
472.           if ( v33 == v17 && ((v17 - v33) >> 2) < 1 )
473.           {
474.             v38 = (v33 - v16) >> 2;
475.             if ( (0x3FFFFFFF - v38) < 1 )
476.             {
477. LABEL_121:
478.               std::_Xlength_error("vector<T> too long");
479. LABEL_122:
480.               v63 = operator new(0x20u);
481.               v244 = v63;
482.               LOBYTE(v260) = 1;
483.               if ( v63 )
484.               {
485.                 v64 = sub_300670(v63);
486.               }
487.               else
488.               {
489.                 v64 = 0;
490.               }
491.               LOBYTE(v260) = 0;
492.               v255 = 15;
493.               v254 = 0;
494.               LOBYTE(v253) = 0;
495.               sub_14C1E0(&v253, "Invalid input device configuration.", 0x23u);
496.               LOBYTE(v260) = 2;
497.               sub_301530(&v253);
498.               LOBYTE(v260) = 0;
499.               if ( v255 >= 0x10 )
500.               {
501.                 operator delete(v253);
502.               }
503.               sub_302A00(v1[102], v64, 0);
504.               v260 = -1;
505.               if ( v247 )
506.               {
507.                 operator delete(v247);
508.                 v247 = 0;
509.                 v248 = 0;
510.                 v249 = 0;
511.               }
512.               break;
513.             }
514.             v39 = (v17 - v16) >> 2;
515.             if ( 0x3FFFFFFF - (v39 >> 1) >= v39 )
516.             {
517.               v40 = (v39 >> 1) + v39;
518.             }
519.             else
520.             {
521.               v40 = 0;
522.             }
523.             if ( v40 < v38 + 1 )
524.             {
525.               v40 = v38 + 1;
526.             }
527.             sub_277E90(v40);
528.             v33 = v248;
529.           }
530.           if ( v33 )
531.           {
532.             *v33 = 55;
533.             goto LABEL_97;
534.           }
535.         }
536.         else
537.         {
538.           v34 = &v226 - v16;
539.           if ( v33 == v17 && ((v17 - v33) >> 2) < 1 )
540.           {
541.             v35 = (v33 - v16) >> 2;
542.             if ( (0x3FFFFFFF - v35) < 1 )
543.             {
544.               goto LABEL_121;
545.             }
546.             v36 = (v17 - v16) >> 2;
547.             Size = v35 + 1;
548.             if ( 0x3FFFFFFF - (v36 >> 1) >= v36 )
549.             {
550.               v37 = (v36 >> 1) + v36;
551.             }
552.             else
553.             {
554.               v37 = 0;
555.             }
556.             if ( v37 < Size )
557.             {
558.               v37 = Size;
559.             }
560.             sub_277E90(v37);
561.             v33 = v248;
562.             v16 = v247;
563.           }
564.           if ( v33 )
565.           {
566.             *v33 = v16[v34];
567. LABEL_97:
568.             v33 = v248;
569.             goto LABEL_98;
570.           }
571.         }
572. LABEL_98:
573.         v248 = (v33 + 4);
574.         v41 = operator new(0x50u);
575.         v244 = v41;
576.         LOBYTE(v260) = 4;
577.         if ( v41 )
578.         {
579.           v42 = sub_3008D0(v41, v245, v196, &v247, &v256, v219, v198, v199, v187, v195, v197);
580.         }
581.         else
582.         {
583.           v42 = 0;
584.         }
585.         v43 = v1[102];
586.         LOBYTE(v260) = 3;
587.         sub_302A00(v43, v42, 0);
588.         v44 = operator new(0xCu);
589.         v45 = v44;
590.         v244 = v44;
591.         LOBYTE(v260) = 5;
592.         if ( v44 )
593.         {
594.           *v44 = 1;
595.           v44[1] = 1;
596.           Size = 8;
597.           v46 = new_array(8u);
598.           v47 = v46;
599.           if ( v46 )
600.           {
601.             memset(v46, 0, Size);
602.             *(v45 + 8) = v47;
603.           }
604.           else
605.           {
606.             *(v45 + 8) = 0;
607.           }
608.         }
609.         else
610.         {
611.           v45 = 0;
612.         }
613.         v48 = v45;
614.         Size = v45;
615.         LOBYTE(v260) = 6;
616.         v49 = sub_2FD790(&v245);
617.         if ( v49 != &Size )
618.         {
619.           v48 = 0;
620.           Size = *v49;
621.           v50 = Size;
622.           *v49 = v45;
623.           if ( v50 )
624.           {
625.             if ( *(v50 + 8) )
626.             {
627.               operator delete[](*(v50 + 8));
628.               v50 = Size;
629.             }
630.             operator delete(v50);
631.           }
632.         }
633.         LOBYTE(v260) = 3;
634.         if ( v48 )
635.         {
636.           if ( *(v48 + 8) )
637.           {
638.             operator delete[](*(v48 + 8));
639.           }
640.           operator delete(v48);
641.         }
642.         v1[103] = (v1[103] + 1);
643.         LODWORD(v51) = Xtime_get_ticks();
644.         reverse_bits(v51 - v1[96], (v51 - *(v1 + 48)) >> 32);
645.         v233 = v2.m128d_f64[0];
646.         reverse_bits(10000000, 0);
647.         v233 = v233 / v2.m128d_f64[0];
648.         reverse_bits(1000, 0);
649.         v2.m128d_f64[0] = v2.m128d_f64[0] * v233;
650.         sub_3BD63F(v2);
651.         v53 = v52;
652.         v55 = v54;
653.         sub_2FCFF0(&v184, 2);
654.         LOBYTE(v260) = 7;
655.         reverse_bits(v53, v55);
656.         v56 = v232;
657.         v57 = v184;
658.         v58 = (v232 + 112);
659.         *v184 = _mm_unpckl_pd(v2, v2);
660.         sub_2FD820(v58, &v245);
661.         sub_2FD550(&v184);
662.         *sub_2FD670(v56 + 126, &v245) = 0;
663.         sub_2FCFF0(&v188, 2);
664.         v59 = v188;
665.         LOBYTE(v260) = 8;
666.         *v188 = xmmword_4CB160;
667.         sub_2FD820(v56 + 118, &v245);
668.         sub_2FD550(&v188);
669.         *sub_2FD670(v56 + 122, &v245) = 0;
670.         v60 = sub_2FD700(&v245);
671.         sub_14C1E0(v60, "EPOC", 4u);
672.         sub_2FCFF0(&v192, 2);
673.         v61 = v192;
674.         LOBYTE(v260) = 9;
675.         v62 = v232;
676.         *v192 = v224;
677.         v2 = *&v228;
678.         v61[1] = v228;
679.         sub_2FD820(v62 + 114, &v245);
680.         sub_2FD550(&v192);
681.         operator delete(v61);
682.         v192 = 0;
683.         v193 = 0;
684.         v194 = 0;
685.         operator delete(v59);
686.         v188 = 0;
687.         v189 = 0;
688.         v190 = 0;
689.         operator delete(v57);
690.         v184 = 0;
691.         v185 = 0;
692.         v186 = 0;
693.         if ( v258 >= 0x10 )
694.         {
695.           operator delete(v256);
696.         }
697.         v258 = 15;
698.         v257 = 0;
699.         LOBYTE(v256) = 0;
700.         v260 = -1;
701.         if ( v247 )
702.         {
703.           operator delete(v247);
704.           v247 = 0;
705.           v248 = 0;
706.           v249 = 0;
707.         }
708.         v1 = v232;
709.       }
710.       while ( v1[103] < (*(*v232[98] + 4))() );
711.     }
712.     if ( !v1[103] )
713.     {
714.       sub_3262B0(0xAu);
715.       continue;
716.     }
717.     v65 = *v1[99];
718. LABEL_132:
719.     v238 = v65;
720.     while ( 1 )
721.     {
722.       if ( v65 == v1[99] )
723.       {
724.         goto LABEL_2;
725.       }
726.       v240 = 1;
727.       v241 = 1;
728.       Size = 8;
729.       v66 = new_array(8u);
730.       v67 = v66;
731.       if ( v66 )
732.       {
733.         memset(v66, 0, Size);
734.       }
735.       else
736.       {
737.         v67 = 0;
738.       }
739.       Src = v67;
740.       v260 = 10;
741.       Dst = 1;
742.       v235 = 1;
743.       Size = 8;
744.       v68 = new_array(8u);
745.       v69 = v68;
746.       if ( v68 )
747.       {
748.         memset(v68, 0, Size);
749.       }
750.       else
751.       {
752.         v69 = 0;
753.       }
754.       v236 = v69;
755.       v70 = v65[4];
756.       v71 = Xtime_get_ticks;
757.       LOBYTE(v260) = 11;
758.       v252 = v70;
759.       LODWORD(v72) = Xtime_get_ticks();
760.       reverse_bits(v72 - v1[94], (v72 - *(v1 + 47)) >> 32);
761.       v223 = v2.m128d_f64[0];
762.       reverse_bits(10000, 0);
763.       if ( v223 / v2.m128d_f64[0] > 1000.0 )
764.       {
765.         (*(*v1[98] + 24))(v252, &v209);
766.         if ( ((*v1)[10])(v1, v252) )
767.         {
768.           v73 = *v1[107];
769.           v74 = ((*v1)[9])(v1, v252, v209 == 0);
770.           (*(v73 + 28))(v1[107], v74);
771.           v71 = Xtime_get_ticks;
772.         }
773.         v75 = operator new(0x10u);
774.         v244 = v75;
775.         LOBYTE(v260) = 12;
776.         if ( v75 )
777.         {
778.           v76 = sub_300AB0(v75, v252, v209);
779.         }
780.         else
781.         {
782.           v76 = 0;
783.         }
784.         v77 = v1[102];
785.         LOBYTE(v260) = 11;
786.         sub_302A00(v77, v76, 0);
787.         v1[94] = v71();
788.         v1[95] = v78;
789.       }
790.       v79 = (*(*v1[98] + 16))(v252, &v240);
791.       Size = 3;
792.       if ( !v79 )
793.       {
794.         v80 = v1[98];
795.         LOBYTE(v260) = 13;
796.         Size = (*(*v80 + 36))(v252, &Dst, v240);
797.         if ( v241 == 23 || v241 == 27 )
798.         {
799.           sub_1BA1B0(&v181);
800.           LOBYTE(v260) = 14;
801.           v220 = 1;
802.           v221 = 12;
803.           v251 = 96;
804.           v81 = new_array(0x60u);
805.           v82 = v81;
806.           v250 = v81;
807.           if ( v81 )
808.           {
809.             memset(v81, 0, v251);
810.           }
811.           else
812.           {
813.             v82 = 0;
814.             v250 = 0;
815.           }
816.           v222 = v82;
817.           LOBYTE(v260) = 15;
818.           new_list_array(&v220);
819.           v83 = 0;
820.           LOBYTE(v260) = 16;
821.           if ( Dst * v235 != 1 )
822.           {
823.             goto LABEL_299;
824.           }
825.           v2 = *v236;
826.           __asm { lahf }
827.           if ( __SETP__(_AH & 0x44, 0) )
828.           {
829. LABEL_299:
830.             v83 = Dst;
831.             if ( Dst >= v240 )
832.             {
833.               v83 = v240;
834.             }
835.             sub_280180(&Dst, 2);
836.             sub_167C40(&Dst, 0, 0);
837.             v251 = v236;
838.             sub_167C40(&v220, 0, 0);
839.             *v250 = *v251;
840.             sub_167C40(&Dst, 0, 1u);
841.             v251 = v236;
842.             sub_167C40(&v220, 0, 1u);
843.             *(v250 + 8) = *(v251 + 8);
844.             sub_167C40(&Dst, 0, 2u);
845.             v251 = v236;
846.             sub_167C40(&v220, 0, 2u);
847.             *(v250 + 16) = *(v251 + 16);
848.             sub_167C40(&Dst, 0, 3u);
849.             v251 = v236;
850.             sub_167C40(&v220, 0, 3u);
851.             v2 = *(v251 + 24);
852.             *(v250 + 24) = v2.m128d_f64[0];
853.           }
854.           while ( v83 < v240 )
855.           {
856.             sub_280180(&v220, 2);
857.             ++v83;
858.             v250 = v222;
859.           }
860.           concat_items(&v240, &v181, 2);
861.           if ( v250 )
862.           {
863.             operator delete[](v250);
864.           }
865.           LOBYTE(v260) = 13;
866.           if ( v182 )
867.           {
868.             operator delete[](v182);
869.           }
870.         }
871.         v211 = v240;
872.         v212 = 1;
873.         v251 = 8 * v240 | -(v240 >> 29 != 0);
874.         v85 = new_array(v251);
875.         v86 = v85;
876.         v237 = v85;
877.         if ( v85 )
878.         {
879.           memset(v85, 0, v251);
880.         }
881.         else
882.         {
883.           v86 = 0;
884.           v237 = 0;
885.         }
886.         v213 = v86;
887.         LOBYTE(v260) = 17;
888.         new_list_array(&v211);
889.         v215 = v240;
890.         LOBYTE(v260) = 18;
891.         v216 = 1;
892.         v251 = 8 * v240 | -(v240 >> 29 != 0);
893.         v87 = new_array(v251);
894.         v88 = v87;
895.         v239 = v87;
896.         if ( v87 )
897.         {
898.           memset(v87, 0, v251);
899.         }
900.         else
901.         {
902.           v88 = 0;
903.           v239 = 0;
904.         }
905.         v217 = v88;
906.         LOBYTE(v260) = 19;
907.         new_list_array(&v215);
908.         v203 = v240;
909.         LOBYTE(v260) = 20;
910.         v204 = 1;
911.         v250 = 8 * v240 | -(v240 >> 29 != 0);
912.         v89 = new_array(v250);
913.         v90 = v89;
914.         v251 = v89;
915.         if ( v89 )
916.         {
917.           memset(v89, 0, v250);
918.         }
919.         else
920.         {
921.           v90 = 0;
922.           v251 = 0;
923.         }
924.         v205 = v90;
925.         LOBYTE(v260) = 21;
926.         new_list_array(&v203);
927.         v91 = v1[98];
928.         LOBYTE(v260) = 22;
929.         (*(*v91 + 52))(v252, &v191);
930.         LODWORD(v92) = Xtime_get_ticks();
931.         v93 = sub_3BD860(v92 - *(v1 + 48), 0x2710u, 0);
932.         reverse_bits(v93, v94);
933.         v2.m128d_f64[0] = v2.m128d_f64[0] / 1000.0;
934.         v95 = 0;
935.         v233 = v2.m128d_f64[0];
936.         while ( v95 < v240 )
937.         {
938.           sub_167C40(&v240, v95, 5u);
939.           if ( *(Src + v241 * v95 + 5) > v228 )
940.           {
941.             v1[111] = (v1[111] + 1);
942.           }
943.           sub_167C40(&v240, v95, 0x13u);
944.           v96 = floor(*(Src + v241 * v95 + 19));
945.           if ( v191 != 2 || v96 != 32 )
946.           {
947.             v97 = sub_2FD820(v1 + 114, &v252);
948.             sub_22E250(v97);
949.             LOBYTE(v260) = 23;
950.             v98 = *v206;
951.             __asm { lahf }
952.             if ( __SETP__(_AH & 0x44, 0) && v233 - *(v206 + 1) > 0.5 )
953.             {
954.               sub_167C40(&v211, v95, 0);
955.               *(v237 + 8 * v95) = v233;
956.               sub_167C40(&v215, v95, 0);
957.               v239[v95] = v233;
958.               v100 = sub_2FD820(v1 + 112, &v252);
959.               **v100 = v233;
960.               v101 = sub_2FD820(v1 + 112, &v252);
961.               *(*v101 + 8) = v233;
962.               *sub_2FD670(v1 + 126, &v252) = 1;
963.             }
964.             else
965.             {
966.               sub_167C40(&v240, v95, 1u);
967.               v244 = floor(*(Src + v241 * v95 + 1));
968.               v250 = v252;
969.               v223 = **sub_2FD820(v1 + 118, &v250);
970.               v102 = sub_300260(v1, 1, v250, v244);
971.               v103 = (v1 + 112);
972.               if ( v102 == -1 )
973.               {
974.                 v243 = **sub_2FD820(v103, &v250);
975.               }
976.               else
977.               {
978.                 v243 = v102 / v223;
979.                 v104 = sub_2FD820(v103, &v250);
980.                 v243 = v224 / v223 + **v104 + v243;
981.                 v105 = sub_2FD820(v1 + 112, &v250);
982.                 **v105 = v243;
983.               }
984.               sub_167C40(&v211, v95, 0);
985.               *(v237 + 8 * v95) = v243;
986.               v244 = *sub_2FD820(v1 + 112, &v252) + 8;
987.               sub_167C40(&v215, v95, 0);
988.               v239[v95] = *v244;
989.             }
990.             v106 = sub_2FD820(v1 + 114, &v252);
991.             **v106 = v224;
992.             v107 = sub_2FD820(v1 + 114, &v252);
993.             LOBYTE(v260) = 22;
994.             *(*v107 + 8) = v233;
995.             if ( v206 )
996.             {
997.               std::_Container_base0::_Orphan_all(&v206);
998.               operator delete(v206);
999.               v206 = 0;
1000.               v207 = 0;
1001.               v208 = 0;
1002.             }
1003.           }
1004.           else
1005.           {
1006.             sub_167C40(&v240, v95, 1u);
1007.             v250 = v241 * v95;
1008.             v244 = Src;
1009.             sub_167C40(&v215, v95, 0);
1010.             v223 = sub_2FDAE0(v252, floor(*(v244 + 8 * v250 + 8)));
1011.             v239[v95] = v223;
1012.             v244 = *sub_2FD820(v1 + 112, &v252);
1013.             sub_167C40(&v211, v95, 0);
1014.             *(v237 + 8 * v95) = *v244;
1015.           }
1016.           sub_167C40(&v203, v95, 0);
1017.           v2 = *&v233;
1018.           *(v251 + 8 * v95++) = v233;
1019.         }
1020.         concat_items(&v240, &v211, 2);
1021.         concat_items(&v240, &v203, 2);
1022.         concat_items(&v240, &v215, 2);
1023.         if ( ((*v1)[10])(v1, v252) )
1024.         {
1025.           v108 = ((*v1)[9])(v1, v252);
1026.           (*(*v1[107] + 16))(v108, &v240);
1027.         }
1028.         v109 = *sub_2FD790(&v252);
1029.         v250 = v109;
1030.         if ( *(v109 + 4) * *v109 != 1 )
1031.         {
1032.           goto LABEL_300;
1033.         }
1034.         v2 = **(v109 + 8);
1035.         __asm { lahf }
1036.         if ( __SETP__(_AH & 0x44, 0) )
1037.         {
1038. LABEL_300:
1039.           sub_280180(&v240, 2);
1040.         }
1041.         else if ( v109 != &v240 )
1042.         {
1043.           *v109 = v240;
1044.           *(v109 + 4) = v241;
1045.           v244 = 8 * v241 * *v109 | -((v241 * *v109) >> 29 != 0);
1046.           v111 = new_array(v244);
1047.           v251 = v111;
1048.           if ( v111 )
1049.           {
1050.             memset(v111, 0, v244);
1051.           }
1052.           else
1053.           {
1054.             v251 = 0;
1055.           }
1056.           if ( *(v109 + 8) )
1057.           {
1058.             operator delete[](*(v109 + 8));
1059.           }
1060.           *(v109 + 8) = v251;
1061.           memmove(*(v109 + 8), Src, 8 * *(v109 + 4) * *v109 & 0xFFFFFFF8);
1062.         }
1063.         if ( v1[111] >= v1[101] )
1064.         {
1065.           v112 = operator new(0xCu);
1066.           v239 = v112;
1067.           v251 = v112;
1068.           LOBYTE(v260) = 24;
1069.           if ( v112 )
1070.           {
1071.             v113 = *v109;
1072.             *v112 = *v109;
1073.             v114 = *(v109 + 4);
1074.             *(v112 + 1) = v114;
1075.             v244 = 8 * v114 * v113 | -((v114 * v113) >> 29 != 0);
1076.             v115 = new_array(v244);
1077.             v251 = v115;
1078.             if ( v115 )
1079.             {
1080.               memset(v115, 0, v244);
1081.               v116 = v251;
1082.             }
1083.             else
1084.             {
1085.               v116 = 0;
1086.             }
1087.             v117 = v239;
1088.             *(v239 + 2) = v116;
1089.             memmove(*(v117 + 8), *(v109 + 8), 8 * *(v109 + 4) * *v109 & 0xFFFFFFF8);
1090.             v118 = v239;
1091.           }
1092.           else
1093.           {
1094.             v118 = 0;
1095.             v239 = 0;
1096.           }
1097.           LOBYTE(v260) = 22;
1098.           sub_16C010(v118);
1099.           v258 = 15;
1100.           v257 = 0;
1101.           LOBYTE(v256) = 0;
1102.           v119 = v1[98];
1103.           LOBYTE(v260) = 25;
1104.           (*(*v119 + 32))(v252, &v256);
1105.           (*(*v1[98] + 40))(v252, &v214);
1106.           (*(*v1[98] + 44))(v252, &v200);
1107.           (*(*v1[98] + 20))(v252, &v210);
1108.           (*(*v1[98] + 48))(v252, &v201);
1109.           (*(*v1[98] + 52))(v252, &v202);
1110.           (*(*v1[98] + 56))(v252, &v183);
1111.           v229 = 0;
1112.           v230 = 0;
1113.           v231 = 0;
1114.           LOBYTE(v260) = 26;
1115.           v255 = 15;
1116.           v254 = 0;
1117.           LOBYTE(v253) = 0;
1118.           sub_14C1E0(&v253, ":,", 2u);
1119.           LOBYTE(v260) = 27;
1120.           sub_1B9D00(&v256, &v229, &v253);
1121.           LOBYTE(v260) = 26;
1122.           if ( v255 >= 0x10 )
1123.           {
1124.             operator delete(v253);
1125.           }
1126.           v120 = (v230 - v229) / 24;
1127.           if ( v120 && !(v120 & 1) )
1128.           {
1129.             v121 = 0;
1130.             while ( 2 )
1131.             {
1132.               v251 = v121;
1133.               if ( v121 >= (v230 - v229) / 24 )
1134.               {
1135.                 v109 = v250;
1136.                 break;
1137.               }
1138.               v127 = *(v229 + 6 * v121 + 5) < 0x10u;
1139.               headsetType = v229 + 24 * v121;
1140.               v123 = *(headsetType + 4);
1141.               v237 = (headsetType + 24);
1142.               v244 = v123;
1143.               if ( !v127 )
1144.               {
1145.                 headsetType = *headsetType;
1146.               }
1147.               v124 = 11;
1148.               if ( v123 < 0xB )
1149.               {
1150.                 v124 = v123;
1151.               }
1152.               if ( !v124 )
1153.               {
1154.                 goto LABEL_235;
1155.               }
1156.               v125 = "headsetType";
1157.               v127 = v124 < 4;
1158.               v126 = v124 - 4;
1159.               if ( v127 )
1160.               {
1161. LABEL_223:
1162.                 if ( v126 != -4 )
1163.                 {
1164.                   goto LABEL_224;
1165.                 }
1166.               }
1167.               else
1168.               {
1169.                 while ( *headsetType == *v125 )
1170.                 {
1171.                   headsetType += 4;
1172.                   v125 += 4;
1173.                   v127 = v126 < 4;
1174.                   v126 -= 4;
1175.                   if ( v127 )
1176.                   {
1177.                     goto LABEL_223;
1178.                   }
1179.                 }
1180. LABEL_224:
1181.                 v127 = *headsetType < *v125;
1182.                 if ( *headsetType != *v125
1183.                   || v126 != -3
1184.                   && ((v128 = headsetType[1], v127 = v128 < v125[1], v128 != v125[1])
1185.                    || v126 != -2
1186.                    && ((v129 = headsetType[2], v127 = v129 < v125[2], v129 != v125[2])
1187.                     || v126 != -1 && (v130 = headsetType[3], v127 = v130 < v125[3], v130 != v125[3]))) )
1188.                 {
1189.                   v131 = -v127 | 1;
1190.                   goto LABEL_233;
1191.                 }
1192.               }
1193.               v131 = 0;
1194. LABEL_233:
1195.               v132 = v131 == 0;
1196.               if ( v131 )
1197.               {
1198.                 goto LABEL_239;
1199.               }
1200.               v123 = v244;
1201. LABEL_235:
1202.               if ( v123 >= 0xB )
1203.               {
1204.                 v133 = v123 != 11;
1205.               }
1206.               else
1207.               {
1208.                 v133 = -1;
1209.               }
1210.               v132 = v133 == 0;
1211. LABEL_239:
1212.               if ( v132 )
1213.               {
1214.                 v134 = sub_2FD700(&v252);
1215.                 if ( v134 != v237 )
1216.                 {
1217.                   sub_14C0C0(v134, v237, 0, 0xFFFFFFFF);
1218.                 }
1219.               }
1220.               v121 = v251 + 2;
1221.               continue;
1222.             }
1223.           }
1224.           sub_2FDC00(v1, v252, v210, v214);
1225.           v135 = operator new(0x40u);
1226.           v244 = v135;
1227.           LOBYTE(v260) = 28;
1228.           if ( v135 )
1229.           {
1230.             v136 = sub_300820(v135, v252, v239, &v256, v214, v200, v210, v201, v202, v183);
1231.           }
1232.           else
1233.           {
1234.             v136 = 0;
1235.           }
1236.           v137 = v1[102];
1237.           LOBYTE(v260) = 26;
1238.           sub_302A00(v137, v136, 0);
1239.           v138 = sub_1BA1B0(&v159);
1240.           *v109 = *v138;
1241.           v139 = *(v138 + 4);
1242.           v140 = (v138 + 8);
1243.           *(v109 + 4) = v139;
1244.           v141 = (v109 + 8);
1245.           if ( v141 != v140 )
1246.           {
1247.             v142 = *v140;
1248.             *v140 = 0;
1249.             v143 = *v141;
1250.             v244 = v142;
1251.             if ( v143 )
1252.             {
1253.               operator delete[](v143);
1254.               v142 = v244;
1255.             }
1256.             *v141 = v142;
1257.           }
1258.           if ( v160 )
1259.           {
1260.             operator delete[](v160);
1261.           }
1262.           v132 = v229 == 0;
1263.           v1[111] = 0;
1264.           LOBYTE(v260) = 25;
1265.           if ( !v132 )
1266.           {
1267.             std::_Container_base0::_Orphan_all(&v229);
1268.             v144 = v230;
1269.             v145 = v229;
1270.             v244 = v230;
1271.             if ( v229 != v230 )
1272.             {
1273.               do
1274.               {
1275.                 if ( *(v145 + 5) >= 0x10u )
1276.                 {
1277.                   operator delete(*v145);
1278.                   v144 = v244;
1279.                 }
1280.                 *(v145 + 5) = 15;
1281.                 *(v145 + 4) = 0;
1282.                 *v145 = 0;
1283.                 v145 = v145 + 24;
1284.               }
1285.               while ( v145 != v144 );
1286.               v145 = v229;
1287.             }
1288.             operator delete(v145);
1289.             v229 = 0;
1290.             v230 = 0;
1291.             v231 = 0;
1292.           }
1293.           LOBYTE(v260) = 22;
1294.           if ( v258 >= 0x10 )
1295.           {
1296.             operator delete(v256);
1297.           }
1298.         }
1299.         std::_Container_base0::_Orphan_all((v1 + 104));
1300.         v1[105] = v1[104];
1301.         if ( v205 )
1302.         {
1303.           operator delete[](v205);
1304.         }
1305.         if ( v217 )
1306.         {
1307.           operator delete[](v217);
1308.         }
1309.         if ( v213 )
1310.         {
1311.           operator delete[](v213);
1312.         }
1313.         goto LABEL_273;
1314.       }
1315.       v146 = (v1 + 104);
1316.       if ( v79 != 3 )
1317.       {
1318.         break;
1319.       }
1320.       std::_Container_base0::_Orphan_all(v146);
1321.       v1[105] = v1[104];
1322.       v147 = sub_2FD820(v1 + 114, &v252);
1323.       v2 = *&v228;
1324.       **v147 = v228;
1325.       v244 = operator new(0xCu);
1326.       LOBYTE(v260) = 30;
1327.       if ( v244 )
1328.       {
1329.         v148 = sub_300990(v252);
1330.       }
1331.       else
1332.       {
1333.         v148 = 0;
1334.       }
1335.       v149 = v1[102];
1336.       LOBYTE(v260) = 11;
1337.       sub_302A00(v149, v148, 0);
1338. LABEL_273:
1339.       if ( v236 )
1340.       {
1341.         operator delete[](v236);
1342.       }
1343.       v260 = -1;
1344.       if ( Src )
1345.       {
1346.         operator delete[](Src);
1347.       }
1348.       if ( !*(v65 + 13) )
1349.       {
1350.         v150 = v65[2];
1351.         if ( *(v150 + 13) )
1352.         {
1353.           for ( i = v65[1]; !*(i + 13); i = i[1] )
1354.           {
1355.             if ( v65 != i[2] )
1356.             {
1357.               break;
1358.             }
1359.             v65 = i;
1360.           }
1361.           v65 = i;
1362.         }
1363.         else
1364.         {
1365.           v65 = v65[2];
1366.           for ( j = *v150; !*(j + 13); j = *j )
1367.           {
1368.             v65 = j;
1369.           }
1370.         }
1371.         goto LABEL_132;
1372.       }
1373.     }
1374.     std::_Container_base0::_Orphan_all(v146);
1375.     v1[105] = v1[104];
1376.     v153 = sub_2FD790(&v252);
1377.     v154 = *v153;
1378.     *v153 = 0;
1379.     if ( v154 )
1380.     {
1381.       if ( *(v154 + 8) )
1382.       {
1383.         operator delete[](*(v154 + 8));
1384.       }
1385.       operator delete(v154);
1386.     }
1387.     (*(*v1[98] + 12))(v252);
1388.     sub_2FE0B0(&v168, v65);
1389.     v1[103] = (v1[103] - 1);
1390.     sub_2FD9B0(v1 + 112, &v169, &v252);
1391.     sub_15D7E0(v1 + 112, &v166, v169, v170);
1392.     sub_2FD9B0(v1 + 120, &v179, &v252);
1393.     sub_28D010(v1 + 120, &v164, v179, v180);
1394.     sub_2FD9B0(v1 + 122, &v175, &v252);
1395.     sub_291F20(v1 + 122, &v161, v175, v176);
1396.     sub_2FD9B0(v1 + 118, &v171, &v252);
1397.     sub_15D7E0(v1 + 118, &v162, v171, v172);
1398.     sub_2FD9B0(v1 + 114, &v177, &v252);
1399.     sub_15D7E0(v1 + 114, &v163, v177, v178);
1400.     sub_2FD9B0(v1 + 126, &v173, &v252);
1401.     sub_291F20(v1 + 126, &v165, v173, v174);
1402.     ((*v1)[10])(v1, v252);
1403.     ((*v1)[8])(v1, v252);
1404.     v155 = operator new(0xCu);
1405.     v244 = v155;
1406.     LOBYTE(v260) = 31;
1407.     if ( v155 )
1408.     {
1409.       v156 = sub_3009C0(v155, v252);
1410.     }
1411.     else
1412.     {
1413.       v156 = 0;
1414.     }
1415.     v157 = v1[102];
1416.     LOBYTE(v260) = 11;
1417.     sub_302A00(v157, v156, 0);
1418.     if ( v236 )
1419.     {
1420.       operator delete[](v236);
1421.     }
1422.     v260 = -1;
1423.     if ( Src )
1424.     {
1425.       operator delete[](Src);
1426.     }
1427.   }
1428.   v5 = sub_2367D0(v3);
1429.   if ( v5 != 9 )
1430.   {
1431.     if ( v5 == 11 )
1432.     {
1433.       ((*v1)[6])(v1, v4);
1434.     }
1435.     else if ( v5 == 13 )
1436.     {
1437.       v9 = *v1;
1438.       v10 = sub_301270(v4, &v167);
1439.       v11 = sub_291C60(v238);
1440.       (*(v9 + 28))(v1, *v10, v11);
1441.       (**v238)(1);
1442.     }
1443.     goto LABEL_20;
1444.   }
1445.   (**v4)(v4, 1);
1446.   result = v1[99];
1447.   v7 = *result;
1448.   if ( *result != result )
1449.   {
1450.     do
1451.     {
1452.       result = (*(*v1[98] + 12))(v7[4]);
1453.       if ( !*(v7 + 13) )
1454.       {
1455.         v8 = v7[2];
1456.         if ( *(v8 + 13) )
1457.         {
1458.           for ( result = v7[1]; !*(result + 13); result = result[1] )
1459.           {
1460.             if ( v7 != result[2] )
1461.             {
1462.               break;
1463.             }
1464.             v7 = result;
1465.           }
1466.           v7 = result;
1467.         }
1468.         else
1469.         {
1470.           v7 = v7[2];
1471.           for ( result = *v8; !*(result + 13); result = *result )
1472.           {
1473.             v7 = result;
1474.           }
1475.         }
1476.       }
1477.     }
1478.     while ( v7 != v1[99] );
1479.   }
1480.   return result;
1481. }
1482. 
1483. 
warrenarea commented 7 years ago

again, this is part of the data acquisition thread. i posted this because... it gets interesting right around line 642

i renamed the function "reverse_bits" because that Sub is linked to a function that says it reverses the bits.

and then after that, you'll notice there is a negotiation between 64-bit Floating doubles.

and then a little bit below, a function to "floor"

warrenarea commented 7 years ago

another nearby function . . .

double *__thiscall sub_2FDC00(int this, char a2, signed int a3, signed int a4)
{
  signed int v4; // ebx@1
  int v5; // edi@1
  int v6; // eax@2
  int v7; // ecx@2
  unsigned int v8; // esi@2
  unsigned int v9; // eax@4
  int v10; // eax@6
  int *v11; // edi@9
  double **v12; // eax@9
  double v13; // xmm0_8@9
  double **v14; // eax@14
  double *v15; // esi@15
  double v16; // ST18_8@15
  double *result; // eax@15

  v4 = a3;
  v5 = this;
  if ( a3 == 128 )
  {
    v6 = sub_2FD700(&a2);
    v7 = v6;
    v8 = *(v6 + 16);
    if ( *(v6 + 20) >= 0x10u )
    {
      v7 = *v6;
    }
    v9 = 4;
    if ( v8 < 4 )
    {
      v9 = v8;
    }
    v10 = sub_159A70(v7, "EPOC", v9);
    if ( v10 || v8 < 4 || (LOBYTE(v10) = v8 != 4, v10) )
    {
      v11 = (v5 + 472);
      v12 = sub_2FD820(v11, &a2);
      v13 = *&qword_4CB148;
    }
    else
    {
      v11 = (v5 + 472);
      v12 = sub_2FD820(v11, &a2);
      v13 = *&qword_4CB150;
    }
  }
  else
  {
    v11 = (this + 472);
    v12 = sub_2FD820((this + 472), &a2);
    if ( v4 == 256 )
    {
      v13 = *&qword_4CB158;
    }
    else
    {
      v13 = v4;
    }
  }
  **v12 = v13;
  v14 = sub_2FD820(v11, &a2);
  if ( a4 )
  {
    v15 = *v14;
    v16 = round(COERCE_UNSIGNED_INT64((v4 / a4)), COERCE_UNSIGNED_INT64((v4 / a4)) >> 32);
    result = *sub_2FD820(v11, &a2);
    result[1] = *v15 / v16;
  }
  else
  {
    result = *v14;
    *(result + 1) = 0i64;
  }
  return result;
}
warrenarea commented 7 years ago

we can also know, that these functions provided, are not sub functions, or some part of other pieces of code, because each one makes reference to "Epoc" or "Epoc Plus".

warrenarea commented 7 years ago

_mm_unpckl_pd means to unpack and interleave double. which seems relevant.

also, i think you've probably noticed by now, theres lines like: "6d467bcbb30e27f94a7b01ee11fd18a5"

I'm pretty sure they are related to profiles, not entirely how that works, but pretty sure that's what they're related to.

SETP you may have seen that before as well, i believe its related to retrieving the HID device.

warrenarea commented 7 years ago

Also, SignalQualitySW... apparently it stands for "Signal Quality Square Wave"

warrenarea commented 7 years ago

pretty sure that long function is the one we're primarily after, it makes another reference to sub_2FDAE0 which also makes use of a qword_4C38C0: dq 3FA0000000000000h

which i believe is a double representation of 0.03125

theres a few other functions that reference it, and they seem to do a right shift 31 places, and then multiplies by 0.03125

I think at this point though, we're going to need someone who actually has the Epoc+ to set up a breakpoint, and look at the actual variables.

It might be difficult to read the memory as well in IDA, because we're using a double float, and I had a hard time deciphering the 0.03125 without the use of hex rays. In some places, I think it rounds off to integers too, so we should at least be able to see "some" recognizable integers probably in the 4000 range.

warrenarea commented 7 years ago

actually 3d000000h is the hex for float 0.03125

not sure if the 3FA0 provided above, may be something else entirely.

warrenarea commented 7 years ago
  sub_8BC1E0(
    &v11,
    "3581.5 3785.1 3401.0 3433.3 3581.5 3741.5 4079.0 3971.8 3967.7 3814.4 3581.0 3841.5 3396.9 3372.3",
    0x61u); 

Found this hard coded into a function, not sure why they would hard-code data values into it. only thing i could think of, was maybe to potentially set an initial baseline, or maybe some sort of testing code.

the code doesn't really show any indicators of being anything important, so not sure about this one.

warrenarea commented 7 years ago

heres another similar function. some sort of initialization.


 LOBYTE(v35) = 0;
  sub_8BC1E0(&v35, "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", 0x4Eu);
  LOBYTE(v48) = 1;
  v40 = 15;
  v39 = 0;
  LOBYTE(v38) = 0;
  sub_8BC1E0(&v38, "1.0,1.0, 1.0, 1.0, 1.0, 0.9, 1.0, 1.0, 1.0, 1.0, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0", 0x4Du);
  LOBYTE(v48) = 2;
  v43 = 15;
  v42 = 0;
  LOBYTE(v41) = 0;
  sub_8BC1E0(&v41, "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0", 0x4Eu);
  LOBYTE(v48) = 3;
  v1 = sub_A96060(&v30, qword_C3B530);
  LOBYTE(v48) = 4;
warrenarea commented 7 years ago

whats interesting is, a couple of these values are hard-coded at 0.9 not sure why they'd do that.

warrenarea commented 7 years ago

I've been looking into what we'll need for python, and it looks like we'll need a "long double"

i seen tons of Boost functions in pure.eeg, so i'm thinking they may have been trying to use it to improve performance.... so we might also try looking for some specific "boost" commands.

we might have to use an addon for python, like numpy or gmpy not entirely sure python has the capabilities to take care of the high precision floats natively.

ghost commented 7 years ago

Baseline is a good guess. Nice finds, I'll look at this more later this weekend.

minifiredragon commented 7 years ago

When I get a chance I will set a break point in that and run some tests and posts some screens. Should be able to by Sunday.

warrenarea commented 7 years ago

alright, so using my Epoc model, i've zeroed in on the functions for handling the data, and i'm pretty certain this is the function for handling the get_level for the Epoc.

warrenarea commented 7 years ago

okay so i found this nested in a HID function for "get free preparsed data"

i believe its a "wait" loop for incoming HID data.

char __thiscall sub_1254C00(void *this, int a2, DWORD dwMilliseconds)
{
  void *v3; // esi@1
  int v4; // eax@1
  int v5; // ecx@2
  unsigned int v6; // ebx@4
  int v7; // edi@5
  int v8; // edi@6
  int v9; // eax@6
  DWORD v10; // eax@8
  int v11; // eax@12
  int v12; // ecx@14
  unsigned __int16 v13; // ax@17
  size_t v14; // edi@19
  int v15; // ecx@19
  int v16; // eax@19
  unsigned int v17; // ebx@19
  int v18; // eax@19
  unsigned int v19; // ecx@19
  int v20; // eax@27
  __int16 v21; // ax@27
  void *v22; // ST08_4@27
  int v23; // eax@27
  int v24; // eax@27
  int v25; // eax@27
  void **v26; // edi@27
  int v27; // eax@34
  __int16 v28; // cx@37
  void *v30; // [sp-Ch] [bp-264h]@17
  const void *v31; // [sp-8h] [bp-260h]@17
  void *v32; // [sp+10h] [bp-248h]@27
  int v33; // [sp+14h] [bp-244h]@30
  int v34; // [sp+18h] [bp-240h]@30
  void *v35; // [sp+1Ch] [bp-23Ch]@27
  int v36; // [sp+20h] [bp-238h]@32
  int v37; // [sp+24h] [bp-234h]@32
  void *v38; // [sp+28h] [bp-230h]@27
  int v39; // [sp+2Ch] [bp-22Ch]@28
  int v40; // [sp+30h] [bp-228h]@28
  void *v41; // [sp+34h] [bp-224h]@1
  unsigned int v42; // [sp+38h] [bp-220h]@19
  int v43; // [sp+3Ch] [bp-21Ch]@19
  void **v44; // [sp+40h] [bp-218h]@1
  int v45; // [sp+44h] [bp-214h]@4
  char Src[512]; // [sp+48h] [bp-210h]@22
  int v47; // [sp+254h] [bp-4h]@27

  v3 = this;
  v41 = this;
  v4 = *this;
  v44 = a2;
  if ( !(*(v4 + 16))() )
  {
    return 0;
  }
  v5 = *(v3 + 134);
  if ( v5 >= *(v3 + 88) || WaitForSingleObject(*(32 * v5 + *(v3 + 87) + 28), dwMilliseconds) != 0 )
  {
    *(a2 + 4) = *a2;
    return 1;
  }
  v6 = 0;
  v45 = 0;
  do
  {
    v7 = *(v3 + 134);
    if ( v7 < *(v3 + 88) )
    {
      v8 = 32 * v7;
      v9 = v8 + *(v3 + 87);
      if ( *v9 || GetOverlappedResult(*(v3 + 90), (v9 + 12), v9, 0) )
      {
        ResetEvent(*(v8 + *(v3 + 87) + 28));
        v14 = 0;
        v15 = 32 * *(v3 + 134);
        v42 = *(v3 + 194);
        v16 = *(v3 + 87);
        v17 = *(v15 + v16);
        v18 = *(v15 + v16 + 4);
        v19 = 0;
        v43 = v18;
        if ( v17 )
        {
          do
          {
            if ( v14 >= 0x200 )
            {
              break;
            }
            if ( v19 % v42 )
            {
              Src[v14++] = *(v19 + v18);
            }
            ++v19;
          }
          while ( v19 < v17 );
          v3 = v41;
        }
        memcpy((v45 + *(v3 + 131)), Src, v14);
        v6 = v14 + v45;
        v45 += v14;
        goto LABEL_12;
      }
      v10 = GetLastError();
      if ( v10 == 38 || v10 == 1167 )
      {
        *(v3 + 540) = 1;
      }
    }
    if ( *(v3 + 540) )
    {
      (*(*v3 + 12))(v3);
      return 0;
    }
LABEL_12:
    sub_1253F20(v3, *(v3 + 134));
    ++*(v3 + 134);
    v11 = *(v3 + 88);
    if ( *(v3 + 134) >= v11 )
    {
      *(v3 + 134) = 0;
    }
    v12 = *(v3 + 134);
  }
  while ( v12 < v11 && WaitForSingleObject(*(32 * v12 + *(v3 + 87) + 28), 0) == 0 && v6 < *(v3 + 130) - 512 );
  v13 = (*(*v3 + 108))(v3, *(v3 + 541) == 0);
  v31 = *(v3 + 131);
  v30 = *(v3 + 133);
  if ( v13 < 0x10u )
  {
    memcpy(v30, v31, v6);
  }
  else
  {
    sub_1250980(v3, v30, v31, v6);
  }
  v20 = *v3;
  *(v3 + 541) = 1;
  v21 = (*(v20 + 80))(v3);
  v22 = *(v3 + 133);
  *(v3 + 75) = v21;
  v23 = sub_1250030(&v35, v22, v6);
  v47 = 0;
  v24 = sub_12503A0(v3, &v32, v23);
  LOBYTE(v47) = 1;
  v25 = sub_1250F40(v3, &v38, v24);
  v26 = v44;
  LOBYTE(v47) = 2;
  sub_1253BB0(v44, v25);
  if ( v38 )
  {
    operator delete(v38);
    v38 = 0;
    v39 = 0;
    v40 = 0;
  }
  if ( v32 )
  {
    operator delete(v32);
    v32 = 0;
    v33 = 0;
    v34 = 0;
  }
  v47 = -1;
  if ( v35 )
  {
    operator delete(v35);
    v35 = 0;
    v36 = 0;
    v37 = 0;
  }
  if ( (v26[1] - *v26) / 96 )
  {
    v27 = clock();
    sub_1252860(v3, v27);
  }
  if ( *(v3 + 8) != 1 )
  {
    (*(*v3 + 108))(v3, 1);
    if ( !sub_1250A00(*(v3 + 74)) )
    {
      v28 = *(v3 + 74);
      if ( v28 >= 0x25u && (v28 & 0xFF00) != 1280 )
      {
        sub_125B7D0(v3);
        *(v3 + 8) = 1;
        return 1;
      }
      (*(*v3 + 40))(v3);
    }
    *(v3 + 8) = 1;
  }
  return 1;
}
warrenarea commented 7 years ago

line 142

  v23 = sub_1250030(&v35, v22, v6);   ------ Possible "space" splitting function.
  v47 = 0;
  v24 = sub_12503A0(v3, &v32, v23);   ------ I believe this contains the get_level function.
  LOBYTE(v47) = 1;
  v25 = sub_1250F40(v3, &v38, v24);   ------ not entirely sure, a lot going on in this one, data formatting?
warrenarea commented 7 years ago

sub_1250030 nothing spectacular about this one other than a reference to 32 decimal, which would translate to a character space... and some vector references, which would go along with the theory that its splitting the data up into an array.

plus it references a long 64byte value, which is likely the parsed data.

warrenarea commented 7 years ago

sub_12503A0

int __thiscall sub_12503A0(void *this, int a2, int a3)
{
  void *v3; // ebx@1
  int v4; // edi@1
  int i; // esi@1
  unsigned int v6; // ecx@3
  int v7; // eax@3
  unsigned int v8; // eax@6
  unsigned int v9; // edx@6
  signed int v10; // edi@6
  unsigned int v11; // ecx@7
  int v12; // ecx@11
  unsigned __int8 v13; // al@19
  bool v14; // sf@19
  int v15; // eax@20
  void *v16; // eax@22
  unsigned int v17; // edx@22
  int v18; // edi@22
  __m128i v19; // xmm1@22
  int v20; // ecx@22
  __m128i v21; // xmm0@22
  void *v22; // eax@22
  void *v24; // [sp+14h] [bp-90h]@22
  int v25; // [sp+20h] [bp-84h]@1
  void *v26; // [sp+24h] [bp-80h]@6
  int v27; // [sp+28h] [bp-7Ch]@6
  int v28; // [sp+30h] [bp-74h]@1
  char Dst; // [sp+34h] [bp-70h]@1
  int v30; // [sp+38h] [bp-6Ch]@3
  int v31; // [sp+3Ch] [bp-68h]@3
  int v32; // [sp+40h] [bp-64h]@14
  __m128i v33; // [sp+44h] [bp-60h]@6
  int v34; // [sp+54h] [bp-50h]@22
  int v35; // [sp+60h] [bp-44h]@13
  __int128 v36; // [sp+64h] [bp-40h]@22
  __int128 v37; // [sp+74h] [bp-30h]@22
  unsigned int v38; // [sp+84h] [bp-20h]@17
  unsigned int v39; // [sp+88h] [bp-1Ch]@17
  unsigned int v40; // [sp+8Ch] [bp-18h]@17
  unsigned int v41; // [sp+90h] [bp-14h]@4
  int v42; // [sp+A0h] [bp-4h]@1

  v3 = this;
  v4 = a2;
  v25 = a2;
  *a2 = 0;
  *(a2 + 4) = 0;
  *(a2 + 8) = 0;
  v42 = 0;
  v28 = 1;
  memset(&Dst, 0, 0x60u);
  for ( i = *a3; i != *(a3 + 4); *(v3 + 55) += (*(v4 + 4) - *v4) / 96 )
  {
    if ( (*(*v3 + 76))(v3) == 2 )
    {
      v6 = *(i + 1);
      v30 = *i;
      v7 = v6 & 0x7F;
      v31 = v7;
      if ( v7 == 16 )
      {
        v41 = v6 >> 7;
      }
      else
      {
        v41 = 0;
      }
      sub_1252F80(&v26, v7, i, 30);
      v8 = 0;
      v9 = (v27 - v26) >> 2;
      v10 = v26 - &v33;
      while ( 1 )
      {
        v11 = 16;
        if ( v9 < 0x10 )
        {
          v11 = v9;
        }
        if ( v8 >= v11 )
        {
          break;
        }
        v33.m128i_i32[v8] = *(&v33.m128i_i32[v8] + v10);
        ++v8;
      }
      v12 = v31;
      if ( v30 != *(v3 + 75) - 1 || v31 != 16 )
      {
        v32 = *(v3 + 49);
        if ( v31 == 32 )
        {
          *(v3 + 23) = v33.m128i_i64[0];
        }
      }
      else if ( v35 )
      {
        v32 = v35 & 0x7F;
        *(v3 + 49) = v32;
      }
      v38 = *(v3 + 46);
      v39 = *(v3 + 47);
      v40 = v12;
      if ( v26 )
      {
        operator delete(v26);
        v26 = 0;
        v27 = 0;
      }
    }
    else
    {
      v13 = *i;
      v14 = *i < 0;
      v31 = 0;
      if ( v14 )
      {
        v15 = v13 & 0x7F;
        v30 = 128;
        *(v3 + 49) = v15;
      }
      else
      {
        v30 = v13;
        v15 = *(v3 + 49);
      }
      v32 = v15;
      sub_1252F80(&v24, 0, i, 32);
      v16 = v24;
      v17 = *(i + 31);
      v18 = 16 * *(i + 29);
      v19 = _mm_loadu_si128(v24 + 2);
      v20 = 16 * *(i + 30);
      _mm_storeu_si128(&v33, _mm_loadu_si128(v24));
      v40 = v17;
      v21 = _mm_loadu_si128(v16 + 1);
      _mm_storeu_si128(&v36, v19);
      _mm_storeu_si128(&v34, v21);
      _mm_storeu_si128(&v37, _mm_loadu_si128(v16 + 3));
      v41 = (_mm_cvtsi128_si32(v19) >> 13) & 1;
      v38 = (v17 >> 4) | v18;
      *(v3 + 46) = v38;
      v22 = v24;
      v39 = v17 & 0xF | v20;
      *(v3 + 47) = v39;
      if ( v22 )
      {
        operator delete(v22);
        v24 = 0;
      }
    }
    v4 = v25;
    sub_1251AE0(v25, &Dst);
    i += 32;
  }
  return v4;
}
warrenarea commented 7 years ago

Note: only when the headset is turned on and its receiving data... does it stop in these functions.

if ( ((v3 + 76))(v3) == 2 )

my Epoc does not enter into this function, i think its possible that this may be a differential indetermining which headset is being used.

the functions to note here though, is: sub_1252F80(&v26, v7, i, 30)

There is another Else condition, that my Epoc model enters into: sub_1252F80(&v26, v7, i, 32)

when i hover over on v33 _mm_storeu_si128(&v33, _mm_loadu_si128(v24)); i get i8{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }} obviously an 8-bit array of ints.

v19 appears to be 16 hex bytes in an array.

sub_1252F80(&v26, v7, i, 32) references a sub_1252AB0(a1, a2, a3, a4, 14, 16);


1. int __stdcall sub_1252AB0(int a1, int a2, int a3, signed int a4, int a5, int a6)
2. {
3.   int *v6; // edx@1
4.   int *v7; // esi@1
5.   int v8; // ecx@1
6.   int result; // eax@2
7.   int v10; // ebx@3
8.   signed int v11; // edi@4
9.   unsigned int v12; // esi@5
10.   int v13; // eax@6
11.   int v14; // eax@9
12.   int v15; // ecx@21
13.   int v16; // ecx@21
14.   int v17; // ecx@21
15.   int v18; // ecx@21
16.   int v19; // ecx@21
17.   int v20; // ecx@21
18.   signed int v21; // ebx@22
19.   signed int v22; // eax@26
20.   int v23; // edi@27
21.   int v24; // ecx@27
22.   signed int v25; // esi@28
23.   int v26; // edi@29
24.   int v27; // edx@29
25.   int v28; // eax@29
26.   unsigned int v29; // edx@31
27.   _DWORD *v30; // edx@31
28.   int v31; // eax@36
29.   bool v32; // zf@42
30.   int v33; // ecx@46
31.   void *v34; // [sp+10h] [bp-24h]@1
32.   int *v35; // [sp+14h] [bp-20h]@1
33.   int *v36; // [sp+18h] [bp-1Ch]@1
34.   int v37; // [sp+1Ch] [bp-18h]@1
35.   int v38; // [sp+20h] [bp-14h]@31
36.   int v39; // [sp+24h] [bp-10h]@10
37.   int v40; // [sp+30h] [bp-4h]@1
38. 
39.   v6 = 0;
40.   v37 = 0;
41.   v7 = 0;
42.   v34 = 0;
43.   v35 = 0;
44.   v36 = 0;
45.   v8 = a3;
46.   v40 = 0;
47.   if ( !a3 )
48.   {
49.     result = a1;
50.     *a1 = a3;
51.     *(a1 + 4) = v8;
52.     *(a1 + 8) = v8;
53.     return result;
54.   }
55.   v10 = 0;
56.   if ( a2 > 0 )
57.   {
58.     v11 = 2;
59.     if ( (a4 + 2) > 2 )
60.     {
61.       v12 = a4 + 2;
62.       while ( 1 )
63.       {
64.         v13 = a2;
65.         if ( !(v11 % 2) )
66.         {
67.           v10 = *(v11 + v8);
68.           goto LABEL_15;
69.         }
70.         if ( a2 == 32 )
71.         {
72.           v14 = (v10 | (*(v11 + v8) << 8));
73.           if ( v11 == 5 )
74.           {
75.             v39 = (0x8000 - v14) >> 2;
76.           }
77.           else
78.           {
79.             v39 = (v14 + 0x8000) >> 2;
80.           }
81.         }
82.         else
83.         {
84.           if ( a2 != 16 )
85.           {
86.             goto LABEL_15;
87.           }
88.           v39 = (*(v11 + v8) << 8) | v10;
89.         }
90.         (sub_12C52D0)(&v39);
91.         v10 = v39;
92.         v13 = a2;
93. LABEL_15:
94.         if ( v11 == 17 && v13 == 16 )
95.         {
96.           a6 = 0;
97.           (sub_12C52D0)(&a6);
98.         }
99.         v8 = a3;
100.         if ( ++v11 >= v12 )
101.         {
102.           v7 = v35;
103.           v6 = v34;
104.           break;
105.         }
106.       }
107.     }
108.     if ( a2 == 32 )
109.     {
110.       a2 = 0;
111.       (sub_12C52D0)(&a2);
112.       v6 = v34;
113.       v7 = v35;
114.       v15 = *v34;
115.       *v34 = *(v34 + 2);
116.       v6[2] = v15;
117.       v16 = *v6;
118.       *v6 = v6[1];
119.       v6[1] = v16;
120.       v17 = v6[3];
121.       v6[3] = v6[5];
122.       v6[5] = v17;
123.       v18 = v6[3];
124.       v6[3] = v6[4];
125.       v6[4] = v18;
126.       v19 = v6[6];
127.       v6[6] = v6[8];
128.       v6[8] = v19;
129.       v20 = v6[6];
130.       v6[6] = v6[7];
131.       v6[7] = v20;
132.     }
133.     goto LABEL_46;
134.   }
135.   v21 = a5;
136.   if ( 8 * a4 >= (a6 * a5) )
137.   {
138.     a2 = 0;
139.     v22 = 1;
140.     a4 = 1;
141.     if ( !a6 )
142.     {
143. LABEL_44:
144.       if ( (v7 - v6) >= 0x10 )
145.       {
146.         v6[1] = floor(8192.0 - (v6[1] - 8192.0));
147.         v6[10] = floor(8192.0 - (v6[10] - 8192.0));
148.         v6[15] = floor(8192.0 - (v6[15] - 8192.0));
149.       }
150. LABEL_46:
151.       result = a1;
152.       v33 = v36;
153.       *a1 = v6;
154.       *(a1 + 4) = v7;
155.       *(a1 + 8) = v33;
156.       return result;
157.     }
158.     while ( 1 )
159.     {
160.       v23 = 0;
161.       v24 = 8 - a2;
162.       if ( a5 > 8 - a2 )
163.       {
164.         v25 = a4;
165.         a2 = 0;
166.         do
167.         {
168.           v21 -= v24;
169.           v26 = v23 << v24;
170.           v27 = *(v25++ + a3);
171.           v28 = (1 << v24) - 1;
172.           v24 = 8;
173.           v23 = v28 & v27 | v26;
174.         }
175.         while ( v21 > 8 );
176.         a4 = v25;
177.         v7 = v35;
178.         v22 = a4;
179.       }
180.       a2 += v21;
181.       v29 = (v23 << v21) | ((1 << v21) - 1) & (*(v22 + a3) >> (v24 - v21));
182.       v38 = v29;
183.       v39 = v29;
184.       v30 = v34;
185.       if ( &v39 >= v7 || v34 > &v39 )
186.       {
187.         if ( v7 == v36 )
188.         {
189.           (vector_list)(1);
190.           v7 = v35;
191.         }
192.         if ( !v7 )
193.         {
194.           goto LABEL_42;
195.         }
196.         v31 = v38;
197.       }
198.       else
199.       {
200.         if ( v7 == v36 )
201.         {
202.           (vector_list)(1);
203.           v7 = v35;
204.           v30 = v34;
205.         }
206.         if ( !v7 )
207.         {
208.           goto LABEL_42;
209.         }
210.         v31 = v30[(&v39 - v34) >> 2];
211.       }
212.       *v7 = v31;
213. LABEL_42:
214.       v22 = a4;
215.       ++v7;
216.       v32 = a6-- == 1;
217.       v21 = a5;
218.       v35 = v7;
219.       if ( v32 )
220.       {
221.         v6 = v34;
222.         goto LABEL_44;
223.       }
224.     }
225.   }
226.   (sub_112D5B0)(&v34);
227.   if ( v34 )
228.   {
229.     operator delete(v34);
230.   }
231.   return a1;
232. }

line 59 if ( (a4 + 2) > 2 )

my Epoc does not trigger any breakpoints here, possibly Epoc+ function.

line 108. if ( a2 == 32 )

my Epoc does not trigger any breakpoints here, possibly Epoc+ function.

line 136 my Epoc starts going into the IF-statements. Line 144 if ( (v7 - v6) >= 0x10 ) ------- i think this is looking for the End of data line.

Line 146-148 v6[1] = floor(8192.0 - (v6[1] - 8192.0)); v6[10] = floor(8192.0 - (v6[10] - 8192.0)); v6[15] = floor(8192.0 - (v6[15] - 8192.0));

This is where it gets interesting, and is a clear indicator it is handling the data values.

Line 166 - 174 I really think this is the get_level for the Epoc, it looks very similar to the math used in the Emotiv.py

def get_level(data, bits):
    """
    Returns sensor level value from data using sensor bit mask in micro volts (uV).
    """
    level = 0
    for i in range(13, -1, -1):
        level <<= 1
        b, o = (bits[i] / 8) + 1, bits[i] % 8
        level |= (ord(data[b]) >> o) & 1
    return level

This python format isn't really the greatest for readability, as its been optimized. I think I did tinker with it in the past, and some of the values do seem familiar.

Just like in this function, the value of 'a2' goes backwards, from 8, 6, 4, 2, 0 where I think it may skip some... which i think bits[i] does something similar, as its reading the bits from sensor_bits

a few of the other variables seem to be going backwards too. I don't think there is a reference to 14 (coded value 13) sensors, because i think its just looping until it reaches the Line Feed. 0x10.

Line 181 might be more relevant though, because... python get_level seems to do a | >> &

where the code in 168-173 does a << left shift.

on line 181

      v29 = (v23 << v21) | ((1 << v21) - 1) & (*(v22 + a3) >> (v24 - v21));

the code exits out at line 156, right before this though, it seems to pass 3 values back to the previous function. one of the values is data... one "result" its passing back is 0x348f284 which converts to 55112324... this could be potentially important. this seems to be static... at first i thought maybe it was the quality... but it wasn't.

warrenarea commented 7 years ago

i am pretty confident this is the function we're looking for... at least for the regular Epoc.

warrenarea commented 7 years ago

For Insight, it seems to be a little more straight forward.

char __thiscall sub_1189C70(int this, int a2, struct QString::Data *a3, int a4)
{
  int v4; // edi@1
  int v5; // eax@1
  struct QString::Data *v6; // esi@2
  struct QString::Data *v7; // ST20_4@2
  int v8; // esi@3
  const struct QString *v9; // eax@9
  const struct QString *v10; // esi@12

  v4 = this;
  LOBYTE(v5) = (*(*(this + 16) + 4) >> 15) & 1;
  if ( v5 )
  {
    v6 = a3;
    v7 = a3;
    *(this + 28) = 1;
    *(this + 40) = sub_119BCE0(v7, 3);
    *(v4 + 44) = sub_119BCE0(v6, 16);
    *(v4 + 48) = sub_119BCE0(v6, 7);
    *(v4 + 52) = sub_119BCE0(v6, 12);
    *(v4 + 56) = sub_119BCE0(v6, 9);
    v5 = sub_114E290(*(v4 + 36));
    if ( a2 == v5 )
    {
      v8 = sub_119BCF0(v6);
      a3 = QString::fromAscii_helper("image:url(:/Resources/Sensorsignal/", -1);
      if ( v8 )
      {
        if ( *(v4 + 40) || *(v4 + 44) || *(v4 + 48) || *(v4 + 52) || *(v4 + 56) )
        {
          v9 = QString::fromAscii(&a2, "fr1.png);", -1);
        }
        else
        {
          v9 = QString::fromAscii(&a2, "fr2.png);", -1);
        }
      }
      else
      {
        v9 = QString::fromAscii(&a2, "fr3.png);", -1);
      }
      v10 = QString::append(&a3, v9);
      QString::~QString(&a2);
      QWidget::setStyleSheet(*(*(v4 + 20) + 48), v10);
      sub_118A090(v4);
      LOBYTE(v5) = QString::~QString(&a3);
    }
  }
  return v5;
}

and then... sub_119BCF0(v6) references:

signed int __cdecl sub_125BFE0(int a1)
{
  __m128 v1; // xmm2@1
  signed int result; // eax@2

  v1 = *(a1 + 116);
  if ( v1.m128_f32[0] > 0.0 )
  {
    if ( COERCE_DOUBLE(_mm_cvtps_pd(v1)) > 0.79 )
    {
      result = 0;
      if ( v1.m128_f32[0] <= 1.0 )
      {
        result = 2;
      }
    }
    else
    {
      result = 1;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}
warrenarea commented 7 years ago

let me know if you guys have any decompiler failures, i've managed to work my way through a few of them.

and i'm going to assume you guys are using hex-rays too.

warrenarea commented 7 years ago
signed int __stdcall sub_12ABD80(int a1)
{
  unsigned int v1; // ecx@1
  int v2; // esi@1
  signed int v3; // ecx@1
  double v4; // xmm1_8@1
  signed int result; // eax@2

  v1 = *(a1 + 4);
  v2 = v1 - 1;
  array_indexing(a1, (v1 - 1) / v1, (v1 - 1) % v1);
  v3 = 0;
  v4 = *(*(a1 + 8) + 8 * v2);
  if ( v4 < 106.0 )
  {
    if ( v4 <= 102.0 || v4 >= 106.0 )
    {
      if ( v4 <= 99.0 || v4 >= 103.0 )
      {
        __asm { lahf }
        if ( __SETP__(_AH & 0x44, 0) )
        {
          if ( v4 >= 99.0 || v4 <= 90.0 )
          {
            if ( v4 <= 90.0 )
            {
              v3 = -1;
            }
            result = v3;
          }
          else
          {
            result = 0;
          }
        }
        else
        {
          result = 1;
        }
      }
      else
      {
        result = 2;
      }
    }
    else
    {
      result = 3;
    }
  }
  else
  {
    result = 4;
  }
  return result;
}

I can say with certainty that this is the function for the battery level (at very least for the Epoc, but i think its the same for Epoc+)

my unit had a fresh charge, and the battery indicator said it was full. So I patched the program "Result = 4" to one of the lower numbers, (ie 4,3,2,1,0) and the battery indicator dropped down accordingly.

So I think we can nail down that one, line 11, puts the battery data into an array (and performs some division) then line 13 uses a pointer to access the array.

warrenarea commented 7 years ago

v2 = 3F (ie 63) v4, i think is the raw data, and it is iterating through the data. v2 is probably just to index the data by 64-bit long chunks.


                     <= 90  ==  -1
       Check Device Failure ==   0
                     90-99  ==   1
                    99-103  ==   2
                   102-106  ==   3
                     > 106  ==   4
warrenarea commented 7 years ago

another great find, this is the function that creates the crypt key, and also shows the research version as well. again, this function is nested inside the "HID_FreePreparsedData" import symbol. Which seems to be where most of the emokit functions seem to reside.

char __thiscall sub_129B680(void *this)
{
  _DWORD *v1; // edi@1
  char v2; // bl@2
  char *v3; // eax@3
  int v4; // edi@5
  char v5; // cl@5
  char *v6; // eax@5
  char v7; // dl@7
  char *v8; // eax@7
  char v9; // bl@9
  char *v10; // eax@9
  char v11; // al@11
  int v13; // [sp+Ch] [bp-20h]@1
  void *v14; // [sp+10h] [bp-1Ch]@1
  unsigned int v15; // [sp+20h] [bp-Ch]@1
  unsigned int v16; // [sp+24h] [bp-8h]@3
  unsigned int v17; // [sp+28h] [bp-4h]@1
  _DWORD *savedregs; // [sp+2Ch] [bp+0h]@1

  savedregs = &savedregs;
  v17 = &savedregs ^ __security_cookie;
  v1 = this;
  _mm_storeu_si128((this + 158), 0i64);
  v13 = this + 158;
  (*(*this + 96))(&v14);
  if ( v15 < 5 )
  {
    v2 = 0;
    goto LABEL_19;
  }
  v3 = &v14;
  if ( v16 >= 8 )
  {
    v3 = v14;
  }
  v4 = v1[1];
  v5 = v3[2 * v15 - 2];
  v6 = &v14;
  if ( v16 >= 8 )
  {
    v6 = v14;
  }
  v7 = v6[2 * v15 - 4];
  v8 = &v14;
  if ( v16 >= 8 )
  {
    v8 = v14;
  }
  v9 = v8[2 * v15 - 6];
  v10 = &v14;
  if ( v16 >= 8 )
  {
    v10 = v14;
  }
  v11 = v10[2 * v15 - 8];
  if ( v4 != -1 )
  {
    *v13 = v5;
    if ( !v4 )
    {
      *(v13 + 1) = 0;
      *(v13 + 2) = v7;
      *(v13 + 3) = 72;
      *(v13 + 4) = v5;
      *(v13 + 5) = 0;
      *(v13 + 6) = v7;
      *(v13 + 7) = 84;
      *(v13 + 8) = v9;
      *(v13 + 9) = 16;
      *(v13 + 10) = v11;
      *(v13 + 11) = 66;
LABEL_17:
      *(v13 + 12) = v9;
      *(v13 + 13) = 0;
      *(v13 + 14) = v11;
      *(v13 + 15) = 80;
      goto LABEL_18;
    }
    if ( v4 != 2 )
    {
      *(v13 + 1) = 0;
      *(v13 + 2) = v7;
      *(v13 + 3) = 84;
      *(v13 + 4) = v9;
      *(v13 + 5) = 16;
      *(v13 + 6) = v11;
      *(v13 + 7) = 66;
      *(v13 + 8) = v5;
      *(v13 + 9) = 0;
      *(v13 + 10) = v7;
      *(v13 + 11) = 72;
      goto LABEL_17;
    }
    *(v13 + 1) = v5;
    *(v13 + 2) = v7;
    *(v13 + 3) = v7;
    *(v13 + 4) = v9;
    *(v13 + 5) = v9;
    *(v13 + 6) = v11;
    *(v13 + 7) = v11;
    *(v13 + 8) = v5;
    *(v13 + 9) = v5;
    *(v13 + 10) = v7;
    *(v13 + 11) = v7;
    *(v13 + 12) = v9;
    *(v13 + 13) = v9;
    *(v13 + 14) = v11;
    *(v13 + 15) = v11;
  }
LABEL_18:
  v2 = 1;
LABEL_19:
  if ( v16 >= 8 )
  {
    operator delete(v14);
  }
  return v2;
}

The memory result in IDA matches up to being the emokit Research Key however the data output for emokit seemed incorrect using that key. but seemed to output correctly using the non-research key.

not entirely sure what is going on there, unless its just piecing the research key together as well. will have to look into.

**Update: I can confirm thats whats happening, it pieces together both keys. accessing the function twice and pieces them together separately.

warrenarea commented 7 years ago

to verify some of the primary ascii characters above (at a glance) B=66 P=80 84=T H=72