0x1 分析算法
要解密的函数自身很简单,没有常用算法和复杂的逻辑,纯粹位移操作,ida动态调试一番 确定函数传参和返回值之后分析得知
大致分为三步
1.cpu_clock_star()初始化struct x的值
2.cpu_clock_x(struct x, string data, int dataLen) 循环取data的64个字节作为参数放入sub_1b80
3.sub_1b80(struct x, string data) 取data中的字符hex值与固定值进行运算将结果放入struct+0 和struct+ 4处
4.cpu_clock_release(struct x) 同上计算data中不足64字节的字符
0x2 还原算法
最后结果是要在c#中实现调用,本来觉得用c/c++应该好写点,然后编译dll供c#调用,由于长期侵淫于java对于本来不精通的c几乎都还给书籍了,最后在某大牛,和无名基友的帮助下完成c#版本
public struct cpu_clock_struct
{
public uint[] key ;
public byte[] data ;
public byte[] result;
public uint[] length;
}
class Program
{
private static string[] s = { "38", "27", "00", "b5", "63", "f4" };
public static string getClock(string data)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data);
cpu_clock_struct cc = cpu_clock_start();
cpu_clock_x(cc, bytes, bytes.Length);
for (int i = 0; i < s.Length; i++)
{
byte[] tmpBytes = System.Text.Encoding.UTF8.GetBytes(s[i]);
cpu_clock_x(cc, tmpBytes, 2);
}
cpu_clock_release(cc);
return BitConverter.ToString(cc.result).Replace("-", string.Empty);
}
public static void cpu_clock_release(cpu_clock_struct cc )
{
uint[] tmps = new uint[16];
uint tmp = (cc.length[0] << 0x17) >> 0x1a;
if (tmp > 0x37 )
{
tmp = 0x78 - tmp;
}
else
{
tmp = 0x38 - tmp;
}
byte[] unk_6004 = new byte[tmp];
for (int i = 0; i < tmp; i++)
{
unk_6004[i] = 0x00;
}
unk_6004[0] = 0x80;
tmps[14] = cc.length[0];
tmps[15] = cc.length[1];
cpu_clock_x(cc, unk_6004,(int)tmp);
for (int k = 0, h = 0; k < 56; k += 4, h++)
{
tmps[h] = (uint)(cc.data[k] | cc.data[k + 1] << 8 | cc.data[k + 2] << 0x10 | cc.data[k + 3] << 0x18);
}
sub_1B80(cc.key, tmps);
for (int i = 0; i < 16; i++)
{
cc.result[i]=(byte)((cc.key[i/4]>>((i%4)*8)) &0xFF);
}
}
public static cpu_clock_struct cpu_clock_start()
{
cpu_clock_struct cc = new cpu_clock_struct();
cc.key = new uint[4];
cc.data = new byte[64];
cc.result = new byte[16];
cc.length = new uint[2];
cc.length[0] = 0;
cc.length[1] = 0;
cc.key[0] = 0x67452301;
cc.key[1] = 0xefcdab89;
cc.key[2] = 0x98badcfe;
cc.key[3] = 0x10325476;
return cc;
}
public static void cpu_clock_x(cpu_clock_struct cc, byte[] bytes, int len)
{
int jtmp = (int)((cc.length[0] << 23) >> 26);
if (cc.length[0] > (len * 8 + cc.length[0]))
{
cc.length[1] += 1;
}
cc.length[0] += (uint)len << 3;
cc.length[1] += (uint)len >> 0x1d;
uint[] tmp = new uint[16];
for (int i = len, m = 0,j = jtmp; i > 0; --i)
{
cc.data[j] = bytes[m];
++m;
++j;
if (j == 64)
{
for (int k = 0, h = 0; k < 64; k += 4, h++)
{
tmp[h] = (uint)(cc.data[k] | cc.data[k + 1] << 8 | cc.data[k + 2] << 0x10 | cc.data[k + 3] << 0x18);
}
sub_1B80(cc.key, tmp);
j = 0;
}
}
}
public static void sub_1B80(uint[] result, uint[] data)
{
uint v2; // r3@1
uint v3; // ST04_4@1
uint v4; // r2@1
uint v5; // r10@1
uint v6; // ST08_4@1
uint v7; // r4@1
uint v8; // ST0C_4@1
uint v9; // r4@1
uint v10; // r2@1
uint v11; // r12@1
uint v12; // ST10_4@1
uint v13; // r7@1
uint v14; // r2@1
uint v15; // ST14_4@1
uint v16; // r2@1
uint v17; // r7@1
uint v18; // r9@1
uint v19; // ST18_4@1
uint v20; // r7@1
uint v21; // r4@1
uint v22; // ST1C_4@1
uint v23; // r4@1
uint v24; // r7@1
uint v25; // r12@1
uint v26; // ST20_4@1
uint v27; // r6@1
uint v28; // r2@1
uint v29; // ST24_4@1
uint v30; // r2@1
uint v31; // r6@1
uint v32; // r9@1
uint v33; // ST28_4@1
uint v34; // r6@1
uint v35; // r4@1
uint v36; // ST2C_4@1
uint v37; // r4@1
uint v38; // r6@1
uint v39; // r12@1
uint v40; // ST30_4@1
uint v41; // r7@1
uint v42; // r2@1
uint v43; // ST34_4@1
uint v44; // r2@1
uint v45; // r7@1
uint v46; // r5@1
uint v47; // ST38_4@1
uint v48; // r4@1
uint v49; // r4@1
uint v50; // ST00_4@1
uint v51; // r7@1
uint v52; // r7@1
uint v53; // ST3C_4@1
uint v54; // r2@1
uint v55; // r2@1
uint v56; // r5@1
uint v57; // r5@1
uint v58; // r4@1
uint v59; // r4@1
uint v60; // r7@1
uint v61; // r1@1
uint v62; // r2@1
uint v63; // r2@1
uint v64; // r5@1
uint v65; // r5@1
uint v66; // r4@1
uint v67; // r4@1
uint v68; // r1@1
uint v69; // r1@1
uint v70; // r2@1
uint v71; // r2@1
uint v72; // r5@1
uint v73; // r5@1
uint v74; // r4@1
uint v75; // r4@1
uint v76; // r1@1
uint v77; // r1@1
uint v78; // r2@1
uint v79; // r2@1
uint v80; // r5@1
uint v81; // r5@1
uint v82; // r4@1
uint v83; // r4@1
uint v84; // r1@1
uint v85; // r1@1
uint v86; // r2@1
uint v87; // r2@1
uint v88; // r5@1
uint v89; // r5@1
uint v90; // r4@1
uint v91; // r4@1
uint v92; // r7@1
uint v93; // r7@1
uint v94; // r2@1
uint v95; // r2@1
uint v96; // r5@1
uint v97; // r5@1
uint v98; // r4@1
uint v99; // r4@1
uint v100; // r7@1
uint v101; // r7@1
uint v102; // r2@1
uint v103; // r2@1
uint v104; // r1@1
uint v105; // r1@1
uint v106; // r4@1
uint v107; // r4@1
uint v108; // r7@1
uint v109; // r7@1
uint v110; // r2@1
uint v111; // r2@1
uint v112; // r1@1
uint v113; // r1@1
uint v114; // r4@1
uint v115; // r4@1
uint v116; // r7@1
uint v117; // r7@1
uint v118; // r2@1
uint v119; // r2@1
uint v120; // r1@1
uint v121; // r1@1
uint v122; // r4@1
uint v123; // r4@1
uint v124; // r7@1
uint v125; // r7@1
uint v126; // r2@1
uint v127; // r2@1
uint v128; // r1@1
uint v129; // r1@1
uint v130; // r4@1
uint v131; // r4@1
uint v132; // r7@1
uint v133; // r7@1
uint v134; // r2@1
uint v135; // r2@1
uint v136; // r1@1
uint v137; // r1@1
uint v138; // r4@1
uint v139; // r4@1
uint v140; // r7@1
uint v141; // r7@1
uint v142; // r2@1
uint v143; // r2@1
uint v144; // r1@1
uint v145; // r1@1
uint v146; // r4@1
uint v147; // r4@1
uint v148; // r7@1
uint v149; // r7@1
uint v150; // r2@1
uint v151; // r4@1
v2 = result[1];
v3 = data[0];
v4 = RORS(result[0] - 0x28955B88 + data[0] + (result[2] & v2 | result[3] & ~v2), 25);
v5 = v4 + v2;
v6 = data[1];
v7 = RORS(result[3] - 0x173848AA + v6 + (v5 & v2 | result[2] & ~v5), 20);
v8 = data[2];
v9 = v7 + v4 + v2;
v10 = RORS(result[2] + 0x242070DB + v8 + ((v4 + v2) & v9 | v2 & ~v9), 15);
v11 = v10 + v9;
v12 = data[3];
v13 = data[4];
v14 = RORS(v2 - 0x3E423112 + v12 + (v5 & ~(v10 + v9) | (v10 + v9) & v9), 10);
v15 = v13;
v16 = v14 + v11;
v17 = RORS((v9 & ~v16 | v11 & v16) + v5 + v13 - 0xA83F051, 25);
v18 = v17 + v16;
v19 = data[5];
v20 = data[6];
v21 = RORS(v9 + v19 + 0x4787C62A + (v11 & ~v18 | v18 & v16), 20);
v22 = v20;
v23 = v21 + v18;
v24 = RORS(v11 + v20 - 0x57CFB9ED + (v16 & ~v23 | v18 & v23), 15);
v25 = v24 + v23;
v26 = data[7];
v27 = data[8];
v28 = RORS(v16 + v26 - 0x2B96AFF + (v18 & ~v25 | v25 & v23), 10);
v29 = v27;
v30 = v28 + v24 + v23;
v31 = RORS(v18 + v27 + 0x698098D8 + (v23 & ~v30 | (v24 + v23) & v30), 25);
v32 = v31 + v30;
v33 = data[9];
v34 = data[10];
v35 = RORS(v23 + v33 - 0x74BB0851 + ((v24 + v23) & ~v32 | v32 & v30), 20);
v36 = v34;
v37 = v35 + v32;
v38 = RORS(v25 + v34 - 0xA44F + (v30 & ~v37 | v32 & v37), 15);
v39 = v38 + v37;
v40 = data[11];
v41 = data[12];
v42 = RORS(v30 + v40 - 0x76A32842 + (v32 & ~v39 | v39 & v37), 10);
v43 = v41;
v44 = v42 + v38 + v37;
v45 = RORS((v37 & ~v44 | (v38 + v37) & v44) + v32 + v41 + 0x6B901122, 25);
v46 = v45 + v44;
v47 = data[13];
v48 = RORS(v37 + v47 - 0x2678E6D + ((v38 + v37) & ~(v45 + v44) | v44 & (v45 + v44)), 20);
v49 = v48 + v45 + v44;
v50 = data[14];
v51 = RORS((~v49 & v44 | (v45 + v44) & v49) + v39 + v50 - 0x5986BC72, 15);
v52 = v51 + v49;
v53 = data[15];
v54 = RORS(v44 + v53 + 0x49B40821 + (v49 & v52 | ~v52 & v46), 10);
v55 = v54 + v52;
v56 = RORS(v46 + v6 - 0x9E1DA9E + (v49 & v55 | ~v49 & v52), 27);
v57 = v56 + v55;
v58 = RORS(v49 + v22 - 0x3FBF4CC0 + (v52 & v57 | ~v52 & v55), 23);
v59 = v58 + v57;
v60 = RORS(v52 + v40 + 0x265E5A51 + (v57 & ~v55 | v55 & v59), 18);
v61 = v60 + v59;
v62 = RORS(v55 + v3 - 0x16493856 + (v59 & ~v57 | v57 & (v60 + v59)), 12);
v63 = v62 + v60 + v59;
v64 = RORS(v57 + v19 - 0x29D0EFA3 + (v59 & v63 | (v60 + v59) & ~v59), 27);
v65 = v64 + v63;
v66 = RORS(v59 + v36 + 0x2441453 + ((v60 + v59) & v65 | v63 & ~(v60 + v59)), 23);
v67 = v66 + v65;
v68 = RORS(v61 + v53 - 0x275E197F + (v63 & v67 | v65 & ~v63), 18);
v69 = v68 + v67;
v70 = RORS(v63 + v15 - 0x182C0438 + (v65 & v69 | v67 & ~v65), 12);
v71 = v70 + v69;
v72 = RORS(v65 + v33 + 0x21E1CDE6 + (v67 & v71 | v69 & ~v67), 27);
v73 = v72 + v71;
v74 = RORS(v67 + v50 - 0x3CC8F82A + (v69 & v73 | v71 & ~v69), 23);
v75 = v74 + v73;
v76 = RORS(v69 + v12 - 0xB2AF279 + (v71 & v75 | v73 & ~v71), 18);
v77 = v76 + v75;
v78 = RORS(v71 + v29 + 0x455A14ED + (v73 & v77 | v75 & ~v73), 12);
v79 = v78 + v77;
v80 = RORS(v73 + v47 - 1444681467 + (v75 & v79 | v77 & ~v75), 27);
v81 = v80 + v79;
v82 = RORS(v75 + v8 - 0x3105C08 + (v77 & v81 | v79 & ~v77), 23);
v83 = v82 + v81;
v84 = RORS(v77 + v26 + 0x676F02D9 + (v79 & v83 | v81 & ~v79), 18);
v85 = v84 + v83;
v86 = RORS(v79 + v43 - 0x72D5B376 + (v81 & v85 | v83 & ~v81), 12);
v87 = v86 + v85;
v88 = RORS(v81 + v19 - 0x5C6BE + (v85 ^ v83 ^ v87), 28);
v89 = v88 + v87;
v90 = RORS(v83 + v29 - 0x788E097F + (v87 ^ v85 ^ v89), 21);
v91 = v90 + v89;
v92 = RORS(v85 + v40 + 0x6D9D6122 + (v89 ^ v87 ^ v91), 16);
v93 = v92 + v91;
v94 = RORS(v87 + v50 - 0x21AC7F4 + (v91 ^ v89 ^ v93), 9);
v95 = v94 + v93;
v96 = RORS(v89 + v6 - 0x5B4115BC + (v93 ^ v91 ^ v95), 28);
v97 = v96 + v95;
v98 = RORS(v91 + v15 + 0x4BDECFA9 + (v95 ^ v93 ^ v97), 21);
v99 = v98 + v97;
v100 = RORS(v93 + v26 - 0x944B4A0 + (v97 ^ v95 ^ v99), 16);
v101 = v100 + v99;
v102 = RORS(v95 + v36 - 0x41404390 + (v99 ^ v97 ^ v101), 9);
v103 = v102 + v101;
v104 = RORS(v97 + v47 + 0x289B7EC6 + (v101 ^ v99 ^ v103), 28);
v105 = v104 + v103;
v106 = RORS(v99 + v3 - 0x155ED806 + (v103 ^ v101 ^ v105), 21);
v107 = v106 + v105;
v108 = RORS(v101 + v12 - 0x2B10CF7B + (v105 ^ v103 ^ v107), 16);
v109 = v108 + v107;
v110 = RORS(v103 + v22 + 0x4881D05 + (v107 ^ v105 ^ v109), 9);
v111 = v110 + v109;
v112 = RORS(v105 + v33 - 0x262B2FC7 + (v109 ^ v107 ^ v111), 28);
v113 = v112 + v111;
v114 = RORS(v107 + v43 - 0x1924661B + (v111 ^ v109 ^ v113), 21);
v115 = v114 + v113;
v116 = RORS(v109 + v53 + 0x1FA27CF8 + (v113 ^ v111 ^ v115), 16);
v117 = v116 + v115;
v118 = RORS(v111 + v8 - 0x3B53A99B + (v115 ^ v113 ^ v117), 9);
v119 = v118 + v117;
v120 = RORS(v113 + v3 - 0xBD6DDBC + ((~v115 | v119) ^ v117), 26);
v121 = v120 + v119;
v122 = RORS(((~v117 | v121) ^ v119) + v26 + 0x432AFF97 + v115, 22);
v123 = v122 + v121;
v124 = RORS(v50 - 0x546BDC59 + v117 + ((~v119 | v123) ^ v121), 17);
v125 = v124 + v123;
v126 = RORS(((~v121 | v125) ^ v123) + v19 - 0x36C5FC7 + v119, 11);
v127 = v126 + v125;
v128 = RORS(((~v123 | v127) ^ v125) + v43 + 0x655B59C3 + v121, 26);
v129 = v128 + v127;
v130 = RORS(((~v125 | v129) ^ v127) + v12 - 0x70F3336E + v123, 22);
v131 = v130 + v129;
v132 = RORS(((~v127 | v131) ^ v129) + v36 - 0x100B83 + v125, 17);
v133 = v132 + v131;
v134 = RORS(((~v129 | v133) ^ v131) + v6 - 0x7A7BA22F + v127, 11);
v135 = v134 + v133;
v136 = RORS(((~v131 | v135) ^ v133) + v29 + 0x6FA87E4F + v129, 26);
v137 = v136 + v135;
v138 = RORS(((~v133 | v137) ^ v135) + v53 - 0x1D31920 + v131, 22);
v139 = v138 + v137;
v140 = RORS(((~v135 | v139) ^ v137) + v22 - 0x5CFEBCEC + v133, 17);
v141 = v140 + v139;
v142 = RORS(((~v137 | v141) ^ v139) + v47 + 0x4E0811A1 + v135, 11);
v143 = v142 + v141;
v144 = RORS(((~v139 | v143) ^ v141) + v15 - 0x8AC817E + v137, 26);
v145 = v144 + v143;
v146 = RORS(v139 + v40 - 0x42C50DCB + ((~v141 | v145) ^ v143), 22);
v147 = v146 + v145;
v148 = RORS(v141 + v8 + 0x2AD7D2BB + ((~v143 | v147) ^ v145), 17);
v149 = v148 + v147;
result[0] += v145;
v150 = RORS(v33 - 0x14792C6F + v143 + ((~v145 | v149) ^ v147), 11);
v151 = v147 + result[3];
result[2] += v149;
result[1] = v149 + v2 + v150;
result[3] = v151;
return;
}
public static uint RORS(uint value, uint moveLen)
{
value = ((value >> (int)moveLen) | (value << (int)(sizeof(uint) * 8 - moveLen)));
return value;
}
}
0x3 Thinking
1. c#中操作结构体中的数值.