(原创)bls文件格式的解析

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

wow的shader都是放在bls文件中的,前几天对这些文件分析了一下,发现wowdev.org里对bls的解析不大对,这里对bls的文件格式做一下说明。

文件前四个字节肯定是"SVXG"或"SPXG",分别表示这个bls里保存的是vs或ps。 
接下来一个uint表示版本号,没什么用。
接下来一个uint是用来表示每个profile里的shader数目,以下检测pc。
接下来是data block的偏移量,如果是vs,会有6个偏移量,如果是ps,会有12个偏移量,其中有些可能会是0。
然后就可以根据这些偏移量,移动到文件中的指定位置,开始读取shader的数据和代码了。

以下是我写的一个解析bls文件的代码,可以把指定的bls里的shader输出到一个文本文件中。

/********************************************************************
filename:   Blsparser.cpp
created:    2006/07/29
author:     Weiliang Xie (feiyurainy at 163.com)

purpose:    To parse the wow shader file(.bls),and log the shader data
            a file.
*********************************************************************/

#include <iostream>
#include <fstream>
#include <string>

#include <assert.h>

#include <d3dx9.h>
#include <dxerr9.h>

typedef unsigned int uint32;

struct BlsHeader
{
    char    shaderType[4];  /// shader type,must be "SPXG" or "SVXG"
    uint32  version;        /// shader version,useless
    uint32  shaderCount;    /// shader count in each shader block
};

/// global shader header for the input bls file
BlsHeader gBlsHeader;

/// input bls file stream
std::ifstream gBlsFStream;

/// output log file stream
std::ofstream gOutputFile;

/** read the data from the gBlsFStream
@param count num of byte to read
@return num of byte read
*/
size_t _readData(void* buf, size_t count)
{
    gBlsFStream.read( static_cast<char*>(buf), static_cast<std::streamsize>(count) );

    return gBlsFStream.gcount();
}

/** parse the bls file,and log the shader data to file
@param offsetCount the num of block offset, in vertex shader file, it must
       be 6, and in pixel shader file, it must be 12
*/
void _parseShaderData(const size_t offsetCount)
{
    uint32* blockOffset = new uint32[offsetCount];

    // read the offsets of blocks
    _readData(blockOffset, sizeof(uint32) * offsetCount);

    // for each block
    for (size_t offsetIndex = 0; offsetIndex < offsetCount; ++offsetIndex)
    {
        uint32 offset = blockOffset[offsetIndex];

        // some block offset is zero, i don't know why
        if (offset > 0)
        {
            // go to the address of the block
            gBlsFStream.seekg(offset, std::ios::beg);

            // for each shader in this block
            for (uint32 shaderIndex = 0; shaderIndex < gBlsHeader.shaderCount; ++shaderIndex)
            {
                gOutputFile << "===== Shader start : " << std::endl;

                /** block header is four uint
                0x0 number of shader parameters
                if this number is not zero, there will be some string follow it,
                each string contain a parameter name and value, and the size is 0x90
                0x4 number of shader texture names
                if this number is not zero, there will be some string follow it,
                each string contain a texture name, and the size is 0x90
                0x8 always 0 or 2
                useless
                0xc number byte of shader code text
                the size of code text
                */
                uint32 blockHeader[4] = {0};

                _readData(&blockHeader[0], sizeof(uint32));

                if (blockHeader[0] > 0)
                {
                    gOutputFile << "Parameter section start :" << std::endl;

                    // log each parameter name
                    for (uint32 i = 0; i < blockHeader[0]; ++i)
                    {
                        char paraName[0x90];
                        _readData(paraName, 0x90);

                        gOutputFile << paraName << std::endl;
                    }

                    gOutputFile << "Parameter section end/n" << std::endl;
                }

                _readData(&blockHeader[1], sizeof(uint32));

                if (blockHeader[1] > 0)
                {
                    gOutputFile << "Texture names section start :/n" << std::endl;

                    // log each texture name
                    for (uint32 i = 0; i < blockHeader[1]; ++i)
                    {
                        char texName[0x90];
                        _readData(texName, 0x90);

                        gOutputFile << texName << std::endl;
                    }

                    gOutputFile << "Texture names section end/n" << std::endl;
                }

                _readData(&blockHeader[2], sizeof(uint32));

                // get the size of shader code text
                _readData(&blockHeader[3], sizeof(uint32));

                uint32 codeSize = blockHeader[3];
                if (codeSize > 0)
                {
                    gOutputFile << "Code section start :" << std::endl;

                    char* codeText = new char[codeSize];

                    // read code text
                    size_t read = _readData(codeText, codeSize);

                    assert (read == codeSize);

                    size_t pos = gBlsFStream.tellg();
                    // if the first char is '!', this shader is written by
                    // arbfp or arbvp, and there will be some unused datas
                    // between two shaders
                    if (codeText[0] == '!')
                    {
                        gOutputFile << codeText << std::endl;

                        // find out the length of the unused datas
                        size_t nowPos = gBlsFStream.tellg();

                        size_t skipCount = 0;

                        if (nowPos % 4 == 0)
                            skipCount = 0;
                        else
                            skipCount = 4 - nowPos % 4;

                        // and skip to the next shader
                        gBlsFStream.seekg(skipCount, std::ios::cur);
                    }
                    else // it is the dx shader
                    {
                        // use d3dx to get the shader code from the binary shader code
                        LPD3DXBUFFER codeBuffer;
                        HRESULT hr = D3DXDisassembleShader(
                            static_cast<DWORD*>( static_cast<void*>(codeText) ),
                            0, NULL, &codeBuffer );

                        if (FAILED(hr))
                        {
                            std::cout << DXGetErrorDescription9(hr) << std::endl;
                        }

                        gOutputFile << static_cast<char*>( codeBuffer->GetBufferPointer() ) << std::endl;
                    }

                    gOutputFile << "Code section end/n" << std::endl;

                    delete [] codeText;
                }

                gOutputFile << "===== Shader end/n" << std::endl;
            } // end of each shader
        }
    } // end of each block

    delete [] blockOffset;
}

