新CrackMe160之160 - MD5 - BytePtr - kgme1
汇编写的程序,直接使用OD查看源码,载入程序后, 直接下翻就看到关键算法处了00401B27为关键对比,上面00401B13和00401B18两个关键函数
- 00401B02 将用户与固定串"BytePtr [e!]"拼接在一起作为新的用户名user1
- 00401B13 将user1传入这个方法,得到一个新串str1 (后记: 后面看了大佬的破文才知道,这步是MD5加密,所以注册机中的方法也改为Md5了)
- 00401B18 将str1传入这个方法得到最终正确系列号
- 00401B27 比较
需要对2.3.进行详细分析
注册机:
#include <stdio.h>
#include <string.h>
unsigned int rol(unsigned int num, int i){
return (num << i) | (num >> (sizeof(int) * 8 - i));
}
unsigned int mysum(int i, unsigned int l1, unsigned int l2, unsigned int l3, unsigned int l4, unsigned int edi, unsigned int num, int roln){
unsigned int eax = l1;
unsigned int ebx = l2;
unsigned int ecx = l3;
if(i<4){
ebx &= eax;
eax = ~eax;
eax &= ecx;
eax |= ebx;
} else if(i<8){
eax &= ecx;
ecx = ~ecx;
ecx &= ebx;
eax |= ecx;
} else if(i<12){
eax ^= ebx;
eax ^= ecx;
} else{
ecx = ~ecx;
eax |= ecx;
eax ^= ebx;
}
eax += l4;
eax += edi;
eax += num;
eax = rol(eax, roln);
eax += l1;
return eax;
}
void MD5(char *user, char *code) {
int i;
int len = strlen(user);
user[len] = 0x80;
user[56] = len * 8;
unsigned int l1 = 0x67452301;
unsigned int l2 = 0xEFCDAB89;
unsigned int l3 = 0x98BADCFE;
unsigned int l4 = 0x10325476;
int rn[4][4] = {{0x7,0xC,0x11,0x16},{0x5,0x9,0xE,0x14},{0x4,0xB,0x10,0x17},{0x6,0xA,0xF,0x15}};
int n[64] = {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,4,24,44,0,20,40,60,16,36,56,12,32,52,8,28,48,20,32,44,56,4,16,28,40,52,0,12,24,36,48,60,8,0,28,56,20,48,12,40,4,32,60,24,52,16,44,8,36};
unsigned int nums[64] = {0xD76AA478,0xE8C7B756,0x242070DB,0xC1BDCEEE,0xF57C0FAF,0x4787C62A,0xA8304613,0xFD469501,0x698098D8,0x8B44F7AF,0xFFFF5BB1,0x895CD7BE,0x6B901122,0xFD987193,0xA679438E,0x49B40821,0xF61E2562,0xC040B340,0x265E5A51,0xE9B6C7AA,0xD62F105D,0x2441453,0xD8A1E681,0xE7D3FBC8,0x21E1CDE6,0xC33707D6,0xF4D50D87,0x455A14ED,0xA9E3E905,0xFCEFA3F8,0x676F02D9,0x8D2A4C8A,0xFFFA3942,0x8771F681,0x6D9D6122,0xFDE5380C,0xA4BEEA44,0x4BDECFA9,0xF6BB4B60,0xBEBFBC70,0x289B7EC6,0xEAA127FA,0xD4EF3085,0x4881D05,0xD9D4D039,0xE6DB99E5,0x1FA27CF8,0xC4AC5665,0xF4292244,0x432AFF97,0xAB9423A7,0xFC93A039,0x655B59C3,0x8F0CCC92,0xFFEFF47D,0x85845DD1,0x6FA87E4F,0xFE2CE6E0,0xA3014314,0x4E0811A1,0xF7537E82,0xBD3AF235,0x2AD7D2BB,0xEB86D391};
for(i=0; i<16; i++){
l1 = mysum(i, l2, l3, l4, l1, *(unsigned int *)(user+n[i*4+0]), nums[i*4+0], rn[i/4][0]);
l4 = mysum(i, l1, l2, l3, l4, *(unsigned int *)(user+n[i*4+1]), nums[i*4+1], rn[i/4][1]);
l3 = mysum(i, l4, l1, l2, l3, *(unsigned int *)(user+n[i*4+2]), nums[i*4+2], rn[i/4][2]);
l2 = mysum(i, l3, l4, l1, l2, *(unsigned int *)(user+n[i*4+3]), nums[i*4+3], rn[i/4][3]);
}
l1 += 0x67452301;
l2 += 0xEFCDAB89;
l3 += 0x98BADCFE;
l4 += 0x10325476;
code[0] = (l1 >> 24) & 0xFF;
code[1] = (l1 >> 16) & 0xFF;
code[2] = (l1 >> 8) & 0xFF;
code[3] = l1 & 0xFF;
code[4] = (l2 >> 24) & 0xFF;
code[5] = (l2 >> 16) & 0xFF;
code[6] = (l2 >> 8) & 0xFF;
code[7] = l2 & 0xFF;
code[8] = (l3 >> 24) & 0xFF;
code[9] = (l3 >> 16) & 0xFF;
code[10] = (l3 >> 8) & 0xFF;
code[11] = l3 & 0xFF;
code[12] = (l4 >> 24) & 0xFF;
code[13] = (l4 >> 16) & 0xFF;
code[14] = (l4 >> 8) & 0xFF;
code[15] = l4 & 0xFF;
}
int main() {
int i;
char user[65] = {0};
unsigned char code[33] = {0};
printf("用户名: "); scanf("%s", user); getchar();
MD5(user,code);
printf("MD5(32): ");
for(i=0; i<16; i++){
printf("%02X", code[i]);
}
unsigned int l1 = *(unsigned int *)code;
unsigned int l2 = *(unsigned int *)(code+4);
unsigned int l3 = *(unsigned int *)(code+8);
unsigned int l4 = *(unsigned int *)(code+12);
l1 = l1 ^ l2;
sprintf(code, "%08X", l1);
l2 = l2 ^ 0xFBD0099;
sprintf(code+8, "%08X", l2);
l3 = l3 ^ l2;
sprintf(code+16, "%08X", l3);
sprintf(code+24, "%08X", l4);
printf("\n系列号: %s\n", code);
getchar();
return 0;
}
运行示例:
用户名: kgme
MD5(32): 1220D6CB0C3A154A79E99AA625AC39FE
系列号: 81C31A1E45A83A95E332D3ECFE39AC25
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号