re刷题记录

re2

1.下载文件后解压,拖入pe无壳,32位
解压
2. IDA32位,查看字符串,直接F5进入伪代码,主要内容及分析如下(其中scanf,print是n键更改)

 do
  {
    print("**************************我的Flag出了什么问题??**************************\n", v4);
    print("您的一些重要数据被我们加密了,就算您叫破喉咙来也没有办法恢复。\n", v5);
    print("**************************那有没有恢复的方法呢??**************************\n", v6);
    print(
      "有的。只能通过我们的财付通,支付宝服务才能恢复,我以人格担保,只要充钱,就能解密\n"
      "\n",
      v7);
    print("做出你的选择:\n", v8);
    print("1.充钱\n2.退出\n", v9);
    scanf("%d", (char)v10);
    if ( v10[0] == 1 )
    {
      v13 = fopen("flag.txt", "r");		// 要有flag.txt文件
      if ( !v13 )
      {
        print("打开源文件失败!\n", v4);
        getchar();
        exit(0);
      }
      v12 = fopen("enflag.txt", "w");		// 要有enflag.txt文件
      if ( !v12 )
      {
        print("找不到加密文件!\n", v4);
        getchar();
        exit(0);
      }
      print("\n请输入您的密钥:", v4);
      scanf("%s", (char)&Str);			//输入密钥
      sub_401069(&Str, &Str1);			// 点击进去观察,是对密钥进行了加密,包含函数sub_401A70
      // 传入参数的顺序有助于我们更好的看到逆向的内容
      sub_401028(&Str, v15, v14, v13, v12);		// 里面包含了sub_4014E0函数,对enflag.txt内容进行操作
    }
    else if ( v10[0] == 2 )
    {
      v11 = 0;
    }
    else
    {
      print("\n操作不合法!\n\n", v4);
    }
  }
  while ( v11 );
