爱飞的猫 发表于 2024-3-15 10:46

易语言 CM2

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

## 易语言 (?) CM 第二弹

相信大家都知道易语言常用的 (https://www.52pojie.cn/thread-1236701-1-1.html)吧。

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

压缩包解压密码:`52pojie`

-
-
- [百度网盘镜像](https://pan.baidu.com/s/1XgzEZanxeAtrDq22z4swbA?pwd=pi5z) | (https://www.virustotal.com/gui/file/8f0d957d794795d5167615d4125607c70f15e240e22f1e8267ac2c8c7cee069b)

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

## 挑战说明

挑战:

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

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

小提示/使用技巧:

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

## 测试信息

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

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

## 成功提示

![](https://imgsrc.baidu.com/forum/pic/item/500fd9f9d72a6059032f30206e34349b033bbac9.png)

## 失败提示

> [爱飞的猫 @52pojie]
>
>   挑战失败,请继续加油哦!

## 更新记录

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

---

    爱飞的猫 @52pojie
         2024 春

---

## 结语

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

可执行文件对资源做了个简单的过 EWnd 插件处理。虽然只是图一乐,但读者若是有兴趣可以试试恢复它 :D
![](https://imgsrc.baidu.com/forum/pic/item/d50735fae6cd7b8921c4d0b9492442a7d9330e64.png)

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

---

- 第一弹: [易语言 CM1 - 无壳](https://www.52pojie.cn/thread-820714-1-1.html)

solly 发表于 2024-3-19 23:40

本帖最后由 solly 于 2024-3-20 00:02 编辑

#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;

/// 001EE15000 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};
/// 001EE16000 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};
/*
001EE17032 33 34 36 37 39 41 43 44 45 46 47 48 4A 4B 4C234679ACDEFGHJKL
001EE1804D 4E 50 52 54 55 56 57 58 59 5A 61 63 64 65 66MNPRTUVWXYZacdef
*/
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;
};

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[] = "°®·ÉµÄè @52pojie";
      //char key[] = "CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49\0";
      char pname;
      
      int n = GbkToUtf8(name, pname, 2048);
      
      int m = generate(pname, 1, key1);
      int k = generate(pname, 2, key2);
      
      printf("\n\nYour name: %s\nKey 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;
      //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;
      UINT8 d0,d1,d2,d3,d4,d5,d6,d7;
      result_tmp = '\0';
      int k=0;
      for(int i=0; i<size; i+=5) {
                d0 = (data>>3) & 0x1F;
                result_tmp = base32table;
                d1 = ((data<<2) & 0x1C) | ((data>>6) & 0x03);
                result_tmp = base32table;
                d2 = (data>>1) & 0x1F;
                result_tmp = base32table;
                d3 = ((data<<4) & 0x10) | ((data>>4) & 0x0F);
                result_tmp = base32table;
                d4 = ((data<<1) & 0x1E) | ((data>>7) & 0x01);
                result_tmp = base32table;
                d5 = (data>>2) & 0x1F;
                result_tmp = base32table;
                d6 = ((data<<3) & 0x18) | (data>>5 & 0x07);
                result_tmp = base32table;
                d7 = (data) & 0x1F;
                result_tmp = base32table;
                for(int j=0; j<8; j++) {
                        result = result_tmp;
                }
                k+=8;
                result = '\0';
      }
      
      return k;
}

PBOX * permute(PBOX * result, char * data, int length) {
      UINT8 key;
      //logger("permute1", NULL, 0, 0);
      
      for(int i=0; i<16; i++) {
                key = name_base;
      }
      strncpy((char *)&key, 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 + 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;
                j = j + tmp - key;
                //// sawp()
                result->data = result->data;
                result->data = 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;
                //// swap()
                UINT8 tmp = result->data;
                result->data = result->data;
                result->data = 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;
      PBOX name_permuted;
      UINT8 key_buff;
      
      int len_name = strlen(name);
      len_name = (len_name<60) ? len_name : 59;

      for(int i=0; i<len_name; i++) {
                name_buff = name;
      }
      name_buff = '\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;                  //// key[] = "CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49"
                        //printf("check idx: %02X\n", idx);
                        shift_bits += 5;
                        ///
                        shift_data = (shift_data << 5) | idx_base;

                        if(shift_bits>=8) {
                              i = i + 1;
                              j = j + name_permuted.data;
                              //// swap()
                              UINT8 tmp = name_permuted.data;
                              name_permuted.data = name_permuted.data;
                              name_permuted.data = tmp;
                              ////
                              UINT8 t = name_permuted.data + name_permuted.data;
                              ////
                              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 = (t ^ (UINT8)data);
                              //printf("data =%08X, t=%02X, key_buff = %02X, ", data, t, key_buff);
                        }
                        //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;
      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;
                name_permuted.idx2 = dh;
                UINT8 idx1 = (unsigned)dh;
                UINT8 idx2 = (unsigned)dl;
                UINT8 a = name_permuted.data;
                UINT8 c = name_permuted.data;
                name_permuted.data = a;
                name_permuted.data = c;
                dh = name_permuted.idx2;
                dl = name_permuted.idx1;
                UINT8 idx3 = (unsigned)dh;
                UINT8 idx4 = (unsigned)dl;
                c = name_permuted.data;
                c += name_permuted.data;
                c ^= key_buff;// c == key_buff, 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;
      name_permuted.idx2 = dh;
      unsigned int idx1 = dh;
      unsigned int idx2 = dl;
      char a = name_permuted.data;
      char c = name_permuted.data;
      name_permuted.data = a;
      name_permuted.data = c;
      unsigned int idx3 = name_permuted.idx2;
      unsigned int idx4 = name_permuted.idx1;
      dh = name_permuted.data;
      dh += name_permuted.data;
      dh ^= key_buff;               /// 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;
                dl = (dl>>5) | (dl<<3);
                dl ^= al;
      }
      char al = key_buff;   /// 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;
      PBOX name_permuted;
      UINT8 key_buff;
      UINT8 key_final;
      
      int len_name = strlen(name);
      len_name = (len_name<60) ? len_name : 59;

      for(int i=0; i<len_name; i++) {
                name_buff = name;
      }
      name_buff = '\0';
      
      //printf("name: %s\n", name_buff);
      char bl = 0;
      char * ptrPWD = (char *)&love_base;
      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;
               
                UINT8 tmp = name_permuted.data;
                name_permuted.data = name_permuted.data;
                name_permuted.data = tmp;
                key_buff = name_permuted.data + name_permuted.data;
      }
      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;
               
      UINT8 tmp = name_permuted.data;
      name_permuted.data = name_permuted.data;
      name_permuted.data = tmp;
      UINT8 ver_xor = name_permuted.data + name_permuted.data;
      key_buff = (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;
                crc = (crc>>5) | (crc<<3);
                crc ^= al;
      }
      key_buff = crc;
      key_buff = '\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;
                //// swap()
                UINT8 tmp = name_permuted.data;
                name_permuted.data = name_permuted.data;
                name_permuted.data = 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 >= 0) {
                        key_buff[--kk] ^= name_permuted.data + name_permuted.data;
                        //// 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;
                        name_permuted.data = name_permuted.data;
                        name_permuted.data = tmp;
                        j = j - name_permuted.data;
                        i = i - 1;
                }
      }
      base32encode(key_buff, 20, (char *)key_final);
    key_final = '\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);
                        }
                        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;
      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;
}


