重定位

编译原理学习笔记

强颜欢笑 提交于 2019-12-27 01:51:57
机器语言:可以被计算机直接理解 汇编语言:引入助记符,依赖特定机器,编写效率低 高级语言:类似于数学定义或自然语言的简洁形式,编写效率高 编译:将高级语言翻译成汇编语言或机器语言的过程。 源程序——>(预处理器)——>经过预处理的源程序——>(编译器)——>汇编语言程序——>(汇编器)——>可重定位的机器代码——>(链接器/加载器)——>目标机器代码 预处理器: 1、把存储在不同文件中的源程序聚合在一起 2、把被称为宏的缩写语句转换为原始语句 可重定位:在内存中存放的起始位置不是固定的 连接器: 1、将多个可重定位的机器代码文件(包括库文件)连接到一起 2、解决外部内存地址问题 加载器: 1、修改可重定位地址 2、将修改后的指令和数据放到内存中适当的位置 编译分为两个阶段: 1、词法分析 2、语法分析:语法分析器从词法分析器输出的token序列中识别出各类短语,并构造语法分析树,语法分析树描述了句子的语法结构 语义分析的主要任务: 1、手机标识符的属性信息 2、语义检查 (1)变量或过程未经声明就使用 (2)变量或过程名重复声明 (3)运算分量类型不匹配 (4)操作符与操作数之间的类型不匹配 1)数组下标不是整数 2)对非数组标量使用数组访问操作符 3)对非过程名使用过程调用操作符 4)过程调用的参数类型或数目不匹配 5)函数返回类型有误 常用的中间表示形式: 1、三地址码

ORBSLAM2解析(2)——Tracking 线程

北慕城南 提交于 2019-12-22 23:04:24
文章目录 主要参考 Tracking线程 输入的预处理 地图的初始化 相机位姿的估计(包括重定位) 局部地图的跟踪 关键帧的判断与创建 主要参考 双目ORB-SLAM2代码个人总结(一) -> 非常详细描述了跟踪线程 ORB SLAM2源码解读 -> 整个系列按各个类(Frame、MapPoint、KeyFrame…)来解读 Tracking线程 Tracking线程作为系统的主线程,主要实现输入的预处理、地图的初始化、相机位姿估计、局部地图的跟踪、关键帧的判断与创建。( 注意:文章以RGBD输入下的定位且建图模式进行分析 ) 输入的预处理 在图像每一帧的初始化中,ORBSLAM2中将双目或者RGB-D相机输入的数据都转化成了 Stereo Keypoint ,即 ( u L , v L , u R ) (u_L, v_L, u_R) ( u L ​ , v L ​ , u R ​ ) ,这样后续对于双目或者RGB-D的处理是几乎一样的。 地图的初始化 地图初始化是发生在SLAM系统运行的最开始时候,创建一个能提取足够特征点的关键帧作为第一帧,并将第一帧固定,创建特征点对应的地图点。 相机位姿的估计(包括重定位) 相机位姿估计应该是整个跟踪线程最重要的部分了,这里重点讲述下个人的理解。这部分主要分为三种情况:跟踪运动模型、跟踪关键帧、运动丢失后重定位。(每部分思维图就不展开了

ELF文件格式

点点圈 提交于 2019-12-20 19:32:46
ELF头 Object目标文件类型 Object文件格式 数据表示 ELF Header结构体 e_ident e_type类型 e_machine ELF节 section头表结构体 section介绍 符号表 字符串表 符号值 重定位 重定位类型 Linux命令行 ELF头 Object目标文件类型 一个可重定位(relocation)文件保存着代码和适当的数据,用来和其他的object文件一起创建一个可执行文件或一个共享文件。 一个可执行(executable)文件保存着一个用来执行的程序,该文件指出exec(BA_OS)如何创建程序进程映像。 一个共享object文件保存着代码和合适的数据,用来被链接器链接。第一个链接器[ld(SD_CMD)],可以和其他的可重定位和共享object文件来创建其他的object;第二个动态链接器,联合一个可执行文件和其他共享object文件来创建一个进程映像。 Object文件格式 数据表示 ELF Header结构体 # define EI_NIDENT 16 typedef struct { unsigned char e_ident [ EI_NIDENT ] ; Elf32_Half e_type ; Elf32_half e_machine ; Elf32_Word e_version ; //目标文件的版本,若为0

作为一个新人,怎样学习嵌入式Linux

你离开我真会死。 提交于 2019-12-20 02:14:43
作为一个新人,怎样学习嵌入式Linux 作者:管理员 发布于:2012-10-05 15:01:20 文字:【 大 】【 中 】【 小 】 作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下。 在学习嵌入式Linux之前,肯定要有C语言基础。汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会)。 C语言要学到什么程度呢?越熟当然越好,不熟的话也要具备基本技能。比如写一个数组排序、输入数字求和什么的。 学C语言唯一的方法是多写程序多练习,编译出错没关系,自己去解决;执行出错没关系,自己去分析。以前我是用VC来练习C语言的,经常去尝试着写一些C语言竞赛的题目。它们是纯C、纯数学、纯逻辑的题目,不涉及界面这些东西,很适合煅炼你的编程能力。 回到主题,首先我们要明白你的目的是什么,大概来说所谓嵌入式Linux可以分为两部分:底层系统、应用开发。 如果你是想做应用开发,那么你去把C语言、数据结构、JAVA什么的学好吧。嵌入式应用开发和PC上的应用开发并没有什么特别要注意的。也许你说在嵌入式上要做些优化,是的,要优化,但是未经优化的程序和PC上的程序开发没什么差别。另外,当你有能力去优化时,你已经不用来问这个问题了。具体到某个例子,比如说开发界面,在PC上我们用VC;在嵌入式Linux里也许我们用QT也许用Android,这个时候你应该去学学QT

