jmp

程序的一生:从源程序到进程的辛苦历程

一曲冷凌霜 提交于 2020-03-17 10:34:39
某厂面试归来,发现自己落伍了!>>> 摘要:一个程序的一生,从源程序到进程的辛苦历程!本文不深入研究编译原理、操作系统原理,主要聚焦于程序的加载和链接。 一、前言 作为计算机专业的人,最遗憾的就是在学习编译原理的那个学期被别的老师拉去干活了,而对一个程序怎么就从源代码变成了一个在内存里活灵活现的进程,一直也心怀好奇。这种好奇驱使我要找个机会深入了解一下,所以便有了本文,来督促自己深入研究程序的一生。不过, 本文没有深入研究编译原理、操作系统原理,而是主要聚焦于程序的链接和加载。 学习的过程中主要参考了三本书、一个视频、一个音频(文末有列出),三本书里,最主要的还是**《程序员的自我修养 - 链接、装载与库》**,里面的代码放到了 我的github 上,并且配有shell脚本和说明,运行后可以实操理解到更多内容。 南大袁春风老师的计算机原理讲解 对我帮助最大,视频是最直接传达知识的方式。另外,为了方便自己的实验,制作了一个ubuntu的环境,并且内置了代码,方便实验:阿里docker镜像 docker pull registry.cn-hangzhou.aliyuncs.com/piginzoo/learn:1.0 二、概述 每天都有无数的程序被编译、部署,不停地跑着,它们干着千奇百怪的事情。如同这个光怪陆离的世界,是由每个人、每个个体组成的,如果我们剖析每个人

条件转移指令详解

故事扮演 提交于 2020-03-09 08:23:16
程序控制指令又称为控制转移指令,包括:转移指令、循环控制指令、过程调用指令和 中断指令 4 类。转移指令又分为无条件转移指令和条件转移指令。 1.无条件转移指令 JMP 计算机程序的执行完全按照 CS:IP 的指向执行指令。 通常情况下 CS 保持不变,IP 自动 增量,程序就按照指令的先后顺序执行。无条件转移指令会修改 CS 和 IP 的值,使程序跳 转到另一个位置去执行,改变指令的执行顺序。 根据程序的转移范围可分为段内转移和段间转移。 在同一段的范围之内进行转移,只需 要修改 IP 的值,称为段内转移。如果 CS 的值被修改,意味着程序将转移到另外的段去执行, 这称为段间转移。段间转移不仅修改段基址 CS 的值,还修改IP 的值。 JMP 指令不影响标志位。 1)段内转移 指令格式: JMP OPRD 功能:段内转移,IP IP+位移量,或给 IP 赋值。 说明:根据 OPRD 的类型又分为段内直接转移和段内间接转移。指令不影响标志位。 例如: JMP LABEL ,程序转移到 LABEL 指明的指令处继续执行。例如【例题 3-17】程序段中的 FOUND 和 DONE。 JMP SHORT LABEL ,程序转移到 LABEL指明的指令处继续执行。SHORT 为属性说明符, 说明转移范围,以当前 IP 为中心,转移范围-128~+127。 JMP NEAR LABEL

汇编跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等

a 夏天 提交于 2020-03-02 13:20:51
转自: http://www.cnblogs.com/del/archive/2010/04/16/1713886.html http://pan.baidu.com/s/1gVTSi 跳转指令分三类: 一、无条件跳转: JMP ;无条件跳转 二、根据CX、ECX寄存器的值跳转: JCXZ ;CX 为 0 则跳转 JECXZ ;ECX 为 0 则跳转 三、根据 EFLAGS 寄存器 的 PSW 标志位 跳转, 这个太多了. 根据标志位跳转的指令: JE ;等于则跳转 同JZ JNE ;不等于则跳转 同JNZ JA ;无符号大于则跳转 JNA ;无符号不大于则跳转 JAE ;无符号大于等于则跳转 同JNB JNAE ;无符号不大于等于则跳转 同JB JB ;无符号小于则跳转 JNB ;无符号不小于则跳转 JBE ;无符号小于等于则跳转 同JNA JNBE ;无符号不小于等于则跳转 同JA JG ;有符号大于则跳转 JNG ;有符号不大于则跳转 JGE ;有符号大于等于则跳转 同JNL JNGE ;有符号不大于等于则跳转 同JL JL ;有符号小于则跳转 JNL ;有符号不小于则跳转 JLE ;有符号小于等于则跳转 同JNG JNLE ;有符号不小于等于则跳转 同JG JZ ;为零则跳转 JNZ ;不为零 则跳转 JS ;为负则跳转 JNS ;不为负则跳转 JC ;进位则跳转 JNC

IDA教程_IDA逆向训练

