安全矩阵

 找回密码
 立即注册
搜索
楼主: ethereel

李文艺学习日记

[复制链接]

5

主题

40

帖子

215

积分

中级会员

Rank: 3Rank: 3

积分
215
 楼主| 发表于 2020-5-2 00:29:22 | 显示全部楼层
OAuth
1. 简介
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。
OAuth在客户端与服务端之间,设置了一个授权层(authorization layer)。客户端不能直接登录服务端,只能登录授权层,以此将用户与客户端区分开来。客户端登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。
客户端登录授权层以后,服务端根据令牌的权限范围和有效期,向客户端开放用户储存的资料。
OAuth 2.0定义了四种授权方式:授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password credentials)和客户端模式(client credentials)。
2. 流程
·        用户打开客户端以后,客户端要求用户给予授权
·        用户同意给予客户端授权
·        客户端使用上一步获得的授权,向认证服务器申请令牌
·        认证服务器对客户端进行认证以后,确认无误,同意发放令牌
·        客户端使用令牌,向资源服务器申请获取资源
·        资源服务器确认令牌无误,同意向客户端开放资源
3. 授权码模式
授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与服务端的认证服务器进行互动。
其流程为:
·        用户访问客户端,后者将前者导向认证服务器
·        用户选择是否给予客户端授权
·        假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI) ,同时附上一个授权码
·        客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌
·        认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)
A步骤中,客户端申请认证的URI,包含以下参数:
·        response_type:表示授权类型,必选项,此处的值固定为 code
·        client_id:表示客户端的ID,必选项
·        redirect_uri:表示重定向URI,可选项
·        scope:表示申请的权限范围,可选项
·        state:表示客户端的当前状态,需动态指定,防止CSRF
例如:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2FcbHTTP/1.1
Host: server.example.com
C步骤中,服务器回应客户端的URI,包含以下参数:
·        code:表示授权码,必选项。该码的有效期应该很短且客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
·        state:如果客户端的请求中包含这个参数,认证服务器回应与请求时相同的参数
例如:
HTTP/1.1 302 Found
D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:
·        grant_type:表示使用的授权模式,必选项,此处的值固定为 authorization_code
·        code:表示上一步获得的授权码,必选项
·        redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致
·        client_id:表示客户端ID,必选项
例如:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
E步骤中,认证服务器发送的HTTP回复,包含以下参数:
·        access_token:表示访问令牌,必选项
·        token_type:表示令牌类型,该值大小写不敏感,必选项,可以是 bearer 类型或 mac 类型
·        expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间
·        refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项
·        scope:表示权限范围,如果与客户端申请的范围一致,此项可省略
例如:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}
4. 简化模式
简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了授权码这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
其步骤为:
·        客户端将用户导向认证服务器
·        用户决定是否给于客户端授权
·        假设用户给予授权,认证服务器将用户导向客户端指定的重定向URI,并在URI的Hash部分包含了访问令牌
·        浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值
·        资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌
·        浏览器执行上一步获得的脚本,提取出令牌
·        浏览器将令牌发给客户端
A步骤中,客户端发出的HTTP请求,包含以下参数:
·        response_type:表示授权类型,此处的值固定为 token ,必选项
·        client_id:表示客户端的ID,必选项
·        redirect_uri:表示重定向的URI,可选项
·        scope:表示权限范围,可选项
·        state:表示客户端的当前状态,需动态指定,防止CSRF
例如:
GET/authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2FcbHTTP/1.1
Host: server.example.com
C步骤中,认证服务器回应客户端的URI,包含以下参数:
·        access_token:表示访问令牌,必选项
·        token_type:表示令牌类型,该值大小写不敏感,必选项
·        expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间
·        scope:表示权限范围,如果与客户端申请的范围一致,此项可省略
·        state:如果客户端的请求中包含这个参数,认证服务器回应与请求时相同的参数
例如:
HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600
在上面的例子中,认证服务器用HTTP头信息的Location栏,指定浏览器重定向的网址。注意,在这个网址的Hash部分包含了令牌。
根据上面的D步骤,下一步浏览器会访问Location指定的网址,但是Hash部分不会发送。接下来的E步骤,服务提供商的资源服务器发送过来的代码,会提取出Hash中的令牌。
5. 密码模式
密码模式(Resource Owner Password CredentialsGrant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。
其步骤如下:
·        用户向客户端提供用户名和密码
·        客户端将用户名和密码发给认证服务器,向后者请求令牌
·        认证服务器确认无误后,向客户端提供访问令牌
B步骤中,客户端发出的HTTP请求,包含以下参数:
·        grant_type:表示授权类型,此处的值固定为 password ,必选项
·        username:表示用户名,必选项
·        password:表示用户的密码,必选项
·        scope:表示权限范围,可选项
例如:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w
C步骤中,认证服务器向客户端发送访问令牌,例如:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "example",
    "expires_in": 3600,
    "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
    "example_parameter": "example_value"
}
6. 客户端模式
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向服务端进行认证。
其步骤如下:
·        客户端向认证服务器进行身份认证,并要求一个访问令牌
·        认证服务器确认无误后,向客户端提供访问令牌
A步骤中,客户端发出的HTTP请求,包含以下参数:
·        granttype:表示授权类型,此处的值固定为 clientcredentials ,必选项
·        scope:表示权限范围,可选项
例如:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
B步骤中,认证服务器向客户端发送访问令牌,例如:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "example",
    "expires_in": 3600,
    "example_parameter": "example_value"
}

