Symbolic Execution for Software Testing(翻译)

4 篇文章 0 订阅
订阅专栏

原文:https://people.eecs.berkeley.edu/~ksen/papers/cacm13.pdf

注:该翻译纯属自嗨


0.介绍

符号执行在近几年获得了大量关注,它作为一种很有效率的技术用于产生高覆盖率的测试组件和找出复杂软件应用的深层错误。在符号执行背后的关键理念在三十多年前就被提出了,由于约束可满足性的显著发展,以及结合了具体符号执行的更具扩展性的动态方法,它到最近才开始变得实用起来。在这篇文章中,我们概述了现代符号执行技术在路径探索,条件约束和内存模型几个方面的挑战,并讨论几个主要在作者工作中得出的解决方案。需要注意的是,我们并非全面考察在该领域的现有工作,而是去说明一些关键性的挑战,并通过作者在工作中所遇一些实例,来提出解决方案。有关符号执行的详细概述,请参考该领域中以前发表的文献。

在软件测试环境中,符号执行的关键目的是在给定的一段时间内,尽可能发现不同的程序执行路径。每一条路径生成一系列输入来执行该路径,并检查各种各样的错误,包括断言违反,未捕获的异常,安全漏洞和内存崩溃。得到具体输入值的能力是符号执行最主要的优势之一:从测试生成的观点来看,它允许生成高覆盖率的测试组件;从寻找bug的观点来看,它提供给开发者触发bug的具体输入值,这些输入值可以单独用于debug,它们由符号执行工具生成。

此外,在给定程序路径上寻找错误方面,符号执行比传统的动态执行技术更强大,比如一些流行工具Valgrind或Purify的应用,它们依赖于有效的具体输入来触发错误。最后,与其他一些程序分析技术不同,符号执行技术不仅仅限制于找出一般的错误,如缓冲区溢出,还可以推断出更高级的程序属性,比如复杂的程序断言。

 

1.经典符号执行概述

在符号执行的背后是关键理念是使用符号性质的值,而不是作为输入的具体数据值,并将程序变量的值表示为符号表达式。因此,程序计算出的输出值就表示为符号输入值的函数。在软件测试中,符号执行用于为程序的每条执行路径生成测试输入。一条执行路径就是true和false的集合,其中,序列中第i个位置的true表示沿该路径执行的第i个条件语句使用then分支。程序的所有执行路径可以表示为一棵树,名为执行树。

 

int twice(int v){
    return 2*v;
}

void testme(int x, int y){
    z = twice(y);
    if (z == x){
        if (x > y+10)
            ERROR;
    }
}

int main(){
    x = sym_input();
    y = sym_input();
    testme(x, y);
    return 0;
}

举个例子,在上方代码中,函数testme()有三条执行路径,如下图。

当输入取{x = 0,y = 1},{x = 2,y = 1} and {x = 30,y = 15}时,这些路径可以成为实例执行。

其目的是生成这样一组输入,使所有执行路径都依赖于符号输入,或尽可能的在给定的时间预算中,通过运行程序找到来精确的找到这些输入。

符号执行维护一个符号状态σ,它将变量映射为一个符号表达式。以及一个符号化路径约束PC,它是一个符号表达是上的无量词一阶公式。在符号执行的起始阶段,σ被初始化为空映射,PC则被初始化为true,在符号执行期间,σ和PC都会进行更新。顺着程序的一条执行路径符号执行到结尾时,使用约束求解器求解PC来生成具体的输入值。如果程序使用这些输入值进行执行,那么它会精确地执行在相同路径上并以相同的方式结束。

举例来说,上方代码以σ为空映射,且PC为true初始化然后执行。在每一个读取语句var = sym_imput()接收程序的一个输入,符号执行添加一个映射var->s到σ中,这里s是个无约束条件的新符号值。比如,符号执行main()函数的前两行,会得到结果σ={x->x0, y->y0},这里x0和y0是两个刚初始化无条件约束的符号值。对每一个赋值操作v=e,符号执行都会更新σ,将v映射到σ(e),通过e在当前符号状态下的值得到符号表达式。比如,在执行到第6行后,σ={x->x0, y->y0, z->2y0}。