char __cdecl sub_401A70(char *Str, char *Str1)
{
 char v3; // [esp+0h] [ebp-E4h]
 signed int i; // [esp+D0h] [ebp-14h]
 signed int v5; // [esp+DCh] [ebp-8h]

 __CheckForDebuggerJustMyCode(&unk_40B027);
 v5 = strlen(Str);
 for ( i = 0; i < v5; ++i )
   Str1[i] += Str[i] ^ 0x1F;
 if ( !strcmp(Str1, "DH~mqqvqxB^||zll@Jq~jkwpmvez{") )		// 对密钥进行亦或1F后与该字符串相等
   print("充值成功.\n", v3);
 else
   print("Error!\n", v3);
 return *Str1;
}
int __cdecl sub_4014E0(char *Str, int a2, int a3, FILE *Stream, FILE *a5)
{
  char v6; // [esp+0h] [ebp-D8h]
  size_t v7; // [esp+D0h] [ebp-8h]

  __CheckForDebuggerJustMyCode(&unk_40B027);
  v7 = strlen(Str);
  sub_4010F0(a2, Str, v7);
  /* 传参时 a2为str,即输入的密钥,a3为密钥长度
  // 此处是初始化key表
  int __cdecl sub_401800(int a1, int a2, int a3)
{
  int result; // eax
  int j; // [esp+D0h] [ebp-14h]
  int i; // [esp+DCh] [ebp-8h]

  result = __CheckForDebuggerJustMyCode(&unk_40B027);
  if ( a3 <= 256 )
  { // 当len(key<256)时,k[i] = key[i % Len_k];
    for ( i = 0; i < 256; ++i )
    {
      *(_BYTE *)(i + a1) = *(_BYTE *)(a2 + i % a3);
      result = i + 1;
    }
  }
  if ( a3 > 256 )
  {
    for ( j = 0; j < 256; ++j )
    {
      *(_BYTE *)(j + a1) = *(_BYTE *)(j + a2);
      result = j + 1;
    }
  }
  return result;
}
*/
  sub_4010C8(a3);
  /* 对a3进行初始化,产生了一个 1~256 的s表
   result = __CheckForDebuggerJustMyCode(&unk_40B027);
  for ( i = 0; i < 256; ++i )
  {
    *(_BYTE *)(i + a1) = i;
    result = i + 1;
  }
   return result;
  */
  sub_40116D(a3, a2);
  /* a3传入时参数为a1
  // 产生的1~256的s表的简单swap操作
  result = __CheckForDebuggerJustMyCode(&unk_40B027);
  v5 = 0;
  for ( i = 0; i < 256; ++i )
  {
    v5 = (*(unsigned __int8 *)(i + a2) + v5 + *(unsigned __int8 *)(i + a1)) % 256;
    v4 = *(_BYTE *)(i + a1);
    *(_BYTE *)(i + a1) = *(_BYTE *)(v5 + a1);
    *(_BYTE *)(v5 + a1) = v4;
    result = i + 1;
  }
  return result;
 */
  sub_4010EB(a3, Stream, a5);		// 看传入参数的顺序,此函数是对enflag.txt进行函数操作,包含了sub_4015E0函数
  /* for循环将a1[v6]与a1[v7]进行交换,即对s表部分进行交换
  int __cdecl sub_4015E0(int a1, FILE *Stream, FILE *a3)
{
  int result; // eax
  char v4; // [esp+103h] [ebp-35h]
  char i; // [esp+11Bh] [ebp-1Dh]
  int v6; // [esp+124h] [ebp-14h]
  int v7; // [esp+130h] [ebp-8h]

  __CheckForDebuggerJustMyCode(&unk_40B027);
  v7 = 0;
  v6 = 0;
  for ( i = fgetc(Stream); ; i = fgetc(Stream) )
  {
    result = i;
    if ( i == -1 )
      break;
    v7 = (v7 + 1) % 256;
    v6 = (v6 + *(unsigned __int8 *)(v7 + a1)) % 256;
    v4 = *(_BYTE *)(v7 + a1);
    *(_BYTE *)(v7 + a1) = *(_BYTE *)(v6 + a1);
    *(_BYTE *)(v6 + a1) = v4;
    fputc(*(_BYTE *)((*(unsigned __int8 *)(v6 + a1) + *(unsigned __int8 *)(v7 + a1)) % 256 + a1) ^ i, a3);
  }
  return result;
}
  */
  fclose(Stream);
  fclose(a5);
  return print("\n加密成功!\n您的充值金额不足。\n\n", v6);
  1. 将enflag.txt拖入010editor查看16进制数,复制出来,脚本跑出来即可
    enflag.txt
  2. RC4脚本
    #include<stdio.h>
    void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k) //初始化函数
    {
    	int i = 0, j = 0;
    	char k[256] = { 0 };
    	unsigned char tmp = 0;
    	for (i = 0; i < 256; i++) {
    		s[i] = i;
    		k[i] = key[i % Len_k];
    	}
    	for (i = 0; i < 256; i++) {
    		j = (j + s[i] + k[i]) % 256;
    		tmp = s[i];
    		s[i] = s[j];
    		s[j] = tmp;
    	}
    }
    void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
    {
    	unsigned char s[256];
    	rc4_init(s, key, Len_k);
    	int i = 0, j = 0, t = 0;
    	unsigned long k = 0;
    	unsigned char tmp;
    	for (k = 0; k < Len_D; k++) {
    		i = (i + 1) % 256;
    		j = (j + s[i]) % 256;
    		tmp = s[i];
    		s[i] = s[j];
    		s[j] = tmp;
    		t = (s[i] + s[j]) % 256;
    		Data[k] = Data[k] ^ s[t];
    	}
    }
    int main()
    {
    	unsigned char key[] = "[Warnning]Access_Unauthorized";
    	unsigned long key_len = sizeof(key) - 1;
    	unsigned char data[] = { 0xC3,0x82,0xA3,0x25,0xF6,0x4C,
    	0x36,0x3B,0x59,0xCC,0xC4,0xE9,0xF1,0xB5,0x32,0x18,0xB1,
    	0x96,0xAe,0xBF,0x08,0x35};
    	rc4_crypt(data, sizeof(data), key, key_len);
    	for (int i = 0; i < sizeof(data); i++)
    	{
    		printf("%c", data[i]);
    	}	// flag{RC4&->ENc0d3F1le}
    	printf("\n");
    }
    