int main(int argc, char **argv)
{
    gBlsFStream.open(argv[1], std::ios::binary | std::ios::in);

    if (!gBlsFStream)
    {
        std::cout << "can't find the file : " << argv[1] << std::endl;
        return 1;
    }

    std::string outputName(argv[1]);
    outputName += ".log";

    gOutputFile.open(outputName.c_str(), std::ios::out | std::ios::binary);

    if (!gOutputFile)
    {
        std::cout << "can't create the output file : " << outputName << std::endl;
        return 1;
    }

    // read the header
    _readData(&gBlsHeader, sizeof(BlsHeader));

    gOutputFile << "shader type : " << gBlsHeader.shaderType << std::endl;

    size_t offsetCount;

    // find out this bls file is vs or ps
    if (gBlsHeader.shaderType[1] == 'V')
    {
        offsetCount = 6;       
    }
    else if (gBlsHeader.shaderType[1] == 'P')
    {
        offsetCount = 12;
    }
    else
    {
        std::cout << "the content of the file is wrong : " << argv[1] << std::endl;
        return 1;
    }

    _parseShaderData(offsetCount);

    gBlsFStream.close();
    gOutputFile.close();

    return 0;
}


 

BLS with Random Oracle; BLS 短签名在随机谕言机模型下的安全证明 内容小结 BLS with Random Oracle 密码学安全规约推荐书目: 《密码学中的可证明安全性》杨波 清华大学出版社 《Introduction to Security Reduction》Fuchun Guo;Willy Susilo;Yi Mu Springer 数字签名的安全证明 数字签名的安全证明我们需要明确以下三个关键问题: (1)模拟者构造的模拟协议是不是可模拟的?是不是和真实协议不可区分的? (2)敌手伪造的数字签名是不是可规约的?是不是能解决困难问题实例的? (3)规约是不 阅读详情

相关推荐

基于IBM TSS库的BLS门限签名实战:从分布式密钥生成到签名验证

在分布式系统和区块链领域,数字签名是确保身份认证与交易授权的核心技术。传统单点签名存在密钥丢失和单点故障风险,而门限签名(Threshold Signature Scheme, TSS)通过秘密共享技术,将签名权分散给多个参与者,仅需达到门限数量的成员协作即可生成有效签名,从而提升了系统的安全性与鲁棒性。BLS(Boneh–Lynn–Shacham)签名方案因其签名短、可聚合的特性,与门限签名结合后,在密钥管理和签名验证效率上展现出显著技术价值,广泛应用于以太坊2.0等区块链项目的共识与多签场景。本文聚焦于

weixin_29009339的博客 288

blst:多语言BLS12-381签名库

blst blst(读作“ blast”)是一个BLS12-381签名库,专注于性能和安全性。 它是用C和汇编语言编写的。 目录 特定语言的注释 去 锈 储存库结构 表现 执照 地位 该库尚未审核。 使用风险自负。 已计划对该库进行正式验证,并将使用Cryptol和Coq来验证字段,曲线和批量签名操作。 该库符合以下IETF规范草案: IETF BLS签名V4 IETF哈希到曲线V10 序列化格式是根据IETF规范的附录A.BLS12-381实现的,该规范要求使用ZCash定义。 有关实施的一般说明 blst库的目标是为需要高性能和经过正式验证的BLS12-381操作的应用程序和其他库提供基础组件。 考虑到这一点,我们做出了一些决定,以使公众利益最大化,超越BLS12-381。 例如,与专门针对381位BLS12-381曲线参数进行了调整相反,现场操作针对通用384位使用进