在每一个条件语句if(e) S1 else S2,PC会被更新为PC∧σ(e)(then分支),一个新的条件约束PC'就会被创建,它初始化为PC∧¬σ(e)(else分支)。如果对符号值进行一些适当的赋值能使PC有效,即PC是可满足的,则符号执行沿着then分支继续执行下去,并维持现有的PC和σ。同样的,若PC'是可满足的,则另一个符号执行被创建,它维持现有的PC'和σ,沿else分支执行。需要注意的是,与具体的执行不同,两个分支都可以被执行,结果会有两条执行路径。如果某个PC或PC'是不可满足的,则符号执行沿着相应路径终止。比如,在上述代码第7行后,有两个符号执行实例被创建,它们的路径约束分别是 x0=2y0 和 x0!=2y0;类似的,在第8行后,两个符号执行实例被创建,它们的路径约束分别是(x0=2y0)∧(x0>y0+10)和(x0=2y0)∧(x0<=y0+10)。

如果一个符号执行实例碰到了exit或error时,当前符号执行实例就会被终止,并利用一个现成的约束求解器来生成一个可满足当前路径约束的赋值。这个可满足赋值形成了测试输入,也就是说,若程序使用这些具体的输入值来执行,那就一定会沿着相应的路径来执行,并以相同方式终止。举例来说,在上述代码中,我们得到了符号执行的3个实例,它们的测试输入分别是{x=0, y=1},{x=2, y=1}和{x=30, y=15}。

若代码中包含循环或递归结构,且它们的终止条件是符号化的,则可能导致有无穷多条路径。

void testme_inf(){
    int sum = 0;
    int N = sym_input();
    while (N > 0){
        sum = sum + N;
        N = sym_input();
    }
}

比如在上方代码中就有无数条执行路径,每条执行路径是任意数量的trues然后跟着一个false,或就是无数的trues。n个true后跟一个false的路径的符号路径约束为

每一个Ni都是一个符号值,且执行到最后的符号状态为{N->Nn+1, sum->∑i∈[1,n] Ni}。在实践过程中,需要对路径搜索设置一个限制,例如timeout,限制路径数量,循环迭代次数或探测深度。

经典的符号执行有一个关键的缺点,若符合执行路径的符号路径约束无法使用约束求解器进行有效的求解,则无法生成输入。举例来说,符号执行在最上方那段代码中有两种变体,其中一个变体,我们将twice函数修改为以下代码

 

int twice(int v){
    return (v*v) % 50;
}

另一种变体,我们假设twice函数的代码未知。让我们假设我们的约束求解器不能求解非线性运算。在第一种变体中,在执行完第一条条件语句后,符号执行会产生路径约束x0!=(y0y0) mod 50和x0=(y0y0) mod 50。在第二中变体中,符号执行会产生路径约束x0!=twice(y0)和x0=twice(y0),这里twice是未有解释的函数。由于余数求解器无法求解这些约束条件,符号执行将无法为修改后的程序生成任何输入。我们接下来会描述两种现代符号执行技术,它们缓解这个问题并至少为修改后的程序生成一些输入。

 

2.现代符号执行技术

现代符号执行技术的关键要素之一是将具体执行和符号执行混合的能力。我们提出以下两种扩展方式,然后讨论它们提供的关键优势。

向导性随机测试(Concolic Testing):有向自动随机测试,或动态符号执行的向导性随机测试,同时程序在具体的输入值上运行。Concolic testing维护了一个具体化状态和一个符号化状态:该具体化状态映射所有变量到它们的具体值;该符号化状态仅映射没有具体值的变量。和经典符号执行不同,由于concolic执行维护全部程序执行的具体化状态,它需要给输入初始化具体的值。Concolic testing通过给定的或随机的输入值开始执行,并将执行中的符号约束混合到输入值中,然后使用约束求解器来推断先前输入的变化,以便引导程序接下来的执行该走向哪一个执行路径。这个过程系统的或启发式的重复,直到所有执行路径探索完毕,或者达到用户规定的覆盖率,或者时间预算耗尽。

举个例子,依旧是这段代码

int twice(int v){
    return 2*v;
}

void testme(int x, int y){
    z = twice(y);
    if (z == x){
        if (x > y+10)
            ERROR;
    }
}

int main(){
    x = sym_input();
    y = sym_input();
    testme(x, y);
    return 0;
}

 

