linux系统下file使用的magic文件格式说明

本文档详细介绍了file命令使用的magic文件格式,包括不同类型的检测规则、偏移量的应用、层级匹配原理及复杂文件类型的识别方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

magic
本手册是file命令所使用的magic文件的格式说明文档,版本是5.04.
file命令用于识别文件类型,其他检测,检测文件内容中是否符合 'magic模式',也就是规则。
/usr/share/misc/magic 文件指定什么模式将被用于检测,当匹配到规则时什么信息或者MIME type将打印输出。从文件提取额外信息
文件每行都指定一个可执行的测试。一个测试比较的是在数据中的起始位置开始,在特定的偏移位置文件的字节值。一个字符串或者一个数字值。如果测试成功,将打印信息。magic文件中的行由以下字段构成
offset 
    一个数字说明偏移量,用字节,从数据文件中哪里开始检测
type 检测的数据的类型,可以是以下值:
    byte   一个字节值
    short  两个字节值在此计算机本机字节序
    long   四个字节值在此计算机本机字节序
    quad  八个字节值在此计算机本机字节序
    float   32位的单精度浮点数在此计算机本机字节序
    double   64位的双精度浮点数在此计算机本机字节序
    string   一个字符串字节,字符串类型说明可以随意跟 /[Bbc]*
            B标志压缩目标中的空格,必须包含至少一个空格字符。如果magic有n个连续的空白字符,目标需要至少n个连续的空格去匹配。
            b标志处理每个目标的空白字符作为一个可选空白
            c标志说明大小写不敏感的匹配,magic中的小写字符匹配目标的大写和小写字符,然而magic中的大写字符串仅仅匹配目标的大写字符。
    pstring  一个Pascal-style字符串第一个字节解释为无符号的长度。这个字符串不是以空结尾
    date  一个四字节的值,解释为一个UNIX日期
    qdate  一个八字节的值,解释为一个UNIX日期
    ldate   一个四字节的值,解释为一个UNIX-style日期,并且是解释为本地时间而不是UTC
    qldate  一个八字节值解释为一个UNIX-style日期,并且解释为本地时间不是UTC
     beid3  一个32位ID3长度以大端字节序表示
     beshort 一个两字节值以大端字节序表示
     belong  一个四字节值以大端字节序表示
     bequad  一个八字节值以大端字节序表示
     befloat  一个32位单精度浮点数以大端字节序表示
     bedoublt  一个64位双精度浮点数以大端字节序表示
     bedate  一个四字节值大端字节序表示,解释为一个Unix日期     
     beqdate  一个八字节值大端字节序表示,解释为一个Unix日期
      beldate  一个四字节值以大端字节序表示,解释为一个UNIX-style日期,并且解释为本地时间不是UTC
     beldate  一个八字节值以大端字节序表示,解释为一个UNIX-style日期,并且解释为本地时间不是UTC

     bestring16 一个两个字节unicode(UCS16)字符串以大端字节序表示

 
     leid3  一个32位ID3长度以小端字节序表示
     leshort 一个两字节值以小端字节序表示
     lelong  一个四字节值以大端字节序表示
     lequad  一个八字节值以小端字节序表示
     lefloat  一个32位单精度浮点数以小端字节序表示
     ledoublt  一个64位双精度浮点数以小端字节序表示
     bedate  一个四字节值小端字节序表示,解释为一个Unix日期     
     leqdate  一个八字节值小端字节序表示,解释为一个Unix日期
     leldate  一个四字节值以小端字节序表示,解释为一个UNIX-style日期,并且解释为本地时间不是UTC
     leldate  一个八字节值以小端字节序表示,解释为一个UNIX-style日期,并且解释为本地时间不是UTC
     lestring16 一个两个字节unicode(UCS16)字符串以小端字节序表示
 
     melong 一个四字节值以中端(PDP-11)字节序表示
     medate  一个四字节值以中端(PDP-11)字节序表示,解释为一个Unix日期   
     meldate 一个八字节值以中端(PDP-11)字节序表示,解释为一个UNIX-style日期,并且解释为本地时间不是UTC  
      indirect  在偏移的起始位置,再次查询magic数据库
      regex 一个匹配的正则表达式,使用扩展的POSXI正则表达式语法。正则表达式可以花费指数级时间在程序中。他们的效率很难被预测。所以尽量不要使用。当用在生产环境中他们的效率需要仔细检查。类型参数可以跟[c][s]任意一个。
                 c标志将使匹配大小写不敏感
                 s标志更新偏移量为匹配后偏移的起始位置,而不是最后。
       正则表达式再次检测前面的N+1行。N是已经知道的偏移量。行尾是假定匹配机器的本地格式。^和$分别匹配单独的行首和行尾,不是分解的开始和结尾
       search  搜索一个字面字符串从给定偏移的起始位置。相同的修饰符可以被使用做为字符串规则。如果有修饰符标志,必须根据/number范围内。也就是说,位置数量将要试图匹配,从起始位置开始偏移。这是适合搜索大的二进制表达式用变量偏移。特殊字符使用\ 转义。偏移量作为正则表达式。
         default  这个是打算用做测试 x (这个始终是真的)和一个消息时使用,如果这里不匹配
 
