精华内容
下载资源
问答
  • 翻译鼠标悬停的二进制文本 支持语言:English
  •  0x00 Diaphora介绍 Diaphora(διαφορά, 希腊语中的“different”)是一个IDA插件,用来帮助二进制文件对比。他和其他的比较工具很类似,有一个著名的开源工具就叫做Zynamics BinDiff。还有其他的开源...

    本博客由闲散白帽子胖胖鹏鹏胖胖鹏潜力所写,仅仅作为个人技术交流分享,不得用做商业用途。转载请注明出处,未经许可禁止将本博客内所有内容转载、商用。 

    0x00 Diaphora介绍

          Diaphora(διαφορά, 希腊语中的“different”)是一个IDA插件,用来帮助二进制文件对比。他和其他的比较工具很类似,有一个著名的开源工具就叫做Zynamics BinDiff。还有其他的开源工具,比如DarunGrim或者是TurboDiff。但是从实际使用结果上来看,这些Diaphora能够进行更多的操作,并且能够更好地识别效果。Diaphora源码下载。

          这里我们使用Diaphora对库函数文件以及固件进行对比,从而进行库函数的识别工作。其实也不算是识别,只是进行比对。而我们在使用IDA过程中,使用过FLIRT进行函数签名,同时也使用过Bindiff进行二进制对比,但是其效果都不如Diaphora的效果好。所以我们这次以Diaphora为例,分析其进行函数签名及比对的算法,之后再对算法进行改进,获得我们想要的功能。

    0x01 Diaphora文件结构

           各位如果有兴趣看官方文档的话,我还是推荐先看一遍官方的帮助文档。虽然我这里面也会进行一部分的翻译,但是我觉得原汁原味的还是最好的。帮助文档。

    ——Diaphora.py:IDAPython 插件。包含了所有启发,图形显示,输出接口等等
    ——jkutils/kfuzzy.py:这是未经修改的kfuzzy.py库版本,他是DeepToad项目的一部分,该项目主要对二进制文件进行模糊哈希(fuzzy hash)。 因为Diaphora对伪代码进行模糊哈希,所以我们引用了这个文件
    ——jkutils/factor.py:这是经过修改的基于图论的私有恶意软件集群工具(a private malware clusterization toolkit)。这个库提 供了在Python内快速factor数字的功能,并且能够对比素factor的数组。Diaphora使用该工具进行模糊AST哈希对比以及调用流图模糊哈希对比,这两个对比是基于小素数产品的( small-primes-products,BinDiff作者的思想,可以参考论文

    Pygments:此目录包含了未经修改的pygments库,是一个生成高亮代码的小工具,说英语代码保管,论坛,wiki以及其他需要美化源码的场景。

    这其中,我们更关心两个文件Diaphora.py以及factor.py,因为我们其实主要是想了解Diaphora进行函数签名的算法以及对比的算法,这样我们才方便进行迁移,而一些代码美化和结果输出的内容,有兴趣开发IDA插件或者感兴趣的同学可以自行研究~

    0x02 Diaphora的匹配规则

          这里我们只针对Best match进行分析。顾名思义,Best Match是可信度最高的匹配结果,基本上能够达到95%以上的可信度。因为我们在进行二进制分析的时候,需要的是确定正确的匹配结果,如果使用了不可靠的匹配,将导致分析结果的错误。我们舍弃了部分匹配的结果,因此造成了较高的漏报;如果加入了部分匹配结果,将造成误报;从人工分析的角度来看漏漏报造成的影响将小于误报。比如你需要确定malloc函数的位置,进而分析哪个函数调用了malloc函数。而使用best match能够得到1个确定的结果,使用partial match得到了3个可能的结果,但是这3个函数实际上并不是malloc函数,这将增加我们的二进制分析工作,甚至导致分析结果的谬误。因此我们只选择完全匹配的函数。

          好了,我们来看下官方文档怎么说明的。“diaphora首先会为两个二进制文件生成不同的的数据库,并且对比两个数据库中的数据是否相同,甚至是主键值都要相同。如果相同的话,数据库就认为是100%相同,并且不进行多余的比较。”那么我们都需要比较那些键值呢?

    伪代码:IDA生成的伪代码应该相同,它能够匹配x86,x86_64和ARM指令集
    汇编代码:两个函数的汇编必须完全相同
    byte哈希和名字:每条汇编指令的第一个字节要相同,同时对应的真实名字,而不是IDA自动生成的伪指令名,要相同
    相同的地址、节点、边界和内存:数据库中存储的基本块的数量、快的地址、边界的名字和内存都要相同
    RVS和hash:RVA(Relative Virtual Address)相关虚拟地址以及字节哈希都要相同
    相同的顺序和hash:两个函数应该具有相同的hash并且在IDA中的顺序应该相同(比如同为第100个函数)
    函数hash:两个函数的hash相同。hash = MD5(所有指令的字节)
    Byte hash:两个函数的Byte hash应该相同。这个hash是计算了所有指令字节的集合,但是和上面的函数hash不同,他去除了有地址依赖的指令,比如重定位和jump以及relative call。
    Byte 数目:这两个函数的长度(也就是字节数)应该完全相同

          从这些比对的条件来看,diaphora是一个比较严格的二进制文件对比工具,其实用作于补丁对比更合适,并不完全适合于库函数识别,并且大量使用了函数特征、block、反汇编和伪代码的内容,我们如果想要融入Angr还是需要大量的修改的,同时我们也并不是很确定他能兼容的很好。(鹏鹏小声bb:改什么改呀,直接使用IDA进行文件对比,然后根据生成的比对结果,从中抽选出best match,直接导入Angr不是更方便么)(理智的鹏鹏:我们当然可以这样做,但是这将导致自动化分析工具的不完整性)

    0x04 FLIRT 的函数匹配算法介绍

          使用过IDA的同学都知道,IDA自带了一个FLIRT工具,该工具能够自动生成函数的签名。我们既然说他不是很好用,就需要首先了解FLIRT是如何进行函数签名的。一下内容节选自官方文档

          FLIRT的识别原则基于以下几条。FLIRT只考虑C/C++(我们做的固件分析也主要是这两个语言);FLIRT并不试图进行完美的函数识别,因为某些函数完整的识别将导致不可遇见的结果(比如C/C++中两个不同名字的函数具有相同的代码,这种情况很常见);我们只识别代码段的函数(这个可以理解);只识别函数,不管参数和函数行为。(以上几条,我们也都是同意的。)

          同时我们应该遵守以下约束:1.我们应该极力避免误报,理想的情况下误报应该为0(前文我们阐述了);2.识别的函数必须只是用有限的寄存次和内存资源;3.生成的签名必须是无处理器依赖的,能够跨平台使用;4.main函数应该识别出来并且被合理的标注。(注:我们和FLIRT的需求是有一些相关性的,上述两端的要求,我们基本上是同意的,但是我们并不满足于这些要求,我们期望得到更高的准确率和0误报率,我想这也就是FLIRT的局限性;同时,即使是FLIRT采用了避免误报的手段,我们在实际使用中还是会出现很多漏报,当函数比较短时,曾经有过46个函数误识别)。

            FLIRT列出了很多库函数识别时遇到的阻碍。主要有:

            1.很多字节是难以确定的。比如动态加载地址,某些地址是需要动态加载的时候进行重新纠正的,而连接的时候并不能知道。这些地址有external 名字,所以一定程度上缓解了这种情况。优化技术同时还引入了新的问题,就是可能导致常量字节不同。

                   0000: 9A........        call    far ptr xxx
           替换成了
                   0000: 90                nop
                   0001: 0E                push    cs
                   0002: E8....            call    near ptr xxx
            2.某些函数功能相同,但是调用方式不同,比如strcmp和fstrcmp在大内存模型中相同。问题在于,我们在进行识别的时候不想忽略这些函数,但是这对用户很重要,而我们却不能分辨出他们。
    3.另外一个问题
                    call    xxx
                    ret
           或者
                    jmp     xxx
          第一眼没有什么异常,但是问题在于目前标准库中存在着大量这样的代码。直接对比这些函数不会有什么结果,识别出这些函数的唯一方法就是找到他们调用的函数。通常来说,所有的端函数(2-3行指令)很难识别,并且误识别率很高。然而不识别他们也不行,可能会导致雪崩式错误:你没有识别出这个函数,调用他的函数你也识别不了。
           IDA的解决方案:
          IDA为我们行识别的函数库中的所有函数创建了一个数据库。IDA检查每个程序开头的byte是否被反汇编了,以及是否能够作为标准库函数的开始标志。识别算法所需要的信息都写在了一个 signature(签名)文件中,每个函数书都以pattern的形式表示。pattern是一个函数的前32字节,并且所有的变量字节都被标记出来。
          558BEC0EFF7604..........59595DC3558BEC0EFF7604..........59595DC3 _registerbgidriver
          558BEC1E078A66048A460E8B5E108B4E0AD1E9D1E980E1C0024E0C8A6E0A8A76 _biosdisk
          558BEC1EB41AC55604CD211F5DC3.................................... _setdta
          558BEC1EB42FCD210653B41A8B5606CD21B44E8B4E088B5604CD219C5993B41A _findfirst
          在pattern中,"."表示的是变量byte。一些函数的起始字节队列是相通的。因此,树形结构似乎特别适合于这些函数的存储。上面的paatern可以修改为:
    558BEC
          0EFF7604..........59595DC3558BEC0EFF7604..........59595DC3 _registerbgidriver
          1E
            078A66048A460E8B5E108B4E0AD1E9D1E980E1C0024E0C8A6E0A8A76 _biosdisk
          B4
            1AC55604CD211F5DC3                                       _setdta
            2FCD210653B41A8B5606CD21B44E8B4E088B5604CD219C5993B41A   _findfirst
          树中的节点就是byte队列。在此例中,树的根节点包含队列"558BEC",并且派生出三个字数,分别以"0E","1E","B4"开头。以B4开头的子树又派生出了两个子树。每个子树都以叶子节点结束。函数名字就保存在叶子节点中(上述例子中尽有函数名可见)
    树形数据结构主要完成了两个目标:
           1.我们在树种存储了多个函数共有的几个byte,因此了内存使用。当然这种接生的效果和函数数量成正比。
           2.他非常适合快速模式匹配。如果是将某个函数与函数库中所有函数进行匹配,进行匹配的次数将随着特征文件中的函数数量成对数增长。O(n)=log(n)
          那么根据函数的前32byte进行匹配就是一件明智的事情了。正如前文所述,二进制库中有很多函数的开头几个byte是相同的:
    558BEC
          56
            1E
              B8....8ED8
                       33C050FF7608FF7606..........83C406
                                                          8BF083FEFF
                        0. _chmod   (20 5F33)
                        1. _access  (18 9A62)
          但是当两个函数有超过32字节向同师,我们将这两个叶子都存储下来。为了解决这个问题,我们计算33字节到第一个变量字节的CRC16值。CRC存储在签名文件中。进行CRC签名的bytre同样需要存储,因为它随着函数不同而不同。在上面例子中,CRC16是对——chmod函数的从33到52这20个字节进行计算的,对于_access函数计算18个字节。
          当然,第一个变量字节在33字节处也是有可能的,用于计算CRC16的字节长度为0.实际上这很少发生,而且这种算法给出误识别的概率非常低。
          有时候,函数的前32字节的pattern是相同的,CRC16也是相同的。比如下面的例子。
          05B8FFFFEB278A4606B4008BD8B8....8EC0
                    0. _tolower (03 41CB) (000C:00)
                    1. _toupper (03 41CB) (000C:FF)
          我们这里只使用3个字节计算CRC16,他在两个函数中是一样的。在这种情况下,我们将尝试找到一个位置,其中叶子中的所有函数有不同字节。在这个例子中,是32+3+000c
    但即使这样,我们仍不能识别出所有的函数,比如:
    ... (partial tree is shown here)
                    0D8A049850E8....83C402880446803C0075EE8BC7:
                      0. _strupr (04 D19F) (REF 0011: _toupper)
                      1. _strlwr (04 D19F) (REF 0011: _tolower)
          这两个函数在没有变量字节的情况下是相同的,而是根据调用他们的函数而产生了不同。在这个例子红,唯一的办法就是识别出在偏移11处使用他们的函数的名称。这个算法的缺点是,识别_strupr()和_strlwr依赖于识别出__toupper和_tolower,而在后者未识别之前,我们就要推迟识别;这就需要二次识别,但是好在只有几个函数需要二次识别。
    最后我们还会遇到两个函数名字不同,但是代码相同的情况。这种情况在C++代码中很常见,我们将这种情况成为“碰撞”。看来只有人工智能能够解决此问题,FLIRT还在等待后续开发。
        总结:FLIRT进行函数识别算法如下。
           1.采用树形结构存储函数的前32字节,并且识别函数时进行逐一比对;
       2.当32字节出现冲突时,使用CRC16对从第33字节开始到第一个变量字节处的byte串进行计算;
       3.让CRC16相同时,尝试寻找一个每个函数的byte都不相同的位置;
       4.当函数字节完全相同,只有调用者不同时,先记录下来,随后进行二次检查;

       5.当代码相同名字不同时,等待人工智能的应用。

       总之FLIRT还是很智能的,进行库函数识别的也很好,但是我想Diaphora应该做的不会比FLIRT差,我们先分析下算法在进行讨论。

    展开全文
  • 二进制转换工具plus

    2018-11-30 16:03:42
    对之前二进制工具的升级版本,能识别32位的数据,基本功能应该全了,压缩包里面包含源码,如果想扩展功能可以私信我
  • 二进制

    2017-11-14 09:58:00
    二进制 编辑 本词条由“科普中国”百科科学词条编写与应用工作项目审核 。 二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则...

    二进制

      编辑
    二进制是计算技术中广泛采用的一种 数制二进制数据是用0和1两个 数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师 莱布尼兹发现。当前的 计算机系统使用的基本上是 二进制系统,数据在 计算机中主要是以补码的形式存储的。计算机中的二进制则是一个非常微小的开关,用“开”来表示1,“关”来表示0。
    20世纪被称作 第三次科技革命的重要标志之一的 计算机的发明与应用,因为数字计算机只能 识别处理由‘0’.‘1’符号串组成的 代码。其运算模式正是二进制。19世纪爱尔兰逻辑学家乔治布尔对逻辑命题的思考过程转化为对符号"0''.''1''的某种代数演算,二进制是逢2进位的进位制。0、1是基本 算符。因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。
     
    中文名
    二进制
    外文名
    binary system
    类    别
    算法
    属    性
    数学

    表示法

    二进制数据的表示法
    二进制数据也是采用位置 计数法,其 位权是以2为底的 。例如二进制数据110.11,逢2进1,其权的大小顺序为2²、2¹、2º、
     
       
    。对于有n位 整数,m位 小数的二进制数据用加权系数展开式表示,可写为:
    二进制数据一般可写为:
     
    【例1102】将二进制数据111.01写成加权 系数的形式。
    解:
     
    二进制和 十六进制八进制一样,都以二的 来进位的。

    运算

    加法

    有四种情况: 0+0=0
    0+1=1
    1+0=1
    1+1=10
    0 进位为1
    【例1103】求 1011(2)+11(2) 的和
    解:
    1011+11 1011+11

    乘法

    有四种情况: 0×0=0
    1×0=0
    0×1=0
    1×1=1

    减法

    0-0=0,1-0=1,1-1=0,0-1=1。

    除法

    0÷1=0,1÷1=1。

    拈加法

    拈加法二进制是加减乘除外的一种特殊算法。
    拈加法运算与进行加法类似,但不需要做进位。此算法在 博弈论(Game Theory)中被广泛利用
    计算机中的十进制小数转换二进制
    计算机中的十进制小数用二进制通常是用乘二取整法来获得的。
    比如0.65换算成二进制就是:
    0.65 × 2 = 1.3 取1,留下0.3继续乘二取整
    0.3 × 2 = 0.6 取0, 留下0.6继续乘二取整
    0.6 × 2 = 1.2 取1,留下0.2继续乘二取整
    0.2 × 2 = 0.4 取0, 留下0.4继续乘二取整
    0.4 × 2 = 0.8 取0, 留下0.8继续乘二取整
    0.8 × 2 = 1.6 取1, 留下0.6继续乘二取整
    0.6 × 2 = 1.2 取1,留下0.2继续乘二取整
    .......
    一直循环,直到达到精度限制才停止(所以,计算机保存的小数一般会有误差,所以在编程中,要想比较两个小数是否相等,只能比较某个精度范围内是否相等。)。这时,十进制的0.65,用二进制就可以表示为:01010011。
    还值得一提的是,在计算机中,除了十进制是有符号的外,其他如二进制、八进制、16进制都是无符号的。
    在现实生活和记数器中,如果表示数的“器件”只有两种状态,如电灯的“亮”与“灭”,开关的“开”与“关”。一种状态表示数码0,另一种状态表示数码1,1加1应该等于2,因为没有数码2,只能向上一个数位进一,就是采用“满二进一”的原则,这和十进制是采用“满十进一”原则完全相同。
    1+1=10,10+1=11,11+1=100,100+1=101,
    101+1=110,110+1=111,111+1=1000,……,
    可见二进制的10表示二,100表示四,1000表示八,10000表示十六,……。
    二进制同样是“位值制”。同一个数码1,在不同数位上表示的数值是不同的。如11111,从右往左数,第一位的1就是一,第二位的1表示二,第三位的1表示四,第四位的1表示八,第五位的1表示十六。
    所谓二进制,也就是计算机运算时用的一种算法。二进制只由一和零组成。
    比方说吧,你上一年级时一定听说过“进位筒”(“数位筒”)吧!十进制是个位上满十根小棒就捆成一捆,放进十位筒,十位筒满十捆就捆成一大捆,放进百位筒……
    二进制也是一样的道理,个位筒上满2根就向十位进一,十位上满两根就向百位进一,百位上满两根…… 二进制是世界上第一台计算机上用的算法,最古老的计算机里有一个个灯泡,当运算的时候,比如要表达“一”,第一个灯泡会亮起来。要表达“二”,则第一个灯泡熄灭,第二个灯泡就会亮起来。
    二进制就是等于2时就要进位。
    0=00000000
    1=00000001
    2=00000010
    3=00000011
    4=00000100
    5=00000101
    6=00000110
    7=00000111
    8=00001000
    9=00001001
    10=00001010
    ……
    即是逢二进一,二进制广泛用于最基础的运算方式,计算机的运行计算基础就是基于二进制来运行。只是用二进制执行运算,用其他进制表现出来。
    其实把二进制三位一组分开就是 八进制, 四位一组就是 十六进制

    进制转换

    十进制数转换为二进制数、 八进制数十六进制数的方法:
    二进制数、 八进制数十六进制数转换为十进制数的方法:按权展开求和法

    与十进制

    (1)二进制转十进制
    方法:“按权展开求和”
    【例】:
     
    规律:个位上的数字的次数是0,十位上的数字的次数是1,......,依次递增,而十
    分位的数字的次数是-1,百分位上数字的次数是-2,......,依次递减。
    注意:不是任何一个十进制小数都能转换成有限位的二进制数。
    · 十进制整数转二进制数:“除以2取余,逆序排列”(除二取 余法
    【例】:
     
    89÷2 ……1
    44÷2 ……0
    22÷2 ……0
    11÷2 ……1
    5÷2 ……1
    2÷2 ……0
    1
    ·  十进制小数转二进制数:“乘以2取整,顺序排列”(乘2取整法)
    【例】: (0.625)10= (0.101)2
    0.625X2=1.25 ……1
    0.25 X2=0.50 ……0
    0.50 X2=1.00 ……1
    十进制1至128的二进制表示:
    0=0
    1=1
    2=10
    3=11
    4=100
    5=101
    6=110
    7=111
    8=1000
    9=1001
    10=1010
    11=1011
    12=1100
    13=1101
    14=1110
    15=1111
    16=10000
    17=10001
    18=10010
    19=10011
    20=10100
    21=10101
    22=10110
    23=10111
    24=11000
    25=11001
    26=11010
    27=11011
    28=11100
    29=11101
    30=11110
    31=11111
    32=100000
    33=100001
    34=100010
    35=100011
    36=100100
    37=100101
    38=100110
    39=100111
    40=101000
    41=101001
    42=101010
    43=101011
    44=101100
    45=101101
    46=101110
    47=101111
    48=110000
    49=110001
    50=110010
    51=110011
    52=110100
    53=110101
    54=110110
    55=110111
    56=111000
    57=111001
    58=111010
    59=111011
    60=111100
    61=111101
    62=111110
    63=111111
    64=1000000
    65=1000001
    66=1000010
    67=1000011
    68=1000100
    69=1000101
    70=1000110
    71=1000111
    72=1001000
    73=1001001
    74=1001010
    75=1001011
    76=1001100
    77=1001101
    78=1001110
    79=1001111
    80=1010000
    81=1010001
    82=1010010
    83=1010011
    84=1010100
    85=1010101
    86=1010110
    87=1010111
    88=1011000
    89=1011001
    90=1011010
    91=1011011
    92=1011100
    93=1011101
    94=1011110
    95=1011111
    96=1100000
    97=1100001
    98=1100010
    99=1100011
    100=1100100
    101=1100101
    102=1100110
    103=1100111
    104=1101000
    105=1101001
    106=1101010
    107=1101011
    108=1101100
    109=1101101
    110=1101110
    111=1101111
    112=1110000
    113=1110001
    114=1110010
    115=1110011
    116=1110100
    117=1110101
    118=1110110
    119=1110111
    120=1111000
    121=1111001
    122=1111010
    123=1111011
    124=1111100
    125=1111101
    126=1111110
    127=1111111
    128=10000000

    与八进制

    二进制数转换成八进制数:从小数点开始, 整数部分向左、小数部分向右,每3位为一组用一位八进制数的数字表示,不足3位的要用“0”补足3位,就得到一个八进制数。
    八进制数转换成二进制数:把每一个八进制数转换成3位的二进制数,就得到一个二进制数。
    八进制数字与十进制数字对应关系如下:
    000 -> 0 | 004-> 4 | 010=8
    001 -> 1 |005 -> 5| 011=9
    002 -> 2 |006 -> 6 | 012=10
    003 -> 3 |007 -> 7 | 013=11
    【例】:将八进制的37.416转换成二进制数:
    3 7 . 4 1 6
    011 111 .100 001 110
    即:(37.416)8 =(11111.10000111)2
    【例】:将 二进制的10110.0011 转换成八进制:
    0 1 0 1 1 0 . 0 0 1 1 0 0
    2 6 . 1 4
    即:(10110.0011)2 = (26.14)8

    与十六进制

    二进制数转换成十六进制数:二进制数转换成十六进制数时,只要从小数点位置开始,向左或向右每四位二进制划分一组(不足四位数可补0),然后写出每一组二进制数所对应的十六进制数码即可。
    十六进制数转换成二进制数:把每一个十六进制数转换成4位的二进制数,就得到一个二进制数。
    十六进制数字与二进制数字的对应关系如下:
    0000 -> 0 0100 -> 4 1000 -> 8 1100 -> C
    0001 -> 1 0101 -> 5 1001 -> 9 1101 -> D
    0010 -> 2 0110 -> 6 1010 -> A 1110 -> E
    0011 -> 3 0111 -> 7 1011 -> B 1111 -> F
    【例】:将十六进制数5DF.9 转换成二进制:
    5 D F . 9
    0101 1101 1111 .1001
    即:(5DF.9)16 =(10111011111.1001)2{十六进制怎么会有小数点}
    【例】:将二进制数1100001.111 转换成十六进制:
    0110 0001 . 1110
    6 1 . E
    即:(1100001.111)2 =(61.E)16
    与十进制的区别
    二进制与十进制的区别在于数码的个数和进位规律有很大的区别,顾名思义,二进制的计数规律为逢二进一,是以2为基数的计数体制。10这个数在二进制和十进制中所表示的意义完全不同,在十进制中就是我们通常所说的十,在二进制中,其中的一个意义可能是表示一个大小等价于十进制数2的数值。
    仿照例题1.3.1,我们可以将二进制数10表示为:10=1×2^1+0×2^0
    十进制与二进制的关系 十进制与二进制的关系
    一般地,任意二进制数可表示为:
    例题 1.3.2 试将二进制数(01010110)B转换为十进制数。
    解:将每一位二进制数乘以位权后相加便得相应的十进制数
    在数字电子技术和计算机应用中,二值数据常用数字波形来表示
    。使用数字波形可以使得数据比较直观,也便于使用电子示波器进行监视。图1.3.3表示一计数器的波形。
    图1.3.3 用二进制数表示0~15波形图
    图中给出了四个二进制波形。看这种二进制波形图时,我们应当沿着图中虚线所示的方向来看,即使图中没有标出虚线(一般都没有标出),也要想象出虚线来。其中在每一个波形上方的数字表示了与波形对应的位的数值,最后一行则是相应的十进制数 ,其中LSB是英文Least Significant Bit的缩写,表示最低位,MSB是Most Significant Bit的缩写,表示二进制数的最高位。显然,这是一组4位的二进制数,总共有16组,最左边的二进制数为0000,最上边的波形代表二进制数的最低位,也就是通常在十进制数中我们所说的个位数,最下面的是最高位。图中最右边的二进制数为1111,对应的十进制数为15。再来看看对应于十进制数5的二进制数是多少呢?是0101,对了,读数的顺序是从下往上。
    二进制数在数字系统(比如计算机之间)中的传输的方式分为串行和并行两种。
    其中串行传输时二进制数是按照逐位传递的方式进行传输,根据实际情况可以从最高位或最低位开始传输,一般情况下是从最高位开始传输的。只需要一根数据线。如图1.3.4所示,要完成八位二进制数的传输,需要经历八个时钟周期。
    图1.3.4 二进制数据的串行传输
    (a) 两台计算机之间的串行通信 (b) 二进制数据的串行表示
    典型的例子是调制解调器与计算机之间的通信就是通过串行传输来完成的。
    并行传输的效率要高于串行传输,一次可以传输完整的一组二进制数。但是根据所要传输的二进制数的位数的多少,需要备足足够多的数据线。一般来说,常见的并行传输采用的数据线有8、16、32等,再多就很少见了。典型的并行传输例子是打印机与计算机之间的通信传输,见图1.3.5。
    图1.3.5 并行传输数据的示意图
    (a) 计算机与打印机之间的并行通信 (b) 二进制数据的并行表示
    图1.3.5显示了采用并行传输模式,只需要一个时钟周期,即可完成八位二进制数的传输。

    莱布尼茨

    在德国图灵根著名的 郭塔王宫图书馆(Schlossbiliothke zu Gotha)保存着
    用ftp工具以二进制方式上传 用ftp工具以二进制方式上传
    一份弥足珍贵的手稿,其标题为:“1与0,一切数字的神奇渊源。这是造物的秘密美妙的典范,因为,一切无非都来自上帝。”这是德国天才大师 莱布尼茨(Gottfried Wilhelm Leibniz,1646 - 1716)的手迹。但是,关于这个神奇美妙的 数字系统,莱布尼茨只有几页异常精炼的描述。
    莱布尼茨不仅发明了二进制,而且赋予了它宗教的内涵。他在写给当时在中国传教的法国耶稣士会牧师布维(Joachim Bouvet,1662 - 1732)的信中说:“第一天的伊始是1,也就是上帝。第二天的伊始是2,……到了第七天,一切都有了。所以,这最后的一天也是最完美的。因为,此时世间的一切都已经被创造出来了。因此它被写作‘7’,也就是‘111’(二进制中的111等于十进制的7),而且不包含0。只有当我们仅仅用0和1来表达这个数字时,才能理解,为什么第七天才最完美,为什么7是神圣的数字。特别值得注意的是它(第七天)的特征(写作二进制的111)与三位一体的关联。”
    布维是一位汉学大师,他对中国的介绍是17、18世纪欧洲学界中国热最重要的原因之一。布维是莱布尼茨的好朋友,一直与他保持着频繁的书信往来。莱布尼茨曾将很多布维的文章翻译成德文,发表刊行。恰恰是布维向莱布尼茨介绍了《 周易》和 八卦的系统,并说明了《周易》在中国文化中的权威地位。
    八卦是由八个符号组构成的 占卜系统,而这些符号分为连续的与间断的横线两种。这两个后来被称为“阴”、“阳”的符号,在莱布尼茨眼中,就是他的二进制的中国翻版,但实际莱布尼茨是受中国阴阳太极影响,只不过他付出了诸多研究,推演出二进制。他感到这个来自古老中国文化的 符号系统与他的二进制之间的关系实在太明显了,因此断言:二进制乃是具有世界普遍性的、最完美的逻辑语言。
    另一个可能引起莱布尼茨对八卦的兴趣的人是坦泽尔(Wilhelm Ernst Tentzel),他当时是图灵根大公爵硬币珍藏室的领导,也是莱布尼茨的好友之一。在他主管的这个硬币珍藏中有一枚印有八卦符号的硬币。
    与中国易经联系
    1679年3月15日 戈特弗里德·威廉·莱布尼茨发明了一种计算法,用两位数代替原来的十位数,即
    1 和 0。 1701年他写信给在北京的神父 Grimaldi(中文名字闵明我)和 Bouvet(中文名字 白晋)告知自己的新发明,希望能引起他心目中的“算术爱好者”康熙皇帝的兴趣。
    白晋很惊讶,因为他发现这种“二进制的算术”与中国古代的一种建立在两个符号基础上的符号系统是非常近似的,这两个符号分别由一条直线和两条短线组成,即── 和 — —。这是中国最著名大概也是最古老的书《易经》的基本组成部分,据今人推测,该书大约产生于公元前第一个千年的初期,开始主要是一部占卜用书,里边的两个符号可能分别代表“是”和“不”。莱布尼茨对这个相似也很吃惊,和他的笔友白晋一样,他也深信《 易经》在 数学上的意义。他相信古代的中国人已经掌握了二进制并在科学方面远远超过当代的中国人。
    这一次将数学与 古代中国《易经》相联的尝试是不符合实际的。莱布尼茨的二进制数学指向的不是古代中国,而是未来。莱布尼茨在1679年3月15日记录下他的二进制体系的同时,还设计了一台可以完成数码计算的机器。我们今天的现代科技将此设想变为现实,这在莱布尼茨的时代是超乎人的想象能力的。

    特点

    优点

    数字装置简单可靠,所用元件少;
    只有两个 数码0和1,因此它的每一位数都可用任何具有两个不同稳定状态的元件来表示;
    基本运算规则简单,运算操作方便。

    缺点

    用二进制表示一个数时,位数多。因此实际使用中多采用送入数字系统前用十进制,送入机器后再转换成二进制数,让数字系统进行运算,运算结束后再将 二进制转换为十进制供人们阅读。
    二进制和十六进制的互相转换比较重要。不过这二者的转换却不用计算,每个C, C++ 程序员都能做到看见二进制数,直接就能转换为十六进制数,反之亦然。
    我们也一样,只要学完这一小节,就能做到。
    首先我们来看一个二进制数:1111,它是多少呢?
    你可能还要这样计算:1 × 2º + 1 × 2¹ + 1 × 2² + 1 × 2³ = 1 × 1 + 1 × 2 + 1 × 4 + 1 × 8 = 15。
    然而,由于1111才4位,所以我们必须直接记住它每一位的权值,并且是从高位往低位记,:8、4、2、1。即,最高位的权值为2³ = 8,然后依次是 2² = 4,2¹=2, 2º = 1。
    记住8421,对于任意一个4位的二进制数,我们都可以很快算出它对应的10进制值。
    下面列出四位二进制数 xxxx 所有可能的值(中间略过部分)
    仅4位的 2进制数快速计算方法 十进制值 十六进值
    1111 = 8 + 4 + 2 + 1 = 15 F
    1110 = 8 + 4 + 2 + 0 = 14 E
    1101 = 8 + 4 + 0 + 1 = 13 D
    1100 = 8 + 4 + 0 + 0 = 12 C
    1011 = 8 + 0 + 2+ 1 = 11 B
    1010 = 8 + 0 + 2 + 0 = 10 A
    1001 = 8 + 0 + 0 + 1 = 9
    ....
    0001 = 0 + 0 + 0 + 1 = 1
    0000 = 0 + 0 + 0 + 0 = 0 0
    二进制数要转换为十六进制,就是以4位一段,分别转换为十六进制。
    如(上行为二制数,下面为对应的十六进制):
    1111 1101 , 1010 0101 , 1001 1011
    F D , A 5 , 9 B
    反过来,当我们看到 FD时,如何迅速将它转换为二进制数呢?
    先转换F:
    看到F,我们需知道它是15(可能你还不熟悉A~F这六个数),然后15如何用8421凑呢?应该是8 + 4 + 2 + 1,所以四位全为1 :1111。
    接着转换 D:
    看到D,知道它是13,13如何用8421凑呢?应该是:8 + 4 + 1,即:1101。
    所以,FD转换为二进制数,为: 1111 1101
    由于 十六进制转换成二进制相当直接,所以,我们需要将一个十进制数转换成2进制数时,也可以先转换成 16进制,然后再转换成2进制。
    比如,十进制数 1234转换成二制数,如果要一直除以2,直接得到2进制数,需要计算较多次数。所以我们可以先除以16,得到16进制数:
    被除数 计算过程 商 余数
    1234 1234/16 77 2
    77 77/16 4 13 (D)
    4 4/16 0 4
    结果16进制为: 0x4D2
    同样,如果一个二进制数很长,我们需要将它转换成10进制数时,除了前面学过的方法是,我们还可以先将这个二进制转换成16进制,然后再转换为10进制。

    采用原因

    (1)技术实现简单,计算机是由 逻辑电路组成,逻辑电路通常只有两个状态,开关的接通与断开,这两种状态正好可以用“1”和“0”表示。
    (2)简化运算规则:两个二进制数和、积运算组合各有三种,运算规则简单,有利于简化计算机内部结构,提高 运算速度
    (3)适合 逻辑运算:逻辑代数是逻辑运算的理论依据,二进制只有两个数码,正好与逻辑代数中的“真”和“假”相吻合。
    (4)易于进行转换,二进制与十进制数易于互相转换。
    (5)用二进制表示数据具有抗干扰能力强,可靠性高等优点。因为每位数据只有高低两个状态,当受到一定程度的干扰时,仍能可靠地分辨出它是高还是低。

    澄清关系

    二进制是一种非常古老的进位制,由于在 现代被用于电子计算机中,而旧貌换新 颜变 得身价倍增起来。或许是出于证明我国古代人的伟大智慧这样的好心吧 ,许多人从我国伟大而神秘 的《周易》中发现了二进制。当有人发现 莱布尼兹曾将二进制与中国《周易》联系在一起时, 就自认为找到了一个更为有力的证据。于是,一个 神话就被泡制出来了。其大意是:莱布尼 兹通过在中国的传教士,得到了八卦图,他领悟到只要把八卦中的阴爻代表0,阳爻代表1, 就可以创立一种新的记数法:二进制。这一神话虽然已经被部分数学史家进行了 批驳,但至今仍广为传播。因而,我们有必要更详尽地对莱布尼兹、二进制与《周易》三者的关系做一澄清、说明 的工作。[1]  
    改革开放前,大多数中国人不知道计算机是什么东西。1980年,美国人第一台8086CPU芯片个人计算机(PC,俗称电脑)上市,80年代初,中国出现了进口电脑。一台苹果机,价格近两万元,是普通干部工人工资的数百倍,个人根本没有能力购买。90年代以后中国有了互联网,电脑才逐步为中国人所熟悉。

    处理数据

    我们在使用数据库时,有时会用到图像或其它一些二进制数据,这个时候你们就必须使用
    二进制循环编码盘 二进制循环编码盘
    getchunk这个方法来从表中获得二进制大对象,我们也可以使用AppendChunk来把数据插入到表中.
    我们平时来取数据是这样用的!
    Getdata=rs("fieldname")
    而取二进制就得这样
    size=rs("fieldname").acturalsize
    getdata=rs("fieldname").getchunk(size)
    我们从上面看到,我们取二进制数据必须先得到它的大小,然后再搞定它,这个好像是ASP中处理二进制数据的常用方法,我们在获取从 客户端传来的所有数据时,也是用的这种方法。
    下面我们也来看看是怎样将二进制数据加入数据库
    rs("fieldname").appendchunk binarydata
    一步搞定!
    另外,使用getchunk和appendchunk将数据一步一步的取出来!
    下面演示一个取数据的例子!
    Addsize=2
    totalsize=rs("fieldname").acturalsize
    offsize=0
    Do Where offsize Binarydata=rs("fieldname").getchunk(offsize)
    data=data&Binarydata
    offsize=offsize+addsize
    Loop
    当这个程序运行完毕时,data就是我们取出的数据.

    换算

    从小数点开始3位(不足3位补0)二进制数得到1位八进制数
    (用B代表二进制,用O代表八进制):000B=0O、001B=1O、010B=2O、011B=3O、100B=4O、101B=5O、110B=6O。
    二进制与十进制的“1248"换算法:例
    十进制168421
    二进制10101
    即16+4+1=21
    简单来说,就是把二进制数代入表格内,十进制数不变,只要把有十进制中对应1的数加起来就可以得出结果。
     
     

    转载于:https://www.cnblogs.com/wangyiwei/p/7831036.html

    展开全文
  • 二进制编译器

    2016-02-25 19:48:47
    英文,我也不知怎么翻译,不过很好用哦
  • Linux 二进制分析

    千次阅读 2018-11-06 11:55:21
    二进制分析属于信息安全业界逆向工程中的一种技术,通过利用可执行的机器代码(二进制)来分析应用程序的控制结构和运行方式,有助于信息安全从业人员更好地分析各种漏洞、病毒以及恶意软件,从而找到相应的解决方案...

    内容简介

    二进制分析属于信息安全业界逆向工程中的一种技术,通过利用可执行的机器代码(二进制)来分析应用程序的控制结构和运行方式,有助于信息安全从业人员更好地分析各种漏洞、病毒以及恶意软件,从而找到相应的解决方案。本书将带领读者探索连一些专家都未曾接触的领域,正式进入计算机黑客世界。

    本书是一本剖析 Linux ELF 工作机制的图书,共分为9章,其内容涵盖了 Linux 环境和相关工具、ELF 二进制格式、Linux 进程追踪、ELF 病毒技术、Linux 二进制保护、Linux 中的 ELF 二进制取证分析、进程内存取证分析、扩展核心文件快照技术、Linux/proc/kcore 分析等。

    如果你是一名软件工程师或者逆向工程师,想要学习 Linux 二进制分析相关的内容,本书实为明智之选。本书提供了在安全、取证和杀毒领域中实施二进制分析的解决方案。本书也适合安全爱好者和系统工程师阅读。为了更好地理解本书内容,读者需要具备一定的 C 语言编程基础和 Linux 命令行知识

    作者简介

    Ryan O'Neill(ELF 大师)是一名计算机安全研究员兼软件工程师,具有逆向工程、软件开发、安全防御和取证分析技术方面的背景。他是在计算机黑客亚文化的世界中成长起来的——那个由 EFnet、BBS 系统以及系统可执行栈上的远程缓冲区溢出组成的世界。他在年轻时接触了系统安全、开发和病毒编写等领域。他对计算机黑客的极大热情如今已经演变成了对软件开发和专业安全研究的热爱。Ryan 在 DEFCON 和 RuxCon 等很多计算机安全会议上发表过演讲,还举办了一个为期两天的 ELF 二进制黑客研讨会。

    他的职业生涯非常成功,曾任职于 Pikewerks、Leviathan 安全集团这样的大公司,近在 Backtrace 担任软件工程师。

    Ryan 还未出版过其他图书,不过他在 Phrack 和 VXHeaven 这样的在线期刊上发表的论文让他声名远扬。还有许多其他的作品可以从他的网站上找到。

    本书内容

    译者序

    译者棣琦(本名张萌萌),曾梦想成为一名高级口译,却阴差阳错成了一个爱写代码的程序员。在 IT 江湖升级打怪的过程中,为了不断提高自己的技能,看书是少不了的;而要想成为高级玩家,看英文书自然也是必须。一个很偶然的机会,我接触到了本书的英文版。第一遍翻看时略显吃力,毕竟书中讲述的许多概念都是作者的原创,网上几无相关资料。但是这些稀缺的内容对于深入理解二进制分析却非常重要,译者由此尝到了知识的甜头。本着“独乐乐不如众乐乐”和“知识分享”的目的,本书的翻译之路就这样顺理成章地开始了。

    要想成为一名真正的黑客,不仅要会编写程序,还需要解析程序,对已有的二进制文件进行反编译,洞悉程序的工作原理。而本书完全是作者多年来在逆向工程领域的实战经验总结,其内容从 Linux 二进制格式的简单介绍到二进制逆向的细节,不一而足。书中还穿插了作者自己维护的许多项目或软件代码示例。相信通过本书的学习,读者完全可以掌握 Linux 二进制分析相关的一套完整的知识体系,为成长为一名高水平的黑客打下坚实的基础。考虑到本书并非针对零基础的读者编写,因此建议读者能够有一定的 C 语言和 Linux 基础,以便更好地理解领会书中精华。另外,任何 IT 技术的学习掌握,都离不开动手操作。读者要想叩开 Linux 二进制世界的大门,需要亲自动手实践书中示例,才能将书本知识转换为自身技能。

    最后,不能免俗的是各种致谢(虽然俗,但诚意百分百)。感谢我的父母对我闯荡江湖的支持,感谢 Linux 中国创始人王兴宇的信赖,感谢语音识别领域的技术大牛姚光超提出的宝贵建议,感谢我的朋友 Ray 对我的鼓励。当然,更要感谢各位读者的支持。

    最后的最后,由于译者水平有限,外加本书作者在表达上多有晦涩之处,因此译文难免有纰漏,还望广大读者以及业内同行批评指正。

    2017年9月

    北京

    关于作者

    Ryan O'Neill 是一名计算机安全研究员兼软件工程师,具有逆向工程、软件开发、安全防御和取证分析技术方面的背景。他是在计算机黑客亚文化的世界中成长起来的——那个由 EFnet、BBS 系统以及系统可执行栈上的远程缓冲区溢出组成的世界。他在年轻时就接触了系统安全、开发和病毒编写等领域。他对计算机黑客的极大热情如今已经演变成了对软件开发和专业安全研究的热爱。Ryan 在 DEFCON 和 RuxCon 等很多计算机安全会议上发表过演讲,还举办了一个为期两天的 ELF 二进制黑客研讨会。

    他的职业生涯非常成功,曾就职于 Pikewerks、Leviathan 安全集团这样的大公司,最近在 Backtrace 担任软件工程师。

    Ryan 还未出版过其他图书,不过他在 PhrackVXHeaven 这样的在线期刊上发表的论文让他声名远扬。还有许多其他的作品可以从他的网站(http://www.bitlackeys.org)上找到。

    致谢

    首先,要向我的母亲 Michelle 致以真诚的感谢,我已经将对她的感谢表达在这本书里了。这一切都是从母亲为我买的第一台计算机开始的,随后是大量的图书,从 UNIX 编程,到内核内部原理,再到网络安全。在我生命中的某一刻,我以为会永远放弃计算机,但是大约过了5年之后,当我想要重新点燃激情时,却发现已经把书扔掉了。随后我发现母亲偷偷地把那些书帮我保存了起来,一直到我重新需要的那一天。感谢我的母亲,你是最美的,我爱你。

    还要感谢我生命中最重要的一个女人,她是我的另一半,是我的孩子的母亲。毫无疑问,如果没有她,就不会有我今天生活和事业上的成就。人们常说,每一个成功男人的背后都有一个伟大的女人。这句古老的格言道出的的确是真理。感谢 Marilyn 给我带来了极大的喜悦,并进入了我的生活。我爱你。

    我的父亲 Brian O'Neill 在我生活中给了我巨大的鼓舞,教会了我为人夫、为人父和为人友的许多东西。我爱我的父亲,我会一直珍惜我们之间哲学和精神层面的交流。

    感谢 Michael 和 Jade,感谢你们如此独特和美好的灵魂。我爱你们。

    最后,要感谢我的3个孩子:Mick、Jayden 和 Jolene。也许有一天你们会读到这本书,知道你们的父亲对计算机略知一二。我会永远把你们放在生活的首位。你们3个是令我惊奇的存在,为我的生活带来了更深刻的意义和爱。

    Silvio Cesare 在计算机安全领域是一个传奇的名字,因为他在许多领域都有高度创新和突破性的研究,从 ELF 病毒,到内核漏洞分析方面的突破。非常感谢 Silvio 的指导和友谊。我从你那里学到的东西要远远多于从我们行业其他人处所学的东西。

    Baron Oldenburg 也对本书起了很大的推动作用。好多次由于时间和精力的原因我几乎要放弃了,幸好 Baron 帮我进行了初始的编辑和排版工作。这为本书的编写减轻了很大的负担,并最终促使本书问世。谢谢 Baron!你是我真正的朋友。

    Lorne Schell 是一位真正的文艺复兴式的人物——软件工程师、音乐家、艺术家。本书的封面就是出自他的聪慧之手。Vitruvian(维特鲁威风格的)Elf 与本书的描述艺术性的重合是多么令人惊喜!非常感谢你的才华,以及为此付出的时间和精力。

    Chad Thunberg 是我在 Leviathan 安全集团工作时的老板,他为我编写本书提供了所需要的资源和支持。非常感谢!

    感谢 Efnet 网站所有在#bitlackeys上的朋友的友谊和支持!

    关于审稿人

    Lubomir Rintel 是一名系统程序员,生活在捷克的布尔诺市。他是一位全职的软件开发人员,目前致力于 Linux 网络工具的开发。除此之外,他还对许多项目做出过贡献,包括 Linux 内核和 Fedora 发行版。活跃在开源软件社区多年之后,他懂得一本好书涵盖的主题要比参考手册更加广泛。他相信本书就是这样,希望你也能够像他一样喜欢这本书。另外,他还喜欢食蚁兽。

    截至2015年11月,Kumar Sumeet 在 IT 安全方面已经有4年多的研究经验了,在此期间,他开创了黑客和间谍工具的前沿。他拥有伦敦大学皇家霍洛威分校的信息安全硕士学位,最近的重点研究领域是检测网络异常和抵御威胁的机器学习技术。

    Sumeet 目前是 Riversafe 公司的一名安全顾问。Riversafe 是伦敦的一家网络安全和 IT 数据管理咨询公司,专注于一些尖端的安全技术。该公司也是2015年在 EMEA 地区的 Splunk Professional Services 的合作伙伴。他们已经完成了涉及许多领域(包括电信、银行和金融市场、能源和航空局)的大型项目。

    Sumeet 也是 Penetration Testing Using Raspberry Pi(Packt Publishing 出版)一书的技术审稿人。

    enter image description here

    有关他的项目和研究的更多详细信息,可以访问他的网站https://krsumeet.com,或者扫描右侧的二维码。

    你也可以通过电子邮件contact@krsumeet.com联系他。

    Heron Yang 一直致力于创造人们真正想要的东西。他在高中时就建立了这样坚定的信仰。随后他在台湾交通大学和卡内基梅隆大学专注于计算机科学的研究。在过去几年,他专注于在人和满足用户需求之间建立联系,致力于开发初创企业创意原型、新应用或者网站、学习笔记、出书、写博客等。


    感谢 Packt 给我这个机会参与本书的创作过程,并感谢 Judie Jose 在本书的创作过程中给我的很多帮助。此外,感谢我经历过的所有挑战,这让我成为一个更好的人。本书深入二进制逆向的诸多细节,对于那些关心底层机制的人来说会是很好的资料。大家可通过heron.yang.tw@gmail.com或者http://heron.me跟我打招呼或讨论图书内容。

    前言

    软件工程是创建能够在微处理器上存在、运行和发挥作用的造物行为。我们称这种造物为程序。逆向工程是发现程序如何运行和发挥作用的行为,进一步讲,就是使用反编译器和逆向工具进行组合,并依靠我们的专业技能来控制要进行反编译的目标程序,来理解、解析或者修改程序的行为。我们需要理解二进制格式、内存布局和给定处理器的指令集的复杂性,才能控制微处理器上某个程序的生命周期。逆向工程师是掌握了二进制领域相关知识的技术人员。本书将教会你成为一名 Linux 二进制黑客所需要的合理的课程、洞察力和相关任务。当一个人自称逆向工程师的时候,他自己其实已经超出了工程师的水平。一个真正的黑客不仅可以编写代码,还可以解析代码,反编译二进制文件和内存段,他追求的是修改软件程序的内部工作原理。这就是反编译工程师的动力。

    从专业或者兴趣爱好的角度来看,我都会在计算机安全领域(无论是漏洞分析、恶意软件分析、防病毒软件、rootkit 检测,还是病毒设计)使用自己在逆向工程方面的技能。本书的大部分内容专注于计算机安全方面。我们会分析内存转储、进程镜像重建,并对二进制分析更深奥的领域进行探索,包括 Linux 病毒感染和二进制取证分析。我们将会解析被恶意软件感染的二进制文件,还会感染运行中的进程。本书旨在解释 Linux 逆向工程所必需的组件,因此我们会深入学习 ELF(可执行文件和链接格式)。ELF 是 Linux 中可执行文件、共享库、核心转储文件和目标文件的二进制格式。本书最重要的一个方面是针对 ELF 二进制格式的结构复杂性给出了深入的分析。ELF 节、段、动态链接等这些概念都是非常重要的,也是逆向工程方面相关知识的比较有意思的分支。我们将会深入探索 ELF 二进制攻击,并了解如何将这些技能应用到更广泛的工作中。

    本书的目标是让读者成为对 Linux 二进制攻防有扎实基础的少数人之一,这将会为打开创新性研究的大门提供一个非常广泛的主题,并将读者带领到 Linux 操作系统高级黑客技术的前沿。你将掌握 Linux 二进制修补、病毒工程化/分析、内核取证分析和 ELF 二进制格式这一套宝贵的知识体系。读者也会对程序执行和动态链接有更深入的了解,对二进制保护和调试的内部原理有更深入的理解。

    我是一名计算机安全研究员、软件工程师,也是一名黑客。本书只是有组织地对我所做过的研究进行了文档性描述,也是对已经做出研究结果的一些基础知识的描述。

    本书所涵盖的很多知识都无法在互联网上找到。本书试图将一些相关联的主题集中在一起,以便作为 Linux 二进制和内存攻击这一主题的入门手册和参考。虽然不是非常完善,不过也涵盖了入门需要的很多核心信息。

    本书涵盖的内容

    第1章,Linux 环境和相关工具,简要介绍了 Linux 环境和相关的工具,在整本书中都会用到。

    第2章,ELF 二进制格式,帮助读者了解 ELF 二进制格式每个主要的组件,在 Linux 和大多数类 UNIX 系统上都会用到。

    第3章,Linux 进程追踪,教会读者使用 ptrace 系统调用读写进程内存并注入代码。

    第4章,ELF 病毒技术——Linux/UNIX 病毒,将会介绍 Linux 病毒的过去、现在和将来,以及病毒的工程化和围绕病毒进行的相关研究。

    第5章,Linux 二进制保护,解释 ELF 二进制保护的基本原理。

    第6章,Linux 下的 ELF 二进制取证分析,通过解析 ELF 目标文件来研究病毒、后门和可疑的代码注入。

    第7章,进程内存取证分析,将会介绍如何解析进程的地址空间,以研究内存中的恶意软件、后门和可疑的代码注入。

    第8章,ECFS——扩展核心文件快照技术,是对 ECFS 这一用于深入进程内存取证分析的新开源产品的介绍。

    第9章,Linux/proc/kcore 分析,介绍了如何使用/proc/kcore 进行内存分析来检测 Linux 内核中的恶意软件。

    阅读本书的先决条件

    阅读本书的先决条件如下:假定读者具有 Linux 命令行相关的操作知识,对 C 语言编程技巧有一定的理解,对 x86 汇编语言知识有基本的掌握(不是必需,但会有很大的帮助)。有句话说得好:“如果你可以读懂汇编语言,那么一切都是开源的”。

    本书读者对象

    如果你是一名软件工程师或者逆向工程师,想学习 Linux 二进制分析相关的更多知识,本书将会为你提供在安全、取证分析和防病毒领域进行二进制分析所需要用到的一切知识。假如你是一位安全技术领域的爱好者或者是一名系统工程师,并且有 C 语言编程和 Linux 命令行相关的经验,这本书将非常适合你。

    第1章 Linux 环境和相关工具

    本章将集中介绍 Linux 环境,因为这将贯穿整本书的始终。本书的重点是对 Linux 二进制进行分析,那么利用好 Linux 自带的一些通用的本地环境工具将会对 Linux 二进制分析非常有帮助。Linux 自带了应用普遍的 binutils 工具,该工具也可以在网站http://www.gnu.org/software/binutils/中找到,里面包含了一些用于二进制分析和破解的工具。本书不会介绍二进制逆向工程的通用软件 IDA Pro,但还是鼓励读者使用它。不过,在本书中不会使用 IDA。然而,通过本书的学习,你可以利用现有的环境对任何 Linux 系统进行二进制破解。由此,便可以欣赏到作为一个真正的黑客可以利用许多免费工具的 Linux 环境之美。在本书中,我们将会展示各种工具的使用,随着每个章节的推进,也会不断回顾这些工具的使用方法。现在我们将本章作为参考章节,介绍 Linux 环境下的相关工具和技巧。如果你已经非常熟悉 Linux 环境以及反编译、调试、转换 ELF 文件的工具,可以跳过本章。

    1.1 Linux 工具

    在本书中将用到许多公开发布的免费工具。本节内容将会对其中某些工具进行概要阐述。

    1.1.1 GDB

    GNU 调试器(GDB)不仅可以用来调试有 bug 的应用程序,也可以用来研究甚至改变一个程序的控制流,还可以用来修改代码、寄存器和数据结构。对于一个致力于寻找软件漏洞或者破解一个内部非常复杂的病毒的黑客来讲,这些都是非常常见的工作。GDB 主要用于分析 ELF 二进制文件和 Linux 进程,是 Linux 黑客的必备工具,在本书中我们也会在各种不同的例子中使用到 GDB。

    1.1.2 GNU binutils 中的 objdump

    object dump(objdump)是一种对代码进行快速反编译的简洁方案,在反编译简单的、未被篡改的二进制文件时非常有用,但是要进行任何真正有挑战性的反编译任务,特别是针对恶意软件时,objdump 就显示出了它的局限性。其最主要的一个缺陷就是需要依赖 ELF 节头,并且不会进行控制流分析,这极大地降低了 objdump 的健壮性。如果要反编译的文件没有节头,那么使用 objdump 的后果就是无法正确地反编译二进制文件中的代码,甚至都不能打开二进制文件。不过,对于一些比较平常的任务,如反编译未被加固、精简(stripped)或者以任何方式混淆的普通二进制文件,objdump 已经足够了。objdump 可以读取所有常用的 ELF 类型的文件。下面是关于 objdump 使用方法的一些常见例子。

    • 查看 ELF 文件中所有节的数据或代码:
        objdump –D <elf_object> 
    • 只查看 ELF 文件中的程序代码:
        objdump –d <elf_object> 
    • 查看所有符号:
        objdump –tT <elf_object> 

    在第2章介绍ELF二进制格式时,我们将更加深入地介绍objdump和其他相关工具。

    1.1.3 GNU binutils 中的 objcopy

    object copy(objcopy)是一款非常强大的小工具,很难用一句话对其进行概述。推荐读者参考objcopy的使用手册,里面描述得非常详细。虽然objcopy的某些特征只针对特定的ELF目标文件,但是,它还可以用来分析和修改任意类型的ELF目标文件,还可以修改ELF节,或将ELF节复制到ELF二进制中(或从ELF二进制中复制ELF节)。

    要将.data节从一个ELF目标文件复制到另一个文件中,可以使用下面的命令:

    objcopy –only-section=.data <infile> <outfile> 

    objcopy工具会在本书的后续内容中用到。现在只要记住有这样一个工具,并且知道这是对 Linux 二进制黑客来说非常有用的一个工具就可以了。

    1.1.4 strace

    system call trace(strace,系统调用追踪)是基于ptrace(2)系统调用的一款工具,strace通过在一个循环中使用PTRACE_SYSCALL请求来显示运行中程序的系统调用(也称为 syscalls)活动相关的信息以及程序执行中捕捉到的信号量。strace在调试过程中非常有用,也可以用来收集运行时系统调用相关的信息。

    使用strace命令来跟踪一个基本的程序:

    strace /bin/ls –o ls.out 

    使用strace命令附加到一个现存的进程上:

    strace –p <pid> -o daemon.out 

    原始输出将会显示每个系统调用的文件描述编号,系统调用会将文件描述符作为参数,如下所示:

    SYS_read(3, buf, sizeof(buf)); 

    如果想查看读入到文件描述符3中的所有数据,可以运行下面的命令:

    strace –e read=3 /bin/ls 

    也可以使用–e write=fd命令查看写入的数据。strace是一个非常有用的小工具,会在很多地方用到。

    1.1.5 ltrace

    library traceltrace,库追踪)是另外一个简洁的小工具,与strace非常类似。ltrace 会解析共享库,即一个程序的链接信息,并打印出用到的库函数。

    1.1.6 基本的 ltrace 命令

    除了可以查看库函数调用之外,还可以使用-S标记查看系统调用。ltrace命令通过解析可执行文件的动态段,并打印出共享库和静态库的实际符号和函数,来提供更细粒度的信息:

    ltrace <program> -o program.out 

    1.1.7 ftrace

    function traceftrace,函数追踪)是我自己设计的一个工具。ftrace 的功能与ltrace类似,但还可以显示出二进制文件本身的函数调用。我没有找到现成的实现这个功能的 Linux 工具,于是就决定自己编码实现。这个工具可以在网站https://github.com/elfmaster/ftrace找到。下一章会对这个工具的使用进行介绍。

    1.1.8 readelf

    readelf命令是一个非常有用的解析ELF二进制文件的工具。在进行反编译之前,需要收集目标文件相关的信息,该命令能够提供收集信息所需要的特定于ELF的所有数据。在本书中,我们将会使用readelf命令收集符号、段、节、重定向入口、数据动态链接等相关信息。readelf命令是分析ELF二进制文件的利器。第2章将对该命令进行更深入的介绍,下面是几个常用的标记。

    • 查询节头表:
        readelf –S <object> 
    • 查询程序头表:
        readelf –l <object> 
    • 查询符号表:
        readelf -s <object> 
    • 查询 ELF 文件头数据:
        readelf –e <object> 
    • 查询重定位入口:
        readelf –r <object> 
    • 查询动态段:
        readelf –d <object> 

    1.1.9 ERESI——ELF 反编译系统接口

    ERESI 工程(http://www.eresi-project.org)中包含着许多 Linux 二进制黑客梦寐以求的工具。令人遗憾的是,其中有些工具没有持续更新,有的与64位 Linux 不适配。ERESI 工程支持许多的体系结构,无疑是迄今为止最具创新性的破解 ELF 二进制文件的工具集合。由于我个人不太熟悉 ERESI 工程中工具的用法,并且其中有些不再更新,因此在本书中就不再对该工程进行更深入的探讨了。不过,有两篇 Phrack 的文章能够说明 ERESI 工具的创新和强大的特性:

    • Cerberus ELF interface(http://www.phrack.org/archives/issues/61/8.txt
    • Embedded ELF debugging(http://www.phrack.org/archives/issues/63/9.txt

    1.2 有用的设备和文件

    Linux 有许多文件、设备,还有/proc入口,它们对狂热的黑客还有反编译工程师来说都非常有用。在本书中,我们将会展示其中许多有用的文件。下面介绍本书中常用的一些文件。

    1.2.1 /proc/<pid>/maps

    /proc/<pid>/map文件保存了一个进程镜像的布局,通过展现每个内存映射来实现,展现的内容包括可执行文件、共享库、栈、堆和 VDSO 等。这个文件对于快速解析一个进程的地址空间分布是至关重要的。在本书中会多次用到该文件。

    1.2.2 /proc/kcore

    /proc/kcoreproc文件系统的一项,是 Linux 内核的动态核心文件。也就是说,它是以 ELF 核心文件的形式所展现出来的原生内存转储,GDB 可以使用/proc/kcore来对内核进行调试和分析。第9章会更深入地介绍/proc/kcore。

    1.2.3 /boot/System.map

    这个文件在几乎所有的 Linux 发行版中都有,对内核黑客来说是非常有用的一个文件,包含了整个内核的所有符号。

    1.2.4 /proc/kallsyms

    kallsymsSystem.map类似,区别就是 kallsyms 是内核所属的/proc的一个入口并且可以动态更新。如果安装了新的 LKM(Linux Kernel Module),符号会自动添加到/proc/kallsyms中。/proc/kallsyms包含了内核中绝大部分的符号,如果在CONFIG_KALLSYMS_ALL内核配置中指明,则可以包含内核中全部的符号。

    1.2.5 /proc/iomem

    iomem是一个非常有用的 proc 入口,与/proc/<pid>/maps类似,不过它是跟系统内存相关的。例如,如果想知道内核的 text 段所映射的物理内存位置,可以搜索Kernel字符串,然后就可以查看 code/text段、data段和bss段的相关内容:

      $ grep Kernel /proc/iomem   01000000-016d9b27 : Kernel code   016d9b28-01ceeebf : Kernel data   01df0000-01f26fff : Kernel bss 

    1.2.6 ECFS

    extended core file snapshot(ECFS,扩展核心文件快照)是一项特殊的核心转储技术,专门为进程镜像的高级取证分析所设计。这个软件的代码可以在https://github.com/elfmaster/ecfs看到。第8章将会单独介绍 ECFS 及其使用方法。如果你已经进入到了高级内存取证分析阶段,你会非常想关注这一部分内容。

    1.3 链接器相关环境指针

    动态加载器/链接器以及链接的概念,在程序链接、执行的过程中都是避不开的基本组成部分。在本书中,你还会学到更多相关的概念。在 Linux 中,有许多可以代替动态链接器的方法可供二进制黑客使用。随着本书的深入,你会开始理解链接、重定向和动态加载(程序解释器)的过程。下面是几个很有用处的链接器相关的属性,在本书中将会用到。

    1.3.1 LD_PRELOAD 环境变量

    LD_PRELOAD环境变量可以设置成一个指定库的路径,动态链接时可以比其他库有更高的优先级。这就允许预加载库中的函数和符号能够覆盖掉后续链接的库中的函数和符号。这在本质上允许你通过重定向共享库函数来进行运行时修复。在后续的章节中,这项技术可以用来绕过反调试代码,也可以用作用户级 rootkit。

    1.3.2 LD_SHOW_AUXV 环境变量

    该环境变量能够通知程序加载器来展示程序运行时的辅助向量。辅助向量是放在程序栈(通过内核的 ELF 常规加载方式)上的信息,附带了传递给动态链接器的程序相关的特定信息。第3章将会对此进行进一步验证,不过这些信息对于反编译和调试来说非常有用。例如,要想获取进程镜像 VDSO 页的内存地址(也可以使用maps文件获取,之前介绍过),就需要查询AT_SYSINFO

    下面是一个带有LD_SHOW_AUXV辅助向量的例子:

    $ LD_SHOW_AUXV=1 whoami AT_SYSINFO: 0xb7779414 AT_SYSINFO_EHDR: 0xb7779000 AT_HWCAP: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmovpat pse36 clflush mmx fxsr sse sse2 AT_PAGESZ: 4096 AT_CLKTCK: 100 AT_PHDR:  0x8048034 AT_PHENT: 32 AT_PHNUM: 9 AT_BASE:  0xb777a000 AT_FLAGS: 0x0 AT_ENTRY: 0x8048eb8 AT_UID:  1000 AT_EUID: 1000 AT_GID:  1000 AT_EGID: 1000 AT_SECURE: 0 AT_RANDOM: 0xbfb4ca2b AT_EXECFN: /usr/bin/whoami AT_PLATFORM: i686 elfmaster 

    第2章将会进一步介绍辅助向量。

    1.3.3 链接器脚本

    链接器脚本是我们的一个兴趣点,因为链接器脚本是由链接器解释的,把程序划分成相应的节、内存和符号。默认的链接器脚本可以使用ld–verbose查看。

    ld链接器程序有其自己解释的一套语言,当有文件(如可重定位的目标文件、共享库和头文件)输入时,ld链接器程序会用自己的语言来决定输出文件(如可执行程序)的组织方式。例如,如果输出的是一个 ELF 可执行文件,链接器脚本能够决定该输出文件的布局,以及每个段里面包含哪些节。另外举一个例子:.bss节总是放在data段的末尾,这就是链接器脚本决定的。你可能很好奇,这为什么就成了我们的一个兴趣点呢?一方面,对编译时链接过程有一定深入的了解是很重要的。gcc依赖于链接器和其他程序来完成编译的任务,在某些情况下,能够控制可执行文件的布局相当重要。ld命令语言是一门相当深入的语言,尽管它超出了本书的范围,但是非常值得探究。另一方面,在对可执行文件进行反编译时,普通段地址或者文件的其他部分有时候会被修改,这就表明引入了一个自定义的链接器脚本。gcc通过使用–T标志来指定链接器脚本。第5章会介绍一个使用链接器脚本的例子。

    1.4 总结

    本章仅介绍了 Linux 环境和工具相关的一些基本概念,在后续的每个章节中都会经常用到。二进制分析主要是了解一些可用的工具和资源并进行相关的整合。目前,我们只简要介绍了这部分工具,在接下来的章节中,随着对 Linux 二进制破解这个广阔领域进行更进一步的探索,我们会有机会对每一个工具进行深入介绍。下一章将会对 ELF 二进制格式进行更深入的探索,也会涉及其他一些有趣的概念,如动态链接、重定位、符号和节(section)等。

    第2章 ELF 二进制格式(上)
    第2章 ELF 二进制格式(下)
    第3章 Linux 进程追踪(上)
    第3章 Linux 进程追踪(下)
    第4章 ELF 病毒技术——Linux/UNIX 病毒
    第5章 Linux 二进制保护
    第6章 Linux 下的 ELF 二进制取证分析
    第7章 进程内存取证分析
    第8章 ECFS——扩展核心文件快照技术(上)
    第8章 ECFS——扩展核心文件快照技术(下)
    第9章 Linux/proc/kcore 分析

    阅读全文: http://gitbook.cn/gitchat/geekbook/5ba9eb5b0110e7701d264575

    展开全文
  • 文本文件 二进制文件A question came to me when I was reading posts in “Django users group” (a google group of active Django programmers): 当我在阅读“ Django用户组”(一个活跃的Django程序员的Google组)...

    文本文件 二进制文件

    A question came to me when I was reading posts in “Django users group” (a google group of active Django programmers):

    当我在阅读“ Django用户组”(一个活跃的Django程序员的Google组)中的帖子时,我遇到了一个问题:

    What is the difference between an ordinary txt file and a csv file in Python programming?

    Python编程中的普通txt文件和csv文件有什么区别?

    It was reminiscent of the days when I first understood files (I was teaching myself Visual Basic 6.0 at that time). Although it’s not a hard question, it represents a small conceptual gap that every beginner programmer has to jump over, and once you have done that, you have a better mental picture of how computing systems work. So I wrote a quick answer under that post. Although that answer was not well formatted (email is really not a good place for technical questions), I was very pleasant that a couple of guys found it useful. I decided to completely re-write it, making it better organized and more pedagogical with easier-to-understand examples. I’ll be happy if more people found it useful.

    这让我想起了我第一次了解文件的日子(当时我正在自学Visual Basic 6.0 )。 尽管这不是一个难题,但它代表了每个初学者都必须跳过的很小的概念鸿沟,一旦完成,就可以更好地了解计算系统的工作原理。 因此,我在该帖子下写了一个快速解答。 尽管答案的格式不正确(电子邮件确实不是解决技术问题的好地方),但我很高兴几个人发现它很有用。 我决定完全重新编写它,并通过易于理解的示例使它更好地组织和更具教学性。 如果更多的人觉得它有用,我会很高兴。

    While the original answer was more python specific, I have removed those python parts. Although this discussion is more relevant to programmers, I believe no programming background is needed in order to understand how files work. There are some python codes and HTML codes below, but they are just examples of different file formats. Understanding the meaning of those codes are not required to understand this article (those are trivial codes anyway).

    虽然原始答案更特定于python,但我已删除了这些python部分。 尽管此讨论与程序员更相关,但我认为不需要编程背景即可了解文件的工作原理 。 下面有一些python代码和HTML代码,但它们只是不同文件格式的示例。 不需要了解这些代码的含义就可以理解本文(无论如何,这些代码都是微不足道的)。

    Ready? Let’s dive into the world of files!

    准备? 让我们深入了解文件世界!

    什么是文件? (What is a file?)

    One can easily answer what is in a file: data, represented as a sequence of bytes (each byte is 8 digits of 0s and 1s).

    可以轻松回答文件中的内容: data以字节序列表示 (每个字节是0和1的8位数字)。

    Given a sequence of bytes, what does each byte stand for? What are the rules that all the bytes follow to convey the correct information?

    给定一个字节序列,每个字节代表什么? 所有字节传达正确信息所遵循的规则是什么?

    These questions are completely up to the author of the file. Imagine that you are given a piece of paper, and are allowed to write anything on it. You don’t have to write English letters; in fact, you don’t have to write letters or characters in any known language. You can invent your own symbol, and define your own rules on how these symbols are assembled to record meaningful information. You are in the same situation when you want to create your own files.

    这些问题完全取决于文件的作者。 想象一下,您得到一张纸,并且可以在上面写任何东西。 您不必写英文字母。 实际上,您不必用任何已知语言编写字母或字符。 您可以发明自己的符号,并定义有关如何组合这些符号以记录有意义的信息的规则。 当您要创建自己的文件时,您处于相同的情况。

    On the other hands, not many people want to create a completely new format, for at least two reasons:

    另一方面,出于至少两个原因,没有多少人希望创建全新的格式:

    1. Designing a meaningful and easy-to-use set of rules is hard.

      设计一套有意义且易于使用的规则非常困难。
    2. It causes communication problem. One purpose of creating a file is to share information with others (this “others” can include your future self). So it’s better if more people can understand the format you use.

      它导致通讯问题。 创建文件的目的之一是与他人共享信息(“他人”可以包括您将来的自己)。 因此,如果有更多的人可以理解您使用的格式,那就更好了。

    Therefore, whenever writing to a file, people usually (usually, not always) prefer to use an existing file format instead of creating their own.

    因此,每当写入文件时,人们通常(通常并非总是如此)更喜欢使用现有的文件格式而不是创建自己的文件格式

    Let’s look at some examples of these “existing file formats”.

    让我们看一下这些“ 现有文件格式 ”的示例。

    从二进制文件到文本文件 (From binary files to text files)

    Let’s start with a basic file format: text files. Many beginner programmers make a mistake by saying “there are two types of files: binary files and text files”, as if a text file cannot be a binary file and vice versa. As we mentioned, every file is a sequence of bytes. So every file is a binary file, including the text files. Text files are merely a special family of (binary) files. What’s special about them is that every byte in the file corresponds to a symbol in the ASCII table (Let’s only worry about English characters and punctuation in this article. If you like to use other characters, replace “ASCII” by “Unicode” throughout this article). Below is the ASCII table (image from www.LookupTables.com).

    让我们从一种基本的文件格式开始:文本文件。 许多初学者程序员都说“文件有两种类型:二进制文件和文本文件”,这使文本文件不能是二进制文件,反之亦然。 如前所述,每个文件都是一个字节序列。 因此, 每个文件都是二进制文件,包括文本文件 。 文本文件仅仅是(二进制)文件的特殊族。 它们的特殊之处在于文件中的每个字节都对应于ASCII表中的符号(本文仅需担心英文字符和标点符号。如果您想使用其他字符,请在本文中用“ Unicode”替换“ ASCII”文章)。 下面是ASCII表(图片来自www.LookupTables.com )。

    Image for post
    http://www.LookupTables.com) http://www.LookupTables.com )

    To see the format of ASCII codes in action, I opened an online converter (available at https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html), and typed “Hello, medium.” in “ASCII text” text box. The figure below shows the binary, hex and decimal representations of all symbols I typed in.

    要查看实际使用的ASCII代码格式,我打开了一个在线转换器(可从https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html访问 ),然后键入“ Hello,中。 在“ ASCII文本 ”文本框中。 下图显示了我键入的所有符号的二进制,十六进制和十进制表示形式。

    Image for post
    https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html.) (Screenshot by author) https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html 。)(作者截屏)

    Using the above ASCII table (first figure), you can see indeed “H” is the Number 72 symbol in the table, and number 72 in decimal is “01001000” in binary representation. When you save “Hello, medium.” in a text file, what is stored in the hard disk is “01001000”. Important thing here is that you created this file using the text format, and therefore you can read it using any tool which understands the text format (a text editor, for example).

    使用上面的ASCII表(第一个图),您可以看到表中的数字“ H”确实是72号符号,而十进制的数字72中的二进制表示形式是“ 01001000”。 当您保存“您好,中”时。 在文本文件中,硬盘中存储的是“ 01001000”。 这里重要的是您使用文本格式创建了此文件,因此可以使用任何了解文本格式的工具 (例如,文本编辑器) 读取该文件

    不同格式的文本文件 (Different formats of text files)

    Now we understand that text files are merely binary files in a certain format. I’ve also used the word “format” to mean any rule defined for bytes in the file in order to represent information (in this case, the ASCII table). For another example of file format, think about a game save file, in which the first 4 bytes could be an integer recording how much money the player has; the next 10 bytes could be ASCII bytes recording player’s name, and so on.

    现在我们了解到,文本文件仅仅是某种格式的二进制文件。 我还用过“ 格式 ”一词来表示为文件中的字节定义的任何规则,以表示信息(在本例中为ASCII表)。 再以文件格式为例,考虑一个游戏保存文件,其中前4个字节可以是一个整数,用于记录玩家拥有多少钱; 接下来的10个字节可以是记录播放器名称的ASCII字节,依此类推。

    In our analogue of writing on a piece of blank paper, resorting to text files is analogous to restricting ourselves to ASCII characters. Note that even with this restriction, we still have a big freedom.

    在我们在一张空白纸上书写的模拟中,诉诸文本文件类似于将自己限制为ASCII字符。 请注意,即使有此限制,我们仍然有很大的自由度。

    The following is a text file.

    以下是一个文本文件。

    import os
    print("Hello, medium!")
    print(os.getcwd())

    Since it’s a text file, we can open it using any text editor. In addition, it’s in the format of a python script, a python interpreter can run it, and a syntax highlighter can decorate different components using different colors.

    由于它是一个文本文件,因此我们可以使用任何文本编辑器将其打开。 另外,它采用python脚本的格式,python解释器可以运行它,语法突出显示器可以使用不同的颜色装饰不同的组件。

    Here’s another example.

    这是另一个例子。

    <html>
    <head>
    <title>A beautiful web page</title>
    </head>
    <body>
    <h1>Hello, medium!</h1>
    <img src="img/beautiful_image.jpg" />
    </body>
    </html>

    Again, it’s a text file (so can be opened by any text editing tool) and it’s also in the HTML format (so it can be rendered by a browser into a very beautiful web page).

    同样,它是一个文本文件(因此可以通过任何文本编辑工具打开),并且它也是HTML格式(因此可以由浏览器呈现为一个非常漂亮的网页)。

    In these two examples, python and HTML can be viewed as two formats on top of the text format, which is, in turn, on top of the general bytes. We see a hierarchy of formats consisting of 3 levels. It’s up to you which level you want to stay in. The higher level of formats you go, the easier your life will be because of tools available to handle that specific format (e.g. a python interpreter, or a browser). The lower you go, the more work you have to do yourself, but the more freedom you have. For example, if you change import os to Import os, you still have a valid text file, but logically speaking, it’s no longer a python script (ask a python interpreter, it will tell you the same by throwing to you an error). You can create your own tool to interpret this text file, though (you essentially just invented another language).

    在这两个示例中,可以将python和HTML视为文本格式之上的两种格式,而文本格式又是常规字节之上的。 我们看到由3个级别组成的格式层次结构。 由您决定要保留的级别。要使用的格式越高,使用可用于处理特定格式的工具(例如python解释器或浏览器)的作用就越容易。 您走得越低,您要做的工作就越多,但是您拥有的自由就越多。 例如,如果将import os更改为Import os ,您仍然有一个有效的文本文件,但是从逻辑上讲,它不再是python脚本(询问python解释器,它会向您抛出错误来告诉您相同的内容)。 不过,您可以创建自己的工具来解释此文本文件(实际上您只是发明了另一种语言)。

    文件扩展名重要吗? (Are filename extensions important?)

    Before we talk about filename extensions (like .txt, .jpg, etc), I’d like to emphasize one point. When I say a file is of HTML format, I don’t mean that file has a .html or .htm extension. Filename extension is merely a part of the file’s name. It’s never fundamentally important what the file name is! When I talk about file formats above, what I refer to is the way how data is organized in a file(in this html example, whether the contents are in the valid HTML syntax).

    在讨论文件扩展名(如.txt.jpg等)之前,我想强调一点。 当我说一个文件是HTML格式时,并不意味着该文件具有 .html .htm 扩展名 。 文件扩展名只是文件名的一部分。 文件名是什么从根本上不重要! 当我在上面谈论文件格式时,我指的是文件中 数据的组织方式 (在此html示例中,内容是否使用有效HTML语法)。

    To demonstrate this, let’s open a text editor (e.g.: notepad, or vim, whatever text editor available to you), type the following:

    为了演示这一点,让我们打开一个文本编辑器(例如: notepadvim ,任何可用的文本编辑器),键入以下内容:

    import sys
    print("hello! This is a python file!")
    print("Some error message here!", file=sys.stderr)

    and save them to a file called print_message.jpg. Yes, the extension is .jpg! Does it make this file an image file? Definitely not. (Try to open it using an image viewer.) It’s a python script. You can go to command line and enter python print_message.jpg. The codes will run!

    并将它们保存到名为print_message.jpg的文件中。 是的,扩展名是 .jpg ! 是否使该文件成为图像文件? 当然不。 (尝试使用图像查看器打开它。)这是一个python脚本。 您可以转到命令行并输入python print_message.jpg 。 代码将运行!

    Back to the question: Do the filename extensions mean anything? Well, not much to a programmer. Why do we use filename extensions, then?

    回到问题: 文件扩展名是什么意思吗? 好吧,对程序员来说不算多。 那么为什么要使用文件扩展名呢?

    Mainly for two reasons.

    主要有两个原因。

    First, In a system with a graphical interface, users usually access a file by simply double clicking it. It’s very troublesome for a user to specify which format it is (or which tool should be used to access it) every time. When we double click cute_cat.jpg, we want to view it as an image. To indulge the users, a graphical operating system secretly keeps a table of the filename extensions, each with a default tool to open files with that extension. By naming a file cute_cat.jpg, the creator of this file gives a promise to the operating system that this file is of jpeg format. (The print_message.jpg above failed to keep this promise, so when you double click it, the operating system angrily throw to you a red error box with an unpleasant sound.)

    首先,在具有图形界面的系统中,用户通常只需双击即可访问文件。 对于用户来说,每次都指定它是哪种格式(或应该使用哪种工具来访问它)是非常麻烦的。 双击cute_cat.jpg ,我们希望将其作为图像查看。 为了吸引用户,图形操作系统秘密地保存了文件扩展名表,每个文件扩展名都有一个默认工具来打开具有该扩展名的文件。 通过命名一个文件cute_cat.jpg ,该文件的创建者给出了一个承诺操作系统这个文件是JPEG格式的。 (上面的print_message.jpg无法兑现这一承诺,因此,当您双击它时,操作系统会愤怒地向您抛出一个红色的错误框,并发出令人不快的声音。)

    Image for post
    A graphical interface OS (like Windows) keeps secretly a table of all filename extensions, each with a default tool to open it. (Screenshot by author)
    图形界面操作系统(例如Windows)秘密地保存所有文件扩展名的表,每个文件扩展名都有一个默认工具来打开它。 (作者截屏)

    Second, In an extension-agnostic system like Linux (we are not talking about a window/desktop manager in Linux), file extensions become completely immaterial. However, it’s still a good practice to give a reasonable extension to a file. By doing this, you are giving your promise not to the system, but to other users (including your future self). For example, /etc is a big directory on my Linux machine with various types of files in it, but if I’m only interested in config files (they are have .conf extension), I can list only config file by ls *.conf (see the figure below).

    其次,在诸如Linux之类的与扩展无关的系统中(我们不是在谈论Linux中的窗口/桌面管理器),文件扩展变得完全无关紧要。 但是,对文件进行合理的扩展仍然是一个好习惯。 通过这样做,您的承诺不是对系统,而是对其他用户(包括您将来的自己)。 例如, /etc是Linux计算机上的一个大目录,其中包含各种类型的文件,但是如果我只对配置文件感兴趣(它们具有.conf扩展名),我只能用ls *.conf列出配置文件ls *.conf (请参见下图)。

    Image for post
    Although Linux is extension-agnostic, it’s a good practice to give a reasonable filename extension according to the nature of file. In this figure, the filename extension makes listing easy. (Screenshot by author)
    尽管Linux与扩展名无关,但是根据文件的性质给出合理的文件扩展名是一个好习惯。 在此图中,文件扩展名使列出变得容易。 (作者截屏)

    Thanks for reading this far. Hope you find something interesting about files! Please feel free to give any comment or feedback to me.

    感谢您阅读本文。 希望您找到有关文件的有趣信息! 请随时给我任何评论或反馈。

    Until next time!

    直到下一次!

    翻译自: https://medium.com/the-innovation/as-a-programmer-you-need-to-understand-these-about-files-b542c60d9285

    文本文件 二进制文件

    展开全文
  • C#读写二进制文件 http://www.cnblogs.com/top5/archive/2011/02/07/1949675.html 本文要介绍的C#本地读写二进制文件,二进制文件指保存在物理磁盘的一个文件。 第一步:读写文件转成流对象。其实就是读写...
  • JavaScript 二进制的 AST

    2017-08-24 06:20:26
    原文地址:Towards a JavaScript Binary AST 原文作者:Yoric 译文出自:掘金翻译计划 ...译者:Cherry ...在这个博客文章中,我想介绍一下 JavaScript 二进制 AST,我们希望在我们的项目中这将有助于使网...
  • 二进制与字符编码

    2016-08-21 21:06:00
    十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。 二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一...
  • 转载连接:... C读写二进制文件C二进制文件比较程序C Parsing 类实现的 PDF 文件分析器Windows下的开源二进制文件编辑器HexEdit C#读写二进制文件 http://www.cnblogs.com
  • MySQL-日志&二进制日志binlog初探

    千次阅读 2020-01-31 10:32:17
    文章目录MySQL日志分类服务层日志存储引擎层日志 MySQL日志分类 ...二进制日志 慢查询日志 通用日志 … 存储引擎层日志 以Innodb存储引擎来讲,主要由 Redo log 和 Undo log , 为了支持事务。 ...
  • 作业_二进制炸弹_手把手教学讲解

    千次阅读 多人点赞 2020-11-09 13:55:52
    最近的作业有个二进制炸弹问题,具体点说就是使用汇编语言完成一些小问题,形式比较有趣,一起看看吧。 题目描述 实验目的 通过对一个二进制可执行程序(称为“二进制炸弹”)的理解和逆向工程,加深对对程序的...
  • 十进制与二进制相比,十进制的数字长度更短,更容易辨识书写,另一方面十进制的应用需要掌握比二进制应用更复杂的加法表与乘法表。 二进制的发明追溯至莱布尼茨。莱布尼茨对二进制情有独钟,用法国数学家、物理学家...
  • 标识符 、二进制

    千次阅读 2018-03-24 13:32:25
    一、java开发环境:·jvm:Java虚拟街·jre:java运行时环境,包括jvm和Java程序运行时所需要的核心类库·jdk:java开发工具包,包括了jre和java程序开发时所需要的工具 1.安装jdk: www.oracle.com 2.配置环境...
  • 二进制二进制是数学和数字电路中使用的记数系统,计算机使用的是二进制。因为电子器件只有通电和不通电两种状态,二进制方便计算机进行运算。 用打地鼠解释二进制:先解释一下二进制,举个例子,大家应该都玩过打...
  • 文本文件与二进制文件区别

    千次阅读 2018-11-15 13:50:18
    ... 1)文本文件:这类文件以文本的ASCII码...2)二进制文件:这类文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们,只有通过相应的软件才能将其显示出来。二进制文件一般是可执行程序、图形、图像...
  • 二进制如何变成汇编语言

    千次阅读 2019-06-03 22:27:22
    在纸上写好后,用"操作码表"把伪代码转成二进制机器码,翻译完成后,程序可以喂入计算机并运行。 你可能猜到了,很快人们就厌烦了,所以在 1940~1950 年代,程序员开发出一种新语言, 更可读更高层次,每个操作码...
  • 机器语言:(二进制语言)是用二进制代码表示的计算机语言。能直接识别和执行的一种机器指令的集合。不同机器的机器语言不同。机器语言具有灵活、直接执行和速度快等特点。 (如: 10100010010111100011代表的是A=B...
  • nm命令是linux下自带的特定文件分析工具,一般用来检查分析二进制文件、库文件、可执行文件中的符号表,返回二进制文件中各段的信息。 目标文件、库文件、可执行文件 首先,提到这三种文件,我们不得不提的就是gcc的...
  • 二进制文件一个字节可以存储的值的集合为(0x00-0xFF 中的所有值) // 包括 ascii 表中有翻译的部分 操作系统对换行符('\n')的处理不同 // linux对二进制和文本的处理是相同的,按道理,win 可以做成...
  • 该程序会将大多数RVIMFD64 ISA二进制指令(从二进制或十六进制代码)反汇编成汇编指令。 之所以存在(以及它看起来有些“太原始”而无法发布)的原因是我试图学习指令格式以进行计算机体系结构考试。 长话短说,就...
  • 本篇文章翻译自:(State of) The Art of War: Offensive Techniques in Binary Analysis论文下载链接:http://www.cs.ucsb.edu/~chris/research/doc/oakland16_sokbin.pdf文章主要讲解的是常见的二进制分析技术,...
  • 英文原文全文http://deniable.org/reversing/binary-instrumentation 译转自https://www.4hou.com/binary/13026.html和https://www.4hou.com/binary/13116.html 翻译并不全 感谢翻译作者luochicun 目录 前言 Pin ...
  • *.000001 这样的才是二进制日志,如果直接打开会是这个样子的: mariadb有专门浏览日志的工具mysqlbinlog (戳我跳转官方文档) 使用mysqlbinlog打开Binary Log文件$ mysqlbinlog mysql-bin.000001 结果报错...
  • 英语以外的其他语言的翻译是机器翻译的,尚不准确。 截至2021年3月21日,尚未解决任何错误,请报告翻译错误。 请确保用资料来源备份您的更正并为我提供指导,因为我不太了解英语(我打算最终一名翻译人员)以外的...
  • Cornelis Frank April 10, 2000 翻译:湖北武汉华中师范大学(CCNU) 城市与环境科学学院 陈斌 Email:sunwen@aspcn.com 邮编:430079 引言: 这是一篇深入剖析GCC编译器产生的汇编码的文章,非常精彩.对于初学者来说,这...
  • 这只是直观的表示方法,其实计算机是通过2的补码来表示负数的,那什么是2的补码(同补码,英文是2’s complement,其实应该翻译为2的补码)呢?它是一种用二进制表示有号数的方法,也是一种将数字的正负号变号的方式...
  • 主要介绍了Intel Pin二进制插桩工具的工作原理、PinTool基本使用方法、和其他插桩工具的性能比较、以及不同平台下的性能优化。英文版的,不过内容还是不错的,英文不好的童鞋就自行找个文档翻译站点先翻译下再看吧。
  • python 自制搜狗翻译工具

    千次阅读 热门讨论 2018-12-10 12:37:44
    一、登陆搜狗翻译页面,分析请求 ...在里面输入中文翻译 ...2、输入英文翻译 综合上述分析,当改变里面内容时,Form Data(向后台发送的数据)中to、uuid、s的值在变化,其他几个没有变化 、找到请求的JS ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,097
精华内容 8,838
关键字:

二进制翻译英文工具