Your name: solly@52pojie.cn
Key pro: HRE7L92cc2fRFe3EPHY3P9YTFX7GR3aR
Key full: HRE7L92cc2fRFe3EPHY3P9YTFX7GR36M

solly 发表于 2024-3-15 20:25

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

初看了一下,从 0x00401836 开始的是DLL代码,会拷贝到0x00251000当作DLL调用。大概0x00401917是check函数,在dll中的地址是 0x002510E1,调用处在这里(去掉了花指令):
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:,0       |
00415F16    | A1 D8744B00            | mov eax,dword ptr ds:    | DLL_fun_addresses[] = {0x00251635, 0x002510E1}
00415F1B    | 8945 FC                | mov dword ptr ss:,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:   | esp = 0x0018F7B8 ==>0x00415F23
00415F27    | 892424               | mov dword ptr ss:,esp       | 覆盖花指令call的返回地址: esp = 0x0018F7B8 ==>0x0018F7B8
00415F2A    | FF50 04                | call dword ptr ds:      | call cehck();call DLL_fun_addresses
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的还没有看。

byh3025 发表于 2024-3-15 12:28

这个是不是一定要算出码?改跳转后的恭喜弹窗是空白的

Suppose 发表于 2024-3-15 15:51

不知道你的代码是不是有问题,用户名好像跟序列号没啥关系

爱飞的猫 发表于 2024-3-15 16:54

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

可能哪里错了,我晚点重新看看 {:301_971:}

爱飞的猫 发表于 2024-3-15 16:56

byh3025 发表于 2024-3-15 12:28
这个是不是一定要算出码?改跳转后的恭喜弹窗是空白的

补上数据也可以哦

冥界3大法王 发表于 2024-3-15 17:02

刚一解包就说病毒,被火绒干了。{:301_1008:}

爱飞的猫 发表于 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
check 函数会参与控制流更改。

DLL 方法的原型:


是的,check()正常会返回到 0x00415F2D,实际是返回到了 0x00415F3D。
页: [1] 2 3
查看完整版本: 易语言 CM2