根据使用类型每个顶层的magic规则(看下面的层级说明)分为text和binary。类型 regex和search是被分为text测试,除非非打印字符被用做规则,所有其他测试都被分为binary类型。当一个顶级规则的所有规则是text规则,则把他考虑作为一个text测试,,否则看作是一个binary规则。匹配一个文件时,binary规则是最先尝试的,如果不匹配,并且文件看起来像文本并且编码确定,那将尝试文本模式。
numeric类型可能随意跟&和数字值,指定值被 AND'ed 用数值在匹配完成之前。头部添加一个 u 到类型表明要求比较应该是无符号类型的。
test 比较的值从文件中的值。如果类型是numeric,这个值指定为C格式,如果它是一个字符串,它是指定为一个C字符串允许用通常的转义(例如:\n 新行)
数字值可能在一个字符之前,表明操作被执行。他可能是
          =,文件指定值必须相等和指定值,
          <,文件中的指定值必须小于指定值
          >,文件中的指定值必须大于指定值
          &,文件中的指定值必须设置所有位设置为指定值
          ^,指定值从文件必须清除任何位设置在指定的值
          ~,值指定否定测试 
          x,指定任何值将匹配
          !,指定行匹配如果测试没有成功
如果字符被省略,他被假定为=,操作符&,^,~不能用于float和
double。
数字值被指定为C格式,例如:13是十进制,013是八进制,0x13是十六进制
对于字符串值,文件中的字符串必须匹配指定字符串。操作符=,<,>(除了&)可以被用在字符串。 长度用于在magic文件中字符串参数匹配。这意味着一行可以匹配任意非空字符串(通常使用打印字符串),用 >\0(因为所有的非空字符串是大于空字符串)。
特殊测试X通常指定为true,如果比较成功就打印信息。如果字符串中包含一个printf()格式的参数,文件中的值(使用任何指定的隐蔽完成)用格式化字符串打印输出。如果字符串以\b开始,信息打印剩余字符串用无空格补充,多个匹配通常用一个空格分开。
一个APPLE 4+4字符APPLE创建者和类型可以被指定为:
!:apple
 
creatype
一个MIME type是在单独一行,他必须是下一个非空或者注释行后magic行识别文件类型,有下面的格式:
!:mime  MIMETYPE

 

即,文字字符串 !:mime 跟着 MIME type
一个随机的strength可以被提供在单独的一行,他指定是当前的magic描述,使用下面的格式:
!:strength OP VALUE

 

