本文最后更新于:2021-08-09 晚上
初探 打开程序还是和上一个有很熟悉的画面,不愧是同一个作者做的。
about按钮了解情况,还是需要让按钮消失然后露出logo就算成功了。
分析 无壳,是使用delphi编写的。
还是直接使用DeDark查看,然后去下断
断下来之后进行分析,可以看到一个较为关键的跳转,在此之前的函数比较重要,进去查看一下。
进来之后果然看到了算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 004429EE |. 8945 F4 mov dword ptr ss :[ebp -0xC ],eax 004429F1 |. BE 01000000 mov esi ,0x1 004429F6 |> 8B45 F8 /mov eax ,dword ptr ss :[ebp -0x8 ] 004429F9 |. E8 3610FCFF |call aLoNg3x_. 00403A34 004429FE |. 83F8 01 |cmp eax ,0x1 00442A01 |. 7C 1D |jl short aLoNg3x_. 00442A20 00442A03 |> 8B55 F8 |/mov edx ,dword ptr ss :[ebp -0x8 ] 00442A06 |. 0FB65432 FF ||movzx edx ,byte ptr ds :[edx +esi -0x1 ] 00442A0B |. 8B4D F8 ||mov ecx ,dword ptr ss :[ebp -0x8 ] 00442A0E |. 0FB64C01 FF ||movzx ecx ,byte ptr ds :[ecx +eax -0x1 ] 00442A13 |. 0FAFD1 ||imul edx ,ecx 00442A16 |. 0FAFD7 ||imul edx ,edi 00442A19 |. 03DA ||add ebx ,edx 00442A1B |. 48 ||dec eax 00442A1C |. 85C0 ||test eax ,eax 00442A1E |.^ 75 E3 |\jnz short aLoNg3x_. 00442A03 00442A20 |> 46 |inc esi 00442A21 |. FF4D F4 |dec dword ptr ss :[ebp -0xC ] 00442A24 |.^ 75 D0 \jnz short aLoNg3x_. 004429F6 00442A26 |> 8BC3 mov eax ,ebx 00442A28 |. 99 cdq 00442A29 |. 33C2 xor eax ,edx 00442A2B |. 2BC2 sub eax ,edx 00442A2D |. B9 2A2C0A00 mov ecx ,0xA2C2A 00442A32 |. 99 cdq 00442A33 |. F7F9 idiv ecx 00442A35 |. 8BDA mov ebx ,edx 00442A37 |. 8B45 FC mov eax ,dword ptr ss :[ebp -0x4 ] 00442A3A |. B9 59000000 mov ecx ,0x59 00442A3F |. 99 cdq 00442A40 |. F7F9 idiv ecx 00442A42 |. 8BC8 mov ecx ,eax 00442A44 |. 8B45 FC mov eax ,dword ptr ss :[ebp -0x4 ] 00442A47 |. BE 50000000 mov esi ,0x50 00442A4C |. 99 cdq 00442A4D |. F7FE idiv esi 00442A4F |. 03CA add ecx ,edx 00442A51 |. 41 inc ecx 00442A52 |. 894D FC mov dword ptr ss :[ebp -0x4 ],ecx 00442A55 |. 3B5D FC cmp ebx ,dword ptr ss :[ebp -0x4 ]
但是问题是,其中edi的值一直为0,这导致一直在计算的值都是0,然后再进行比较,是不可以的,必须要找到edi在何处被赋值。
往上慢慢寻找一下,可以看到此处edi的值是通过eax赋值的,那么又要寻找eax的值,函数内部没有,需要出去函数寻找。
出函数之后,看到eax的值是通过一个地址传递的
继续找寻此地址的值是从何处得来,下硬件断点,没有断下来,说明不满足条件,不过在上面不远处就可以看到这个地址的赋值。看到如果想要进入此处需要让上面的JZ跳转不跳走,进入前面的函数看看
进去发现是一个判断你输入的codice中是否含有非数字的一个判断,但是其中又有一点限制,就是第一位如果输入-,+,$,X,x,剩下都是数字的话,也是可以的,反正就是,输入非纯数字的codice以便可以进入后面,如果输入第一位为以上几个的话,那么其中还需要至少再含有一个非数字就可以。
继续分析,再赋值前一条语句的函数就是关键的生成函数,进入分析,发现算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 00442ACD |. B9 01000000 mov ecx,0x1 00442AD2 |> 8B45 FC /mov eax,dword ptr ss:[ebp-0x4 ]00442AD5 |. 0FB60408 |movzx eax,byte ptr ds:[eax+ecx]00442AD9 |. BF 11000000 |mov edi,0x11 00442ADE |. 33D2 |xor edx,edx00442AE0 |. F7F7 |div edi00442AE2 |. 42 |inc edx00442AE3 |. 8B45 FC |mov eax,dword ptr ss:[ebp-0x4 ]00442AE6 |. 0FB64408 FF |movzx eax,byte ptr ds:[eax+ecx-0x1 ]00442AEB |. 0FAFD0 |imul edx,eax00442AEE |. 03F2 |add esi,edx00442AF0 |. 41 |inc ecx ; user32.75B16D5100442AF1 |. 4B |dec ebx00442AF2 |.^ 75 DE \jnz short aLoNg3x_.00442AD2 00442AF4 |. EB 02 jmp short aLoNg3x_.00442AF8 00442AF6 |> 33F6 xor esi,esi00442AF8 |> 8BC6 mov eax,esi00442AFA |. B9 48710000 mov ecx,0x7148 00442AFF |. 99 cdq00442B00 |. F7F9 idiv ecx ; user32.75B16D5100442B02 |. 8BC2 mov eax,edx00442B04 |. 99 cdq00442B05 |. 33C2 xor eax,edx ; XOR000442B07 |. 2BC2 sub eax,edx ; -0 00442B09 |. 8BD8 mov ebx,eax00442B0B |. 33C0 xor eax,eax
这里会生成一个标志值,用于后面的计算
int len = strlen (szCodice);int remainder;int sum = 0x37B ;for (int i = 1 ; i < len ; i++) { remainder = szCodice[i] % 0x11 + 1 ; sum += remainder * szCodice[i - 1 ]; } sum = sum % 0x7148 ;return sum;
生成标志值之后就可以继续刚才的算法计算了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int len = strlen (szName);int sum = 0 ;for (int i = 0 ; i <= len; i++) { for (int j = 0 ; j <= len; j++) { sum += (szName[i] * szName[len - j]) * FlagNumber; } } __asm { mov eax,sum cdq xor eax,edx sub eax,edx mov ecx,0xA2C2A cdq idiv ecx mov ebx,edx mov sum,ebx }int serial;for (int i = 1 ; i < 0xFFFFFFFF ; i++) { if (((i / 0x59 ) + (i % 0x50 ) + 1 ) == sum) { printf ("codice:%d\n" , i); break ; } }
到这里算出了一个可以用的codice
输入后发现又出现了一个again按钮。
从dedark中找到againClick事件,经过分析发现其实是和OK按钮一模一样的流程,也就是把刚才输入的在输入一次就好了
注册机 完整注册机如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <stdio.h> #include <string.h> #include <Windows.h> int getFlagNumber (char * szCodice) { int len = strlen (szCodice); int remainder; int sum = 0x37B ; for (int i = 1 ; i < len ; i++) { remainder = szCodice[i] % 0x11 + 1 ; sum += remainder * szCodice[i - 1 ]; } sum = sum % 0x7148 ; return sum; }void OkClick (char * szName,int FlagNumber) { int len = strlen (szName); int sum = 0 ; for (int i = 0 ; i <= len; i++) { for (int j = 0 ; j <= len; j++) { sum += (szName[i] * szName[len - j]) * FlagNumber; } } __asm { mov eax,sum cdq xor eax,edx sub eax,edx mov ecx,0xA2C2A cdq idiv ecx mov ebx,edx mov sum,ebx } int serial; for (int i = 1 ; i < 0xFFFFFFFF ; i++) { if (((i / 0x59 ) + (i % 0x50 ) + 1 ) == sum) { printf ("codice:%d\n" , i); break ; } } }int main () { printf ("请先输入第一位是字母的Codice以便生成标志值\n" ); char Codice[20 ]; gets_s(Codice, 20 ); int FlagNumber = getFlagNumber(Codice); printf ("输入用户名\n" ); char name[20 ]; gets_s(name, 20 ); OkClick(name, FlagNumber); return 0 ; }
总结 这个程序就是需要先输入非纯数字codice生成一个标志值计算,然后再输入codice就可以了,连续两次即可。注册机那段内联汇编,实在不知道怎么用C写了…