C语言中.h和.c文件解析

C语言中.h和.c文件解析

模糊宽度学习系统(BLS):提升人工智能视觉计算的新模型

今天来给大家讲解一篇发表在中科院一区顶级期刊上《IEEE Transactions on Cybernetics》的有关于目前人工智能计算机视觉新方向(宽度学习)的文章。作者在这篇文章中基于宽度神经网络提出了一种改进的新模型,融入了模糊规则来提高模型对特殊特征的分辨能力。由于模糊规则的复杂性,本博客用了比较多的博客来讲述,如果大家觉得太难,可以直接下载附件代码先跑起来,从代码入手再回来看数学公式会更直接一点。

博客之路,前途漫漫 2308

BLS12-381 and BLS Signatures

BLS12-381 and BLS Signatures 椭 圆曲线密码算法具有密钥短的优点,为了达到128 bit的安全水平,NIST (美国国家标准与技术研究院)推荐使用 3072 bit 的RSA密钥 ,而椭圆曲线密码算法仅需要256 bit就能达到同等安全强度,这使得密钥长度大大缩短,因而大受欢迎。 一. BLS12-381简介 BLS12-381是Pairing-Friendly的椭圆曲线,Pairing-Friendly的椭圆曲线要满足两点:1.具有大素数阶子群;2.嵌入次数要小。BLS12-3

qq_34793644的博客 2961

密码学系列 - BLS12-381

BLS12-381曲线详细介绍

weixin_40862140的博客 794

【零知识证明】BLS12-381介绍译文

原文链接:https://hackmd.io/@benjaminion/bls12-381#BLS12-381-For-The-Rest-Of-Us 强烈建议阅读原文。 参考链接: 【1】BLS12-381的具体参数: https://tools.ietf.org/id/draft-yonezawa-pairing-friendly-curves-02.html#rfc.section.1.1 部分译文如下: Everything I wish I’d known before I starte

4936

BLS签名库教程:基于Chia-Network的bls-signatures

BLS签名库教程:基于Chia-Network的bls-signatures 项目概述 此教程旨在详细介绍GitHub上的开源项目Chia-Network/bls-signatures,该项目提供了一套实现BLS(Boneh-Lynn-Shacham)签名方案的库。BLS签名是一种高效的群签名方案,特别适用于区块链和分布式系统中的密钥管理和批量验证需求。下面将分别解析项目的目录结构、启动文件以及配...

gitblog_00299的博客 543

BLS+ with Random Oracle; BLS 改进方案在随机谕言机模型下的安全证明;内容小结

BLS+ with Random Oracle; BLS 改进方案在随机谕言机模型下的安全证明;内容小结 密码学安全规约推荐书目(系列博客内容为这两本书学习笔记与内容小结): 《密码学中的可证明安全性》杨波 清华大学出版社 《Introduction to Security Reduction》Fuchun Guo;Willy Susilo;Yi Mu Springer BLS改进方案描述 1. Setup...

密码小仙女 682

了解bls签名

BLS签名 记e: G*G->G’,为一个非退化的双线性映射,G和G’为素数r阶的乘法群,生成元为g。根据双线性映射的性质,e(g1^x, g2^y)=e(g1,g2)^(x*y)。要求在G上,CDH problem是困难的。 BLS签名的三个函数 KeyGen:选取[0, r-1]内的一个随机整数x,作为私钥sk;g^x作为公钥pk。由于CDH问题是困难的,我们相信DL问题也是

zqf675329914的专栏 2217

BLS# with Random Oracle ;BLS 改进方案在随机谕言机下 内容小结

BLS# with Random Oracle ;BLS 改进方案在随机谕言机下 内容小结 密码学安全规约推荐书目(系列博客内容为这两本书学习笔记与内容小结): 《密码学中的可证明安全性》杨波 清华大学出版社 《Introduction to Security Reduction》Fuchun Guo;Willy Susilo;Yi Mu Springer BLS# 方案描述 ...

密码小仙女 542

bls12_381-BLS12-381配对友好的椭圆曲线构造的实现-Rust开发

bls12_381此板条箱提供了BLS12-381配对友好的椭圆曲线构造的实现。 尚未审查此实现bls12_381此板条箱提供了BLS12-381配对友好的椭圆曲线构造的实现。 此实现尚未经过审核或审核。 使用风险自负。 此实现针对Rust 1.36或更高版本。 此实现不需要Rust标准库。 除非明确指出,否则所有操作都是恒定时间。 功能组(默认情况下处于启用状态):启用用于执行G1,G2和GT的组算术的API。 配对(默认情况下处于启用状态):启用som

