吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3181|回复: 23
收起左侧

[CrackMe] 易语言 CM2

[复制链接]
爱飞的猫 发表于 2024-3-15 10:46
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

本帖最后由 爱飞的猫 于 2024-3-20 00:33 编辑

易语言 (?) CM 第二弹

相信大家都知道易语言常用的 PUSH 窗口方法吧。

不过呢,这个 CM 稍微处理了下… :D

压缩包解压密码:52pojie

※ 其实没有用到易语言核心库的窗口,真的不用去尝试…

挑战说明

挑战:

  • 爆破 - 确认弹窗后,程序不会崩溃
  • 算法注册机 - 使用自己的 ID 生成一个序列号吧!

※ 挑战成功后,欢迎分享交流思路

小提示/使用技巧:

  • 不支持 XP,请在 Win7+ 操作系统挑战
  • 序列号长度为 32 字符
  • 程序的文字使用 Unicode 编码,利用易语言的“字节集”类型来储存。
    • 字符串引用可能会找不到有用的东西。
  • 使用了稍微魔改了下的 RC4 算法
  • 在一些地方加入了花指令,如果不注意可能会跑飞哦!
  • 用到了内存加载 DLL 技巧,并抹掉了 PE 头。

测试信息

测试序列号 (注意前后没有空格):

用户名:   爱飞的猫 @52pojie
序列号:   CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49
版 本:   专业版

成功提示

失败提示

[爱飞的猫 @52pojie]

  挑战失败,请继续加油哦!

更新记录

v1.1: 修正了用户名不参与序列号验证的问题
v1.0: 初版发布


    爱飞的猫 @52pojie
         2024 春


结语

感觉做着做着就跑题了,写到后面和易语言关系不是特别大了… 尤其是核心验证代码其实是在 C++ 写的 DLl 内的。

可执行文件对资源做了个简单的过 EWnd 插件处理。虽然只是图一乐,但读者若是有兴趣可以试试恢复它 :D

发布前在调试序列号不通过验证的问题,调试完后忘了把用户名参与计算部分加回去了… v1.1 已修正。旧版本的文件可以在度盘镜像找到。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 2吾爱币 +2 热心值 +1 收起 理由
sivion + 1 + 1 用心讨论,共获提升!
dong823 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

solly 发表于 2024-3-19 23:40
本帖最后由 solly 于 2024-3-20 00:02 编辑

[Asm] 纯文本查看 复制代码
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <windows.h>

typedef unsigned char UINT8;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
typedef unsigned __int128 UINT128;
//typedef unsigned __int256 UINT256;

/// 001EE150  00 6C 6F 76 65 5F 77 69 74 68 5F 65 00 00 00 00  .love_with_e....
//const char * love = "love_with_e";
const char love_base[] = {0x00, 0x6C, 0x6F, 0x76, 0x65, 0x5F, 0x77, 0x69, 0x74, 0x68, 0x5F, 0x65, 0x00, 0x00, 0x00, 0x00};
/// 001EE160  00 31 37 36 30 31 37 5E 35 32 70 6F 6A 69 65 00  .176017^52pojie.
const char name_base[] = {0x00, 0x31, 0x37, 0x36, 0x30, 0x31, 0x37, 0x5E, 0x35, 0x32, 0x70, 0x6F, 0x6A, 0x69, 0x65, 0x00};
/*
001EE170  32 33 34 36 37 39 41 43 44 45 46 47 48 4A 4B 4C  234679ACDEFGHJKL
001EE180  4D 4E 50 52 54 55 56 57 58 59 5A 61 63 64 65 66  MNPRTUVWXYZacdef
*/
const char key_base[] = {
    0x32, 0x33, 0x34, 0x36, 0x37, 0x39, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C,
    0x4D, 0x4E, 0x50, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x63, 0x64, 0x65, 0x66
};