作为一个新人,怎样学习嵌入式Linux?(转载)

一个人想着一个人 提交于 2019-12-15 21:37:55
特此声明此文章为转载,如有侵犯,请告知删除。 原文章地址:http://blog.sina.com.cn/s/blog_7880d33501013j2r.html 作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下。 在学习嵌入式Linux之前,肯定要有C语言基础。汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会)。 C语言要学到什么程度呢?越熟当然越好,不熟的话也要具备基本技能。比如写一个数组排序、输入数字求和什么的。 学C语言唯一的方法是多写程序多练习,编译出错没关系,自己去解决;执行出错没关系,自己去分析。以前我是用 VC来练习C语言的,经常去尝试着写一些C语言竞赛的题目。它们是纯C、纯数学、纯逻辑的题目,不涉及界面这些东西, 很适合煅炼你的编程能力。 回到主题,首先我们要明白你的目的是什么,大概来说所谓嵌入式Linux可以分为两部分:底层系统、应用开发。 如果你是想做应用开发,那么你去把C语言、数据结构、JAVA什么的学好吧。嵌入式应用开发和PC上的 应用开发并没有什么特别要注意的。也许你说在嵌入式上要做些优化,是的,要优化,但是未经优化的程序 和PC上的程序开发没什么差别。另外,当你有能力去优化时,你已经不用来问这个问题了。具体到某个例子, 比如说开发界面,在PC上我们用VC;在嵌入式Linux里也许我们用QT也许用Android

链接过程详解

橙三吉。 提交于 2019-12-11 05:39:26
一:链接的基本概念 链接(linking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。 链接可以执行于编译时,也可以执行于加载时,甚至执行于运行时。在现代系统中,链接是由叫做链接器(linker)的程序自动执行的。 为什么需要链接器呢?一切都是为了简单、为了方便!试想一下,一个巨大的工程有巨大的源文件,包含N多个模块,如果没有链接的存在,那么当你改动某个模块时,不得不重新编译整个工程,消耗巨大的时间和资源。而在链接器的帮助下,你只需要简单编译修改过的模块,之后重新链接生成可执行文件就OK了。 下面,我们将基于一个运行Linux的x86-64系统,详细讨论关于链接的各个方面。 二:从代码到可执行文件 考虑如下的一个c语言程序: code/link/main.c int sun(int *a, int n); int array[2] = {1, 2}; int main() { int val = sum(array, 2); return val; } code/link/sum.c int sum(int *a, int n) { int i, s = 0; for (i = 0; i < n; i++) s += a[i]; return s; } 从源文件到可执行文件需要哪几个步骤呢? 1:预处理器将C的源程序main

PE文件的修改和感染

别等时光非礼了梦想. 提交于 2019-12-07 15:08:05
【转】PE文件的修改和感染 2008-04-29 08:20 既然已经能够搜索磁盘及 网络 共享文件中的所有文件,要实现寄生,那么自然下一步就是对搜索到的PE文件进行感染了。感染PE的很重要的一个考虑就是将病毒代码写入到PE 文件的哪个位置。读写文件一般利用Win32 API CreateFile、CreateFileMapping、MapViewOfFile等API以内存映射文件的方式进行,这样可以避免自己管理缓冲的麻烦,因而为较多病毒所采用。为了能够读写具有只读属性的文 件,病毒在操作前首先利用GetFileAttributes 获取其属性并保存,然后用SetFileAttributes将文件的属性修改为可写,在 感染完毕后再恢复其属性值。      一般说来,有如下几种感染PE文件的方案供选择:   a)添加一个新的节。将病毒代码写入到新的节中,相应修改节表,文件头中文件大小等属性值。由于在PE尾部增加了一个节,因此较容易被用户察觉。在某些情况下,由于原PE头部没有足够的空间存放新增节的节表信息,因此还要对其它 数据 进行搬移等操作。鉴于上述问 题,PE 病毒使用该方法的并不多。   b)附加在最后一个节上。修改最后一个节节表的大小和属性以及文件头中文件大小等属性值。由于越来越多的杀毒软件采用了一种尾部扫描的方式,因此很多病毒还要在病毒代码之后附加随机 数据 以逃避该种扫描

