1.首先Win+R输入Regedit打开注册表编辑器
2.假设我们要看pdf格式的后缀应用程序的注册表路径就是
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pdf
UserChoice下的Hash是win10特有的校验值,防止第三方修改的微软秘密算法,win10经常弹出的默认程序出错就是这里的Hash出了问题。
3.我们通过逆向方法直接从汇编语言逆向出了微软的HASH算法,但是是从二进制逆的,代码风格并不适合人类维护。
所以我修改重写了该hash算法,使其能更好地维护修改。
typedef union{
int v0; // edi
ULONG* v1; // ecx
int v2; // ebp
unsigned int v3; // eax
int v4; // esi
int v5; // eax
unsigned int v6; // eax
int v7; // edx
unsigned int v8; // eax
int v9; // ebx
unsigned int v10; // edx
int v11; // ebx
unsigned int v12; // edx
int v13; // edx
unsigned int v14; // ebp
unsigned int v15; // edx
unsigned int v16; // eax
int v17; // [esp+0h] [ebp-1Ch]
}v;
BOOLEAN _F1(ULONG* a1,int a2,ULONG* a3,int* a4)
{
BOOLEAN result = FALSE;
v vf1;
vf1.v0 = 0; vf1.v1 = a1; vf1.v2 = (*a3 | 1) + 1778057216;
vf1.v3 = (unsigned int)(a2 - 2) >> 1; vf1.v4 = vf1.v3 + 1; vf1.v5 = 0;
vf1.v17 = (a3[1] | 1) + 333119488;
do
{
vf1.v6 = (unsigned int)(vf1.v1 + vf1.v5);
vf1.v7 = vf1.v1[1];//a1[1]
vf1.v1+=2;
vf1.v8 = 2046337941 * (vf1.v6 * vf1.v2 - 284857861 * (vf1.v6 >> 16)) + 1755016095 * ((vf1.v6 * vf1.v2 - 284857861 * (vf1.v6 >> 16)) >> 16);
vf1.v9 = -359202815 * vf1.v8 - 1007687017 * (vf1.v8 >> 16);
vf1.v10 = vf1.v9 + vf1.v7;
vf1.v11 = vf1.v0 + vf1.v9;
vf1.v12 = 1505996589 * (vf1.v10 * vf1.v17 - 1021897765 * (vf1.v10 >> 16))
- 573759729 * ((vf1.v10 * vf1.v17 - 1021897765 * (vf1.v10 >> 16)) >> 16);
vf1.v5 = 516489217 * vf1.v12 + 901586633 * (vf1.v12 >> 16);
vf1.v13 = vf1.v11+vf1.v5;
vf1.v0 = vf1.v11 +vf1.v5;
--vf1.v4;
}while(vf1.v4);
if(a2-vf1.v3 * 2 - 2 == 1 && vf1.v3 * 2 + 2 <512)
{
vf1.v14 = 1755016095 * (((a1[2 * vf1.v3 + 2] + vf1.v5) * vf1.v2 - 284857861 * ((unsigned int)(a1[2 * vf1.v3 + 2] + vf1.v5) >> 16)) >> 16)
+ 2046337941 * ((a1[2 * vf1.v3 + 2] + vf1.v5) * vf1.v2 - 284857861 * ((unsigned int)(a1[2 * vf1.v3 + 2] + vf1.v5) >> 16));
vf1.v15 = -359202815 * vf1.v14 - 1007687017 * (vf1.v14 >> 16);
vf1.v16 = 1505996589 * (vf1.v15 * vf1.v17 - 1021897765 * (vf1.v15 >> 16))
- 573759729 * ((vf1.v15 * vf1.v17 - 1021897765 * (vf1.v15 >> 16)) >> 16);
vf1.v5 = 516489217 * vf1.v16 + 901586633 * (vf1.v16 >> 16);
vf1.v13 = vf1.v5 + vf1.v0 + vf1.v15;
}else
return result;
*a4 = vf1.v5;
a4[1] = vf1.v13;
result = TRUE;
return result;
}
int _F2(ULONG *a1, int a2, ULONG *a3, int *a4)
{
BOOLEAN result = FALSE;
v vf2;
vf2.v0 = 0; vf2.v1 = a1; vf2.v2 = (*a3 | 1);
ULONG v = *a1;
vf2.v3 = (unsigned int)(a2 - 2) >> 1; vf2.v4 = vf2.v3 + 1; vf2.v5 = 0;
vf2.v17 = vf2.v3;
do{
vf2.v7 = v + vf2.v5;
vf2.v1 +=2;
vf2.v6 = -1324285952 * vf2.v7 * vf2.v17 - 812076783 * ((unsigned int)(vf2.v7 * vf2.v17) >> 16);
vf2.v8 = 315537773 * ((1537146880 * vf2.v6 - 2029495393 * (vf2.v6 >> 16)) >> 16)
- 1184038912 * (1537146880 * vf2.v6 - 2029495393 * (vf2.v6 >> 16));
vf2.v9 = 495124480 * vf2.v8 + 629022083 * (vf2.v8 >> 16);
vf2.v10 = 385155072 * vf2.v2 * (vf2.v9 + *(vf2.v1-1)) - 1569450251 * ((unsigned int)(vf2.v2 * (vf2.v9 + *(vf2.v1 - 1))) >> 16);
vf2.v12 = 730398720 * (-1761673216 * vf2.v10 - 746350849 * (vf2.v10 >> 16))
+ 2090019721 * ((-1761673216 * vf2.v10 - 746350849 * (vf2.v10 >> 16)) >> 16);
vf2.v5 = -1620508672 * vf2.v12 - 1079730327 * (vf2.v12 >> 16);
vf2.v11 = vf2.v5 + vf2.v0 + vf2.v9;
vf2.v0 = vf2.v11;
--vf2.v4;
}while(vf2.v4);
if(a2-vf1.v3 * 2 - 2 == 1 && vf1.v3 * 2 + 2 <512)
{
vf2.v15 = -1324285952 * (a1[2 * vf2.v3 + 2] + vf2.v5) * vf2.v17 - 812076783 * ((unsigned int)((a1[2 * vf2.v3 + 2] + vf2.v5) * vf2.v17) >> 16);
vf2.v14 = 315537773 * ((1537146880 * vf2.v15 - 2029495393 * (vf2.15 >> 16)) >> 16)
- 1184038912 * (1537146880 * vf2.v15 - 2029495393 * (vf2.v15 >> 16));
vf2.v13 = 495124480 * vf2.v14 + 629022083 * (vf2.v14 >> 16);
vf2.v16 = -1761673216 * (vf2.v13 * 385155072 * vf2.v2 - 1569450251 * ((unsigned int)(vf2.v13 * vf2.v2) >> 16))
- 746350849 * ((vf2.v13 * 385155072 * vf2.v2 - 1569450251 * ((unsigned int)(vf2.v13 * vf2.v2) >> 16)) >> 16);
vf2.v5 = -1620508672 * (730398720 * vf2.v16 + 2090019721 * (vf2.v16 >> 16))
- 1079730327 * ((730398720 * vf2.v16 + 2090019721 * (vf2.v16 >> 16)) >> 16);
vf2.v11 = vf2.v5 + vf2.v0 + vf2.v13;
}
else
return result;
*a4 = vf2.v5;
a4[1] = vf2.v11;
result = TRUE;
}
BOOLEAN HASH(char* pInput, ULONG ulInput, char* a3, int *hash)
{
ULONG v4;
int v[256] = {0};
v4 = ((ulInput & 4)<1)+(ulInput >> 2)-1;
if(v4<=1 || v4&1 ||
_F1((ULONG)pInput,v4,(ULONG*)a3,&v[0]) == FALSE||
_F1((ULONG)pInput,v4,(ULONG*)a3,&v[2] == FALSE)
{
return FALSE;
}
hash[0] = v[2] ^ v[0];
hash[1] = v[3] ^ v[1];
return TRUE;
}