汇编阶段
汇编阶段将得到真正的机器代码,汇编阶段的输入是在编译阶段生成的汇编语言集,输出是一组对象文件,有时简称为模块。
对象文件原则上包含可由处理器执行的机器指令。
通常情况下,每个源文件对应一个汇编文件,每个汇编文件对应一个对象文件。
生成对象文件,传递-c标志给gcc,
可以使用file工具来确认生成的compilation_example.o文件确实是对象文件。
file输出的第一部分显示了该文件符合二进制可执行文件的ELF规范。具体地,是一个64位的ELF二进制文件(因为在这个示例中编译的是x86_64),并且是最低有效位(Least Significant Bit,LSB),这意味着数在内存中的排序是以最低有效字节优先的。但最重要的是,可以看到该文件是可重定位的。
可重定位文件不依赖于放置在内存中的任何特定地址,相反,它们可以随意移动,而不会破坏代码中的任何假设。当在文件输出中看到术语“可重定位”时,表示正在处理的是对象文件而不是可执行文件。
对象文件相互独立编译,因此汇编程序在组装对象文件时无法知道其他对象文件的内存地址。这就是对象文件需要可重定位的原因,这样就可 ...
二进制分析
未读目标是解析flag,为一个序列号
查看PE文件,可见是一个win32程序,32位exe,并且加壳了,加壳工具是tElock,首先脱壳得到脱壳后的文件。
用IDA反编译:
分析DialogFunc,获取最终的flag;
此处应该是获取了两个输入,用户名和序列号。
DialogFunc中可分析出由一个子函数控制着序列号正确与否,接着去分析sub_401610,该函数接受的参数是lpString,也是输入的序列号,尝试去找到该序列号的正确匹配结果;
查看sub_401610函数的伪代码,其中又调用了其他函数过程,挨个分析吧;
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131 ...
链接阶段
链接阶段是编译过程的最后阶段。顾名思义,此阶段将所有对象文件链接到一个二进制可执行文件中。在现代系统中,链接阶段有时会包含额外的优化过程,被称为链接时优化(Link-Time Optimization, LTO)。
执行链接阶段的程序被称为链接器或者链接编辑器。通常链接器与编译器相互独立,编译器通常实现前面所有的步骤。
对象文件是可重定位的,它们是相互独立编译的,这使得编译器无法假设对象最终会出现在任意特定的基址上。
对象文件可以引用其他对象文件或程序外部库中的函数或者变量。在链接阶段之前,引用代码和数据的地址尚不清楚,因此对象文件只包含重定位符号,这些符号指定最终如何解析函数和变量引用。在链接上下文中,依赖于重定位符号的引用称为符号引用。
当一个对象文件通过绝对地址引用自己的函数或变量时,该引用也会被符号化。
链接器的工作是获取属于程序的所有对象文件,并将它们合并为一个连贯的可执行文件,然后加载到特定的内存地址。既然现在已经知道可执行文件中所有模块的排列,链接器也就可以解析大多数的符号引用了。
根据库文件的类型,对库文件的引用可能会、也可能不会完全解析。 ...
二进制分析
未读反汇编二进制文件
已经了解了如何编译二进制文件,那么让我们来看一下编译汇编阶段生成的对象文件内容。之后,我将会反汇编二进制可执行文 件,显示可执行文件内容与对象文件的内容有何不同。
查看对象文件
使用objdump实用程序来展示如何进行反汇编。objdump是一个简单、易用的反汇编程序,包含在大多数Linux发行版中,非常适合快速了解二进制文件中包含的代码和数据。
此处,调用了objdump两次。
第一次,在 ❶处,调用objdump显示.rodata节的内容。.rodata节代表的是“只 读数据”,二进制文件中所有的常量都存储在该节,包括“Hello, world!”字符串。注意,.rodata节的内容是由 ASCII编码的字符串组成的,显示在左侧的输出中。在右侧,你可以看到相同字节的可读表示。
第二次在❷处调用objdump,以Intel语法反汇编对象文件的所有代码。正如你所看到的,结果仅包含main函数❸的代码,因为这是源文件中定义的唯一函数。大多数情况下,输出与先前由编译阶段生成的汇编 代码非常接近,它采用了一些汇编级宏。有趣的是,指向“Hello, world!”字符串的 ...
二进制分析
未读符号和剥离的二进制文件
符号信息
高级源代码(如C代码)均以有意义的、人类可读的函数和变量命名为中心。编译程序时,编译器会翻译符号,这些符号会跟踪其名称,并记录哪些二进制代码和数据对应哪个符号。
用到了 readelf来显示符号❶。
请注意,在许多不熟悉的符号中,main函数❷有一个符号。你可以看到它指定了当二进制文件加载到内存时main将驻留的地址(0x400526)。输出还显示main的代码大小(32字节),并指出你正在处理一个函数符号(类型为 FUNC)。
符号信息可以作为二进制文件的一部分,或者以单独的符号文件形式转译,它有各种风格。链接器只需要基本符号,但为了调试,可以转译出更广泛的信息。
调试符号提供了源 代码行和二进制指令之间的完整映射关系,甚至描述了函数的参数、堆栈帧信息等。对于ELF二进制文件,调试符号通常以DWARF格式生成,而PE二进制文件通常使用专有的Microsoft可移植调试(如PDB)格式。DWARF信息通常嵌在二进制文件中,而PDB则以单独的符号文件的形式存在。
符号信息对于二进制分析非常有用。一组定义良好的函数符号可以使反汇编更加容易,这是因为可 ...
二进制分析
未读123456789101112131415161718 5 touch a.c 6 gcc -E -P a.c 7 gcc -S -masm=intel a.c 8 cat a.s 9 gcc -c a.c10 file a.o11 gcc a.c12 file a.out13 ls14 ./a.out15 readelf --syms a.out16 strip --strip-all a.out17 file a.out18 objdump -sj .rodata a.o19 objdump -M intel -d a.o20 readelf --relocs a.o21 ls22 objdump -M intel -d ./a.out.stripped
加载并执行二进制文件
加载二进制文件是一个复杂的过程,涉及操作系统的大量工作。同样重要的是,内存中二进制文件的表示不一定与磁盘上二进制文件的表示一一对应。
图1-2显示了如何在Linux操作系统上 加载ELF二进制文件,如刚编译的二进制文件。从高层次上讲,这与在Windows操作系统上加载PE ...
这是一个指南
安知鱼主题指南 (gavinblog.github.io)
布局(Layout)
Hexo 有三种默认布局:post、page 和 draft。在创建这三种不同类型的文件时,它们将会被保存到不同的路径;而您自定义的其他布局和 post 相同,都将储存到 source/_posts 文件夹。
布局
路径
post
source/_posts
page
source
draft
source/_drafts
1 常用命令
123456789101112131415161718hexo inithexo cleanhexo generatehexo serverhexo dhexo new "postName" #新建文章hexo new page "pageName" #新建页面hexo generate #生成静态页面至public目录hexo server #开启预览访问端口(默认端口4000,'ctrl + c'关闭server)hexo deploy #部署到GitHubhexo ...
Intelligent Vulnerability Detector using deep sequence and graph based Hybrid Feature Extraction
This manuscript proposed a graph-based and sequence-based neural network model for detecting vulnerabilities in Java code, utilizing multiple program features,which addresses the detection problem of a range of vulnerabilities collected from the Common Weakness Enumeration (CWE) . It introduces GCN-RFEMLP for extracting graph-based features and employs CodeBERT for extracting sequence-based features ...
代码混淆定义:
原代码 P 通过某种变换变成代码 P’,若 P 和 P’运行结果与过程行为保持一致,该种变换就称之为混淆变换。
具体来说,当混淆转换满足以下两种情况时,这种混淆变化称之为合法的转换:
(1)如果源程序 P 无法停止运行或报错结束运行,则变换后的程序 P’可以结束运行也可以继续运行。
(2)否则,目标程序 P’也结束运行并且输出与源程序相同的结果。
两个程序之间操作并不一定完全相同,且不一定有相同的效率。
实际上,混淆工具预先设定若干混淆规则,并使用其它更为复杂的代码取代源代码中符合条件的代码语句,虽然源代码语义并未改变但混淆后的程序运行过程中空间复杂度往往更高,执行时间也更长,甚至有可能改变系统环境等。
图 2.1 展示了混淆编译的整体流程,
首先混淆工具会对输入的源代码进行代码预处理得到程序控制流图 CFG、抽象语法树 AST 等信息,
然后对数据流、控制流等进行分析,并根据输入的混淆参数选择对应的混淆算法处理源代码,
最后输出混淆编译后的程序。
尽管混淆策略多种多样,但通常按 Collberg 提出的方法将其大致分为四类[16]:
布局混淆
数据流混淆
...