concolic执行会生成一些随机的输入值,比如{x=22, y=7},然后符号化和具体化地一起来执行程序。在第7行代码中,这个具体的执行会走向else分支,然后符号执行会生成x!=2y0的路径约束。Concolic testing否定路径约束中的连接,并求解x0=2y0得到测试输入{x=2, y=1};这个新的输入会强制让程序执行不同的执行路径。Concolic testing利用这个新的输入重复具体执行和符号执行。这次执行的路径与之前不同,它在第7行执行then分支,并在第8行执行else分支。例如之前的执行,concolic testing也会沿着具体执行来进行符号执行,并生成路径约束(x0=2y0)∧(x0<=y0+10)。Concolic testing会生成一个新的测试输入来使程序强制执行沿着之前为执行过的路径。它通过否定连接(x0<=y0+10)并求解约束(x0=2y0)∧(x0>y0+10)得到测试输入{x=30, y=15}。在这个输入下程序收到ERROR语句。在这第三次程序执行后,concolic testing报告所有被探索的执行路径,并终止测试输入的生成。注意在这个例子中,concolic testing使用深度优先搜索的方式来发现所有执行路径。然而,也可以用其他策略来探测不同顺序的路径,这在之后会讨论到。

 

Execution-Generated Testing(EGT):

EGT方法通过区分程序的具体状态和符号状态来工作,使用EXE和KLEE工具来实现和扩展。为此,EGT通过在每次运算之前动态检查所涉及的值是否都是具体的,从而混合具体的和符号执行。这样的话,执行的运行就和原始程序相同。另外,如果至少有一个值是符号值,则进行的是符号化运算。它利用当前路径的路径条件进行更新。依旧用如下代码举例:

 

int twice(int v){
    return 2*v;
}

void testme(int x, int y){
    z = twice(y);
    if (z == x){
        if (x > y+10)
            ERROR;
    }
}

int main(){
    x = sym_input();
    y = sym_input();
    testme(x, y);
    return 0;
}

如果在15行执行y=10,则第6行的twice函数会使用具体值20作为参数被调用,就像会在原本会程序中被调用那样(要注意twice函数可以对输入的值进行任意复杂的操作,但这并不会给符号执行带来什么压力,因为这个调用会被具体的执行)。之后,第7行的分支变为if (20 == x),并且符号执行会遵循then(添加约束x == 20)分支和else分支(添加约束x != 20)。注意在then路径,第8行条件会变为if (x > 20),并且因此then这条分支是不可执行的,因为x在第7行已经被限制为20了,与x>20矛盾。

Concolic testing和EGT是两种现代符号执行技术,它们的主要优势在于能将具体执行与符号执行相结合。为了简单起见,在本文其他地方我们将这些技术统称为动态符号执行技术。

动态符号执行的不精确性和完整性:

将具体执行与符号执行混合的一个关键优点是,与外部代码交互或约束求解超时所造成的不精确性可以通过使用具体值来缓解。

举例来说,大多数实际应用都会与外部进行交互,例如通过调用一些不是符号执行的库,或使用系统调用。如果这些调用的所有参数都是具体的,这个调用就会简单地具体执行,就像原本的程序那样。然而,即使一些操作对象是符号化的,动态符号执行可以使用这个操作对象可能的具体的来执行:在EGT中,这是通过求解当前路径约束的可满足赋值来完成的。而concolic testing可以立即使用当前concolic在运行时取得输入的具体值。

除了外部代码外,不精确性在符号执行中也蔓延到了其他地方,比如无法处理的运算(如浮点运算)或者造成约束求解器超时的复杂的函数,使用具体值允许动态符号执行恢复这种不精确性,虽然这会使得一些执行路径缺失,即牺牲了其完整性。

为了进一步说明,我们描述在twice函数返回非线性值(v*v)%50的运行版本中,concolic testing的行为。我们假设concolic testing开始于一个随机输入{x=22, y=7},它由符号路径约束(x0 != (y0y0) mod 50)生成。如果我们假设约束求解器无法求解非线性约束,则concolic testing无法为一条可选执行路径生成输入,如果源代码中twice函数使用了外部代码(如调用外部函数库,使用系统调用),也会出现类似的情况。在这种情况下路径约束会变为x0!=twice(y0),这里twice是一个粗略的函数。concolic testing处理这种情况是通过将一些符号值替换为具体值,以此得到的简化后的约束可以被现有的约束求解器求解。举个例子,上述例子中,concolic testing将y0替换为具体值7,这样就能简化路径约束为x0!=49。通过求解x0=49这个路径约束,concolic testing生成输入{x=49, y=7}来探索之前未被探测的路径。要注意经典符号执行没这么容易简化执行,这是因为在整个符号执行中,具体状态都是不可取的。

