PwnAdventure3 icon indicating copy to clipboard operation
PwnAdventure3 copied to clipboard

Circuit Reversing

Open balika011 opened this issue 6 years ago • 2 comments

What processes the circuit's state is the GameAPI::GetCircuitOutputs. This function is missing from the GameLogic library. For the offline mode it's implemented in the PwnAdventure3-[Plaform]-Shipping and calls a script in the game. For online mode it's implemented in the GameServer. What you are looking for is the CircuitFinalStage::Update function. If you open it up in IDA this is what you get:

char __fastcall CircuitFinalStage::Update(CircuitFinalStage *this)
{
  char v1; // al
  char v2; // al
  char v3; // al
  char v4; // al
  char v5; // r14
  char v6; // bp
  char v7; // si
  char v8; // al
  char v9; // r15
  char v10; // r8
  char v11; // dl
  char v12; // r12
  char v13; // r9
  char v14; // dl
  char v15; // al
  char v16; // r11
  char v17; // r13
  char v18; // r10
  char v19; // cl
  char v20; // al
  char v21; // r9
  char v22; // al
  char v23; // bl
  char v24; // al
  char v25; // si
  char v26; // cl
  char v27; // al
  char v28; // dl
  char v29; // al
  char v30; // al
  char v31; // al
  char v32; // cl
  char v33; // r11
  char v34; // al
  char v35; // al
  char v36; // r13
  char v37; // al
  char v38; // dl
  char v39; // al
  bool v40; // zf
  char v41; // al
  char v42; // al
  char v43; // al
  char v44; // al
  char v45; // dl
  char v46; // al
  char v47; // r14
  char v48; // al
  char v49; // cl
  char v50; // bl
  char v51; // r9
  char v52; // r8
  char v53; // r13
  char v54; // si
  char v55; // r11
  char v56; // al
  char v57; // cl
  char v58; // dl
  char v59; // r10
  char v60; // al
  bool v61; // r12
  char v62; // bl
  char v63; // r15
  char v64; // al
  char v65; // dl
  char v66; // dl
  char v67; // cl
  char v68; // r9
  char v69; // r14
  char v70; // al
  char v71; // al
  char v72; // si
  char v73; // r13
  char v74; // cl
  char v75; // r8
  char v76; // cl
  char v77; // bp
  bool v78; // r12
  char v79; // bl
  char v80; // bp
  char v81; // dl
  char v82; // bl
  char v83; // al
  bool v84; // dl
  char v85; // r11
  char v86; // r10
  char v87; // cl
  char v88; // r9
  char v89; // al
  char v90; // al
  char v91; // r15
  char v92; // r15
  bool v93; // r8
  char v94; // cl
  bool v95; // r9
  char v96; // al
  char v97; // cl
  char v98; // al
  char v99; // dl
  char v100; // dl
  bool v101; // si
  char v102; // bl
  char v103; // cl
  bool v104; // cl
  char v105; // al
  char v106; // dl
  char v107; // dl
  char v108; // r8
  char v109; // bl
  char v110; // cl
  bool v111; // r8
  char v112; // r14
  char result; // al
  char v114; // dl
  char v115; // bl
  char v116; // cl
  char v117; // [rsp+15h] [rbp-1Bh]
  char v118; // [rsp+16h] [rbp-1Ah]
  char v119; // [rsp+18h] [rbp-18h]
  char v120; // [rsp+1Ah] [rbp-16h]
  char v121; // [rsp+1Bh] [rbp-15h]
  char v122; // [rsp+1Ch] [rbp-14h]
  char v123; // [rsp+1Dh] [rbp-13h]
  char v124; // [rsp+1Eh] [rbp-12h]
  char v125; // [rsp+1Fh] [rbp-11h]
  char v126; // [rsp+1Fh] [rbp-11h]
  char v127; // [rsp+20h] [rbp-10h]
  char v128; // [rsp+20h] [rbp-10h]
  char v129; // [rsp+21h] [rbp-Fh]
  char v130; // [rsp+21h] [rbp-Fh]
  char v131; // [rsp+22h] [rbp-Eh]
  char v132; // [rsp+22h] [rbp-Eh]
  unsigned __int8 v133; // [rsp+23h] [rbp-Dh]
  char v134; // [rsp+24h] [rbp-Ch]
  char v135; // [rsp+24h] [rbp-Ch]
  char v136; // [rsp+25h] [rbp-Bh]
  char v137; // [rsp+25h] [rbp-Bh]
  char v138; // [rsp+26h] [rbp-Ah]
  char v139; // [rsp+27h] [rbp-9h]
  char v140; // [rsp+27h] [rbp-9h]
  char v141; // [rsp+28h] [rbp-8h]
  char v142; // [rsp+29h] [rbp-7h]
  unsigned __int8 v143; // [rsp+29h] [rbp-7h]
  char v144; // [rsp+2Ah] [rbp-6h]
  char v145; // [rsp+2Bh] [rbp-5h]
  char v146; // [rsp+2Bh] [rbp-5h]
  char v147; // [rsp+2Ch] [rbp-4h]
  char v148; // [rsp+2Ch] [rbp-4h]
  char v149; // [rsp+2Dh] [rbp-3h]
  char v150; // [rsp+2Dh] [rbp-3h]
  char v151; // [rsp+2Eh] [rbp-2h]
  char v152; // [rsp+2Eh] [rbp-2h]
  char v153; // [rsp+2Fh] [rbp-1h]
  char v154; // [rsp+2Fh] [rbp-1h]
  char v155; // [rsp+2Fh] [rbp-1h]

  this->m_trace[23] = this->m_input[0];
  this->m_trace[18] = this->m_input[1];
  this->m_trace[13] = this->m_input[2];
  this->m_trace[97] = this->m_input[3];
  this->m_trace[106] = this->m_input[4];
  this->m_trace[117] = this->m_input[5];
  this->m_trace[129] = this->m_input[6];
  this->m_trace[80] = this->m_input[7];
  this->m_trace[76] = this->m_input[8];
  v1 = this->m_input[9];
  v124 = v1;
  this->m_trace[69] = v1;
  v2 = this->m_input[10];
  v125 = v2;
  this->m_trace[62] = v2;
  v3 = this->m_input[11];
  v123 = v3;
  this->m_trace[55] = v3;
  v4 = this->m_input[12];
  v122 = v4;
  this->m_trace[48] = v4;
  v5 = this->m_input[13];
  this->m_trace[42] = v5;
  v6 = this->m_input[14];
  this->m_trace[35] = v6;
  v7 = this->m_input[15];
  this->m_trace[29] = v7;
  v8 = this->m_input[16];
  v147 = v8;
  this->m_trace[44] = v8;
  v9 = this->m_input[17];
  this->m_trace[37] = v9;
  v10 = this->m_input[18];
  this->m_trace[30] = v10;
  v11 = this->m_input[19];
  this->m_trace[25] = v11;
  v12 = this->m_input[20];
  this->m_trace[19] = v12;
  v13 = this->m_input[21];
  this->m_trace[15] = v13;
  this->m_trace[98] = this->m_input[22];
  this->m_trace[107] = this->m_input[23];
  this->m_trace[119] = this->m_input[24];
  this->m_trace[131] = this->m_input[25];
  v13 ^= 1u;
  v14 = v11 ^ 1;
  v15 = this->m_input[26];
  v117 = v15;
  this->m_trace[81] = v15;
  v16 = this->m_input[27];
  this->m_trace[78] = v16;
  v17 = this->m_input[28];
  this->m_trace[71] = v17;
  v18 = this->m_input[29];
  this->m_trace[64] = v18;
  v19 = this->m_input[30];
  this->m_trace[57] = v19;
  v20 = this->m_input[31];
  v153 = v20;
  this->m_trace[50] = v20;
  this->m_trace[14] = v13;
  v21 = this->m_trace[13] ^ v13;
  this->m_trace[12] = v21;
  v22 = this->m_trace[18];
  v119 = v22;
  if ( v22 )
    v22 = v12;
  v121 = v22;
  this->m_trace[17] = v22;
  this->m_trace[24] = v14;
  v23 = this->m_trace[23];
  v118 = v23;
  if ( v23 )
    v23 = v14;
  v145 = v19;
  this->m_trace[22] = v23;
  v24 = v7;
  v120 = v7;
  if ( v7 )
    v24 = v10;
  v136 = v24;
  this->m_trace[28] = v24;
  this->m_trace[34] = v6 ^ 1;
  v25 = 0;
  this->m_trace[36] = v9 ^ 1;
  v26 = 0;
  if ( v6 != 1 )
    v26 = v9 ^ 1;
  this->m_trace[33] = v26;
  this->m_trace[41] = v5 ^ 1;
  this->m_trace[43] = v147 ^ 1;
  v151 = 0;
  if ( v5 != 1 )
    v151 = v147 ^ 1;
  v142 = v14;
  v27 = 0;
  if ( v124 != 1 )
    v27 = v17 ^ 1;
  v134 = v26;
  v149 = 0;
  if ( v125 != 1 )
    v149 = v18 ^ 1;
  v129 = v27;
  v139 = v10;
  v28 = v153 ^ 1;
  v29 = v122;
  if ( v122 )
    v29 = v153 ^ 1;
  v131 = v29;
  this->m_trace[40] = v151;
  this->m_trace[49] = v28;
  v154 = v153 ^ 1;
  this->m_trace[47] = v29;
  v30 = 0;
  if ( v123 != 1 )
    v30 = v145 ^ 1;
  v127 = v30;
  this->m_trace[54] = v123 ^ 1;
  this->m_trace[56] = v145 ^ 1;
  this->m_trace[53] = v30;
  this->m_trace[61] = v125 ^ 1;
  this->m_trace[63] = v18 ^ 1;
  this->m_trace[60] = v149;
  this->m_trace[68] = v124 ^ 1;
  this->m_trace[70] = v17 ^ 1;
  this->m_trace[67] = v129;
  v31 = this->m_trace[76];
  this->m_trace[75] = this->m_trace[76] ^ 1;
  this->m_trace[77] = v16 ^ 1;
  v32 = 0;
  if ( v31 != 1 )
    v32 = v16 ^ 1;
  this->m_trace[74] = v32;
  v33 = v31 ^ v16;
  this->m_trace[82] = v33;
  if ( this->m_trace[80] )
  {
    v34 = v117;
    if ( v117 )
      v34 = v33;
    v25 = v34;
  }
  this->m_trace[79] = v25;
  v35 = 1;
  if ( !v32 )
    v35 = v25 & 1;
  this->m_trace[73] = v35;
  v36 = v124 ^ v17;
  this->m_trace[83] = v36;
  if ( v35 )
    v35 = v36;
  this->m_trace[72] = v35;
  v130 = v35 | v129;
  this->m_trace[66] = v130;
  this->m_trace[84] = v125 ^ v18;
  v37 = v130;
  if ( v130 )
    v37 = v125 ^ v18;
  this->m_trace[65] = v37;
  v150 = v37 | v149;
  v38 = v122 ^ v28;
  this->m_trace[59] = v150;
  this->m_trace[85] = v123 ^ v145;
  v39 = v150;
  if ( v150 )
    v39 = v123 ^ v145;
  this->m_trace[58] = v39;
  v40 = ((unsigned __int8)v39 | (unsigned __int8)v127) == 0;
  v128 = v39 | v127;
  this->m_trace[52] = v128;
  this->m_trace[86] = v38;
  v41 = v128;
  if ( !v40 )
    v41 = v122 ^ v154;
  v133 = v125 ^ v18;
  v155 = v122 ^ v154;
  this->m_trace[51] = v41;
  v40 = ((unsigned __int8)v41 | (unsigned __int8)v131) == 0;
  v132 = v41 | v131;
  this->m_trace[46] = v132;
  this->m_trace[87] = v5 ^ v147;
  v42 = v132;
  if ( !v40 )
    v42 = v5 ^ v147;
  v146 = v123 ^ v145;
  this->m_trace[45] = v42;
  v40 = ((unsigned __int8)v42 | (unsigned __int8)v151) == 0;
  v152 = v42 | v151;
  this->m_trace[39] = v152;
  this->m_trace[88] = v6 ^ v9;
  v43 = v152;
  if ( !v40 )
    v43 = v6 ^ v9;
  this->m_trace[38] = v43;
  v40 = ((unsigned __int8)v43 | (unsigned __int8)v134) == 0;
  v135 = v43 | v134;
  this->m_trace[32] = v135;
  this->m_trace[89] = v120 ^ v10;
  v44 = v135;
  if ( !v40 )
    v44 = v120 ^ v10;
  this->m_trace[31] = v44;
  v45 = v44 | v136;
  this->m_trace[27] = v44 | v136;
  this->m_trace[90] = v118 ^ v142;
  v46 = v45;
  if ( v45 )
    v46 = v118 ^ v142;
  v148 = v5 ^ v147;
  v137 = v45;
  this->m_trace[26] = v46;
  v47 = v46 | v23;
  this->m_trace[21] = v46 | v23;
  this->m_trace[91] = v119 ^ v12;
  v48 = v47;
  if ( v47 )
    v48 = v119 ^ v12;
  v144 = v119 ^ v12;
  v49 = 0;
  this->m_trace[20] = v48;
  v50 = v48 | v121;
  this->m_trace[16] = v48 | v121;
  v51 = (v48 | v121) ^ v21;
  this->m_trace[11] = v51;
  this->m_trace[10] = v51 ^ 1;
  v52 = this->m_trace[37];
  this->m_trace[92] = this->m_trace[37] ^ 1;
  v53 = this->m_trace[97];
  v54 = this->m_trace[98];
  v55 = v53 ^ this->m_trace[98];
  this->m_trace[96] = v55;
  if ( this->m_trace[13] )
    v49 = this->m_trace[14];
  v138 = v6 ^ v9;
  v140 = v120 ^ v139;
  v143 = v118 ^ v142;
  this->m_trace[100] = v49;
  v56 = 0;
  if ( v50 )
    v56 = this->m_trace[12];
  this->m_trace[101] = v56;
  v57 = v56 | v49;
  this->m_trace[99] = v57;
  this->m_trace[95] = v57 ^ v55;
  v58 = v57 ^ v55 ^ 1;
  this->m_trace[94] = v58;
  v59 = this->m_trace[18];
  v60 = this->m_trace[18] ^ 1;
  v61 = 1;
  this->m_trace[102] = v60;
  this->m_trace[93] = v58 | v60;
  if ( v51 == 1 )
    v61 = v57 == v55 || v59 == 0 || v52 == 0;
  this->m_trace[9] = v61;
  v62 = this->m_trace[106];
  v63 = this->m_trace[107];
  v64 = v62 ^ this->m_trace[107];
  this->m_trace[105] = v64;
  v65 = v53;
  if ( v53 )
    v65 = v54;
  this->m_trace[109] = v65;
  if ( v57 )
    v57 = v55;
  this->m_trace[110] = v57;
  v66 = v57 | v65;
  this->m_trace[108] = v66;
  v67 = v66 ^ v64;
  this->m_trace[104] = v66 ^ v64;
  if ( v66 )
    v66 = v64;
  v141 = v47;
  if ( v62 )
    v62 = v63;
  v68 = v66 | v62;
  v69 = v53 ^ 1;
  v70 = this->m_trace[25] ^ 1;
  this->m_trace[111] = v70;
  v71 = v67 | v70;
  this->m_trace[103] = v71;
  v72 = this->m_trace[117];
  v126 = v53;
  v73 = v72 ^ 1;
  this->m_trace[116] = v72 ^ 1;
  v74 = this->m_trace[119];
  v75 = v74 ^ v72;
  v76 = v74 ^ 1;
  v77 = (v66 | v62) ^ v75;
  v40 = !v61;
  this->m_trace[118] = v76;
  this->m_trace[115] = v75;
  this->m_trace[121] = v62;
  this->m_trace[122] = v66;
  this->m_trace[120] = v66 | v62;
  this->m_trace[114] = v77;
  this->m_trace[113] = v77 ^ 1;
  this->m_trace[123] = v69;
  this->m_trace[112] = v77 ^ 1 | v69;
  v78 = 1;
  if ( v40 )
    v78 = v77 != 1 || v126 == 0 || v71 != 0;
  this->m_trace[8] = v78;
  v79 = this->m_trace[129];
  this->m_trace[128] = this->m_trace[129] ^ 1;
  v80 = this->m_trace[131];
  this->m_trace[130] = this->m_trace[131] ^ 1;
  if ( v68 )
    v68 = v75;
  v81 = 0;
  if ( !v72 )
    v81 = v76;
  v82 = v80 ^ v79;
  v83 = (v68 | v81) ^ v82;
  this->m_trace[127] = v82;
  this->m_trace[133] = v81;
  this->m_trace[134] = v68;
  this->m_trace[132] = v68 | v81;
  this->m_trace[126] = v83;
  this->m_trace[125] = v83 ^ 1;
  v40 = v82 == ((unsigned __int8)v68 | (unsigned __int8)v81);
  v84 = 1;
  if ( !v40 )
    v84 = this->m_trace[15] != 0;
  this->m_trace[124] = v84;
  v85 = this->m_trace[80];
  v86 = this->m_trace[81];
  v87 = v85 ^ this->m_trace[81];
  this->m_trace[137] = v87;
  this->m_trace[136] = v87 ^ 1;
  this->m_trace[138] = v73;
  v88 = 1;
  this->m_trace[135] = v73 | v87 ^ 1;
  if ( !v78 )
    v88 = v84 || v87 == 0 || v72 == 0;
  this->m_trace[7] = v88;
  v89 = v85;
  if ( v85 )
    v89 = v86;
  this->m_trace[141] = v89;
  v90 = this->m_trace[82] ^ v89;
  this->m_trace[140] = v90;
  v91 = v63 ^ 1;
  this->m_trace[142] = v91;
  v92 = v90 | v91;
  this->m_trace[139] = v92;
  v93 = 1;
  v94 = this->m_trace[83] ^ this->m_trace[73];
  v40 = v88 == 0;
  this->m_trace[145] = v94;
  this->m_trace[144] = v94 ^ 1;
  this->m_trace[146] = v85 ^ 1;
  this->m_trace[143] = v94 ^ 1 | v85 ^ 1;
  v95 = 1;
  if ( v40 )
    v95 = v94 == 0 || v85 == 0 || v92 != 0;
  this->m_trace[6] = v95;
  this->m_trace[149] = v133 ^ v130;
  this->m_trace[148] = v133 ^ v130 ^ 1;
  this->m_trace[147] = v80 | v133 ^ v130 ^ 1;
  this->m_trace[151] = v146 ^ v150;
  v96 = this->m_trace[69];
  v97 = this->m_trace[69] ^ 1;
  this->m_trace[152] = v97;
  this->m_trace[150] = v97 | v146 ^ v150;
  if ( !v95 )
    v93 = (v133 ^ (unsigned __int8)v130) != 1 || v80 != 0 || v150 != v146 || v96 == 0;
  this->m_trace[5] = v93;
  this->m_trace[155] = v155 ^ v128;
  v98 = v155 ^ v128 ^ 1;
  this->m_trace[154] = v98;
  v99 = this->m_trace[78] ^ 1;
  this->m_trace[156] = v99;
  v100 = v98 | v99;
  this->m_trace[153] = v100;
  v101 = 1;
  this->m_trace[158] = v148 ^ v132;
  v102 = this->m_trace[55];
  v103 = this->m_trace[55] ^ 1;
  this->m_trace[159] = v103;
  this->m_trace[157] = v103 | v148 ^ v132;
  v104 = 1;
  if ( !v93 )
    v104 = v132 != v148 || v102 == 0 || v100 != 0;
  this->m_trace[4] = v104;
  this->m_trace[162] = v138 ^ v152;
  v105 = v138 ^ v152 ^ 1;
  this->m_trace[161] = v105;
  v106 = this->m_trace[64] ^ 1;
  this->m_trace[163] = v106;
  v107 = v105 | v106;
  this->m_trace[160] = v107;
  this->m_trace[165] = v140 ^ v135;
  v108 = this->m_trace[42];
  v109 = this->m_trace[42] ^ 1;
  this->m_trace[166] = v109;
  this->m_trace[164] = v109 | v140 ^ v135;
  if ( !v104 )
    v101 = v135 != v140 || v108 == 0 || v107 != 0;
  this->m_trace[3] = v101;
  this->m_trace[169] = v143 ^ v137;
  this->m_trace[168] = v143 ^ v137 ^ 1;
  v110 = 1;
  v111 = 1;
  if ( (v143 ^ (unsigned __int8)v137) == 1 )
    v111 = this->m_trace[50] != 0;
  this->m_trace[167] = v111;
  v112 = v144 ^ v141;
  this->m_trace[172] = v144 ^ v141;
  result = v144 ^ v141 ^ 1;
  this->m_trace[171] = result;
  v114 = this->m_trace[29];
  v115 = this->m_trace[29] ^ 1;
  this->m_trace[173] = v115;
  this->m_trace[170] = result | v115;
  if ( !v101 )
  {
    result = v112 != 1;
    v110 = v111 || v112 != 1 || v114 == 0;
  }
  this->m_trace[2] = v110;
  v116 = v110 ^ 1;
  this->m_trace[1] = v116;
  this->m_trace[0] = v116;
  return result;
}