const char idx_base[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /// 234679
    0x00, 0x06, 0x00, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00,  /// ACDEFGHJKLMN
    0x12, 0x00, 0x13, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00,  /// PRTUVWXYZ
    0x00, 0x1B, 0x00, 0x1C, 0x1D, 0x1E, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /// acdef 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

///9F7HA36XfHaNDDC7L77HEPeYZ4Z44672
///CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49
char * base32table = "234679ACDEFGHJKLMNPRTUVWXYZacdef";

struct _permute_box {
        UINT8 idx1;
        UINT8 idx2;
        UINT8 data[256];
};

typedef _permute_box PBOX;

int GbkToUtf8(const char *src_str, char * dst_str, int length);
int base32encode(UINT8 * data, int size, char * result);
void logger(const char * title, UINT8 * logMsg, int rows, int cols);
int generate(char * name, int ver, char * key);
bool check(char * name, char * key);

int main(int argc, char** argv) {
        char name[] = "solly@52pojie.cn";
        char key1[]  = "0123456789ABCDEF0123456789ABCDEF\0";
        char key2[]  = "0123456789ABCDEF0123456789ABCDEF\0";
        
        //char name[] = "°&#174;·&#201;&#181;&#196;&#195;¨ @52pojie";
        //char key[] = "CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49\0";
        char pname[2048];
        
        int n = GbkToUtf8(name, pname, 2048);
        
        int m = generate(pname, 1, key1);
        int k = generate(pname, 2, key2);
        
        printf("\n\nYour name: %s\n  Key pro: %s\n Key full: %s\n\n", name, key1, key2);
        
        bool ret1 = check(pname, key1);
        bool ret2 = check(pname, key2);
        if(ret1 && ret2) {
                printf("Check successful.\n");
        } else {
                printf("Check failure.\n");
        }
        
        /// 2A 88 C3 04 78 FB 37 14 20 E4 79 08 C4 CB D9 D0 B4 21 0C 80
        //UINT8 data[] = {0x3C, 0x2F, 0xC3, 0x14, 0xFD, 0x44, 0x99, 0x70, 0xC5, 0x81, 0xEE, 0x76, 0x38, 0xA0, 0x89, 0x21, 0x8E, 0x4F, 0x4C, 0x45};
        //char test_key[33];
        //int k = base32encode(data, 20, test_key);
        //printf("n = %d, key = %s\n", k, test_key);
        
        return 0;
}

int base32encode(UINT8 * data, int size, char * result) {
        char result_tmp[9];
        UINT8 d0,d1,d2,d3,d4,d5,d6,d7;
        result_tmp[8] = '\0';
        int k=0;
        for(int i=0; i<size; i+=5) {
                d0 = (data[i+0]>>3) & 0x1F;
                result_tmp[0] = base32table[d0];
                d1 = ((data[i+0]<<2) & 0x1C) | ((data[i+1]>>6) & 0x03);
                result_tmp[1] = base32table[d1];
                d2 = (data[i+1]>>1) & 0x1F;
                result_tmp[2] = base32table[d2];
                d3 = ((data[i+1]<<4) & 0x10) | ((data[i+2]>>4) & 0x0F);
                result_tmp[3] = base32table[d3];
                d4 = ((data[i+2]<<1) & 0x1E) | ((data[i+3]>>7) & 0x01);
                result_tmp[4] = base32table[d4]; 
                d5 = (data[i+3]>>2) & 0x1F;
                result_tmp[5] = base32table[d5];
                d6 = ((data[i+3]<<3) & 0x18) | (data[i+4]>>5 & 0x07);
                result_tmp[6] = base32table[d6];
                d7 = (data[i+4]) & 0x1F;
                result_tmp[7] = base32table[d7];
                for(int j=0; j<8; j++) {
                        result[k+j] = result_tmp[j];
                }
                k+=8;
                result[k] = '\0';
        }
        
        return k;
}

PBOX * permute(PBOX * result, char * data, int length) {
        UINT8 key[1024];
        //logger("permute1", NULL, 0, 0);
        
        for(int i=0; i<16; i++) {
                key[i] = name_base[i];
        }
        strncpy((char *)&key[16], data, length);
        //logger("data_buff", data_buff, 3, 16);
        
        result->idx1 = 0;
        result->idx2 = 0;
        for(int i=0; i<256; i++) {
                result->data[i] = (i + 0x5C);
        }
        //logger("idx", &result->idx1, 1, 2);
        //logger("base", result->data, 16, 16);

        int len1 = length + 16;  //// len + sizeof(name_base)
        UINT8 i = 0, j = 0;
        for(int i=0; i<256; i++) {
                UINT8 tmp = result->data[i];
                j = j + tmp - key[i % len1];
                //// sawp()
                result->data[i] = result->data[j];
                result->data[j] = tmp;
        }
        //logger("idx", &result->idx1, 1, 2);
        //logger("permute-1", result->data, 16, 16);

        i=result->idx1;
        j=result->idx2;
        int len2 = len1 + 256; ///
        //printf("len2 = %d\n", len2);
        for(int k=0; k<len2; k++) {
                i = i + 1;
                j = j +  result->data[i];
                //// swap()
                UINT8 tmp = result->data[i];
                result->data[i] = result->data[j];
                result->data[j] = tmp;
        }
        result->idx1 = i;
        result->idx2 = j;
        //logger("idx", &result->idx1, 1, 2);
        //logger("permute-2", result->data, 16, 16);

    return result;
}

bool check(char * name, char * key) {
        UINT8 name_buff[60];
        PBOX name_permuted;
        UINT8 key_buff[32];
        
        int len_name = strlen(name);
        len_name = (len_name<60) ? len_name : 59;

        for(int i=0; i<len_name; i++) {
                name_buff[i] = name[i];
        }
        name_buff[len_name] = '\0';
        
        //printf("name: %s\n", name_buff);
        
        int len_key = strlen(key);  /// 0x20
        //printf("key length: %d\n", len_key);
        
        permute(&name_permuted, (char*)name_buff, len_name);
        //printf("permuted1\n");
        
        if(len_key) {
                //UINT32 shift_data = 0, shift_bits = 0;
                UINT64 shift_data = 0; 
                //UINT128 shift_data = 0; 
        UINT8 shift_bits = 0;
                int kk = 0;
                UINT8 i = name_permuted.idx1;
                UINT8 j = name_permuted.idx2;

                for(int k=0; k<len_key; k++) {
                        int idx = key[k];                    //// key[] = "CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49"
                        //printf("check idx: %02X\n", idx);
                        shift_bits += 5;
                        ///
                        shift_data = (shift_data << 5) | idx_base[idx];

                        if(shift_bits>=8) {
                                i = i + 1;
                                j = j + name_permuted.data[i];
                                //// swap()
                                UINT8 tmp = name_permuted.data[i];
                                name_permuted.data[i] = name_permuted.data[j];
                                name_permuted.data[j] = tmp;
                                ////
                                UINT8 t = name_permuted.data[i] + name_permuted.data[j];
                                ////
                                shift_bits -= 8;
                                //printf("%d,", shift_bits); /// 2,4,1,3,0,2,4,1,3,0,2,4,1,3,0,2,4,1,3,0
                                UINT32 data = (shift_data >> shift_bits);
                                ////
                                key_buff[kk++] = (t ^ (UINT8)data);
                                //printf("data =%08X, t=%02X, key_buff = %02X, ", data, t, key_buff[kk-1]);
                        }
                        //printf("\n");
                }        
                name_permuted.idx1 = i;
                name_permuted.idx2 = j;        
        }
        logger("check_key_decoded", key_buff, 1, 20);
        //logger("idx", &name_permuted.idx1, 1, 2);
        //logger("name_permuted1", name_permuted.data, 16, 16);
        
        char bl = 0;
        char * ptrPWD = (char *)&love_base[1];
        permute(&name_permuted, ptrPWD, 11);
        //printf("permuted2\n");
        //logger("generate name_permuted.idx", &name_permuted.idx1, 1, 2);
        //logger("check name_permuted", name_permuted.data, 16, 16);
        
        UINT8 dh = name_permuted.idx2;
        UINT8 dl = name_permuted.idx1;
        for(int i=0; i<18; i++) {
                dl ++;
                name_permuted.idx1 = dl;
                UINT32 idx0 = dl;
                dh += name_permuted.data[idx0];
                name_permuted.idx2 = dh;
                UINT8 idx1 = (unsigned)dh;
                UINT8 idx2 = (unsigned)dl;
                UINT8 a = name_permuted.data[idx1];
                UINT8 c = name_permuted.data[idx2];
                name_permuted.data[idx2] = a;
                name_permuted.data[idx1] = c;
                dh = name_permuted.idx2;
                dl = name_permuted.idx1;
                UINT8 idx3 = (unsigned)dh;
                UINT8 idx4 = (unsigned)dl;
                c = name_permuted.data[idx3];
                c += name_permuted.data[idx4];
                c ^= key_buff[i];  // c == key_buff[i], ok
                bl |= c;    //// result = 0, ok
        }
        //logger("key_permuted", key_buff, 2, 16);
        //logger("idx", &name_permuted.idx1, 1, 2);
        //logger("name_permuted2", name_permuted.data, 16, 16);
        
        dl++;
        name_permuted.idx1 = dl;
        unsigned int idx0 = dl;
        dh += name_permuted.data[idx0];
        name_permuted.idx2 = dh;
        unsigned int idx1 = dh;
        unsigned int idx2 = dl;
        char a = name_permuted.data[idx1];
        char c = name_permuted.data[idx2];
        name_permuted.data[idx2] = a;
        name_permuted.data[idx1] = c;
        unsigned int idx3 = name_permuted.idx2;
        unsigned int idx4 = name_permuted.idx1;
        dh = name_permuted.data[idx3];
        dh += name_permuted.data[idx4];
        dh ^= key_buff[18];               /// flag1 = 0x3E or 0x3D

        //logger("key_permuted", key_buff, 2, 16);
        //logger("idx", &name_permuted.idx1, 1, 2);
        //logger("name_permuted3", name_permuted.data, 16, 16);

        //// crc
        dl = 0xFF; //dl |= 0xFF;
        for(int i=0; i<19; i++) {
                char al = key_buff[i];
                dl = (dl>>5) | (dl<<3);
                dl ^= al;
        }
        char al = key_buff[19];   /// flag2
        al ^= dl;                 /// dl == al, ok
        al |= bl;                 /// bl = 0, ok
        
        /// al=0x8C, dl=0x5F, bl=0xFF, dh=0xFB
        return (al == 0) && ((dh == 0x3E) || (dh == 0x3D));
}

int generate(char * name, int ver, char * key) {
        UINT8 name_buff[60];
        PBOX name_permuted;
        UINT8 key_buff[32];
        UINT8 key_final[36];
        
        int len_name = strlen(name);
        len_name = (len_name<60) ? len_name : 59;

        for(int i=0; i<len_name; i++) {
                name_buff[i] = name[i];
        }
        name_buff[len_name] = '\0';
        
        //printf("name: %s\n", name_buff);
        char bl = 0;
        char * ptrPWD = (char *)&love_base[1];
        permute(&name_permuted, ptrPWD, 11);
        //printf("permuted2\n");
        //logger("generate name_permuted.idx", &name_permuted.idx1, 1, 2);
        //logger("generate name_permuted", name_permuted.data, 16, 16);
        
        UINT8 i = name_permuted.idx1;   /// dl
        UINT8 j = name_permuted.idx2;   /// dh
        for(int k=0; k<18; k++) {
                i += 1;
                j += name_permuted.data[i];
                
                UINT8 tmp = name_permuted.data[i];
                name_permuted.data[i] = name_permuted.data[j];
                name_permuted.data[j] = tmp;
                key_buff[k] = name_permuted.data[i] + name_permuted.data[j];
        }
        name_permuted.idx1 = i;
        name_permuted.idx2 = j;
        
        //logger("key_permuted", key_buff, 1, 18);
        //logger("idx", &name_permuted.idx1, 1, 2);
        //logger("name_permuted2", name_permuted.data, 16, 16);
        
        i += 1;
        j += name_permuted.data[i];
                
        UINT8 tmp = name_permuted.data[i];
        name_permuted.data[i] = name_permuted.data[j];
        name_permuted.data[j] = tmp;
        UINT8 ver_xor = name_permuted.data[i] + name_permuted.data[j];
        key_buff[18] = (ver == 1) ? (ver_xor ^ 0x3E) : (ver_xor ^ 0x3D); /// flag1 = 0x3E or 0x3D


        //logger("key_permuted", key_buff, 2, 16);
        //logger("idx", &name_permuted.idx1, 1, 2);
        //logger("name_permuted3", name_permuted.data, 16, 16);

        //// crc
        UINT8 crc = 0xFF; //dl |= 0xFF;
        for(int k=0; k<19; k++) {
                char al = key_buff[k];
                crc = (crc>>5) | (crc<<3);
                crc ^= al;
        }
        key_buff[19] = crc;
        key_buff[20] = '\0';

        logger("generated key_binary[]", key_buff, 1, 20);

        int len_key = 0x20;//strlen(key);  /// 0x20
        //printf("key length: %d\n", len_key);
        
        permute(&name_permuted, (char*)name_buff, len_name);
        //printf("permuted1\n");
        
        i = name_permuted.idx1;
        j = name_permuted.idx2;
        
        //printf("i=%d, j=%d\n", i, j);

        for(int k=0; k<20; k++) {
                i = i + 1;
                j = j + name_permuted.data[i];
                //// swap()
                UINT8 tmp = name_permuted.data[i];
                name_permuted.data[i] = name_permuted.data[j];
                name_permuted.data[j] = tmp;
        }
        
        name_permuted.idx1 = i;
        name_permuted.idx2 = j;        

        UINT32 shift_data = 0;
        UINT32 shift_data_next = 0;
        
    int shift_bits = 0;
    int shift_bits_orig[] = { 5, 10,  7, 12, 9,  6, 11, 8,  5, 10,  7, 12, 9,  6, 11, 8,  5, 10,  7, 12, 9,  6, 11, 8,  5, 10,  7, 12, 9,  6, 11, 8};
        int shift_bits_sub8[] = {-3,  2, -1,  4, 1, -2,  3, 0, -3,  2, -1,  4, 1, -2,  3, 0, -3,  2, -1,  4, 1, -2,  3, 0, -3,  2, -1,  4, 1, -2,  3, 0};
        int kk = 20; /// 0~19
        for(int k=31; k>=0; k--) {
                shift_bits += 5;
        if(shift_bits_sub8[k] >= 0) {
                        key_buff[--kk] ^= name_permuted.data[i] + name_permuted.data[j];
                        //// key_buff[]: 2A 88 C3 04 78 FB 37 14 20 E4 79 08 C4 CB D9 D0 B4 21 0C 80
                        UINT8 tmp = name_permuted.data[j];
                        name_permuted.data[j] = name_permuted.data[i];
                        name_permuted.data[i] = tmp;
                        j = j - name_permuted.data[i];
                        i = i - 1;
                }
        }
        base32encode(key_buff, 20, (char *)key_final);
    key_final[32] = '\0';

        name_permuted.idx1 = i;
        name_permuted.idx2 = j;        

        //logger("generated key_final[]", key_final, 2, 16);
        
        if(key) {
                strcpy(key, (char *)key_final);
        }

        return strlen((char*)key_final);
}

void logger(const char * title, UINT8 * logMsg, int rows, int cols) {
        if(title != NULL) {
                printf("\n%s:\n", title);
        } else {
                printf("\nlogger:\n");
        }
        if(logMsg != NULL) {
                for(int i=0; i<rows; i++) {
                        for(int j=0; j<cols; j++) {
                                printf(" %02X", (unsigned char)logMsg[i*cols+j]);
                        }
                        printf("\n");
                }
                printf("\n");
        } else {
                printf("log has no message!\n\n");
        }
}

int GbkToUtf8(const char *src_str, char * dst_str, int length) {
        wchar_t wstr[4096];
        if(dst_str == NULL) {
                return 0;
        }
        int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0);
        if(len>4094) {
                len = 4094;
        }
        memset(wstr, 0, len + 2);
        MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len);
        len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
        if(len>=length) {
                len = length-1;
        }
        memset(dst_str, 0, len + 1);
        WideCharToMultiByte(CP_UTF8, 0, wstr, -1, dst_str, len, NULL, NULL);
        return len;
}