操作符OP 可以是:+,-,*,/和VALUE一个0-255的常量。这个常量被用于指定操作数当前的计算机默认的magic strength。
一些文件格式包含额外信息打印文件类型。或者需要额外测试确定文件类型。这些额外的测试由一个或者跟多的>字符,在偏移之前。数字 数目 > 在行表明测试的等级,一行没有>在开始是考虑0级。测试是安排一个树形层级:如果一个测试一行在n级成功,所有一下测试在n+1级被完成。如果测试成功信息被打印。直到一行n级出现。更多的复合文件,一个可以使用空信息去获取"if/then"效果。用以下方法:
 

#在开始位置找到MZ
0 string MZ  

>0x18 leshort <0x40 MS-DOS executable 
>0x18 leshort >0x3f extended PC executable (e.g., MS Windows)
(>0x18)(找到了MZ继续则继续向下找,偏移0X18个字节找值小于0x40匹配)
 
偏移量不需要一定是常量,也可以从文件检查中读取。如果第一个字符跟着最后的>是一个括号,那么括号后的字符串是解释为一种间接抵消,那意味着括号后的数字被用作一个在文件中的偏移量,在偏移量处的值被读取,并被用作在文件中的偏移再次被使用。
间接偏移的格式:(( x [.[bislBISL]][+-][ y ]). )
x的值是用于在文件中的偏移量。一个字节,ID3长,short或者long是被读取在那个偏移量根据[bislBISLm] 类型说明,大写的类型解释数字作为一个大端值,反之小写类型解释为一个小端值。m类型解释数字作为中端值(PDP-11),
y的值,这个数字是额外的结果被用于文件中的偏移。如果没有指定默认类型是long。
 
这样可变长度结构可以被检查
# MS Windows executables are also valid MS-DOS executables
0           string  MZ
>0x18       leshort <0x40   MZ executable (MS-DOS)
# skip the whole block below if it is not an extended executable
>0x18       leshort >0x3f
>>(0x3c.l)  string  PE\0\0  PE executable (MS-Windows)
>>(0x3c.l)  string  LX\0\0  LX executable (OS/2)

 (0x3c.l):读取从开始偏移0x3c个字节位置的long长度的值(l的含义)用该值和PE\0\0做字符串的比较,如果相等就匹配

这种检测的方法有一个缺点,你必须确保你最终打印一些东西,或者用户可以获得空的输出(例如:上面的例子中当既不是PE\0\0 也不是LE\0\0)
如果间接的偏移不能被直接使用,简单计算可以是:附加 [+-*/%&|^]number

圆括号内允许一个去修改从文件中读取的值在他被用作一个偏移量之前。

 
# MS Windows executables are also valid MS-DOS executables
0           string  MZ
# sometimes, the value at 0x18 is less that 0x40 but there's still an
# extended executable, simply appended to the file
>0x18       leshort <0x40
>>(4.s*512) leshort 0x014c  COFF executable (MS-DOS, DJGPP)
>>(4.s*512) leshort !0x014c MZ executable (MS-DOS)

 

有时候你不知道前面字段确切的偏移,它取决于长度或者位置(当间接被使用之前)。你可以指定一个相对偏移最后高等级范围的末尾使用&作为一个前缀给偏移量
0           string  MZ
>0x18       leshort >0x3f
>>(0x3c.l)  string  PE\0\0    PE executable (MS-Windows)
# immediately following the PE signature is the CPU type
>>>&0       leshort 0x14c     for Intel 80386
>>>&0       leshort 0x184     for DEC Alpha

 相对位置偏移0字节(&0)

 

间接和直接偏移可以结合使用
0             string  MZ
>0x18         leshort <0x40
>>(4.s*512)   leshort !0x014c MZ executable (MS-DOS)
# if it's not COFF, go back 512 bytes and add the offset taken
# from byte 2/3, which is yet another way of finding the start
# of the extended executable
>>>&(2.s-514) string  LE      LE executable (MS Windows VxD driver)

 