动态符号执行能够使用具体值来简化约束,这有助于它为卡住的执行路径生成测试输入,但这里有一个问题,由于简化了路径约束,使得它丧失了完整性,即可能无法对一些执行路径生成输入。例如,在我们的例子中,动态符号执行无法仅为路径true和false生成输入(而是以具体值替代)。但是,当遇到不支持的操作或外部调用时,这显然优于简单地终止执行的替代方案。

 

关键性挑战和一些解决方案

路径激增

符号执行的关键挑战之一是,除了非常小的程序外,其余都具有数量庞大的程序路径,这通常是代码中静态分支的指数级别。所以,给定一个固定的时间预算,首先探索最相关的路径十分重要。

首先,要知道符号执行暗中过滤了所有不依赖于输入的所有分支,并且给定当前路径约束是不可行的。尽管有这种过滤,路径激增任是符号执行面临的最大挑战。有两种关键方法用于解决这个问题:启发式优先的考虑最有希望的路径探索和利用完善的程序分析技术来降低路径探索复杂度,我们将依次讨论这两种方法。

启发式技术

符号执行工具进行启发式路径探索使用的关键机制是使用启发式搜索。大部分启发式方法都致力于实现高度陈述和分支覆盖,但它们也存在其他的优化标准。

一种十分有效的方法是使用静态控制流图(CFG)从未覆盖的指令开始,去引导探索最近的路径(即CFG静态测量)。一种类似的方法是偏向之前访问过的,运行时间最少的语句。

再比如,基于随机探索的启发式技术也被证明是成功的。它的关键理念是从程序一开始,在每一个可选的符号化分支上随机选择要探索分支。

另一种成功的方法是将符号探测与随机测试交错执行。这种方法结合了随机测试迅速到达深度的执行状态的能力和符号执行可以彻底执行探索给定邻域内的状态的能力。

... 

 

 

 

