1. 程序的执行
首先我们输入一个用户名密码之后按check,会在密码的输入框弹出“Name must be 4 - 50 chars long!”,告诉我们用户名的长度必须为4-50个字节,如下图:
然后再次尝试如下图,再看程序的有关信息:
这些出现的字符串暂时都可以当作提示字符串便于后面寻找。
2. 查壳
解释:汇编语言编写的小巧程序,而且无壳。
3. 注意
movzx是将源操作数的内容拷贝到目的操作数,并将该值用0扩展至16位或者32位。但是它只适用于无符号整数。 他大致下面的三种格式。
movzx 32位通用寄存器, 8位通用寄存器/内存单元
movzx 32位通用寄存器, 16位通用寄存器/内存单元
movzx 16位通用寄存器, 8位通用寄存器/内存单元
4. 代码分析
这里我主要还是通过OD动态分析主要分析算法的。具体情况跟踪如图下图:
!
image-20221009153141854
解释:上图就是主要算法的计算步骤和过程。
解释:上图就是涉及一些简单的字符串拼接最后对比和暴力破解的关键跳转了。
5. 注册机的编写
- 注册码的格式Bon-a-b-c
其中a代表:用用户输入的用户名依次取得每一个字符的十六进制数据减去0x19,用0来去累差每次前面的带的差值,得到的一个负数总差。
其b代表:总差的三次方。)
其中c代表:储存了总差的地址的平方 减去 这个地址。(这是一个固定的地址,应该直接写上面分析出现的那和地址)
之后注册码注意区分大小写。
- 代码编写
#include <stdio.h> #include <string.h> void generatekey(char username[50]); //声明函数 void input(); int main() { input(); system("pause"); return 0; } void input() { char username[50] = { 0 }; int length = 0; loop: printf("Name must be 4 - 50 chars long!\n"); printf(" please input you username:"); scanf("%s", username); printf("you name long: %d\n", length = strlen(username)); if (length < 4 || length>50) goto loop; generatekey(username, length); } void generatekey(char username[50],int length) { char key[100]={0}; char Bon[] = "Bon"; char str1[10] = { 0 },str2[10] = { 0 }, str3[] = "-41720F48"; int a = 0, b = 0; for (int i = 0; i < length; i++) { username[i] -= 0x19; a -= username[i]; } printf("a = %x\ninput str1:", a); scanf("%s", str1); b = a * a * a; printf("b = %x\ninput str2:", b); scanf("%s", str2); strcat(key, Bon); strcat(key, str1); strcat(key, str2); strcat(key, str3); printf("%s\n", key); }