CrackRTF

  1. 查壳,拖入32位IDA,F5如下

    	int __cdecl main_0(int argc, const char **argv, const char **envp)
    {
      DWORD v3; // eax
      DWORD v4; // eax
      char Str[260]; // [esp+4Ch] [ebp-310h] BYREF
      int v7; // [esp+150h] [ebp-20Ch]
      char String1[260]; // [esp+154h] [ebp-208h] BYREF
      char n1[260]; // [esp+258h] [ebp-104h] BYREF
    
      memset(n1, 0, sizeof(n1));
      memset(String1, 0, sizeof(String1));
      v7 = 0;
      printf("pls input the first passwd(1): ");
      scanf("%s", n1);
      if ( strlen(n1) != 6 )
      {
        printf("Must be 6 characters!\n");
        ExitProcess(0);
      }
      v7 = atoi(n1);	// 将输入的字符串转为数字串
      if ( v7 < 100000 )
        ExitProcess(0);
      strcat(n1, "@DBApp");	// 拼接字符串
      v3 = strlen(n1);
      sub_40100A((BYTE *)n1, v3, String1);	// 对串进行加密,点击进去发现 HASH 字样,应该是哈希算法加密的到的
      if ( !_strcmpi(String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )	// 加密后得到的串
      {
        printf("continue...\n\n");
        printf("pls input the first passwd(2): ");
        memset(Str, 0, sizeof(Str));
        scanf("%s", Str);	// 再次输入,位第二段flag
        if ( strlen(Str) != 6 )
        {
          printf("Must be 6 characters!\n");
          ExitProcess(0);
        }
        strcat(Str, n1);	//将上次输入以及拼接的123321@DBApp再次拼接到新的输入Str中
        memset(String1, 0, sizeof(String1));	// 同样是hash函数
        v4 = strlen(Str);
        sub_401019((BYTE *)Str, v4, String1);
        if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", String1) )
        {
          if ( !(unsigned __int8)sub_40100F(Str) )
          {
            printf("Error!!\n");
            ExitProcess(0);
          }
          printf("bye ~~\n");
        }
      }
      return 0;
    }
    

    atol(): 把字符串转换成长整型数用 法: long atol(const char *nptr); 返回长整型
    atoll(): 把字符串转换成长长整型数用 法: long long atol(const char *nptr); 返回长长整型
    size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ; 返回真实读取的项数,count是最多读取的项数

  2. 哈希碰撞flag1

    import hashlib
    
    flag = "@DBApp"
    
    for i in range(100000,999999):
    	s = str(i)+flag
    	x = hashlib.sha1(s.encode())
    	cnt = x.hexdigest()
    	if "6e32d0943418c2c33385bc35a1470250dd8923a9" in cnt:
    		print(cnt)
    		print(str(i)+flag)	# 123321@DBApp
    
  3. 分析flag2
    CryptCreateHash函数的第二个参数用来确定哈希函数的类型
    0x8004 -> SHA1, 0x800c -> SHA256, 0x8003 -> MD5
    所以第一个密码是爆破SHA1,爆破范围是0-100000,爆破结果是123321
    而第二个是MD5,但是除了后面的12位123321@DBApp前面6位没有给提示,爆破显然不太实际,接着向下看sub_40100F函数,同样是对输入的Str进行函数操作
    tap1
    FindResource
    确定模块中指定类型和名称的资源所在的位置
    如果函数运行成功,那么返回值为指定资源信息块的句柄,可以将这个句柄传递给LoadResource函数来获得这些资源,如果函数运行失败,则返回值为NULL

    SizeOfResource
    获取指定资源的字节数

    LoadResource
    装载指定资源到全局存储器

    LockResource
    锁定资源并得到资源在内存中第一个字节的指针

    总体来说就是sub_401005函数将str与AAA查找的文件内容进行亦或,并将最终结果写入rft文件中;
    利用resource hacker查看资源AAA
    tap2

    当然trf前面的文件肯定是文件头了,随便打开一个ttf文件取其前6位亦或即可
    tap3

    	rtf = '{\\rtf1' 
    	a = [0x05, 0x7D, 0x41, 0x15, 0x26, 0x01]
    	passwd=''
    	for i in range(len(rtf)):
    	    x = ord(rtf[i]) ^ a[i]
    	    passwd+=chr(x)
    	print(passwd)	# ~!3a@0
    
  4. 得到一个dbapp.rtf的word文档,打开获得flagFlag{N0_M0re_Free_Bugs}
    resource hack使用介绍
    FindResource,LoadResource,LockResource简单说明

[2019红帽杯]easyRE

  1. PE查壳,拖入IDA64位,发现全是sub函数,查看字符串,找到如下名称,进入主函数F5反汇编主要如下
    tap1
    tap2

  2. 亦或反过来,得到输入的flag(上面的v12与v13合起来恰好是36位)
    tap3

    v12 = [73, 111, 100, 108, 62, 81, 110, 98, 40, 111, 99, 121, 127, 121, 46, 105, 127, 100, 96, 51, 119, 125, 119, 101, 107, 57, 123, 105, 121, 61, 126, 121, 76, 64, 69, 67]
    
    flag = ''
    for i in range(len(v12)):
        flag+=chr(v12[i] ^ i)
    print(flag)		# Info:The first four chars are `flag`
    
  3. 说的好像是废话一样,hh那就是废话,接着向下看
    sub_400E44函数是base64加密,懂得都懂,进行了10次的base64加密得到v11,最终将v11与off_6CC90进行比较,接下来…
    tap4
    tap5
    base64解密

    import base64
    a = 'Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=='
    for i in range(10):
        a = base64.b64decode(a).decode("utf-8") #必须先转码成byte型,因为python3中字符都为unicode编码,但是b64encode函数的参数为byte类型
    print(a)		#https://bbs.pediy.com/thread-254172.htm
    
  4. 解密出一个网站,访问后什么也找不到,返回IDA接着观看内容
    右键,查找引用,都用到了sub_6CCA0函数,再次交叉引用,观察其从哪调用,发现其是来自.fini_array段处
    tap6
    tap7
    .init中的代码在main之前执行
    .finit中的代码在main之后执行

    .init and .fini讲解

  5. HIBYTE()函数的作用是获取高字节也就是数组的最后一位,同时还有BYTE()BYTE1()BYTE2()第一个是获取数组的第一位,第二个就是获取第二位,依次类推。

    猜测其为flag四个字符,这也印证了前面获得的那四个字符
    answer

  6. 其中sub_410E90()函数是对以上的数组进行亦或v4[j%4],所以要对v4进行反求解,得到原v4数组

    arr = [0x40, 0x35, 0x20, 0x56]
    v4 = ''
    res = 'flag'
    for i in range(4):
        v4 += chr(ord(res[i])^arr[i])
    
  7. byte_6CC0A0数组与v4[j%4]进行亦或,得到flag

    a=[0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
    c=[]
    for i in range(len(a)):
    	print(chr(a[i]^ord(v4[i%4])),end="")
    

[GUET-CTF2019]re

  1. PE查壳,发现upx壳,直接脱壳就行了
  2. 进入main函数
    __int64 sub_400E28()
    {
      const char *v0; // rdi
      __int64 result; // rax
      __int64 v2; // rdx
      unsigned __int64 v3; // rt1
      __int64 v4; // [rsp+0h] [rbp-30h]
      __int64 v5; // [rsp+8h] [rbp-28h]
      __int64 v6; // [rsp+10h] [rbp-20h]
      __int64 v7; // [rsp+18h] [rbp-18h]
      unsigned __int64 v8; // [rsp+28h] [rbp-8h]
    
      v8 = __readfsqword(0x28u);
      v4 = 0LL;
      v5 = 0LL;
      v6 = 0LL;
      v7 = 0LL;
      sub_40F950((__int64)"input your flag:", 0LL, 0LL, 0LL, 0LL);
      sub_40FA80((__int64)"%s", &v4);
      if ( (unsigned int)sub_4009AE(&v4, &v4) )
      {
        v0 = "Correct!";
        sub_410350("Correct!");
      }
      else
      {
        v0 = "Wrong!";
        sub_410350("Wrong!");
      }
      result = 0LL;
      v3 = __readfsqword(0x28u);
      v2 = v3 ^ v8;
      if ( v3 != v8 )
        sub_443550(v0, &v4, v2);
      return result;
    }
    
  3. 发现主要内容correct,进入sub_4009AE函数,进入函数内部
    _BOOL8 __fastcall sub_4009AE(char *a1)
    {
      if ( 1629056 * *a1 != 166163712 )
        return 0LL;
      if ( 6771600 * a1[1] != 731332800 )
        return 0LL;
      if ( 3682944 * a1[2] != 357245568 )
        return 0LL;
      if ( 10431000 * a1[3] != 1074393000 )
        return 0LL;
      if ( 3977328 * a1[4] != 489211344 )
        return 0LL;
      if ( 5138336 * a1[5] != 518971936 )
        return 0LL;
      if ( 7532250 * a1[7] != 406741500 )
        return 0LL;
      if ( 5551632 * a1[8] != 294236496 )
        return 0LL;
      if ( 3409728 * a1[9] != 177305856 )
        return 0LL;
      if ( 13013670 * a1[10] != 650683500 )
        return 0LL;
      if ( 6088797 * a1[11] != 298351053 )
        return 0LL;
      if ( 7884663 * a1[12] != 386348487 )
        return 0LL;
      if ( 8944053 * a1[13] != 438258597 )
        return 0LL;
      if ( 5198490 * a1[14] != 249527520 )
        return 0LL;
      if ( 4544518 * a1[15] != 445362764 )
        return 0LL;
      if ( 3645600 * a1[17] != 174988800 )
        return 0LL;
      if ( 10115280 * a1[16] != 981182160 )
        return 0LL;
      if ( 9667504 * a1[18] != 493042704 )
        return 0LL;
      if ( 5364450 * a1[19] != 257493600 )
        return 0LL;
      if ( 13464540 * a1[20] != 767478780 )
        return 0LL;
      if ( 5488432 * a1[21] != 312840624 )
        return 0LL;
      if ( 14479500 * a1[22] != 1404511500 )
        return 0LL;
      if ( 6451830 * a1[23] != 316139670 )
        return 0LL;
      if ( 6252576 * a1[24] != 619005024 )
        return 0LL;
      if ( 7763364 * a1[25] != 372641472 )
        return 0LL;
      if ( 7327320 * a1[26] != 373693320 )
        return 0LL;
      if ( 8741520 * a1[27] != 498266640 )
        return 0LL;
      if ( 8871876 * a1[28] != 452465676 )
        return 0LL;
      if ( 4086720 * a1[29] != 208422720 )
        return 0LL;
      if ( 9374400 * a1[30] == 515592000 )
        return 5759124 * a1[31] == 719890500;
      return 0LL;
    }
    
  4. 反过来求flag即可
    # -*- coding:utf-8 -*-
    
    a1 = chr(166163712 // 1629056)
    a2 = chr(731332800 // 6771600)
    a3 = chr(357245568 // 3682944)
    a4 = chr(1074393000 // 10431000)
    a5 = chr(489211344 // 3977328)
    a6 = chr(518971936 // 5138336)
    a8 = chr(406741500 // 7532250)
    a9 = chr(294236496 // 5551632)
    a10 = chr(177305856 // 3409728)
    a11 = chr(650683500 // 13013670)
    a12 = chr(298351053 // 6088797)
    a13 = chr(386348487 // 7884663)
    a14 = chr(438258597 // 8944053)
    a15 = chr(249527520 // 5198490)
    a16 = chr(445362764 // 4544518)
    a17 = chr(981182160 // 10115280)
    a18 = chr(174988800 // 3645600)
    a19 = chr(493042704 // 9667504)
    a20 = chr(257493600 // 5364450)
    a21 = chr(767478780 // 13464540)
    a22 = chr(312840624 // 5488432)
    a23 = chr(1404511500 // 14479500)
    a24 = chr(316139670 // 6451830)
    a25 = chr(619005024 // 6252576)
    a26 = chr(372641472 // 7763364)
    a27 = chr(373693320 // 7327320)
    a28 = chr(498266640 // 8741520)
    a29 = chr(452465676 // 8871876)
    a30 = chr(208422720 // 4086720)
    a31 = chr(515592000 // 9374400)
    a32 = chr(719890500 // 5759124)
    
    print (a1,a2,a3,a4,a5,a6,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32)
    #  flag{e165421110ba03099a1c039337}
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
青马易战是一款用于刷题的在线教育平台,可以帮助学生提升编程能力。Python是一门强大的编程语言,具有简单易学、功能丰富的特点,可以用来实现青马易战的自动刷题。 首先,我们可以使用Python的web自动化工具,如Selenium或Pyppeteer,来模拟用户在青马易战网站上的操作。通过编程方式,我们可以自动登录到青马易战网站,并进入题目列表页面。 接下来,我们可以使用Python的数据处理和爬虫库,如BeautifulSoup或Scrapy,来提取题目列表页面中的题目信息,包括题目名称、描述、输入输出样例等。 然后,我们可以使用Python的文本处理库,如re或pandas,来对题目信息进行清洗和解析,将题目描述和输入输出样例提取出来,并保存到相应的变量中,以便后续的处理和分析。 在获取题目信息之后,我们可以使用Python的编程能力来编写算法来解题。根据题目的要求,我们可以使用Python的各种数据结构和算法进行求解,包括字符串处理、列表操作、循环、递归、排序、搜索等。通过编写相应的函数或方法,我们可以将解题过程封装起来,以便于自动化刷题。 最后,我们可以使用Python的自动化测试工具,如unittest或pytest,来对编写的解题代码进行自动化测试。通过提供输入样例,我们可以自动调用解题函数,并将输出结果与预期结果进行比较,以验证解题代码的正确性。如果输出结果正确,我们可以将解题代码保存,继续下一道题的刷题流程。 通过以上步骤,就可以使用Python实现青马易战的自动刷题。这样可以大大提高刷题的效率,并帮助学生更好地学习和理解编程知识。同时,自动刷题也可以帮助学生培养解题思维和编程能力,提升竞赛的成绩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值