回复

使用道具 举报

5

主题

40

帖子

215

积分

中级会员

Rank: 3Rank: 3

积分
215
 楼主| 发表于 2020-5-4 01:39:04 | 显示全部楼层
0503 了解了各类框架中的反射调用以及工厂模式
目前来看,最安全的php框架应该是laravel
回复

使用道具 举报

5

主题

40

帖子

215

积分

中级会员

Rank: 3Rank: 3

积分
215
 楼主| 发表于 2020-5-5 23:53:35 | 显示全部楼层
本帖最后由 ethereel 于 2020-5-5 23:55 编辑

0504 了解了域渗透中最为重要的两个协议:NTLM与Kerberos
回复

使用道具 举报

5

主题

40

帖子

215

积分

中级会员

Rank: 3Rank: 3

积分
215
 楼主| 发表于 2020-5-8 00:21:03 | 显示全部楼层
本帖最后由 ethereel 于 2020-5-8 00:40 编辑

0506-07:
由于最近要做安卓课设,就看了些乌云上有关安卓的漏洞挖掘。
按照利用方法,漏洞主要分为两类:
1.网络接口注入。比如容易被人利用的逻辑漏洞、sql注入和组件暴露等等,这类漏洞的挖掘基本同web,只不过需要通过模拟器进行。
2.逆向分析。审查其源代码,查看接口,逐个分析可能存在的问题和利用方式。
在这一过程中,了解了linux下pm、busybox的使用。
回复

使用道具 举报

5

主题

40

帖子

215

积分

中级会员

Rank: 3Rank: 3

积分
215
 楼主| 发表于 2020-5-13 01:46:04 | 显示全部楼层
本帖最后由 ethereel 于 2020-5-13 01:49 编辑

ELF 文件结构
对象文件参与程序链接(构建程序)和程序执行(运行程序)。ELF 结构几相关信息在 /usr/include/elf.h 文件中。
  • ELF 文件头(ELF Header) 在目标文件格式的最前面,包含了描述整个文件的基本属性。
  • 程序头表(Program Header Table) 是可选的,它告诉系统怎样创建一个进程映像。可执行文件必须有程序头表,而重定位文件不需要。
  • 段(Section) 包含了链接视图中大量的目标文件信息。
  • 段表(Section Header Table) 包含了描述文件中所有段的信息。

文件头
ELF 文件头必然存在于 ELF 文件的开头,表明这是一个 ELF 文件。定义如下:
  1. typedef struct
  2. {
  3.   unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
  4.   Elf32_Half    e_type;         /* Object file type */
  5.   Elf32_Half    e_machine;      /* Architecture */
  6.   Elf32_Word    e_version;      /* Object file version */
  7.   Elf32_Addr    e_entry;        /* Entry point virtual address */
  8.   Elf32_Off e_phoff;        /* Program header table file offset */
  9.   Elf32_Off e_shoff;        /* Section header table file offset */
  10.   Elf32_Word    e_flags;        /* Processor-specific flags */
  11.   Elf32_Half    e_ehsize;       /* ELF header size in bytes */
  12.   Elf32_Half    e_phentsize;        /* Program header table entry size */
  13.   Elf32_Half    e_phnum;        /* Program header table entry count */
  14.   Elf32_Half    e_shentsize;        /* Section header table entry size */
  15.   Elf32_Half    e_shnum;        /* Section header table entry count */
  16.   Elf32_Half    e_shstrndx;     /* Section header string table index */
  17. } Elf32_Ehdr;
复制代码