China☆狼群 提交于 2020-02-29 07:09:10
ZC: IDA新的模式"proximity view",快捷键:"-"触发"proximity view"(应该是小键盘减号),"+"放大返回到 函数 1、   【01:30】笨笨雄(nemo314@gmail.com) 写的教程   【03:22】重新载入exe,关闭时 的设置  【03:28】重新载入的时候,IDA会自动定位到程序入口   【03:36】IDA -->Options-->General...-->标签页"Disassembly"-->将"Line prefixes (graph)" 勾上,将"Number of opcode bytes (graph)"(操作码)设置为6 --> OK  【04:20】"Graph overview"   【05:00】注释 的快捷键 分号";"   【05:36】将 脱壳点 记录一下,用OD将它脱壳  【07:52】用LoadPE "纠正镜像大小"-->"完全脱壳"  【08:42】ImportREC_chs修复IAT   【10:45】介绍IDA功能,如何使用。以后单独一课再讲...   【13:11】见一下什么叫 交叉引用:程序中相互调用的地方。导入表 里面肯定是交叉引用的     【13:35】RegQueryValueExA,有"↑"的地方 就是交叉引用,双击"↑"处 随表来到一个交叉引用的地方     【】ZC:

函数调用堆栈图-c语言

帅比萌擦擦* 提交于 2020-02-26 16:35:18
文章来源: https://blog.seclibs.com/函数调用堆栈图-c语言/ 我们就使用一个简单的c语言程序来对描述一下在函数调用的时候都发生了什么。 中间的一小段没有意义的汇编语言是为了方便设置断点,为后面的调试做好铺垫,因为有时会碰到找不到断点位置的情况,使用这个方法,可以在找不到断点的时候向后执行一次,而不破坏我们想调试的程序当前的堆栈状态,这里对main函数和sum函数的效果是类似的,这里直接跟着断点来执行分析sum函数的堆栈操作。 我们先假设初始状态下的堆栈图如下,esp与ebp的真实距离我们省略。 接下来我们来看一下后面的操作。 在程序的执行当中,我们一般都是按照从右向左的方式去处理的,这里也不例外,我们可以发现当我们调用sum函数对数字1和数字2进行处理的时候,将数字2和1依次压入栈中,这个时候堆栈的情况是这个样子的,esp的值已经减8。 接下来调用了call,这时进行了两步操作,先将call后面的地址push进堆栈,然后再jmp到call所调用的地址。 因为jmp是不会影响堆栈的,所以现在的堆栈情况是这样的 然后因为编译器的原因在call的时候还会有一个jmp来中转到后面的处理函数,因为jmp不影响堆栈,我们可以忽略掉它,这里是跳转到了sum函数的处理位置。 此时的堆栈是没有发生变化的,现在开始到了函数调用的关键阶段了。 首先先将ebp的值push到堆栈中

X86汇编5.高级指令详解

╄→尐↘猪︶ㄣ 提交于 2020-02-26 04:08:14
最近学习了X86汇编,其实无论是古老的8086还是现在i3/5/7/9,Xeon3/5,在最基本原理上,都是相通的,只是CPU位数,寻址空间,寄存器个数,指令集的扩充等方面有所不同,对于学习,8086永不过时。 转移指令 1.转移指令分类: (1)无条件转移指令,如: jmp (2)条件转移指令 (3)循环指令,如: loop (4)过程 (5)中断 操作符 1.offset 释义:由编译器处理的符号,功能是取得标号的偏移地址 start: mov ax,offset start ;相当于mov ax, 0 s: mov ax, offset s ;相当于mov ax, 3 高级指令 1.jmp指令 释义: 无条件转移指令,可以只修改IP,也可以同时修改CS和IP。 jmp指令要给出两种信息: (1)转移的目的地址 (2)转移的距离(段时间转移、段内短转移,段内近转移) 1)依据位移进行转移的jmp指令: jmp short 标号(转到标号处执行指令) 这种指令格式的jmp指令实现的是段内转移,它对IP的修改范围是:-128 ~ 127,也就是说,它向前转移时最多128字节,向后最多127. jmp near ptr 标号,功能为:(IP)= (IP)+ 16 2)转移的目的地址在指令中的jmp指令 jmp far ptr 标号,实现段间转移,又称远转移 (CS) =

shellcode与系统安全