bls12_381:BLS12-381配对友好的椭圆曲线组的实现

bls12_381 此板条箱提供了BLS12-381配对友好的椭圆曲线构造的实现。 此实现尚未经过审核或审核。 使用风险自负。 此实现的目标是Rust 1.47或更高版本。 此实现不需要Rust标准库。 除非明确指出,否则所有操作都是恒定时间。 特征 groups ( groups (默认情况下处于启用状态):启用用于执行G1,G2和GT的组算术的API。 pairings (默认情况下处于启用状态):启用一些用于执行配对的API。 alloc (默认情况下为on):启用需要分配器的API; 其中包括配对优化。 nightly :启用subtle/nightly ,以防止编译器优化可能危及恒定时间的操作。 需要每晚使用Rust编译器。 endo (默认情况下处于启用状态):启用利用曲线同形的优化。 不推荐使用,将在以后的版本中删除。 曲线说明 BLS12-381是的配对友

虚拟币用到的非常哇塞的技术(BLS签名聚合)解读

BLS签名聚合技术是现代区块链和密码学领域的重要创新,它通过椭圆曲线密码学和双线性映射实现了签名的聚合和高效验证。空间效率:将n个签名聚合为单个签名,大幅减少存储和传输开销验证效率:验证聚合签名比验证多个独立签名更高效灵活性:支持相同消息和不同消息的签名聚合安全性:基于成熟的椭圆曲线密码学,提供强大的安全保证BLS签名聚合技术在以太坊2.0等现代区块链系统中得到广泛应用,为解决区块链可扩展性问题提供了重要工具。

zhangzhechun_03的博客 1314

从CDH到BDH:ElGamal与BLS签名背后的密码学安全假设解析

密码学的安全性建立在计算复杂性理论之上,其核心是定义一类在现有计算资源下“不可行”解决的数学难题。离散对数问题作为基础,引出了CDH、DDH、BDH等关键安全假设,它们分别对应不同的攻击者能力和目标。这些假设不仅是理论基石,更直接支撑了现代密码系统的工程实践价值。例如,CDH假设保障了ElGamal加密方案的安全性,而更强的BDH假设结合双线性配对,则催生了BLS短签名这类具有签名聚合特性的前沿技术。在区块链、安全通信和数字证书等应用场景中,理解并正确运用这些假设,对于设计高效、安全的系统至关重要。本文通过

weixin_34372728的博客 386

drand核心概念解析:阈值签名与BLS12-381密码学原理

drand是一个分布式随机性信标守护进程,采用Go语言实现,其核心功能依赖于阈值签名和BLS12-381密码学原理解构随机数生成过程。作为分布式系统的关键组件,drand通过密码学机制确保不可预测、可验证且防篡改的随机数输出,广泛应用于区块链共识、安全协议等场景。 ## 分布式随机性的核心挑战 在中心化系统中,随机数生成通常依赖单一信任源,存在单点故障和篡改风险。drand通过分布式架构解决这

gitblog_01162的博客 718

Triton Inference Server 实战:从模型部署到动态调度(附BLS模式代码解析

本文深入探讨了Triton Inference Server在AI模型部署中的动态调度实践,重点解析BLS(Batch-Level Scheduling)模式的应用与代码实现。通过电商平台推荐系统等案例,展示了如何利用Triton架构实现多模型协作、条件分支判断和智能流量分配,提升生产环境中的推理效率与灵活性。

weixin_29207439的博客 360

如何利用Triton Inference Server的BLS API构建高效复杂控制流:完整指南

Triton Inference Server是一个开源的高性能推理服务框架,支持多种深度学习框架和模型优化技术。其中,BLS(Business Logic Scripting)API是构建复杂推理流程的核心工具,能够帮助开发者轻松实现多模型协同、条件分支和动态数据流控制,为AI应用提供灵活高效的后端支持。 ## Triton Inference Server架构概览 Triton Infer

gitblog_00467的博客 850

lo 库 DropByIndex 详解:按索引精准删除切片元素(支持负索引、去重与越界容错)

`lo.DropByIndex` 是 Lodash 风格 Go 泛型库 lo 中基于索引删除切片元素的实用工具:它接收一个切片和一组可变参数索引,返回删除了这些位置元素后的新切片,并支持负数索引从尾部倒数定位。本文以 [核心文档](https://link.gitcode.com/i/defb8d54d3559bd9603f997facc601a9) 为主线,结合 [slice.go](https

gitblog_00448的博客 363
上一篇: 继续研究m2
下一篇: (原创)OGRE主要渲染流程简介
RAINini
博客等级 码龄22年 11粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值