• 魔改 Rizzo 恢复二进制符号


    简介

    由于其他几种恢复符号的方法不是特别可靠,所以就有了这个魔改 Rizzo 的项目

    STL 模板中大部分函数的实现和具体的实例化类型无关,只要编译选项相同即可正常匹配

    在编译选项对应的前提下,用这个 Rizzo 脚本匹配的成功率大于 95%

    其他方案的缺点

    • BinaryAI:要求有网络环境,上传样本数据后需要额外等待一段时间,服务端上完成训练后才能正常匹配,而且匹配成功率不高
    • BinDiff:无法正常分析部分程序,分析过程中可能会报错退出
    • Lumina:可以本地搭建 Lumina 服务器,但是匹配成功率过低

    改进功能

    1. 针对 STL 模板函数的匹配进行优化
    2. 不丢弃重复的函数签名
      1. 对于重复的签名按容器优先级匹配函数名称
      2. 默认优先级为 ['vector','map','set','queue','deque','list','array','stack']
    3. 签名按模糊程度分成三个等级,按优先级进行匹配
      1. Formal:对所有助记符,所有操作数进行签名
      2. Fuzzy:对所有助记符,部分操作数进行签名
        1. 忽略可能与实例化类型的空间大小有关的操作数
        2. 以下指令的操作数可能与实例化类型的空间大小有关 ['shr','shl','sar','sal','lea','add','sub']
      3. Slim:对所有助记符进行签名,忽略所有操作数
    4. 以函数为单位进行签名,而不是以基本块为单位进行签名
    5. 可能会出现匹配错误的情况,可以根据上下文进行判断
    6. 函数指令数越多,结构越复杂,匹配的可信度越高

    编译选项

    • Ox
      • -O0:做一些不显著增加编译时间的优化
      • -O1:显著提升编译时间,提升代码性能
      • -O2:进一步优化,显著增加可执行文件大小,做不包含 space-speed tradeoff 的所有优化
      • -O3:优化性能同时不增加可执行文件大小,包含 O2 选项中不增加代码大小的优化项
      • -Os:优化性能同时不增加可执行文件大小,包含 O2 选项中不增加代码大小的优化项
      • -Og:优化性能同时不损害可调试性,包含 O1 选项中不损害可调试性的优化项
    • -mno-sse:禁用 SSE 指令集
    • -static:静态链接
    • -shared:编译动态库
    • -fPIC:生成位置无关代码
    • -fvisibility=hidden:编译动态库时不导出 extern 变量,寻址时不需要查找 GOT 表
    • -nostartfiles:不包含入口点 main 函数

    配置样例

    下面以编译 Capstone 为例,由于项目自带的 Cmake 配置文件会引入一些额外的编译选项,不方便控制,所以这里自己配置 gcc 选项

    • 宏定义:-DCAPSTONE_HAS_X86 -DCAPSTONE_DIET
    • 优化选项:-Os
    • 输入:./arch/X86/*.c ./*.c
    • 输出:-o ./libcapstone.so

    然后加上 -shared -fPIC -fvisibility=hidden 编译动态库

    gcc ./arch/X86/*.c ./*.c -o ./libcapstone.so -DCAPSTONE_HAS_X86 -DCAPSTONE_DIET -I./include -Os -shared -fPIC -fvisibility=hidden
    

    或者加上 -nostartfiles 编译可执行文件

    gcc ./arch/X86/*.c ./*.c -o ./libcapstone.so -DCAPSTONE_HAS_X86 -DCAPSTONE_DIET -I./include -Os -nostartfiles
    

    两者编译的指令序列大部分情况下是完全一样的,可能极少数的函数会有细微差别

    PS:前者编译的结果和正常静态链接编译的结果完全一样,后者编译的结果和正常静态链接编译的结果有一些细微差别

    rizzo.py

    from __future__ import print_function
    import idc
    import idaapi
    import idautils
    
    import os
    import time
    import pickle
    import collections
    import hashlib
    
    import ida_shims
    
    
    class RizzoSignatures(object):
    
        def __init__(self):
            self.slim = {}
            self.fuzzy = {}
            self.formal = {}
            self.functions = {}
    
    
    class RizzoFunctionDescriptor(object):
    
        def __init__(self, signatures, functions, key):
            self.ea = signatures[key]
            self.name = None
    
            for key in ['vector','map','set','queue','deque','list','array','stack']:
                for ea in self.ea:
                    if key in functions[ea][0] and self.name == None:
                        self.name = functions[ea][0]
                        break
            
            if self.name == None:
                self.name = functions[self.ea[0]][0]
            self.blocks = functions[self.ea[0]][1]
    
    
    class Rizzo(object):
    
        DEFAULT_SIGNATURE_FILE = "rizzo.sig"
    
        def __init__(self, sigfile=None):
            if sigfile:
                self.sigfile = sigfile
            else:
                self.sigfile = self.DEFAULT_SIGNATURE_FILE
    
            start = time.time()
            self.signatures = self.generate()
            end = time.time()
    
            print("Generated %d formal signatures for %d " 
                  "functions in %.2f seconds." % (len(self.signatures.formal),
                                                  len(self.signatures.functions),
                                                  (end-start)))
    
        def save(self):
            print(("Saving signatures to %s..." % self.sigfile), end=' ')
            fp = open(self.sigfile, "wb")
            pickle.dump(self.signatures, fp)
            fp.close()
            print("done.")
    
        def load(self):
            print(("Loading signatures from %s..." % self.sigfile), end=' ')
            fp = open(self.sigfile, "rb")
            sigs = pickle.load(fp)
            fp.close()
            print("done.")
            return sigs
    
        def sighash(self, value):
            h = hashlib.md5()
            h.update(value.encode("utf-8"))
            hash_value = h.hexdigest()
            del(h)
            return hash_value
    
        def block(self, block):
            formal = []
            fuzzy = []
            slim = []
    
            ea = ida_shims.start_ea(block)
            while ea < ida_shims.end_ea(block):
                insn = ida_shims.decode_insn(ea)
    
                drefs = [x for x in idautils.DataRefsFrom(ea)]
                crefs = [x for x in idautils.CodeRefsFrom(ea, False)]
    
                mnem = ida_shims.print_insn_mnem(ea)
                formal.append(mnem)
                fuzzy.append(mnem)
                slim.append(mnem)
    
                if crefs:
                    for cref in crefs:
                        formal.append("coderef")
                        fuzzy.append("coderef")
                        slim.append("coderef")
               
                elif drefs:
                    for dref in drefs:
                        formal.append("dataref")
                        fuzzy.append("dataref")
                        slim.append("dataref")
               
                elif not drefs and not crefs:
                    ops = ida_shims.get_operands(insn)
                    for n in range(0, len(ops)):
                        opnd_text = ida_shims.print_operand(ea, n)
                        formal.append(opnd_text)
                        if mnem not in ['shr','shl','sar','sal','lea','add','sub']:
                            fuzzy.append(opnd_text)
    
                ea = ida_shims.next_head(ea)
    
            print(''.join(formal),end='')
            print(''.join(fuzzy),end='')
            print(''.join(slim),end='')
    
            return (formal,fuzzy,slim)
    
        def function(self, func):
            blocks = []
    
            for block in idaapi.FlowChart(func):
                blocks.append(self.block(block))
    
            return blocks
    
        def generate(self):
            signatures = RizzoSignatures()
    
            for ea in idautils.Functions():
                func = idaapi.get_func(ea)
                if func:
                    print('
    func 0x%x' % ea, idaapi.get_name(ea))
    
                    raw_formal = []
                    raw_fuzzy = []
                    raw_slim = []
    
                    blocks = self.function(func)
                    for (e, f, s) in blocks:
                        raw_formal.extend(e)
                        raw_fuzzy.extend(f)
                        raw_slim.extend(s)
    
                    formal = self.sighash(''.join(raw_formal))
                    fuzzy = self.sighash(''.join(raw_fuzzy))
                    slim = self.sighash(''.join(raw_slim))
    
                    print('')
                    print('hash 0x%x' % ea, formal)
                    print('hash 0x%x' % ea, fuzzy)
                    print('hash 0x%x' % ea, slim)
    
                    start_ea = ida_shims.start_ea(func)
                    signatures.functions[start_ea] = (ida_shims.get_name(start_ea), blocks)
    
                    if formal not in signatures.formal:
                        signatures.formal[formal]=[]
                    signatures.formal[formal].append(ida_shims.start_ea(func))
    
                    if fuzzy not in signatures.fuzzy:
                        signatures.fuzzy[fuzzy]=[]
                    signatures.fuzzy[fuzzy].append(ida_shims.start_ea(func))
    
                    if slim not in signatures.slim:
                        signatures.slim[slim]=[]
                    signatures.slim[slim].append(ida_shims.start_ea(func))
    
            return signatures
    
        def match(self, extsigs):
            slim = {}
            fuzzy = {}
            formal = {}
    
            start = time.time()
    
            for (extsig, ext_func_ea) in extsigs.formal.items():
                if extsig in self.signatures.formal:
                    new_fun = RizzoFunctionDescriptor(
                        extsigs.formal, extsigs.functions, extsig)
                    curr_fun = RizzoFunctionDescriptor(
                        self.signatures.formal, self.signatures.functions, extsig)
                    formal[curr_fun] = new_fun
    
            for (extsig, ext_func_ea) in extsigs.fuzzy.items():
                if extsig in self.signatures.fuzzy:
                    new_fun = RizzoFunctionDescriptor(
                        extsigs.fuzzy, extsigs.functions, extsig)
                    curr_fun = RizzoFunctionDescriptor(
                        self.signatures.fuzzy, self.signatures.functions, extsig)
                    fuzzy[curr_fun] = new_fun
    
            for (extsig, ext_func_ea) in extsigs.slim.items():
                if extsig in self.signatures.slim:
                    new_fun = RizzoFunctionDescriptor(
                        extsigs.slim, extsigs.functions, extsig)
                    curr_fun = RizzoFunctionDescriptor(
                        self.signatures.slim, self.signatures.functions, extsig)
                    slim[curr_fun] = new_fun
    
            end = time.time()
            print("Found %d formal matches in %.2f seconds." % (len(formal),
                                                                (end-start)))
    
            return (formal, fuzzy, slim)
    
        def rename(self, ea, name):
    
            curname = ida_shims.get_name(ea)
    
            if curname.startswith('sub_') and 
                    name.split('_')[0] not in 
                    ['sub', 'loc', 'unk', 'dword', 'word', 'byte']:
    
                if ida_shims.get_name_ea_simple(name) == idc.BADADDR:
                    if ida_shims.set_name(ea, name):
                        ida_shims.set_func_flags(
                            ea, (ida_shims.get_func_flags(ea) | idc.FUNC_LIB))
                        return 1
            return 0
    
        def apply(self, extsigs):
            count = 0
            rename = {}
            name_count = {}
    
            start = time.time()
    
            (formal, fuzzy, slim) = self.match(extsigs)
    
            for (curfunc, newfunc) in list(formal.items())+list(fuzzy.items())+list(slim.items()):
                print('main ',newfunc.name)
                for ea in curfunc.ea:
                    if ea not in rename:
                        print('	ea 0x%x' % ea)
                        name_root = newfunc.name
                        if name_root not in name_count:
                            name_count[name_root] = 0
                        newname = '%s_%d' % (name_root, name_count[name_root])
                        rename[ea] = newname
                        self.rename(ea, newname)
                        count += 1
                        name_count[name_root] += 1
    
            end = time.time()
            print("Renamed %d functions in %.2f seconds." % (count, (end-start)))
    
    
    def RizzoBuild(sigfile=None):
        print("Building Rizzo signatures, this may take a few minutes...")
        start = time.time()
        r = Rizzo(sigfile)
        r.save()
        end = time.time()
        print("Built signatures in %.2f seconds" % (end-start))
    
    
    def RizzoApply(sigfile=None):
        print("Applying Rizzo signatures, this may take a few minutes...")
        start = time.time()
        r = Rizzo(sigfile)
        s = r.load()
        r.apply(s)
        end = time.time()
        print("Signatures applied in %.2f seconds" % (end-start))
    
    
    def rizzo_produce(arg=None):
        fname = ida_shims.ask_file(1, "*.riz", "Save signature file as")
        if fname:
            if '.' not in fname:
                fname += ".riz"
            RizzoBuild(fname)
    
    
    def rizzo_load(arg=None):
        fname = ida_shims.ask_file(0, "*.riz", "Load signature file")
        if fname:
            RizzoApply(fname)
    
    try:
        class ProduceRizzoAction(idaapi.action_handler_t):
            def __init__(self):
                idaapi.action_handler_t.__init__(self)
    
            def activate(self, ctx):
                rizzo_produce()
                return 1
    
            def update(self, ctx):
                return idaapi.AST_ENABLE_ALWAYS
    
    
        class LoadRizzoAction(idaapi.action_handler_t):
            def __init__(self):
                idaapi.action_handler_t.__init__(self)
    
            def activate(self, ctx):
                rizzo_load()
                return 1
    
            def update(self, ctx):
                return idaapi.AST_ENABLE_ALWAYS
    except AttributeError:
        pass
    
    
    class RizzoPlugin(idaapi.plugin_t):
        flags = 0
        comment = "Function signature"
        help = ""
        wanted_name = "Rizzo"
        wanted_hotkey = ""
        produce_action_name = 'producerizzo:action'
        load_action_name = 'loadrizzo:action'
        menu_name = "Rizzo signature file..."
        produce_tooltip = "Produce rizzo signature file."
        load_tooltip = "Load rizzo signature file."
        menu_tab = 'File/'
        menu_context = []
    
        def init(self):
            if idaapi.IDA_SDK_VERSION >= 700:
                produce_desc = idaapi.action_desc_t(self.produce_action_name,
                                                    self.menu_name,
                                                    ProduceRizzoAction(),
                                                    self.wanted_hotkey,
                                                    self.produce_tooltip,
                                                    199)
    
                load_desc = idaapi.action_desc_t(self.load_action_name,
                                                 self.menu_name,
                                                 LoadRizzoAction(),
                                                 self.wanted_hotkey,
                                                 self.load_tooltip,
                                                 199)
    
                idaapi.register_action(produce_desc)
                idaapi.register_action(load_desc)
    
                idaapi.attach_action_to_menu(
                    os.path.join(self.menu_tab, 'Produce file/'),
                    self.produce_action_name,
                    idaapi.SETMENU_APP)
                idaapi.attach_action_to_menu(
                    os.path.join(self.menu_tab, 'Load file/'),
                    self.load_action_name,
                    idaapi.SETMENU_APP)
            else:
                self.menu_context.append(
                    idaapi.add_menu_item(
                        os.path.join(self.menu_tab, 'Load file/'),
                        "Rizzo signature file...", "", 0, rizzo_load, (None,)))
    
                self.menu_context.append(
                    idaapi.add_menu_item(
                        os.path.join(self.menu_tab, 'Produce file/'),
                        "Rizzo signature file...", "", 0, rizzo_produce, (None,)))
    
            return idaapi.PLUGIN_KEEP
    
        def term(self):
            if idaapi.IDA_SDK_VERSION >= 700:
                idaapi.detach_action_from_menu(
                    self.menu_tab, self.produce_action_name)
                idaapi.detach_action_from_menu(
                    self.menu_tab, self.load_action_name)
            else:
                if self.menu_context is not None:
                    idaapi.del_menu_item(self.menu_context)
            return None
    
        def run(self, arg):
            return None
    
        def rizzo_script(self):
            idaapi.IDAPython_ExecScript(self.script, globals())
    
    
    def PLUGIN_ENTRY():
        return RizzoPlugin()
    

    stl_container.cpp

    #include <iostream>
    #include <array>
    #include <queue>
    #include <forward_list>
    #include <list>
    #include <map>
    #include <queue>
    #include <set>
    #include <stack>
    #include <vector>
    #include <algorithm>
    #include <random>
    
    using namespace std;
    
    struct s{
        int s1;
        int s2;
        friend bool operator<(s a,s b){
            return true;
        }
        friend bool operator>(s a,s b){
            return true;
        }
        friend bool operator==(s a,s b){
            return true;
        }
        friend s operator+(s a,s b){
            return s{0,0};
        }
    }s0;
    
    #define a(x) if (a) x;
    int a;
    
    int main ()
    {
        if (a){
            std::array<int,5> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.size())a(c.max_size())a(c.empty())
            a(c.operator[](0))a(c.at(0))a(c.front())a(c.back())a(c.data())
            a(c.fill(0))a(c.swap(c))
        }
        if (a){
            std::deque<int> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.size())a(c.max_size())a(c.resize(0))a(c.empty())a(c.shrink_to_fit())
            a(c.operator[](0))a(c.at(0))a(c.front())a(c.back())
            a(c.assign(0,0))a(c.push_back(0))a(c.push_front(0))a(c.pop_back())a(c.pop_front())a(c.insert(c.begin(),0))a(c.erase(c.begin()))a(c.swap(c))a(c.clear())a(c.emplace(c.begin(),0))a(c.emplace_front(0))a(c.emplace_back(0))
            a(c.get_allocator())
        }
        if (a){
            std::list<int> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.empty())a(c.size())a(c.max_size())
            a(c.front())a(c.back())
            a(c.assign(0,0))a(c.push_back(0))a(c.push_front(0))a(c.pop_back())a(c.pop_front())a(c.insert(c.begin(),0))a(c.erase(c.begin()))a(c.swap(c))a(c.clear())a(c.emplace(c.begin(),0))a(c.emplace_front(0))a(c.emplace_back(0))a(c.resize(0))
            a(c.splice(c.begin(),c))a(c.remove(0))a(c.remove_if([](int){return true;}))a(c.unique(greater<int>()))a(c.merge(c))a(c.sort(greater<int>()))a(c.reverse())
            a(c.get_allocator())
        }
        if (a){
            std::map<int,int> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.empty())a(c.size())a(c.max_size())
            a(c.operator[](0))a(c.at(0))
            a(c.insert(pair<int,int>(0,0)))a(c.erase(0))a(c.swap(c))a(c.clear())a(c.emplace(0,0))a(c.emplace_hint(c.begin(),0,0))
            a(c.key_comp())a(c.value_comp())a(c.find(0))a(c.count(0))a(c.lower_bound(0))a(c.upper_bound(0))a(c.equal_range(0))
            a(c.get_allocator())
        }
        if (a){
            std::queue<int> c;
            a(c.empty())a(c.size())a(c.front())a(c.back())a(c.push(0))a(c.emplace(0))a(c.pop())a(c.swap(c))
        }
        if (a){
            std::set<int> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.empty())a(c.size())a(c.max_size())
            a(c.insert(0))a(c.erase(0))a(c.swap(c))a(c.clear())a(c.emplace(0))a(c.emplace_hint(c.begin(),0))
            a(c.key_comp())a(c.value_comp())a(c.find(0))a(c.count(0))a(c.lower_bound(0))a(c.upper_bound(0))a(c.equal_range(0))
            a(c.get_allocator())
        }
        if (a){
            std::stack<int> c;
            a(c.empty())a(c.size())a(c.top())a(c.push(0))a(c.emplace(0))a(c.pop())a(c.swap(c))
        }
        if (a){
            std::vector<int> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.size())a(c.max_size())a(c.resize(0))a(c.empty())a(c.shrink_to_fit())a(c.reserve(0))a(c.capacity())
            a(c.operator[](0))a(c.at(0))a(c.front())a(c.back())a(c.data())
            a(c.assign(0,0))a(c.push_back(0))a(c.pop_back())a(c.insert(c.begin(),0))a(c.erase(c.begin()))a(c.swap(c))a(c.clear())a(c.emplace(c.begin(),0))a(c.emplace_back(0))
            a(c.get_allocator())
            all_of(c.begin(),c.end(),[](int){return true;});
            any_of(c.begin(),c.end(),[](int){return true;});
            none_of(c.begin(),c.end(),[](int){return true;});
            for_each(c.begin(),c.end(),[](int){return true;});
            find(c.begin(),c.end(),0);
            find_if(c.begin(),c.end(),[](int){return true;});
            find_if_not(c.begin(),c.end(),[](int){return true;});
            adjacent_find(c.begin(),c.end(),greater<int>());
            count(c.begin(),c.end(),0);
            count_if(c.begin(),c.end(),[](int){return true;});
            copy(c.begin(),c.end(),c.begin());
            move(c);
            swap(c,c);
            transform(c.begin(),c.end(),c.begin(),[](int x){return x;});
            transform(c.begin(),c.end(),c.begin(),c.begin(),plus<int>());
            replace(c.begin(),c.end(),0,0);
            fill(c.begin(),c.end(),0);
            generate(c.begin(),c.end(),[](){return 0;});
            remove(c.begin(),c.end(),0);
            unique(c.begin(),c.end(),greater<int>());
            reverse(c.begin(),c.end());
            rotate(c.begin(),c.end(),c.begin());
            random_shuffle(c.begin(),c.end());
            shuffle(c.begin(),c.end(),std::default_random_engine(0));
            sort(c.begin(),c.end());
            lower_bound(c.begin(),c.end(),0);
            upper_bound(c.begin(),c.end(),0);
            equal_range(c.begin(),c.end(),0);
            binary_search(c.begin(),c.end(),0);
            min(0,0);
            max(0,0);
            minmax({0});
            min_element(c.begin(),c.end(),greater<int>());
            max_element(c.begin(),c.end(),greater<int>());
            minmax_element(c.begin(),c.end(),greater<int>());
            lexicographical_compare(c.begin(),c.end(),c.begin(),c.end());
            next_permutation(c.begin(),c.end());
            prev_permutation(c.begin(),c.end());
        }
    
        if (a){
            std::array<s,5> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.size())a(c.max_size())a(c.empty())
            a(c.operator[](0))a(c.at(0))a(c.front())a(c.back())a(c.data())
            a(c.fill(s0))a(c.swap(c))
        }
        if (a){
            std::deque<s> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.size())a(c.max_size())a(c.resize(0))a(c.empty())a(c.shrink_to_fit())
            a(c.operator[](0))a(c.at(0))a(c.front())a(c.back())
            a(c.assign(0,s0))a(c.push_back(s0))a(c.push_front(s0))a(c.pop_back())a(c.pop_front())a(c.insert(c.begin(),s0))a(c.erase(c.begin()))a(c.swap(c))a(c.clear())a(c.emplace(c.begin(),s0))a(c.emplace_front(s0))a(c.emplace_back(s0))
            a(c.get_allocator())
        }
        if (a){
            std::list<s> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.empty())a(c.size())a(c.max_size())
            a(c.front())a(c.back())
            a(c.assign(0,s0))a(c.push_back(s0))a(c.push_front(s0))a(c.pop_back())a(c.pop_front())a(c.insert(c.begin(),s0))a(c.erase(c.begin()))a(c.swap(c))a(c.clear())a(c.emplace(c.begin(),s0))a(c.emplace_front(s0))a(c.emplace_back(s0))a(c.resize(0))
            a(c.splice(c.begin(),c))a(c.remove(s0))a(c.remove_if([](s){return true;}))a(c.unique(greater<s>()))a(c.merge(c))a(c.sort(greater<s>()))a(c.reverse())
            a(c.get_allocator())
        }
        if (a){
            std::map<s,s> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.empty())a(c.size())a(c.max_size())
            a(c.operator[](s0))a(c.at(s0))
            a(c.insert(pair<s,s>(s0,s0)))a(c.erase(s0))a(c.swap(c))a(c.clear())a(c.emplace(s0,s0))a(c.emplace_hint(c.begin(),s0,s0))
            a(c.key_comp())a(c.value_comp())a(c.find(s0))a(c.count(s0))a(c.lower_bound(s0))a(c.upper_bound(s0))a(c.equal_range(s0))
            a(c.get_allocator())
        }
        if (a){
            std::queue<s> c;
            a(c.empty())a(c.size())a(c.front())a(c.back())a(c.push(s0))a(c.emplace(s0))a(c.pop())a(c.swap(c))
        }
        if (a){
            std::set<s> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.empty())a(c.size())a(c.max_size())
            a(c.insert(s0))a(c.erase(s0))a(c.swap(c))a(c.clear())a(c.emplace(s0))a(c.emplace_hint(c.begin(),s0))
            a(c.key_comp())a(c.value_comp())a(c.find(s0))a(c.count(s0))a(c.lower_bound(s0))a(c.upper_bound(s0))a(c.equal_range(s0))
            a(c.get_allocator())
        }
        if (a){
            std::stack<s> c;
            a(c.empty())a(c.size())a(c.top())a(c.push(s0))a(c.emplace(s0))a(c.pop())a(c.swap(c))
        }
        if (a){
            std::vector<s> c;
            a(c.begin())a(c.end())a(c.rbegin())a(c.rend())a(c.cbegin())a(c.cend())a(c.crbegin())a(c.crend())
            a(c.size())a(c.max_size())a(c.resize(0))a(c.empty())a(c.shrink_to_fit())a(c.reserve(0))a(c.capacity())
            a(c.operator[](0))a(c.at(0))a(c.front())a(c.back())a(c.data())
            a(c.assign(0,s0))a(c.push_back(s0))a(c.pop_back())a(c.insert(c.begin(),s0))a(c.erase(c.begin()))a(c.swap(c))a(c.clear())a(c.emplace(c.begin(),s0))a(c.emplace_back(s0))
            a(c.get_allocator())
            all_of(c.begin(),c.end(),[](s){return true;});
            any_of(c.begin(),c.end(),[](s){return true;});
            none_of(c.begin(),c.end(),[](s){return true;});
            for_each(c.begin(),c.end(),[](s){return true;});
            find(c.begin(),c.end(),s0);
            find_if(c.begin(),c.end(),[](s){return true;});
            find_if_not(c.begin(),c.end(),[](s){return true;});
            adjacent_find(c.begin(),c.end(),greater<s>());
            count(c.begin(),c.end(),s0);
            count_if(c.begin(),c.end(),[](s){return true;});
            copy(c.begin(),c.end(),c.begin());
            move(c);
            swap(c,c);
            transform(c.begin(),c.end(),c.begin(),[](s x){return x;});
            transform(c.begin(),c.end(),c.begin(),c.begin(),plus<s>());
            replace(c.begin(),c.end(),s0,s0);
            fill(c.begin(),c.end(),s0);
            generate(c.begin(),c.end(),[](){return s0;});
            remove(c.begin(),c.end(),s0);
            unique(c.begin(),c.end(),greater<s>());
            reverse(c.begin(),c.end());
            rotate(c.begin(),c.end(),c.begin());
            random_shuffle(c.begin(),c.end());
            shuffle(c.begin(),c.end(),std::default_random_engine(0));
            sort(c.begin(),c.end());
            lower_bound(c.begin(),c.end(),s0);
            upper_bound(c.begin(),c.end(),s0);
            equal_range(c.begin(),c.end(),s0);
            binary_search(c.begin(),c.end(),s0);
            min(s0,s0);
            max(s0,s0);
            minmax({s0});
            min_element(c.begin(),c.end(),greater<s>());
            max_element(c.begin(),c.end(),greater<s>());
            minmax_element(c.begin(),c.end(),greater<s>());
            lexicographical_compare(c.begin(),c.end(),c.begin(),c.end());
            next_permutation(c.begin(),c.end());
            prev_permutation(c.begin(),c.end());
        }
    }
    
  • 相关阅读:
    mysql分页查询优化
    java反射及Method的Invoke方法(转载)
    java需会(转载)
    Java注解(Annotation)原理详解
    深入分析JDK动态代理
    Java并发编程:volatile关键字解析
    安装hadoop
    linux 配置ssh免密登录
    安装Centos 7 并且配置远程登录
    MAC安装VMware fusion
  • 原文地址:https://www.cnblogs.com/algonote/p/15015836.html
Copyright © 2020-2023  润新知