不羁的心 提交于 2020-02-25 16:13:59
shellcode与系统安全 http://tommwq.tech/blog/shellcode-and-security/ 1. 避免shellcode中出现0x00的方法 2. 获取shellcode地址 3. 向函数传递参数 4. 部分Linux系统调用 4.1. execve(32位) 5. 将二进制文件转换为C语言字符串 6. 一个简单的shellcode 7. 一些辅助函数 8. 一个简单的缓冲区溢出示例 9. 示例2:缓冲区溢出攻击 10. 缓冲区溢出攻击的基本流程 11. 数据执行保护和绕过 12. 示例3:绕过DEP 13. ROP 14. 示例4:ROP 15. 思考 1 避免shellcode中出现0x00的方法 使用 xor eax, eax 代替 mov eax, 0x00 。 使用 xor eax, eax; mov al, 0x01 代替 mov eax, 0x01 。 2 获取shellcode地址 从逻辑上看, call target 等效于 dec esp mov [esp], eip jmp target 因此,执行call指令可以将下一条指令的地址写入栈。在call之后执行 pop eax 就可以将目标地址保存到eax中。call分为near call和far call,near call使用的是段内的相对地址

Linux学习之\"setjmp和longjmp函数\"

▼魔方 西西 提交于 2020-02-21 08:21:46
n setjmp和longjmp函数实现函数之间的跳转(需包含头文件" setjmp.h "): 函数原型: int setjmp(jmp_buf env);      void longjmp(jmp_buf env, int val); setjmp函数用于设置跳转的目的位置,longjmp函数进行跳转。 env:保留了需要返回的位置的堆栈情况。 setjmp的返回值:直接调用该函数,则返回0;若由longjmp的调用,导致setjmp被调用,则返回val (longjmp的第二个参数)。 1.longjmp对各类型参数的影响: 考虑下面这个程序: #include<iostream>#include<setjmp.h>#include<stdlib.h>#include<stdio.h>using namespace std;jmp_buf jmpbuffer;void g(){ cout << "in g()" << endl; longjmp(jmpbuffer, 2);}void f(){ cout << "in f()" << endl; g(); cout << "leave f()" << endl;}int globval;int main(){ int autoval; register int regival; volatile int volaval;

汇编跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等

梦想与她 提交于 2020-02-17 02:05:17
跳转指令分三类: 一、无条件跳转: JMP; 二、根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转); 三、根据 EFLAGS 寄存器的标志位跳转, 这个太多了. 根据标志位跳转的指令: JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 JNZ ;不为 0 则跳转 JS ;为负则跳转 JNS ;不为负则跳转 JC ;进位则跳转 JNC ;不进位则跳转 JO ;溢出则跳转 JNO ;不溢出则跳转 JA ;无符号大于则跳转 JNA ;无符号不大于则跳转 JAE ;无符号大于等于则跳转 JNAE ;无符号不大于等于则跳转 JG ;有符号大于则跳转 JNG ;有符号不大于则跳转 JGE ;有符号大于等于则跳转 JNGE ;有符号不大于等于则跳转 JB ;无符号小于则跳转 JNB ;无符号不小于则跳转 JBE ;无符号小于等于则跳转 JNBE ;无符号不小于等于则跳转 JL ;有符号小于则跳转 JNL ;有符号不小于则跳转 JLE ;有符号小于等于则跳转 JNLE ;有符号不小于等于则跳转 JP ;奇偶位置位则跳转 JNP ;奇偶位清除则跳转 JPE ;奇偶位相等则跳转 JPO ;奇偶位不等则跳转 来源: CSDN 作者: Hoto Kokoa 链接: https://blog.csdn.net/weixin

x86平台inline hook原理和实现

隐身守侯 提交于 2020-02-14 10:55:53
概念 inline hook是一种通过修改机器码的方式来实现hook的技术。 原理 对于正常执行的程序,它的函数调用流程大概是这样的: 0x1000地址的call指令执行后跳转到0x3000地址处执行,执行完毕后再返回执行call指令的下一条指令。 我们在hook的时候,可能会读取或者修改call指令执行之前所压入栈的内容。那么,我们可以将call指令 替换 成jmp指令,jmp到我们自己编写的函数,在函数里call原来的函数,函数结束后再jmp回到原先call指令的下一条指令。如图: 通过修改机器码实现的inline hook,不仅不会破坏原本的程序逻辑,而且还能执行我们的代码,读写被hook的函数的数据。 inline hook流程 (1)寻找hook位置 我们hook的时候,会遇到不同类型的call,它们所占的字节可能是不一样的,本文构造一个长度为5字节的jmp指令(jmp的机器码占用1字节,跳转到的地址偏移占用4字节)来替换原来的5字节的call指令。即我们需要寻找长度为5字节的call,来进行inline hook。5字节的call形如: (2)inline hook代码实现 在x86汇编中,同样有很多类型的jmp,本文构造inline hook使用的是近距离地址跳转的jmp指令,它的机器码为 E9 ,这种类型的jmp指令需要一个参数,参数是 当前jmp指令地址 距离