[Shell] 纯文本查看 复制代码
Your name: [email]solly@52pojie.cn[/email]
  Key pro: HRE7L92cc2fRFe3EPHY3P9YTFX7GR3aR
 Key full: HRE7L92cc2fRFe3EPHY3P9YTFX7GR36M

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

点评

我把我这边的源码更新到主贴啦  详情 回复 发表于 2024-3-20 00:34

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
爱飞的猫 + 1 + 1 算法被逆出来啦,我晚点把我的源码也放出来吧。

查看全部评分

solly 发表于 2024-3-15 20:25
本帖最后由 solly 于 2024-3-15 20:32 编辑

初看了一下,从 0x00401836 开始的是DLL代码,会拷贝到0x00251000当作DLL调用。大概0x00401917是check函数,在dll中的地址是 0x002510E1,调用处在这里(去掉了花指令):
[Asm] 纯文本查看 复制代码
00415F06    | 55                     | push ebp                         | esp = 0x0018F7C4
00415F07    | 8BEC                   | mov ebp,esp                      | esp = 0x0018F7C0
00415F09    | 81EC 08000000          | sub esp,8                        | esp = 0x0018F7BC, -4 ==> -8
00415F0F    | C745 FC 00000000       | mov dword ptr ss:[ebp-4],0       |
00415F16    | A1 D8744B00            | mov eax,dword ptr ds:[4B74D8]    | DLL_fun_addresses[] = {0x00251635, 0x002510E1}
00415F1B    | 8945 FC                | mov dword ptr ss:[ebp-4],eax     |
00415F1E    | 90                     | nop                              | 花指令call
00415F1F    | 90                     | nop                              |
00415F20    | 90                     | nop                              |
00415F21    | 90                     | nop                              |
00415F22    | FFC1                   | inc ecx                          |
00415F24    | 8B45 FC                | mov eax,dword ptr ss:[ebp-4]     | esp = 0x0018F7B8 ==>0x00415F23
00415F27    | 892424                 | mov dword ptr ss:[esp],esp       | 覆盖花指令call的返回地址: esp = 0x0018F7B8 ==>0x0018F7B8
00415F2A    | FF50 04                | call dword ptr ds:[eax+4]        | call cehck();  call DLL_fun_addresses[1]
00415F2D    | 90                     | nop                              |
00415F2E    | 90                     | nop                              |
00415F2F    | 90                     | nop                              |
00415F30    | 90                     | nop                              |
00415F31    | 90                     | nop                              |
00415F32    | 90                     | nop                              |
00415F33    | 90                     | nop                              |
00415F34    | 90                     | nop                              |
00415F35    | 90                     | nop                              |
00415F36    | 90                     | nop                              |
00415F37    | 90                     | nop                              |
00415F38    | 90                     | nop                              |
00415F39    | 90                     | nop                              |
00415F3A    | 90                     | nop                              |
00415F3B    | 90                     | nop                              |
00415F3C    | 90                     | nop                              |
00415F3D    | 83E0 00                | and eax,0                        | retval = eax = 0
00415F40    | 89EC                   | mov esp,ebp                      |
00415F42    | 5D                     | pop ebp                          |
00415F43    | C2 0800                | ret 8                            |