或者其他方法:
0                 string  MZ
>0x18             leshort >0x3f
>>(0x3c.l)        string  LE\0\0  LE executable (MS-Windows)
# at offset 0x80 (-4, since relative offsets start at the end
# of the up-level match) inside the LE header, we find the absolute
# offset to the code area, where we look for a specific signature
>>>(&0x7c.l+0x26) string  UPX     \b, UPX compressed

 

或者甚至两个:
1 0                string  MZ
2 >0x18            leshort >0x3f
3 >>(0x3c.l)       string  LE\0\0 LE executable (MS-Windows)
4 # at offset 0x58 inside the LE header, we find the relative offset
5 # to a data area where we look for a specific signature
6 >>>&(&0x54.l-3)  string  UNACE  \b, ACE self-extracting archive

 

最后如果你不得不解决偏移/长度 组合在你的文件中,甚至第二个值在
括号表达式可以从文件自身,使用括号的另外一些设置。注意那是额外的间接偏移是经常相对主的间接偏移开始
1 0                 string       MZ
2 >0x18             leshort      >0x3f
3 >>(0x3c.l)        string       PE\0\0 PE executable (MS-Windows)
4 # search for the PE section called ".idata"...
5 >>>&0xf4          search/0x140 .idata
6 # ...and go to the end of it, calculated from start+length;
7 # these are located 14 and 10 bytes after the section name
8 >>>>(&0xe.l+(-4)) string       PK\3\4 \b, ZIP self-extracting archive

 

 匹配MP3文件的一个示例:

# MP3, M1A
# modified by Joerg Jenderek
# GRR the original test are too common for many DOS files
# so don't accept as MP3 until we've tested the rate
0       beshort&0xFFFE  0xFFFA
# rates
>2      byte&0xF0       0x10           MPEG ADTS, layer III, v1,  32 kbps
!:mime    audio/mpeg
>2      byte&0xF0       0x20           MPEG ADTS, layer III, v1,  40 kbps
!:mime    audio/mpeg
>2      byte&0xF0       0x30           MPEG ADTS, layer III, v1,  48 kbps
!:mime    audio/mpeg>2      byte&0xF0       0xA0           MPEG ADTS, layer III, v1, 160 kbps
!:mime    audio/mpeg
>2      byte&0xF0       0xB0           MPEG ADTS, layer III, v1, 192 kbps
用开始位置的数值的二进制值&(与)0xFFFE结果如果是0XFFFA就匹配,简化后可以这样
1  beshort&0xFE  0xFA

(>2 byte&0xF0 0x10):偏移2个字节的值&0xF0的值是对应0x10、0x20、0x30。。。任意一个都算匹配

 

转载于:https://www.cnblogs.com/etangyushan/p/4629338.html