Not nice, but can readable. The CircuitFinalStage::GetOutputIndex tells you what trace to look for in m_trace. It's 0 in all 5 circuits.

balika011 avatar Jul 28 '18 01:07 balika011

If we take a look at the client we can find out the GetCircuitOutputs is a registered script native. Here we can find the same functions as in the server. APwnAdventure3GameAPIManager::GetCircuitForName is at 4A8590 in the PwnAdventure3-Linux-Shipping binary. CreateCircuitFinalStage is at 0x499A30 CircuitFinalStage::Update is at 0x499AE0 Here is the decomplied code from IDA:

char __fastcall sub_499AE0(CircuitFinalStage *this)
{
  char v1; // al
  char v2; // al
  char v3; // al
  char v4; // al
  char v5; // r14
  char v6; // bp
  char v7; // si
  char v8; // al
  char v9; // r15
  char v10; // r8
  char v11; // dl
  char v12; // r12
  char v13; // r9
  char v14; // dl
  char v15; // al
  char v16; // r11
  char v17; // r13
  char v18; // r10
  char v19; // cl
  char v20; // al
  char v21; // r9
  char v22; // al
  char v23; // bl
  char v24; // al
  char v25; // si
  char v26; // cl
  char v27; // al
  char v28; // dl
  char v29; // al
  char v30; // al
  char v31; // al
  char v32; // cl
  char v33; // r11
  char v34; // al
  char v35; // al
  char v36; // r13
  char v37; // al
  char v38; // dl
  char v39; // al
  bool v40; // zf
  char v41; // al
  char v42; // al
  char v43; // al
  char v44; // al
  char v45; // dl
  char v46; // al
  char v47; // r14
  char v48; // al
  char v49; // cl
  char v50; // bl
  char v51; // r9
  char v52; // r8
  char v53; // r13
  char v54; // si
  char v55; // r11
  char v56; // al
  char v57; // cl
  char v58; // dl
  char v59; // r10
  char v60; // al
  bool v61; // r12
  char v62; // bl
  char v63; // r15
  char v64; // al
  char v65; // dl
  char v66; // dl
  char v67; // cl
  char v68; // r9
  char v69; // r14
  char v70; // al
  char v71; // al
  char v72; // si
  char v73; // r13
  char v74; // cl
  char v75; // r8
  char v76; // cl
  char v77; // bp
  bool v78; // r12
  char v79; // bl
  char v80; // bp
  char v81; // dl
  char v82; // bl
  char v83; // al
  bool v84; // dl
  char v85; // r11
  char v86; // r10
  char v87; // cl
  char v88; // r9
  char v89; // al
  char v90; // al
  char v91; // r15
  char v92; // r15
  bool v93; // r8
  char v94; // cl
  bool v95; // r9
  char v96; // al
  char v97; // cl
  char v98; // al
  char v99; // dl
  char v100; // dl
  bool v101; // si
  char v102; // bl
  char v103; // cl
  bool v104; // cl
  char v105; // al
  char v106; // dl
  char v107; // dl
  char v108; // r8
  char v109; // bl
  char v110; // cl
  bool v111; // r8
  char v112; // r14
  char result; // al
  char v114; // dl
  char v115; // bl
  char v116; // cl
  char v117; // [rsp+1h] [rbp-4Bh]
  char v118; // [rsp+2h] [rbp-4Ah]
  char v119; // [rsp+4h] [rbp-48h]
  char v120; // [rsp+6h] [rbp-46h]
  char v121; // [rsp+7h] [rbp-45h]
  char v122; // [rsp+8h] [rbp-44h]
  char v123; // [rsp+9h] [rbp-43h]
  char v124; // [rsp+Ah] [rbp-42h]
  char v125; // [rsp+Bh] [rbp-41h]
  char v126; // [rsp+Bh] [rbp-41h]
  char v127; // [rsp+Ch] [rbp-40h]
  char v128; // [rsp+Ch] [rbp-40h]
  char v129; // [rsp+Dh] [rbp-3Fh]
  char v130; // [rsp+Dh] [rbp-3Fh]
  char v131; // [rsp+Eh] [rbp-3Eh]
  char v132; // [rsp+Eh] [rbp-3Eh]
  unsigned __int8 v133; // [rsp+Fh] [rbp-3Dh]
  char v134; // [rsp+10h] [rbp-3Ch]
  char v135; // [rsp+10h] [rbp-3Ch]
  char v136; // [rsp+11h] [rbp-3Bh]
  char v137; // [rsp+11h] [rbp-3Bh]
  char v138; // [rsp+12h] [rbp-3Ah]
  char v139; // [rsp+13h] [rbp-39h]
  char v140; // [rsp+13h] [rbp-39h]
  char v141; // [rsp+14h] [rbp-38h]
  char v142; // [rsp+15h] [rbp-37h]
  unsigned __int8 v143; // [rsp+15h] [rbp-37h]
  char v144; // [rsp+16h] [rbp-36h]
  char v145; // [rsp+17h] [rbp-35h]
  char v146; // [rsp+17h] [rbp-35h]
  char v147; // [rsp+18h] [rbp-34h]
  char v148; // [rsp+18h] [rbp-34h]
  char v149; // [rsp+19h] [rbp-33h]
  char v150; // [rsp+19h] [rbp-33h]
  char v151; // [rsp+1Ah] [rbp-32h]
  char v152; // [rsp+1Ah] [rbp-32h]
  char v153; // [rsp+1Bh] [rbp-31h]
  char v154; // [rsp+1Bh] [rbp-31h]
  char v155; // [rsp+1Bh] [rbp-31h]

  this->m_trace[23] = this->m_input[0];
  this->m_trace[18] = this->m_input[1];
  this->m_trace[13] = this->m_input[2];
  this->m_trace[97] = this->m_input[3];
  this->m_trace[106] = this->m_input[4];
  this->m_trace[117] = this->m_input[5];
  this->m_trace[129] = this->m_input[6];
  this->m_trace[80] = this->m_input[7];
  this->m_trace[76] = this->m_input[8];
  v1 = this->m_input[9];
  v124 = v1;
  this->m_trace[69] = v1;
  v2 = this->m_input[10];
  v125 = v2;
  this->m_trace[62] = v2;
  v3 = this->m_input[11];
  v123 = v3;
  this->m_trace[55] = v3;
  v4 = this->m_input[12];
  v122 = v4;
  this->m_trace[48] = v4;
  v5 = this->m_input[13];
  this->m_trace[42] = v5;
  v6 = this->m_input[14];
  this->m_trace[35] = v6;
  v7 = this->m_input[15];
  this->m_trace[29] = v7;
  v8 = this->m_input[16];
  v147 = v8;
  this->m_trace[44] = v8;
  v9 = this->m_input[17];
  this->m_trace[37] = v9;
  v10 = this->m_input[18];
  this->m_trace[30] = v10;
  v11 = this->m_input[19];
  this->m_trace[25] = v11;
  v12 = this->m_input[20];
  this->m_trace[19] = v12;
  v13 = this->m_input[21];
  this->m_trace[15] = v13;
  this->m_trace[98] = this->m_input[22];
  this->m_trace[107] = this->m_input[23];
  this->m_trace[119] = this->m_input[24];
  this->m_trace[131] = this->m_input[25];
  v13 ^= 1u;
  v14 = v11 ^ 1;
  v15 = this->m_input[26];
  v117 = v15;
  this->m_trace[81] = v15;
  v16 = this->m_input[27];
  this->m_trace[78] = v16;
  v17 = this->m_input[28];
  this->m_trace[71] = v17;
  v18 = this->m_input[29];
  this->m_trace[64] = v18;
  v19 = this->m_input[30];
  this->m_trace[57] = v19;
  v20 = this->m_input[31];
  v153 = v20;
  this->m_trace[50] = v20;
  this->m_trace[14] = v13;
  v21 = this->m_trace[13] ^ v13;
  this->m_trace[12] = v21;
  v22 = this->m_trace[18];
  v119 = v22;
  if ( v22 )
    v22 = v12;
  v121 = v22;
  this->m_trace[17] = v22;
  this->m_trace[24] = v14;
  v23 = this->m_trace[23];
  v118 = v23;
  if ( v23 )
    v23 = v14;
  v145 = v19;
  this->m_trace[22] = v23;
  v24 = v7;
  v120 = v7;
  if ( v7 )
    v24 = v10;
  v136 = v24;
  this->m_trace[28] = v24;
  this->m_trace[34] = v6 ^ 1;
  v25 = 0;
  this->m_trace[36] = v9 ^ 1;
  v26 = 0;
  if ( v6 != 1 )
    v26 = v9 ^ 1;
  this->m_trace[33] = v26;
  this->m_trace[41] = v5 ^ 1;
  this->m_trace[43] = v147 ^ 1;
  v151 = 0;
  if ( v5 != 1 )
    v151 = v147 ^ 1;
  v142 = v14;
  v27 = 0;
  if ( v124 != 1 )
    v27 = v17 ^ 1;
  v134 = v26;
  v149 = 0;
  if ( v125 != 1 )
    v149 = v18 ^ 1;
  v129 = v27;
  v139 = v10;
  v28 = v153 ^ 1;
  v29 = v122;
  if ( v122 )
    v29 = v153 ^ 1;
  v131 = v29;
  this->m_trace[40] = v151;
  this->m_trace[49] = v28;
  v154 = v153 ^ 1;
  this->m_trace[47] = v29;
  v30 = 0;
  if ( v123 != 1 )
    v30 = v145 ^ 1;
  v127 = v30;
  this->m_trace[54] = v123 ^ 1;
  this->m_trace[56] = v145 ^ 1;
  this->m_trace[53] = v30;
  this->m_trace[61] = v125 ^ 1;
  this->m_trace[63] = v18 ^ 1;
  this->m_trace[60] = v149;
  this->m_trace[68] = v124 ^ 1;
  this->m_trace[70] = v17 ^ 1;
  this->m_trace[67] = v129;
  v31 = this->m_trace[76];
  this->m_trace[75] = this->m_trace[76] ^ 1;
  this->m_trace[77] = v16 ^ 1;
  v32 = 0;
  if ( v31 != 1 )
    v32 = v16 ^ 1;
  this->m_trace[74] = v32;
  v33 = v31 ^ v16;
  this->m_trace[82] = v33;
  if ( this->m_trace[80] )
  {
    v34 = v117;
    if ( v117 )
      v34 = v33;
    v25 = v34;
  }
  this->m_trace[79] = v25;
  v35 = 1;
  if ( !v32 )
    v35 = v25 & 1;
  this->m_trace[73] = v35;
  v36 = v124 ^ v17;
  this->m_trace[83] = v36;
  if ( v35 )
    v35 = v36;
  this->m_trace[72] = v35;
  v130 = v35 | v129;
  this->m_trace[66] = v130;
  this->m_trace[84] = v125 ^ v18;
  v37 = v130;
  if ( v130 )
    v37 = v125 ^ v18;
  this->m_trace[65] = v37;
  v150 = v37 | v149;
  v38 = v122 ^ v28;
  this->m_trace[59] = v150;
  this->m_trace[85] = v123 ^ v145;
  v39 = v150;
  if ( v150 )
    v39 = v123 ^ v145;
  this->m_trace[58] = v39;
  v40 = ((unsigned __int8)v39 | (unsigned __int8)v127) == 0;
  v128 = v39 | v127;
  this->m_trace[52] = v128;
  this->m_trace[86] = v38;
  v41 = v128;
  if ( !v40 )
    v41 = v122 ^ v154;
  v133 = v125 ^ v18;
  v155 = v122 ^ v154;
  this->m_trace[51] = v41;
  v40 = ((unsigned __int8)v41 | (unsigned __int8)v131) == 0;
  v132 = v41 | v131;
  this->m_trace[46] = v132;
  this->m_trace[87] = v5 ^ v147;
  v42 = v132;
  if ( !v40 )
    v42 = v5 ^ v147;
  v146 = v123 ^ v145;
  this->m_trace[45] = v42;
  v40 = ((unsigned __int8)v42 | (unsigned __int8)v151) == 0;
  v152 = v42 | v151;
  this->m_trace[39] = v152;
  this->m_trace[88] = v6 ^ v9;
  v43 = v152;
  if ( !v40 )
    v43 = v6 ^ v9;
  this->m_trace[38] = v43;
  v40 = ((unsigned __int8)v43 | (unsigned __int8)v134) == 0;
  v135 = v43 | v134;
  this->m_trace[32] = v135;
  this->m_trace[89] = v120 ^ v10;
  v44 = v135;
  if ( !v40 )
    v44 = v120 ^ v10;
  this->m_trace[31] = v44;
  v45 = v44 | v136;
  this->m_trace[27] = v44 | v136;
  this->m_trace[90] = v118 ^ v142;
  v46 = v45;
  if ( v45 )
    v46 = v118 ^ v142;
  v148 = v5 ^ v147;
  v137 = v45;
  this->m_trace[26] = v46;
  v47 = v46 | v23;
  this->m_trace[21] = v46 | v23;
  this->m_trace[91] = v119 ^ v12;
  v48 = v47;
  if ( v47 )
    v48 = v119 ^ v12;
  v144 = v119 ^ v12;
  v49 = 0;
  this->m_trace[20] = v48;
  v50 = v48 | v121;
  this->m_trace[16] = v48 | v121;
  v51 = (v48 | v121) ^ v21;
  this->m_trace[11] = v51;
  this->m_trace[10] = v51 ^ 1;
  v52 = this->m_trace[37];
  this->m_trace[92] = this->m_trace[37] ^ 1;
  v53 = this->m_trace[97];
  v54 = this->m_trace[98];
  v55 = v53 ^ this->m_trace[98];
  this->m_trace[96] = v55;
  if ( this->m_trace[13] )
    v49 = this->m_trace[14];
  v138 = v6 ^ v9;
  v140 = v120 ^ v139;
  v143 = v118 ^ v142;
  this->m_trace[100] = v49;
  v56 = 0;
  if ( v50 )
    v56 = this->m_trace[12];
  this->m_trace[101] = v56;
  v57 = v56 | v49;
  this->m_trace[99] = v57;
  this->m_trace[95] = v57 ^ v55;
  v58 = v57 ^ v55 ^ 1;
  this->m_trace[94] = v58;
  v59 = this->m_trace[18];
  v60 = this->m_trace[18] ^ 1;
  v61 = 1;
  this->m_trace[102] = v60;
  this->m_trace[93] = v58 | v60;
  if ( v51 == 1 )
    v61 = v57 == v55 || v59 == 0 || v52 == 0;
  this->m_trace[9] = v61;
  v62 = this->m_trace[106];
  v63 = this->m_trace[107];
  v64 = v62 ^ this->m_trace[107];
  this->m_trace[105] = v64;
  v65 = v53;
  if ( v53 )
    v65 = v54;
  this->m_trace[109] = v65;
  if ( v57 )
    v57 = v55;
  this->m_trace[110] = v57;
  v66 = v57 | v65;
  this->m_trace[108] = v66;
  v67 = v66 ^ v64;
  this->m_trace[104] = v66 ^ v64;
  if ( v66 )
    v66 = v64;
  v141 = v47;
  if ( v62 )
    v62 = v63;
  v68 = v66 | v62;
  v69 = v53 ^ 1;
  v70 = this->m_trace[25] ^ 1;
  this->m_trace[111] = v70;
  v71 = v67 | v70;
  this->m_trace[103] = v71;
  v72 = this->m_trace[117];
  v126 = v53;
  v73 = v72 ^ 1;
  this->m_trace[116] = v72 ^ 1;
  v74 = this->m_trace[119];
  v75 = v74 ^ v72;
  v76 = v74 ^ 1;
  v77 = (v66 | v62) ^ v75;
  v40 = !v61;
  this->m_trace[118] = v76;
  this->m_trace[115] = v75;
  this->m_trace[121] = v62;
  this->m_trace[122] = v66;
  this->m_trace[120] = v66 | v62;
  this->m_trace[114] = v77;
  this->m_trace[113] = v77 ^ 1;
  this->m_trace[123] = v69;
  this->m_trace[112] = v77 ^ 1 | v69;
  v78 = 1;
  if ( v40 )
    v78 = v77 != 1 || v126 == 0 || v71 != 0;
  this->m_trace[8] = v78;
  v79 = this->m_trace[129];
  this->m_trace[128] = this->m_trace[129] ^ 1;
  v80 = this->m_trace[131];
  this->m_trace[130] = this->m_trace[131] ^ 1;
  if ( v68 )
    v68 = v75;
  v81 = 0;
  if ( !v72 )
    v81 = v76;
  v82 = v80 ^ v79;
  v83 = (v68 | v81) ^ v82;
  this->m_trace[127] = v82;
  this->m_trace[133] = v81;
  this->m_trace[134] = v68;
  this->m_trace[132] = v68 | v81;
  this->m_trace[126] = v83;
  this->m_trace[125] = v83 ^ 1;
  v40 = v82 == ((unsigned __int8)v68 | (unsigned __int8)v81);
  v84 = 1;
  if ( !v40 )
    v84 = this->m_trace[15] != 0;
  this->m_trace[124] = v84;
  v85 = this->m_trace[80];
  v86 = this->m_trace[81];
  v87 = v85 ^ this->m_trace[81];
  this->m_trace[137] = v87;
  this->m_trace[136] = v87 ^ 1;
  this->m_trace[138] = v73;
  v88 = 1;
  this->m_trace[135] = v73 | v87 ^ 1;
  if ( !v78 )
    v88 = v84 || v87 == 0 || v72 == 0;
  this->m_trace[7] = v88;
  v89 = v85;
  if ( v85 )
    v89 = v86;
  this->m_trace[141] = v89;
  v90 = this->m_trace[82] ^ v89;
  this->m_trace[140] = v90;
  v91 = v63 ^ 1;
  this->m_trace[142] = v91;
  v92 = v90 | v91;
  this->m_trace[139] = v92;
  v93 = 1;
  v94 = this->m_trace[83] ^ this->m_trace[73];
  v40 = v88 == 0;
  this->m_trace[145] = v94;
  this->m_trace[144] = v94 ^ 1;
  this->m_trace[146] = v85 ^ 1;
  this->m_trace[143] = v94 ^ 1 | v85 ^ 1;
  v95 = 1;
  if ( v40 )
    v95 = v94 == 0 || v85 == 0 || v92 != 0;
  this->m_trace[6] = v95;
  this->m_trace[149] = v133 ^ v130;
  this->m_trace[148] = v133 ^ v130 ^ 1;
  this->m_trace[147] = v80 | v133 ^ v130 ^ 1;
  this->m_trace[151] = v146 ^ v150;
  v96 = this->m_trace[69];
  v97 = this->m_trace[69] ^ 1;
  this->m_trace[152] = v97;
  this->m_trace[150] = v97 | v146 ^ v150;
  if ( !v95 )
    v93 = (v133 ^ (unsigned __int8)v130) != 1 || v80 != 0 || v150 != v146 || v96 == 0;
  this->m_trace[5] = v93;
  this->m_trace[155] = v155 ^ v128;
  v98 = v155 ^ v128 ^ 1;
  this->m_trace[154] = v98;
  v99 = this->m_trace[78] ^ 1;
  this->m_trace[156] = v99;
  v100 = v98 | v99;
  this->m_trace[153] = v100;
  v101 = 1;
  this->m_trace[158] = v148 ^ v132;
  v102 = this->m_trace[55];
  v103 = this->m_trace[55] ^ 1;
  this->m_trace[159] = v103;
  this->m_trace[157] = v103 | v148 ^ v132;
  v104 = 1;
  if ( !v93 )
    v104 = v132 != v148 || v102 == 0 || v100 != 0;
  this->m_trace[4] = v104;
  this->m_trace[162] = v138 ^ v152;
  v105 = v138 ^ v152 ^ 1;
  this->m_trace[161] = v105;
  v106 = this->m_trace[64] ^ 1;
  this->m_trace[163] = v106;
  v107 = v105 | v106;
  this->m_trace[160] = v107;
  this->m_trace[165] = v140 ^ v135;
  v108 = this->m_trace[42];
  v109 = this->m_trace[42] ^ 1;
  this->m_trace[166] = v109;
  this->m_trace[164] = v109 | v140 ^ v135;
  if ( !v104 )
    v101 = v135 != v140 || v108 == 0 || v107 != 0;
  this->m_trace[3] = v101;
  this->m_trace[169] = v143 ^ v137;
  this->m_trace[168] = v143 ^ v137 ^ 1;
  v110 = 1;
  v111 = 1;
  if ( (v143 ^ (unsigned __int8)v137) == 1 )
    v111 = this->m_trace[50] != 0;
  this->m_trace[167] = v111;
  v112 = v144 ^ v141;
  this->m_trace[172] = v144 ^ v141;
  result = v144 ^ v141 ^ 1;
  this->m_trace[171] = result;
  v114 = this->m_trace[29];
  v115 = this->m_trace[29] ^ 1;
  this->m_trace[173] = v115;
  this->m_trace[170] = result | v115;
  if ( !v101 )
  {
    result = v112 != 1;
    v110 = v111 || v112 != 1 || v114 == 0;
  }
  this->m_trace[2] = v110;
  v116 = v110 ^ 1;
  this->m_trace[1] = v116;
  this->m_trace[0] = v116;
  return result;
}

It's the same as the server side version.

balika011 avatar Jul 28 '18 14:07 balika011

There is an easy way to bruteforce it in offline mode.

for (uint32_t input = 0; input < 0xFFFFFFFF; input++) 
{
	bool done = false;
	Game->GetCircuitOutputs("FinalStage", input, nullptr, 0, &done);
	if (done)
	{
		printf("Correct input: 0x%x\n", input);
		break;
	}
}
The solution: 0x698fabfa aka 0110 1001 1000 1111 1010 1011 1111 1010

balika011 avatar Jul 28 '18 16:07 balika011