e_ident 保存着 ELF 的幻数和其他信息,最前面四个字节是幻数,用字符串表示为 \177ELF,其后的字节如果是 32 位则是 ELFCLASS32 (1),如果是 64 位则是 ELFCLASS64 (2),再其后的字节表示端序,小端序为 ELFDATA2LSB (1),大端序为 ELFDATA2LSB (2)。最后一个字节则表示 ELF 的版本。
可以使用 readelf 命令来查看 elfDome.out 的文件头:
  1. $ readelf -h elfDemo.out
  2. ELF Header:
  3.   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  4.   Class:                             ELF32
  5.   Data:                              2's complement, little endian
  6.   Version:                           1 (current)
  7.   OS/ABI:                            UNIX - System V
  8.   ABI Version:                       0
  9.   Type:                              DYN (Shared object file)
  10.   Machine:                           Intel 80386
  11.   Version:                           0x1
  12.   Entry point address:               0x3e0
  13.   Start of program headers:          52 (bytes into file)
  14.   Start of section headers:          6288 (bytes into file)
  15.   Flags:                             0x0
  16.   Size of this header:               52 (bytes)
  17.   Size of program headers:           32 (bytes)
  18.   Number of program headers:         9
  19.   Size of section headers:           40 (bytes)
  20.   Number of section headers:         30
  21.   Section header string table index: 29
复制代码

程序头
程序头表是由 ELF 头的 e_phoff 指定的偏移量和 e_phentsize、e_phnum 共同确定大小的表格组成。e_phentsize 表示表格中程序头的大小,e_phnum 表示表格中程序头的数量。
程序头的部分定义如下:
  1. typedef struct
  2. {
  3.   Elf64_Word    p_type;         /* Segment type */
  4.   Elf64_Word    p_flags;        /* Segment flags */
  5.   Elf64_Off p_offset;       /* Segment file offset */
  6.   Elf64_Addr    p_vaddr;        /* Segment virtual address */
  7.   Elf64_Addr    p_paddr;        /* Segment physical address */
  8.   Elf64_Xword   p_filesz;       /* Segment size in file */
  9.   Elf64_Xword   p_memsz;        /* Segment size in memory */
  10.   Elf64_Xword   p_align;        /* Segment alignment */
  11. } Elf64_Phdr;
复制代码


使用 readelf 来查看程序头:
  1. $ readelf -l elfDemo.out

  2. Elf file type is DYN (Shared object file)
  3. Entry point 0x3e0
  4. There are 9 program headers, starting at offset 52

  5. Program Headers:
  6.   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  7.   PHDR           0x000034 0x00000034 0x00000034 0x00120 0x00120 R E 0x4
  8.   INTERP         0x000154 0x00000154 0x00000154 0x00013 0x00013 R   0x1
  9.       [Requesting program interpreter: /lib/ld-linux.so.2]
  10.   LOAD           0x000000 0x00000000 0x00000000 0x00780 0x00780 R E 0x1000
  11.   LOAD           0x000ef4 0x00001ef4 0x00001ef4 0x00130 0x0013c RW  0x1000
  12.   DYNAMIC        0x000efc 0x00001efc 0x00001efc 0x000f0 0x000f0 RW  0x4
  13.   NOTE           0x000168 0x00000168 0x00000168 0x00044 0x00044 R   0x4
  14.   GNU_EH_FRAME   0x000624 0x00000624 0x00000624 0x00044 0x00044 R   0x4
  15.   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  16.   GNU_RELRO      0x000ef4 0x00001ef4 0x00001ef4 0x0010c 0x0010c R   0x1

  17. Section to Segment mapping:
  18.   Segment Sections...
  19.    00
  20.    01     .interp
  21.    02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame
  22.    03     .init_array .fini_array .dynamic .got .got.plt .data .bss
  23.    04     .dynamic
  24.    05     .note.ABI-tag .note.gnu.build-id
  25.    06     .eh_frame_hdr
  26.    07
  27.    08     .init_array .fini_array .dynamic .got<b>段</b><div align="left"><font color="rgb(51, 51, 51)"><font "="" face=""><font style="font-size: 16px">段表(Section Header Table)是一个以 Elf32_Shdr 结构体为元素的数组,每个结构体对应一个段,它描述了各个段的信息。ELF 文件头的 e_shoff 成员给出了段表在 ELF 中的偏移,e_shnum 成员给出了段描述符的数量,e_shentsize 给出了每个段描述符的大小。</font></font></font></div>typedef struct
  28. {
  29.   Elf32_Word    sh_name;        /* Section name (string tbl index) */
  30.   Elf32_Word    sh_type;        /* Section type */
  31.   Elf32_Word    sh_flags;       /* Section flags */
  32.   Elf32_Addr    sh_addr;        /* Section virtual addr at execution */
  33.   Elf32_Off sh_offset;      /* Section file offset */
  34.   Elf32_Word    sh_size;        /* Section size in bytes */
  35.   Elf32_Word    sh_link;        /* Link to another section */
  36.   Elf32_Word    sh_info;        /* Additional section information */
  37.   Elf32_Word    sh_addralign;       /* Section alignment */
  38.   Elf32_Word    sh_entsize;     /* Entry size if section holds table */
  39. } Elf32_Shdr;

  40. typedef struct
  41. {
  42.   Elf64_Word    sh_name;        /* Section name (string tbl index) */
  43.   Elf64_Word    sh_type;        /* Section type */
  44.   Elf64_Xword   sh_flags;       /* Section flags */
  45.   Elf64_Addr    sh_addr;        /* Section virtual addr at execution */
  46.   Elf64_Off sh_offset;      /* Section file offset */
  47.   Elf64_Xword   sh_size;        /* Section size in bytes */
  48.   Elf64_Word    sh_link;        /* Link to another section */
  49.   Elf64_Word    sh_info;        /* Additional section information */
  50.   Elf64_Xword   sh_addralign;       /* Section alignment */
  51.   Elf64_Xword   sh_entsize;     /* Entry size if section holds table */
  52. } Elf64_Shdr;