<think>好的,我需要帮助用户在Windows上找到一个类似于Linuxfile命令的工具。首先,用户的需求很明确:判断文件类型,而Linuxfile命令通过读取文件的魔数(magic number)或其他特征来识别类型,而不仅仅是依赖扩展名。 我记得Windows自带的工具有可能实现类似功能。首先想到的是命令行工具,比如PowerShell或者CMD中的某些命令。比如,是否有内置的cmdlet或命令可以检测文件类型?可能需要使用Get-Content或类似命令读取文件头,但手动处理会比较麻烦。 然后,想到是否有第三方工具可以在Windows上使用。之前听说过Cygwin和MinGW,它们提供了Linux工具的移植版本。用户可能可以通过安装Cygwin来使用file命令,但这需要安装额外的环境,可能不太方便。 另外,是否有PowerShell的替代方案?比如,编写一个PowerShell脚本,通过读取文件头部的字节来判断类型。例如,检查文件的前几个字节是否符合特定文件类型的签名。这需要用户有一定的脚本编写能力,但可能更灵活。 我还记得有一个工具叫“TrID”,它可以根据文件内容识别类型,并且支持多种文件格式。用户可能需要下载并安装TrID,然后通过命令行使用。另外,还有“File for Windows”项目,这是GNU Win32项目的一部分,可能直接提供file命令的Windows版本。 另外,用户可能希望找到不需要安装额外软件的方法。比如,使用系统自带的certutil命令来获取文件信息,但不确定是否能准确判断文件类型。或者使用PowerShell的MimeType属性,但这可能依赖于文件扩展名而非内容。 需要验证这些方法的可行性。例如,检查File for Windows是否仍然可用,TrID的下载和使用步骤是否简单。同时,比较不同方法的优缺点,比如是否需要安装、准确性如何等。 最后,总结出几种可行的方案,按照推荐程度排序,并给出每种方法的具体步骤和使用示例。确保用户能够根据自身情况选择最适合的方法。</think>### Windows下类似Linux `file`命令的替代方案 在Windows系统中,可以通过以下方法实现类似Linux `file`命令的功能,用于根据文件内容(而非扩展名)判断文件类型: --- #### 1. **使用`file`命令的Windows移植版本** - **GNU Win32的File工具** 这是Linux `file`命令的Windows移植版本,通过读取文件头部字节(魔数)判断类型。 **步骤**: 1. 下载并安装[GNU Win32工具包](https://sourceforge.net/projects/gnuwin32/),选择`file`组件。 2. 安装后,在命令行输入: ```bash file 文件路径 ``` 示例输出: ```bash C:\> file example.png example.png: PNG image data, 800 x 600, 8-bit/color RGBA, non-interlaced ``` **优点**:与Linux行为一致,无需额外脚本。 **缺点**:需手动安装工具包[^3]。 --- #### 2. **使用第三方工具TrID** - **TrID(文件类型识别工具)** 基于文件内容特征库的开源工具,支持超过10,000种文件类型。 **步骤**: 1. 从[TrID官网](http://mark0.net/soft-trid-e.html)下载工具。 2. 使用命令行: ```bash trid 文件路径 ``` 示例输出: ```bash TrID example.png Results: PNG Image (100%) ``` **优点**:轻量级,识别率高。 **缺点**:需定期更新特征库[^3]。 --- #### 3. **PowerShell脚本实现** - **自定义脚本读取文件头部字节** 通过读取文件前几个字节匹配已知类型签名。 **示例脚本**: ```powershell function Get-FileType { param([string]$filePath) $bytes = Get-Content -Path $filePath -Encoding Byte -ReadCount 4 -TotalCount 4 $hex = $bytes | ForEach-Object { $_.ToString("X2") } $signature = $hex -join ' ' switch ($signature) { '89 50 4E 47' { "PNG Image" } 'FF D8 FF E0' { "JPEG Image" } '25 50 44 46' { "PDF Document" } default { "Unknown" } } } ``` 调用方法: ```powershell Get-FileType -filePath "example.png" ``` **优点**:灵活,可自定义类型。 **缺点**:需手动维护签名库,覆盖类型有限。 --- #### 4. **使用Cygwin或WSL** - **通过Cygwin或Windows子系统Linux(WSL)** 在Windows中运行Linux环境直接使用`file`命令。 **步骤**(以WSL为例): 1. 启用WSL并安装Ubuntu等发行版。 2. 在WSL终端执行: ```bash file /mnt/c/路径/文件 ``` **优点**:原生支持`file`命令。 **缺点**:依赖Linux环境,适合开发者[^1]。 --- ### 方案对比 | 方法 | 是否需要安装 | 准确性 | 易用性 | |------------------|--------------|--------|--------| | GNU Win32 File | 是 | 高 | 高 | | TrID | 是 | 高 | 中 | | PowerShell脚本 | 否 | 中 | 低 | | WSL/Cygwin | 是 | 高 | 中 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值