最后 eax 总是为 0 ,可能就是前面那位説的用户名无关的原因么?

这是老版本的,后面1.1的还没有看。

点评

[md]check 函数会参与控制流更改。 DLL 方法的原型: ``` __declspec(dllexport) int __cdecl have_fun(uint32_t* _ret_addr, uint32_t, uint32_t, uint32_t, ELang::Container **pp_name, ELang::Container  详情 回复 发表于 2024-3-15 20:34
byh3025 发表于 2024-3-15 12:28
这个是不是一定要算出码?改跳转后的恭喜弹窗是空白的

点评

补上数据也可以哦  详情 回复 发表于 2024-3-15 16:56
Suppose 发表于 2024-3-15 15:51
不知道你的代码是不是有问题,用户名好像跟序列号没啥关系

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

点评

可能哪里错了,我晚点重新看看  详情 回复 发表于 2024-3-15 16:54

免费评分

参与人数 3吾爱币 +3 热心值 +3 收起 理由
handsome66chen + 1 + 1 我很赞同!
takatorury + 1 + 1 我很赞同!
爱飞的猫 + 1 + 1 v1.1 修好了用户名不参与验证的问题,感谢报告!

查看全部评分

 楼主| 爱飞的猫 发表于 2024-3-15 16:54
Suppose 发表于 2024-3-15 15:51
不知道你的代码是不是有问题,用户名好像跟序列号没啥关系

可能哪里错了,我晚点重新看看
 楼主| 爱飞的猫 发表于 2024-3-15 16:56
byh3025 发表于 2024-3-15 12:28
这个是不是一定要算出码?改跳转后的恭喜弹窗是空白的

补上数据也可以哦
冥界3大法王 发表于 2024-3-15 17:02
刚一解包就说病毒,被火绒干了。

点评

放虚拟机里面跑啦,易语言的程序是经常被误报的。  详情 回复 发表于 2024-3-15 17:24
 楼主| 爱飞的猫 发表于 2024-3-15 17:24
冥界3大法王 发表于 2024-3-15 17:02
刚一解包就说病毒,被火绒干了。

放虚拟机里面跑啦,易语言的程序是经常被误报的。
 楼主| 爱飞的猫 发表于 2024-3-15 20:34
本帖最后由 爱飞的猫 于 2024-3-15 21:20 编辑
solly 发表于 2024-3-15 20:25
初看了一下,从 0x00401836 开始的是DLL代码,会拷贝到0x00251000当作DLL调用。大概0x00401917是check函数 ...

check 函数会参与控制流更改。

DLL 方法的原型:

__declspec(dllexport) int __cdecl
have_fun(uint32_t* _ret_addr, uint32_t, uint32_t, uint32_t, ELang::Container **pp_name, ELang::Container **pp_password);

_ret_addr 其实是 CALL 之前放入的 esp 值。

CALL 结束后再 ret 一次,就是跳转到修改后的返回地址。 我把自己搞迷糊了,这个 ret 其实是没有用的。


“用户名无关”的问题其实是因为我之前调试的时候遇到 bug,就把用户名部分去掉了后检查… 修正问题后忘了放回去了

solly 发表于 2024-3-15 21:08
爱飞的猫 发表于 2024-3-15 20:34
[md]check 函数会参与控制流更改。

DLL 方法的原型:

是的,check()正常会返回到 0x00415F2D,实际是返回到了 0x00415F3D。

点评

[md](v1.0) 验证成功后,最终的跳转的地址不是 `0x00415F3D` 哦。`check` 函数会改这个地址。[/md]  详情 回复 发表于 2024-3-15 21:14
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-13 04:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表