复制代码


使用 readelf 命令查看目标文件中完整的段:
  1. $ readelf -S elfDemo.o
  2. There are 15 section headers, starting at offset 0x41c:

  3. Section Headers:
  4.   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  5.   [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  6.   [ 1] .group            GROUP           00000000 000034 000008 04     12  16  4
  7.   [ 2] .text             PROGBITS        00000000 00003c 000078 00  AX  0   0  1
  8.   [ 3] .rel.text         REL             00000000 000338 000048 08   I 12   2  4
  9.   [ 4] .data             PROGBITS        00000000 0000b4 000008 00  WA  0   0  4
  10.   [ 5] .bss              NOBITS          00000000 0000bc 000004 00  WA  0   0  4
  11.   [ 6] .rodata           PROGBITS        00000000 0000bc 000004 00   A  0   0  1
  12.   [ 7] .text.__x86.get_p PROGBITS        00000000 0000c0 000004 00 AXG  0   0  1
  13.   [ 8] .comment          PROGBITS        00000000 0000c4 000012 01  MS  0   0  1
  14.   [ 9] .note.GNU-stack   PROGBITS        00000000 0000d6 000000 00      0   0  1
  15.   [10] .eh_frame         PROGBITS        00000000 0000d8 00007c 00   A  0   0  4
  16.   [11] .rel.eh_frame     REL             00000000 000380 000018 08   I 12  10  4
  17.   [12] .symtab           SYMTAB          00000000 000154 000140 10     13  13  4
  18.   [13] .strtab           STRTAB          00000000 000294 0000a2 00      0   0  1
  19.   [14] .shstrtab         STRTAB          00000000 000398 000082 00      0   0  1
  20. Key to Flags:
  21.   W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  22.   L (link order), O (extra OS processing required), G (group), T (TLS),
  23.   C (compressed), x (unknown), o (OS specific), E (exclude),
  24.   p (processor specific)
复制代码

ps.ELF 段表的第一个元素是被保留的,类型为 NULL。

字符串表
字符串表以段的形式存在,包含了以 null 结尾的字符序列。对象文件使用这些字符串来表示符号和段名称,引用字符串时只需给出在表中的偏移即可。字符串表的第一个字符和最后一个字符为空字符,以确保所有字符串的开始和终止。通常段名为 .strtab 的字符串表是 字符串表(Strings Table),段名为 .shstrtab 的是段表字符串表(Section Header String Table)。
可以使用 readelf 读取这两个表:
  1. $ readelf -x .strtab elfDemo.o

  2. Hex dump of section '.strtab':
  3.   0x00000000 00656c66 44656d6f 2e63006c 6f63616c .elfDemo.c.local
  4.   0x00000010 5f737461 7469635f 696e6974 5f766172 _static_init_var
  5.   0x00000020 2e323139 35006c6f 63616c5f 73746174 .2195.local_stat
  6.   0x00000030 69635f75 6e696e69 745f7661 722e3231 ic_uninit_var.21
  7.   0x00000040 39360067 6c6f6261 6c5f696e 69745f76 96.global_init_v
  8.   0x00000050 61720067 6c6f6261 6c5f756e 696e6974 ar.global_uninit
  9.   0x00000060 5f766172 0066756e 63005f5f 7838362e _var.func.__x86.
  10.   0x00000070 6765745f 70635f74 68756e6b 2e617800 get_pc_thunk.ax.
  11.   0x00000080 5f474c4f 42414c5f 4f464653 45545f54 _GLOBAL_OFFSET_T
  12.   0x00000090 41424c45 5f007072 696e7466 006d6169 ABLE_.printf.mai
  13.   0x000000a0 6e00

  14. $ readelf -x .shstrtab elfDemo.o

  15. Hex dump of section '.shstrtab':
  16.   0x00000000 002e7379 6d746162 002e7374 72746162 ..symtab..strtab
  17.   0x00000010 002e7368 73747274 6162002e 72656c2e ..shstrtab..rel.
  18.   0x00000020 74657874 002e6461 7461002e 62737300 text..data..bss.
  19.   0x00000030 2e726f64 61746100 2e746578 742e5f5f .rodata..text.__
  20.   0x00000040 7838362e 6765745f 70635f74 68756e6b x86.get_pc_thunk
  21.   0x00000050 2e617800 2e636f6d 6d656e74 002e6e6f .ax..comment..no
  22.   0x00000060 74652e47 4e552d73 7461636b 002e7265 te.GNU-stack..re
  23.   0x00000070 6c2e6568 5f667261 6d65002e 67726f75 l.eh_frame..grou
  24.   0x00000080 7000
复制代码

符号表
目标文件的符号表保存了定位和重定位程序的符号定义和引用所需的信息。符号表索引是这个数组的下标。索引0指向表中的第一个条目,作为未定义的符号索引。
  1. typedef struct
  2. {
  3.   Elf32_Word    st_name;        /* Symbol name (string tbl index) */
  4.   Elf32_Addr    st_value;       /* Symbol value */
  5.   Elf32_Word    st_size;        /* Symbol size */
  6.   unsigned char st_info;        /* Symbol type and binding */
  7.   unsigned char st_other;       /* Symbol visibility */
  8.   Elf32_Section st_shndx;       /* Section index */
  9. } Elf32_Sym;

  10. typedef struct
  11. {
  12.   Elf64_Word    st_name;        /* Symbol name (string tbl index) */
  13.   unsigned char st_info;        /* Symbol type and binding */
  14.   unsigned char st_other;       /* Symbol visibility */
  15.   Elf64_Section st_shndx;       /* Section index */
  16.   Elf64_Addr    st_value;       /* Symbol value */
  17.   Elf64_Xword   st_size;        /* Symbol size */
  18. } Elf64_Sym;
复制代码


查看符号表:
  1. $ readelf -s elfDemo.o

  2. Symbol table '.symtab' contains 20 entries:
  3.    Num:    Value  Size Type    Bind   Vis      Ndx Name
  4.      0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
  5.      1: 00000000     0 FILE    LOCAL  DEFAULT  ABS elfDemo.c
  6.      2: 00000000     0 SECTION LOCAL  DEFAULT    2
  7.      3: 00000000     0 SECTION LOCAL  DEFAULT    4
  8.      4: 00000000     0 SECTION LOCAL  DEFAULT    5
  9.      5: 00000000     0 SECTION LOCAL  DEFAULT    6
  10.      6: 00000004     4 OBJECT  LOCAL  DEFAULT    4 local_static_init_var.219
  11.      7: 00000000     4 OBJECT  LOCAL  DEFAULT    5 local_static_uninit_var.2
  12.      8: 00000000     0 SECTION LOCAL  DEFAULT    7
  13.      9: 00000000     0 SECTION LOCAL  DEFAULT    9
  14.     10: 00000000     0 SECTION LOCAL  DEFAULT   10
  15.     11: 00000000     0 SECTION LOCAL  DEFAULT    8
  16.     12: 00000000     0 SECTION LOCAL  DEFAULT    1
  17.     13: 00000000     4 OBJECT  GLOBAL DEFAULT    4 global_init_var
  18.     14: 00000004     4 OBJECT  GLOBAL DEFAULT  COM global_uninit_var
  19.     15: 00000000    46 FUNC    GLOBAL DEFAULT    2 func
  20.     16: 00000000     0 FUNC    GLOBAL HIDDEN     7 __x86.get_pc_thunk.ax
  21.     17: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
  22.     18: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
  23.     19: 0000002e    74 FUNC    GLOBAL DEFAULT    2 main
复制代码

重定位
重定位是连接符号定义与符号引用的过程。可重定位文件必须具有描述如何修改段内容的信息,从而运行可执行文件和共享对象文件保存进程程序映像的正确信息。
  1. typedef struct
  2. {
  3.   Elf32_Addr    r_offset;       /* Address */
  4.   Elf32_Word    r_info;         /* Relocation type and symbol index */
  5. } Elf32_Rel;

  6. typedef struct
  7. {
  8.   Elf64_Addr    r_offset;       /* Address */
  9.   Elf64_Xword   r_info;         /* Relocation type and symbol index */
  10.   Elf64_Sxword  r_addend;       /* Addend */
  11. } Elf64_Rela;
复制代码


查看重定位表:

  1. $ readelf -r elfDemo.o

  2. Relocation section '.rel.text' at offset 0x338 contains 9 entries:
  3. Offset     Info    Type            Sym.Value  Sym. Name
  4. 00000008  00001002 R_386_PC32        00000000   __x86.get_pc_thunk.ax
  5. 0000000d  0000110a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
  6. 00000019  00000509 R_386_GOTOFF      00000000   .rodata
  7. 00000021  00001204 R_386_PLT32       00000000   printf
  8. 00000040  00001002 R_386_PC32        00000000   __x86.get_pc_thunk.ax
  9. 00000045  0000110a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
  10. 00000052  00000d09 R_386_GOTOFF      00000000   global_init_var
  11. 0000005d  00000309 R_386_GOTOFF      00000000   .data
  12. 00000068  00000f02 R_386_PC32        00000000   func

  13. Relocation section '.rel.eh_frame' at offset 0x380 contains 3 entries:
  14. Offset     Info    Type            Sym.Value  Sym. Name
  15. 00000020  00000202 R_386_PC32        00000000   .text
  16. 00000044  00000202 R_386_PC32        00000000   .text
  17. 00000070  00000802 R_386_PC32        00000000   .text.__x86.get_pc_thu
复制代码


回复

使用道具 举报

5

主题

40

帖子

215

积分

中级会员

Rank: 3Rank: 3

积分
215
 楼主| 发表于 2020-5-20 22:52:40 | 显示全部楼层
linux下的汇编代码编译工具——nasm用法摘要
主要参考:官方文档
用法:
组装一个文件,你发出一个窗体的命令
nasm −f <format> <filename> [−o <output>]
nasm -f <格式> <文件名> [-o <输出>]

选项:

-o 选项:指定输出文件名称
NASM通常会为您选择输出文件的名称;这究竟是如何依赖的关于对象文件格式。对于Microsoft目标文件格式(obj,win32和win64),它将删除.asm扩展名(或任何你喜欢使用的扩展名--NAMM不关心)从你的源文件名并替换.obj。对于Unix对象文件格式(aout,as86,coff,elf32,elf64,elfx32,ieee,macho32和macho64)将替代.o。对于dbg,rdf,ith和srec,它将使用.dbg,.rdf,.ith和.srec,并且对于bin格式,它将简单地删除扩展名,这样myfile.asm生成输出文件myfile。
如果输出文件已经存在,则NASM将覆盖它,除非它与输入文件具有相同的名称这种情况下会给出警告,并使用nasm.out作为输出文件名。对于这种行为不可接受的情况,NASM提供-o命令行选项,它允许你指定你想要的输出文件名。您通过跟随名称来调用-o您希望输出文件,无论有无间隔空间。例如:
nasm -f bin program.asm -o program.com
nasm -f bin driver.asm -odriver.sys
请注意,这是一个小的o,并且不同于大写字母O,它用于指定数量需要优化通行证。

-f 选项:指定输出文件格式
如果你不提供-f选项给NASM,它会为你自己选择一个输出文件格式。 在里面NASM的分发版本,默认是bin。 如果你编译了自己的NASM副本,你可以在编译时重新定义OF_DEFAULT,并选择你想要的默认。
与-o一样,-f和输出文件格式之间的中间空格是可选的; 所以 −f elf和−felf都是有效的。可用输出文件格式的完整列表可以通过发出命令nasm -hf来给出;

-l 选项:生成列表文件
如果你向NASM提供-l选项,请按照文件名,NASM将会生成一个源代码文件,其中的地址和生成的代码在左边列出实际的源代码,多线宏的扩展。 例如:
nasm -f elf myfile.asm -l myfile.lst
如果选择了一个列表文件,你可以用[list - ]关闭源文件的列表,然后把它关掉回到[list +]。 没有“用户表单”(没有括号)。 这个可以用来列出仅感兴趣的部分,避免过长的列表。

-M 选项:生成Makefile依赖项
这个选项可以用来生成stdout的makefile依赖关系。 这可以重定向到一个文件进一步处理。 例如:
nasm -M myfile.asm> myfile.dep

-MG 选项:生成Makefile依赖项
这个选项可以用来生成stdout的makefile依赖关系。 这与-M选项不同如果遇到一个不存在的文件,它被认为是一个生成的文件,并被添加到依赖列表没有前缀。

-MF 选项:设置Makefile依赖项文件
此选项可与-M或-MG选项一起使用,以将输出发送到文件,而不是标准输出。例如:
nasm -M -MF myfile.dep myfile.asm

-MD 选项:组装并生成相关性
-MD选项充当-M和-MF选项的组合(即,必须指定文件名)。但是,与-M或-MG选项不同,-MD不禁止汇编程序的正常操作。使用它来自动生成更新的每个程序集会话的依赖关系。 例如:
nasm -f elf -o myfile.o -MD myfile.dep myfile.asm

-MT 选项:依赖目标名称
-MT选项可用于覆盖依赖目标的默认名称。 这通常是与由-o选项指定的输出文件名相同。

-MQ 选项:依赖目标名称(引用)
-MQ选项作为-MT选项,除了试图引用在其中有特殊含义的字符Makefile语法。 这并非万无一失,因为并不是所有有特殊含义的人物都可以在Make中引用。默认输出(如果没有指定-MT或-MQ选项)会被自动引用。

-MP 选项:发出假目标
与任何依赖关系生成选项一起使用时,-MP选项会导致NASM发出一个假的目标没有依赖每个头文件。 这可以防止从抱怨,如果一个头文件已被删除。

-MW 选项:Watcom引用引用样式
这个选项会导致NASM尝试根据Watcom Make约定引用依赖关系而不是POSIX Make约定(也被大多数其他Make变体使用)。这引号#为$#而不是\#,使用&而不是\作为连续行,并且包含文件名双引号中的空格。

-F 选项:选择调试信息格式
这个选项用来选择发送到输出文件的调试信息的格式由调试器(或将)使用。 在版本2.03.01之前,使用这个开关并没有启用输出选定的调试信息格式。 使用-g,启用输出。 版本2.03.01和更高版本如果指定-F,则自动启用-g。输出格式的可用调试文件格式的完整列表可以通过发出命令nasm -f <format> -y。 并不是所有的输出格式都支持调试输出。

-g 选项:启用调试信息。
这个选项可以用来以指定的格式生成调试信息。 使用不带-F的-g导致以默认格式发送调试信息,如果有的话,为所选输出格式。 如果当前没有以选定的输出格式执行调试信息,-g是静默的忽略。

-X 选项:选择错误报告格式
这个选项可以用来为可能的错误信息选择错误报告格式由NASM制作。目前,可以选择两种错误报告格式。他们是-Xvc选项和-Xgnu选项。 GNU格式是默认的,如下所示:
filename.asm:65:错误:特定的错误消息
其中filename.asm是检测到错误的源文件的名称,65是源文件
检测到错误的文件行号,错误是错误的严重程度(可能是警告),具体的错误信息是一个更详细的文字信息,这应该有所帮助精确确定问题。
另一种由-Xvc指定的格式是Microsoft Visual C ++和其他一些程序使用的样式。它看起来像这样:filename.asm(65):错误:特定的错误消息
唯一的区别是行号在括号内,而不是由冒号分隔。

-Z 选项:将错误发送到文件
在MS-DOS下,它可能很难(虽然有办法)重定向的标准错误输出程序到一个文件。 由于NASM通常在stderr上产生警告和错误信息,这可以如果(例如)要将它们加载到编辑器中,则很难捕获错误。因此,NASM提供了-Z选项,并带有导致错误发送到的文件名参数指定的文件而不是标准错误。 因此,您可以通过键入将错误重定向到文件中
nasm -Z myfile.err -f obj myfile.asm
在NASM的早期版本中,这个选项被称为-E,但是它被改变了,因为-E是一个选项通常只用于预处理,结果是灾难性的。

-s 选项:将错误发送到标准输出
-s选项将错误消息重定向到标准输出而不是标准错误,因此可以在下面重定向MS-DOS。 要组装文件myfile.asm并将其输出传递给更多程序,可以键入:
nasm -s -f obj myfile.asm | more

-i 选项:包含文件搜索目录
当NASM在源文件中看到%include或%pathsearch指令时,它将不仅在当前目录中搜索给定的文件,而且还将搜索任何文件通过使用-i选项在命令行中指定的目录。所以你可以包含文件从一个宏库,例如,通过键入
nasm -ic:\ macrolib \ -f obj myfile.asm
(像往常一样,-i和路径名之间的空格是允许的,并且是可选的)。
为了完整的源代码可移植性,NASM不理解文件命名正在运行的操作系统的约定;您提供的字符串作为参数的-i选项将是与写入包含文件的名称完全相同。因此在后面的反斜杠上面的例子是必要的。在Unix下,同样需要一个尾随的正斜杠。(你可以使用这个优点,如果你真的反常,注意选项-ifoo会导致%include“bar.i”搜索文件foobar.i ...)如果你想定义一个标准的包含搜索路径,类似于Unix系统上的/ usr / include,那么你应在NASMENV环境变量中放置一个或多个-i指令。对于许多C编译器的Makefile兼容性,此选项也可以指定为-I。

-p 选项:预先包含文件
NASM允许您使用-p选项指定要预先包含在源文件中的文件。 所以赛跑
nasm myfile.asm -p myinc.inc
相当于运行nasm myfile.asm并将指令%include“myinc.inc”放在文件的开始。为了与-I,-D和-U选项保持一致,这个选项也可以被指定为-P。

-d 选项:预定义一个宏
正如-p选项提供了在源文件开始处放置%include指令的替代方法,-d选项给出了放置%define指令的替代方案。 你可以编码
nasm myfile.asm -dFOO = 100
作为放置指令的替代方法
%定义FOO 100
在文件的开始。 您也可以错过宏观价值:选项-dFOO相当于编码%定义FOO。 这种形式的指令对于选择组装时间选项可能是有用的然后使用%ifdef进行测试,例如-dDEBUG。对于许多C编译器的Makefile兼容性,此选项也可以指定为-D。

-u 选项:取消定义宏
-u选项取消定义一个宏,否则它将被自动或者预定义通过前面在命令行中指定的-p或-d选项。
例如,下面的命令行:
nasm myfile.asm -dFOO = 100 -uFOO
会导致FOO不是程序中的预定义宏。 这对覆盖选项很有用在Makefile的不同位置指定。对于许多C编译器的Makefile兼容性,此选项也可以指定为-U。

-E 选项:仅预处理
NASM允许预处理器自己运行,直到一点。 使用-E选项(需要没有参数)将导致NASM预处理其输入文件,展开所有的宏引用,全部删除注释和预处理器指令,并将结果文件打印到标准输出(或保存到一个文件,如果-o选项也被使用)。
该选项不能应用于需要预处理器评估表达式的程序这取决于符号的值:所以代码如%assign tablesize($ --tablestart)会在预处理模式下导致错误。
为了兼容老版本的NASM,这个选项也可以写成-e。 -E在旧版本的NASM相当于现在的-Z选项。

-a 选项:根本不要预处理
如果将NASM用作编译器的后端,则可能需要抑制预处理完全假设编译器已经完成了它,以节省时间和增加编译速度。 -a选项,不需要参数,指示NASM替换其强大的预处理器与不做任何事情的存根预处理器。

-O 选项:指定多通道优化
使用-O选项,您可以告诉NASM执行不同级别的优化。语法是:
-O0:没有优化。如果没有指定一个简短格式,所有操作数都采用长格式有条件的跳转。这是为了匹配NASM 0.98的行为。
-O1:最小化优化。如上所述,但是符合有符号字节的立即操作数是优化,除非长表格被指定。条件跳转默认为长格式,除非否则指定。
-Ox(其中x是实际字母x):Multipass优化。最小化分支偏移并签名即时字节,除非已经使用strict关键字,否则覆盖大小规范)。为了与早期版本兼容,字母x也可以是更大的数字比一个。这个数字对实际的传球次数没有影响。-Ox模式被推荐用于大多数用途,并且是自NASM 2.09以来的默认模式。
请注意,这是一个大写字母O,与用于指定输出文件的小o不同名称。

