写在前面:
大半年忙东忙西,很少有时间弄技术上的东西了,前几天和一个学长闲聊,他说之前做了一个小东西,就是分析010editor的注册算法,然后就找了一个"最新"的来试试。弄了几天基本算完成了,后面一直偷懒没有写文档,这会儿慢慢补充好吧。
.text:00550267 cmp edi, 0DBh ; 同时,要来到这里进行判断,有三条路线
.text:0055026D jnz short loc_5502A7 ; 只有这条路线是正确的,此时edi必须要等于0xDB
.text:0055026F push 0FFFFFFFFh
.text:00550271 push offset aPasswordAccept ; "Password accepted. Thank you for purcha"...
.text:00550276 call ebp ; QString::fromAscii_helper(char const *,int) ; QString::fromAscii_helper(char const *,int)
.text:00550278 mov [esp+40h+var_18], eax
loc_550267: ; 同时,要来到这里进行判断,有三条路线
cmp edi, 0DBh
jnz short loc_5502A7 ; 只有这条路线是正确的,此时edi必须要等于0xDB
push 3C70h
push 5
call sub_403963 ; 有三种返回情况:0xE7,0x4E,0x2D
mov ecx, dword_7D6E24 ; 关键算法点之一
push 3C70h
push 5
mov ebx, eax
call sub_40897C ; 这个函数会影响到edi的值(返回值赋值给edi)
mov ecx, dword_7D6E24 ; 尽管后面有三条路线,但是不管怎么说edi都必须为0xDB
xor edx, edx ; '关键算法点之一'如果返回的是0x2D,那么edi就为0xDB
mov edi, eax ; ‘关键算法点之一’如果返回的是0xE7,那么edi为0x177
mov eax, [ecx+34h]
test eax, eax
setz dl
mov [esp+38h+var_10], edx
cmp ebx, 0E7h
jz loc_550267 ; 如果这一条路想走通,必须满足:ebx为0xE7,edi为0xDB
.text:00616081 jz loc_6163DF ; 类中的标志位比较
.text:00616087 mov ecx, [esi+8]
.text:0061608A cmp [ecx+8], ebp
.text:0061608D jz loc_6163DF ; 类中的标志位比较
.text:00616093 push edi
.text:00616094 lea edx, [esp+30h+var_18] ; edx的值就是存放处理之后的密码串的地址
.text:00616098 push edx
.text:00616099 mov ecx, esi
.text:0061609B call sub_40889B ; 这个函数里面对输入的密码进行了操作
.text:006160A0 mov edi, offset off_7D58B8
.text:006160A5
.text:006160A5 loc_6160A5: ; CODE XREF: sub_616050+71j
.text:006160A5 mov eax, [edi]
.text:006160A7 push eax
.text:006160A8 mov ecx, ebx
.text:006160AA call ds:??8QString@@QBE_NPBD@Z ; QString::operator==(char const *)
.text:006160B0 test al, al
.text:006160B2 jnz loc_616279
.text:006160B8 add edi, 4
.text:006160BB cmp edi, offset unk_7D58BC
.text:006160C1 jl short loc_6160A5
.text:006160C3 mov al, [esp+30h+var_15] ; al = a[3]
.text:006160C7 mov bl, byte ptr [esp+30h+var_14+1] ; bl = a[5]
.text:006160CB cmp al, 9Ch ; 判断a[3]是否为0x9c
.text:006160CD jnz short loc_616149 ; 判断7,8位是不是F,C
.text:00616149 cmp al, 0FCh ; 判断7,8位是不是F,C
.text:0061614B jnz short loc_616165
.text:00616165 cmp al, 0ACh
.text:00616167 jnz loc_616279 ; 判断7,8位是不是A,C
.text:006160CF mov dl, byte ptr [esp+30h+var_14+3] ; 第8位 a[7]
.text:006160D3 xor dl, [esp+30h+var_17] ; dl = a[7] ^ a[1] (第二位)
.text:006160D7 mov cl, byte ptr [esp+30h+var_14+2] ; 第7位 a[6]
.text:006160DB xor cl, [esp+30h+var_18] ; cl = a[6] ^ a[0] (第一位)
.text:006160DF movzx ax, dl ; ax = a[7] ^ a[1]
.text:006160E3 mov byte ptr [esp+30h+var_1C], cl ; [esp+14] = a[6] ^ a[0]
.text:006160E7 mov ecx, 100h
.text:006160EC imul ax, cx ; ax = (a[7] ^ a[1]) << 8
.text:006160F0 mov dl, bl ; dl = a[5] (第6位)
.text:006160F2 xor dl, [esp+30h+var_16] ; dl = a[5] ^ a[2] (第三位)
.text:006160F6 movzx cx, dl ; cx = a[5] ^ a[2]
.text:006160FA mov edx, [esp+30h+var_1C]
.text:006160FE add ax, cx ; ax = (a[7] ^ a[1]) << 8 + a[5] ^a[2]
.text:00616101 push edx ; edx的值来源于[esp+14],等于a[6] ^ a[0]
.text:00616102 movzx edi, ax ; edi = (a[7] ^ a[1]) << 8 + a[5] ^a[2]
.text:00616105 call sub_406D6B ; eax = ((arg0 ^ 0x18) + 0x3D) ^ 0xA7
.text:0061610A movzx eax, al ; eax = (([esp+14] ^ 0x18) + 0x3D) ^ 0xA7
.text:0061610D push edi
.text:0061610E mov [esi+1Ch], eax ; [esi+1c] = (([esp+14] ^ 0x18) + 0x3D) ^ 0xA7
.text:00616111 call sub_4077D4 ; eax = (((arg0 ^ 0x7892) + 0x4d30) ^ 0x3421) / 0xB
.text:00616116 mov ecx, [esi+1Ch] ; 上一步中,除以0xB必须要整出,否则eax = 0,失败
.text:00616119 movzx eax, ax
.text:0061611C add esp, 8
.text:0061611F mov [esi+20h], eax ; 假设得到的eax恰好为0x3E8
.text:00616122 test ecx, ecx ; 坚决不能转 [esi+0x1C]的值不能为0
.text:00616124 jz loc_616279
.text:006162BA loc_6162BA: ; CODE XREF: sub_616050+24Cj
.text:006162BA mov cl, [esp+30h+var_15] ; 取a[3],判断标志位
.text:006162BE cmp cl, 9Ch
.text:006162C1 jnz short loc_6162D2 ; 判断a[3]是否为0x9c
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课