用好ChatGPT之准确分配角色
herosunly的博客
04-06 15万+
本文介绍核心内容为用好ChatGPT之准确分配角色,希望对学习和使用ChatGPT的同学们有所帮助。为了兼顾质量和速度,本专栏的更新频率为一周一到两更。 文章目录 1. 前言 2. 基本概念讲解 3. 实战案例 3.1 案例展示 3.2 范式表示 4. 附录 4. 附录
软件测试用例自动生成技术(一)
热门推荐
jsc9410的专栏
03-19 1万+
软件测试这一环节在软件开发周期中不可或缺。然而软件测试却花费软件开发超过一半的成本。因此利用软件测试用例自动生成技术来降低软件开发成本并提高软件开发效率就变得至关重要。
SYMBOLIC EXECUTION
04-01
SELECT--A FORMAL SYSTEM FOR "ESTING AND DEBUGGING PROGRAMS BY SYMBOLIC EXECUTION
形式化方法 | Symbolic Execution(符号执行)
m0_37714470的博客
11-03 4719
最近写论文遇到了符号执行方法,想起来上学期上《形式化方法》课有专门关于符号执行的内容,在此先就课堂内容和课后作业对符号执行做一个简要的概述吧。 1 背景引言相关 1.1 程序验证方法的范围 程序安全性验证的技术如下: 横轴-Cost 程序验证的代价/要求(对程序员的要求、时间、经验等等) 纵轴-Confidence 可信度 (1)Ad-hoc Testing(随机测试) 随机测试是没有书面测试用例、记录期望结果、检查列表、脚本或指令的测试。主要是根据测试者的经验对软...
[fuzz论文阅读] Symbolic execution for software testing: three decades later
huzai9527的博客
01-27 1220
Symbolic execution for software testing: three decades later 背景介绍 技术难点 路径探索 约束求解 内存建模 关键目标 生成一组具体的测试用例,执行该路径 检查是否存在各种错误,包括内存断言冲突、未捕获的异常、安全漏洞和内存损坏 符号执行的优点 比传统的动态执行技术更强大,不仅能够发现一般性的错误,还能够对复杂程序进行推理 从测试生成来说,能够生成高覆盖率的测试用例 从BUG寻找来说,能够提供具体的测试用例,方便确认和调试错误 符号执
Symbolic Excution for software teting in pratice preliminary assessment
weixin_34126215的博客
10-27 189
本文的主要内容: 1 介绍了符号执行的主要内容(略) (1)Generalized Symbolic Execution GSE具有处理多线程、多程序段和递归数据的能力;GSE通过利用lazy initialization实现对递归数据的处理--当第一次调用该变量的值时, 把它初始化为NULL或一个具有未初始化字段的新对象的引用或前面初始化过程中产生...
【软件分析第13讲-学习笔记】符号执行 Symbolic Execution
the Blog of 等不到天亮丶等时光
11-16 1065
如题,学习一下符号执行 Symbolic Execution的相关知识。参考:熊英飞老师2018《软件分析》课件。
Combining_Symbolic_Execution_and_Model_Checking_for_Data_Flow_Te
01-02
为了解决这些问题,本文提出了一种结合动态符号执行(Dynamic Symbolic Execution, DSE)和模型检查(Model Checking)的方法。DSE允许程序在符号模式下执行,可以探索多种可能的路径,而CEGAR(Counter example-...
ExpoSE:用于JavaScript的动态符号执行(DSE)引擎。 ExpoSE具有高度的可扩展性,与最新JavaScript标准兼容,并支持字符串和正则表达式的符号建模
04-28
暴露 ExpoSE是JavaScript的动态符号执行引擎,由英国伦敦皇家霍洛威大学的( ,邓肯·米切尔(Duncan Mitchell)和( (现为)开发。 ExpoSE支持浏览器中Node.js程序和JavaScript的符号执行。 ExpoSE基于Jalangi2和...
SBSE—基于搜索的软件工程简介
土豆洋芋山药蛋的博客
07-21 5090
土豆洋芋山药蛋原创,转载请注明出处,尤其是注明“土豆洋芋山药蛋”哦 下面我将从4个方面介绍SBSE(Search-Based Software Engineering)——即基于搜索的软件工程: 1.引入背景 2.技术和应用分析 3.SBSE优势 4.总结 话不多说,开始上车··· 1.引入背景 软件工程(SE)中通常会有一大堆令人眼花缭乱的选择,要找到好的解决方案是很...
符号执行Symbolic Execution
qq_41084082的博客
03-05 4359
关键思想   对于给定的程序,希望可以自动生成一组测试用例,效率高,且测试用例满足一定的性质。 主要原理   通过分析程序来得到某段代码区域执行的输入。在达到目标代码时,分析器可以得到相应的路径约束,然后通过约束求解器得到触发目标代码的具体值。并且在分析程序时,使用的是符号值作为输入(而不是具体的值)。 执行框架 实例 void foo(int a, int b){ int x = 1, y = 0; if(a != 0){ y = 3+x; if(b == 0) x
test Symbolic Execution-01-符号执行(Symbolic Execution)简介
最新发布
01-12 934
符号执行(Symbolic Execution)是一种静态分析技术,旨在理解程序在输入条件的不同组合下的行为。与传统的具体执行不同,符号执行使用符号变量代替具体的输入值,从而允许在不实际运行程序的情况下推导执行路径、条件和约束。这样的方法可以帮助发现潜在的程序错误、漏洞和不变性质。在符号执行中,程序的输入和状态被表示为符号变量。这些变量不包含具体的数值,而是包含未知的符号,代表可能的输入条件。符号执行通过在程序的控制流图中模拟执行路径来构建符号执行路径。
SymNet:scalable symbolic execution for modernnetworks论文
syh_486_007的专栏
12-27 1047
SymNet: scalable symbolic execution for modern networks 这篇论文Sigcomm 2016上,本篇论文采用符号执行的方法,采用SEFL语言建立网络模型,对大规模SDN网络开展数据平面验证。 ppt参考了作者参会的ppt,加上一些自己的理解,欢迎下载!!! http://pan.baidu.com/s/1ckVbhs 无密码,欢迎多交流
程序缺陷自动修复(Automated Program Repair)& 符号执行(Symbolic Execution
q1uTruth的博客
07-18 620
程序缺陷如缓冲区溢出、空指针等缺陷的修复步骤静态/动态缺陷定位缺陷;生成补丁;补丁过滤、排序(先用哪个)(针对一个缺陷生成多个补丁)及静态预定义或动态测试验证补丁的正确性提高定位更准确评价指标的分类启发式搜索(朝着预定方向变化),人工模板(),语义约束(转为符号执行、约束求解这类问题),统计分析()............................................................
形式化方法 Assignment 8: Symbolic execution
qq_43400789的博客
03-28 858
LAB8 符号执行 ​ 这里主要讨论三个部分,操作语义、符号执行、并行执行。 Part A Concrete execution B ::= + | - | * | / | == | != | > | < | >= | <= E ::= n | x | E B E S ::= pass | x = E | seq(S, S) | f(E1, ..., En) | if(E, S, S)
【论文分享】Chopped Symbolic Execution
^_^
04-15 586
论文名:Chopped Symbolic Execution 来源会议:ICSE 2018 论文下载地址:https://dl.acm.org/doi/10.1145/3180155.3180251 文章目录简介要解决的问题如何解决的问题具体实现结果如何Failure ReproductionTest Suite Augmentation总结 简介 符号执行是很强大的程序分析技术可以系统地去探索程序的多条路径。然而,尽管技术进步了很多,但符号执行仍然难以到达很深的程序路径,由于路径爆炸问题和约束求解的限制。
符号执行初识
无痕的博客
11-02 1269
符号执行介绍及原理阐述
Symbolic Excution and ProgramTesting
weixin_34223655的博客
10-27 195
Symbolic Excution and ProgramTesting》是一片经典的文章,发表与1975年,被引用次数接近千次。该文在一个简单的程序语言的基础上提出了符号执行的方法: 1程序变量只是有符号整数;只包括简单的赋值语句,IF语句,GOTO语句,以及一些获得输入的方法。 2数学表达式只有限的计算类型:加、减、乘。 3布尔表达式只进行数学表达式是否为真的测试操作。 4分支语句的...
漏洞检测 Symbolic execution符号执行是什么
软件工程小施同学 的专栏
03-28 1056
Symbolic execution 符号执行 Symbolic execution (King 1976) is another vulnerability discovery technique that is considered to be very promising. By symbolizing the program inputs, the symbolic execution maintains a set of constraints for each execution path.
symbolic execution
04-06
Symbolic execution(符号执行)是软件工程中的一种自动化分析技术,通过构造输入参数的符号表达式来代替原始具体的输入值,对程序进行遍历和测试。这种技术可以发现程序中的漏洞和错误,并且能够简化测试和验证工作的过程。
写文章

分类专栏

  • CTF 18篇
  • 逆向工程 11篇
  • 编程技术 12篇
  • 复读机 8篇
  • 安全 11篇
  • 自嗨翻译 4篇
  • pwn 2篇

最新评论

  • dll注入系列——傀儡进程

    二进制怪兽: 有demo吗 大佬

  • angr-example(解CTF题目)

    kddgwfghsjfbhd: 你好,我想请教一下angr如何对.文件操作?

  • Practical Malware Analysis Lab7

    「已注销」: 对的,恶意代码分析实践

  • Practical Malware Analysis Lab7

    十七号城市: 请问是《Practical Malware Analysis》这本书里的内容吗?

大家在看

  • 程序员·买房·留在一线城市 319
  • 学习日记_241023_高等数学中的一些英语表达 157
  • C++学习笔记----9、发现继承的技巧(五)---- 多重继承(1)
  • python画图|图例设置基础教程 752
  • python的上下文管理器

最新文章

  • leecode-试水
  • 两个UAF
  • asis2016-b00ks
2019年46篇
2018年2篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

玻璃钢生产厂家绵阳玻璃钢雕塑翻新沈阳关公玻璃钢雕塑制作长沙玻璃钢雕塑熊猫定制沈阳户外玻璃钢花盆厂西安环保玻璃钢雕塑优势广东秋季商场美陈研发玻璃钢创意仿铜人物雕塑怒江玻璃钢花盆浙江特色商场美陈批发价水泥直塑和玻璃钢雕塑玻璃钢座椅雕塑教程盐城玻璃钢花盆厂家青岛内蒙古玻璃钢雕塑金华玻璃钢雕塑定制厂家乌鲁木齐玻璃钢雕塑价格成都玻璃钢雕塑熊猫厂商山东中庭商场美陈销售公司特色商场美陈市场奇特的玻璃钢雕塑东营玻璃钢人物雕塑价格如何玻璃钢造型雕塑报价单玻璃钢花盆架子玻璃钢的雕塑卡通动物玻璃钢雕塑玻璃钢橘子卡通雕塑玻璃钢仿真雕塑多少钱玻璃钢雕塑进口福建环保玻璃钢雕塑多少钱沧州玻璃钢雕塑哪家强南阳广场标识校园玻璃钢景观雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化