-t 选项:启用TASM兼容模式
NASM包含与Borland的TASM兼容的有限形式。 当使用NASM的-t选项时,做出以下更改:
本地标签可以用@@替代前缀。
括号内支持大小覆盖。 在TASM兼容模式下,广场内的尺寸覆盖括号会更改操作数的大小,而不是操作数的地址类型NASM语法。 例如。 mov eax,[DWORD val]在TASM兼容模式下是有效的语法。 注意您将无法覆盖该指令的默认地址类型。
支持某些指令的前缀形式(arg,elif,else,endif,if,ifdef,ifdifi,ifndef,include,local)

-v 选项:显示版本信息
键入NASM -v将显示您正在使用的NASM的版本以及它所在的日期编译。如果您报告错误,您将需要版本号。对于与Yasm的命令行兼容性,格式--v也可以用于此选项NASM版本.

-y 选项:显示可用的调试信息格式
键入nasm -f <选项> -y 将显示给定的可用调试信息格式的列表输出格式。 默认格式用星号表示。 例如:
nasm -f elf -y

--prefix和--postfix选项。
--prefix和--postfix选项将给定的参数前置或附加到全部全局或外部变量。 例如。 --prefix _将在全局和全部前面加上下划线外部变量,因为C需要在一些系统调用约定中,但不是全部。

示例:
1、将myfile.asm组装成一个ELF对象文件myfile.o
nasm -f elf myfile.asm

2、将myfile.asm组装成一个原始的二进制文件myfile.com
nasm -f bin myfile.asm -o myfile.com

3、要生成列表文件,在原始文件左侧显示从NASM输出的十六进制代码来源,使用-l选项给出一个列表文件名;
nasm -f coff myfile.asm -l myfile.lst

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 14:38 , Processed in 0.014933 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表