Uroburos Rootkit样本简单分析

家住魔仙堡 提交于 2019-12-06 16:50:34
1.首先拿到样本,载入ida发现有一个类似于压缩壳解码的函数,跳过后dump出pe,修复对齐和section header。 2.该样本会检查是否运行在wow64环境,检测名为Ultra3的服务和一系列事件来确保是第一次启动。 3.随后该样本会内存加载资源段的一个pe文件尝试利用CVE-2009-1123执行特权代码 4.如果该漏洞利用成功将直接内存加载驱动文件,然后退出该样本。否则将会尝试利用CVE-2010-0232进行权限提升,该样本通过尝试改写注册表currentversion字段来判断是否权限提升成功。如果提权失败则返回错误代码退出样本。如果该样本运行在vista以上版本并且是64位系统,则会尝试通过virtualbox的驱动漏洞关闭dse。然后打开加载驱动权限,手动填写注册表的服务,通过ZwLoadDriver加载驱动。 5.该驱动会解密自身的代码,然后重新改写pe的入口,我们可以在解码完后用windbg dump出来然后修复。 5.修复完后该样本就是安全客那篇文章最后dump出来的样本( https://www.anquanke.com/post/id/189549) 6.该样本在驱动入口首先创建了一个全局的结构体储存一些信息,随后创建之前在应用层检测的全局事件。 struct { int unknown; //0xffffffff int* DriverStart;

操作系统-Linux-浅析GOT与PLT

荒凉一梦 提交于 2019-12-05 14:53:42
目标模块:你要加载进内存的模块 --加载位置无关代码(PIC)-- 位置无关代码(PIC):   可以加载,无需重定位的代码。 在内存中加载 目标模块 时, 数据段与代码段的距离总是保持不变。 与绝对内存地址无关 (不然程序就难以在代码段中引用数据段的数据) 利用这一点, 编译器会在 目标模块 的数据段的开始创建一个表,用于存放(被加载的) 目标模块 需要 的全局数据目标(函数或变量)。 这个表叫 全局偏移量表(GOT) 。 GOT中每个被 目标模块 引用的全局数据目标都有一个8个字节的条目(全局数据目标的绝对地址)。 编译器会为每个条目生成重定位记录,使得它(指条目)为正确的绝对地址。 我们写的代码会通过GOT间接访问全局数据目标。 这样的话 全局数据目标 即使在 其他模块 也能被正确引用。 示例:尝试加载某个共享模块中的某个函数 链接完成后的情况: 其他模块也可以通过访问GOT[4] 使用 全局变量 addr --调用共享库的函数-- 程序调用 共享库 定义的函数时,编译器无法预测函数的运行地址 (共享库加载地址无法被预测) 解决问题的方法:   1.为这个引用生成一条重定位记录,动态链接器在程序加载时解析。   2.延迟绑定:第一次调用函数时再绑定。 GNU编译系统:"我们使用延迟绑定" 为什么延迟绑定:   一个库装了一堆函数,程序可能就用两个……  

-fPIC编译选项

若如初见. 提交于 2019-12-04 18:42:12
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。 gcc -shared -fPIC -o 1.so 1.c 这里有一个-fPIC参数 PIC就是position independent code PIC使.so文件的代码段变为真正意义上的共享 如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置. 也就是 不加fPIC编译出来的so,是要再加载时根据加载到的位置再次重定位的.(因为它里面的代码并不是位置无关代码) 如果被多个应用程序共同使用,那么它们必须每个程序维护一份.so的代码副本了.(因为.so被每个程序加载的位置都不同,显然这些重定位后的代码也不同,当然不能共享) 我们总是用fPIC来生成so,也从来不用fPIC来生成.a;fPIC与动态链接可以说基本没有关系,libc.so一样可以不用fPIC编译