汇编指令读写内存变量的过程我们称为read-modify-write,简称为RMW操作。也就是说,它们读写一个内存区域两次,第一次读取旧值,第二次写入新值。
在分析上面的汇编程序之前,需要了解rbp、rsp为栈基址寄存器、栈顶寄存器,分别指向栈底和栈顶;edx、eax、esi、edi均为x86CPU上的通用寄存器,可以存放数据(虽然它们还有别的作用,但是本文章不涉及)
本系列是对 陈莉君 老师 Linux 内核分析与应用[1] 的学习与记录。讲的非常之好,推荐观看
该宏的参数中,x为3,name为_write,...代表的__VA_ARGS__为unsigned int, fd, const char __user *, buf, size_t, count。
左边是一段C语言程序,右边是对应的汇编语言,这对于咱们学习逆向、二进制安全的同学来说简直不要太方便了!
从2010年开始的RISC-V 项目,已经有10年的时间,RISC-V基金会先后批准了RISC-V Base ISA, Privileged Architecture,Processor Trace等规范。RISC-V对Linux的基本支持也已经完成。本文尝试通俗易懂的介绍RISC-V对于Linux的基本支持,包括指令集和异常处理。内存管理,迁移到RISC-V,UEFI,KVM等支持,欢迎继续关注本公众号。
在 “Linux 发布 5.1, Linux Lab 同步支持” 一文中,首次得知了 Linux 移除 a.out 格式的消息,这个消息着实令人感叹,因为 a.out 伴随 Linux 的诞生至今在 Linux 中有将近 ~28 年的历史,而 a.out 本身则要追溯到更早的 Unix 时代。
汇编语言对应cpu指令集(二进制机械码),兼容性不好,不能跨平台,arm的汇编和x86汇编差别很大 处理器指令集:https://blog.csdn.net/antony1776/article/details/83743856
汇编的语法风格分为两种,一种是intel风格,一种是at&t风格,intel风格主要用于windows平台,at&t风格主要用于unix平台。
下面的所有资料 , 都可以在博客资源 https://download.csdn.net/download/han1202012/31843542 中下载 ;
本文主要讲述linux平台x86(及x86-64)架构下的ffmpeg编译安装过程。 其他嵌入式平台需要交叉编译,过程类似,不详述。 本实验在opensuse和ubuntu两个平台作了验证。使用lsb_release -a命令查看系统发行版版本: opensuse平台版本:openSUSE Leap 42.3。 ubuntu平台版本:Ubuntu 16.04.5 LTS。
在上一篇博客 【Android 内存优化】Android 原生 API 图片压缩原理 ( 哈夫曼编码开关 | 哈夫曼编码原理 | libjpeg-turbo 函数库 ) 对哈夫曼编码进行了介绍 , 如果需要在所有的 Android 手机上使用哈夫曼编码压缩图片, 那就需要使用 libjpeg-turbo 函数库 , 从 libjpeg-turbo/libjpeg-turbo GitHub 项目的 Release 发布版本页面 下载 Release 版本的源码 , 这里下载最新的 Source code (tar.gz) 源码 ;
GNU最开始其实是一个操作系统,旨为打造一个开源免费自由的操作系统,目前操作系统还在完善中
在X86下,查看inter手册可以清楚的看到x86汇编的指令格式. 图标如下
我们都知道,带有优化的编译器,会尝试重新排序汇编指令,以提高程序的执行速度。但是,当在处理同步问题的时候,重新排序的指令应该被避免。因为重新排序可能会打乱我们之前想要的同步效果。其实,所有的同步原语都可以充当优化和内存屏障。
本文介绍了交叉编译和交叉工具链的基本概念,以及其在嵌入式开发中的应用。同时,还详细描述了交叉工具链的重要组成部分,以及如何使用它们进行交叉编译。
汇编是一类编程语言,每种cpu对应一种cpu语言,这些语言语法大同小异,指令集有所不同,
前两篇文章,我们一起学习了 8086 处理器中关于 CPU、内存的基本使用方式,重点对段寄存器和内存的寻址方式进行了介绍。
The GNU Compiler Collection,通常简称GCC,是一套由GNU开发的编译器集,为什么是编辑器集而不是编译器呢?那是因为它不仅支持C语言编译,还支持C++, Ada, Objective C等许多语言。另外GCC对硬件平台的支持,可以所无所不在,它不仅支持X86处理器架构, 还支持ARM, Motorola 68000, Motorola 8800, Atmel AVR, MIPS等处理器架构。
不同的处理器指令集不一样,而汇编语言中都是一条条指令,所以不同处理器对应的汇编语言必然不一样。
前面我们了解了计算机底层的一些知识,比如计算机体系机构、操作系统、数据库、以及网络的基础知识,今天我们来研究一下计算机底层的语言,相信有了基础知识的铺垫,对于后期的编程学习会有莫大的帮助。
本文主要介绍了Linux操作系统的起源、发展和现状,以及Torvalds如何利用GNU/Linux系统在个人电脑上构建出一个自由的操作系统。同时,还介绍了其他Linux发行版以及相关的操作系统。
Sickle是一个shellcode开发工具,用于加速创建正常运行的shellcode所需的各个步骤。 Sickle主要有以下功能: 识别可能会导致shellcode无法正常执行的坏字符。 支持多种语言输出格式(python,perl,javascript等)。 通过STDIN接收shellcode并格式化。 在Windows和Linux环境中均可执行shellcode。 支持shellcode间差异性比较。 反汇编shellcode到汇编语言(例如ARM,x86等)。 快速错误检查 在实际测试当中,测试人
创建 Capstone 实例对象代码 : 下面代码创建的是 x86 架构的 32 位模式的 Cs 对象 , 也就意味着反汇编的 ELF 文件是 32 位 x86 CPU 架构的动态库 ;
在逐渐深入底层的时候,汇编真的十分重要,它是一门直接操作硬件的语言,可以清楚的知道每一步指令过后 CPU 干了什么事,做到精准打击。在逆向中,学好汇编也是非常重要的,否则连题目都看不懂,这里我就来复习一下关于汇编的一些基础知识
通过对编译代码进行处理来改变现有应用程序的行为,在恶意软件分析、软件逆向工程以及更广泛的安全研究领域中,其实并不少见。而Patching是一款针对IDAPro的交互式源码处理工具,该工具能够扩展IDA Pro反汇编工具的功能,以创建一个功能更加强大的交互式源码处理工作流。
掌握黑客技术一大难点就在于你要非常深入计算机技术的底层。绝大多数程序员只愿意在上层应用上花点时间,毕竟他们只想”混饭吃“,任何有志于不断提升技术能力的工程师都必须跨过几个高门槛,一个是算法,一个是系统设计,还有就是掌握计算机体系结构,与底层,与硬件打交道,这些知识点难度大,有些甚至很枯燥,因此愿意专研的人不多,我们本节所要描述的汇编语言就属于计算机体系结构的一部分。
在通用PC领域,不论是windows还是linux界,我们都会经常听到"32位"与"64位"的说法,类似的还有"x86"与"x86_64","i386"与"amd64",这两组概念之间有着怎样的联系和区别呢?
1.传参方式 首先说明一下,在X64下,是寄存器传参. 前4个参数分别是 rcx rdx r8 r9进行传参.多余的通过栈传参.从右向左入栈. 2.申请参数预留空间 在x64下,在调用一个函数的时候,会申请一个参数预留空间.用来保存我们的参数.比如以前我们通过push压栈 参数的值.相应的栈就会抬高.其实x64下,一样会申请.只不过这个地方在进函数的时候并没有值.进入函数之后才会将寄存器的值在拷贝到这个栈中.其实就相当于你还是push了.只不过我是外边申请空间,内部进行赋值.
很多程序员都觉得汇编是可怕的编程语言,感觉很难学,繁多的指令,各种寄存器,寻址方式和CPU机制紧密相关,一切都让人望而却步。其实,汇编相对众多编程语言来说,是一门非常简单的语言:它没有奇技淫巧式的语法,也没有各种全家桶式的框架。它之所以显得非常难掌握的原因:
在上一篇博客 【Android 逆向】x86 汇编 ( 使用 IDA 解析 x86 架构的动态库文件 | 使用 IDA 打开动态库文件 | IDA 中查找指定的方法 ) 中 , 使用 IDA 反编译 Android SDK 中的 D:\001_Develop\001_SDK\Sdk\build-tools\26.0.3\renderscript\lib\intermediates\x86\libc.so 文件 , 并查找其中的 fork 方法 ;
最近有同学问我:为什么你的《从0写x86 Linux操作系统课程》选择了bochs,而不是qemu?他认为bochs更加好用,很多资料上都写了用该软件。其实我也是经过不断地对比和尝试后,选择使用qemu。
最近由于项目组内要做特征码搜索的东西,便于去Hook一些未导出函数,你懂得...于是就闲着学习了一下x86/x64的汇编指令格式。x86的汇编指令格式请参照http://bbs.pediy.com/s
由于平时业余兴趣和工作需要,研究过并使用过时下流行的各种开源的x86/64汇编和反汇编引擎。如果要对汇编指令进行分析和操作,要么自己研究Intel指令集写一个,要么就用现成的开源引擎。自己写太浪费时间,又是苦力活,还容易出错,所以还是使用现成的好一点。 这里对我曾使用过的比较流行的反汇编引擎做个比较,我使用过的反汇编引擎有: 1. Ollydbg的ODDisassm Ollydbg的ODDisassm,这是我最早使用的一个开源的反汇编引擎,07年在《加密解密》(三) 中我写的一个很简单的虚拟机就是使用的这个库,因为那个时候还没有那么多可选择。不过多亏有这样一个基础库,整个虚拟机从设计到开发完成只用了两个星期便开发完成(当时对反汇编库的要求不高,只要求能用字符串文本做中间表示进行编码/解码)。 这个反汇编库的优点是含有汇编接口(即文本解析,将文本字符串解析并编码成二进制),就拿这个特性来说在当时也算是独树一帜的了,到目前为止开源界在做这个工作的人也很少, 不过近年出现的调试器新秀x64dbg,也附带开发了开源的汇编库XEDParse,功能与OD的文本解析功能相似,并且支持的指令集更加完整,BUG更少,同时还支持X64,维护一直很强劲。 但是ODDisassm的缺点也很多,比如: 1. 指令集支持不全,由于Ollydbg年久失修,现在甚至连对MMX指令集都不全,而现在的INTEL/AMD的扩展指令集标准又更新了多个版本,什么SSE5/AVX/AES/XOP就更别提了,完全无法解析。 2. 解码出来的结构不详细,比如指令前缀支持不够友好,这点从Ollydbg的反汇编窗口可以看出,除了movs/cmps等指令以外,repcc与其他指令组合时都是单独分开的; 再比如寄存器无法表示ah\bh\ch\dh这种高8位寄存器。 3. 作者一次性开源后便不再维护开源版本,对于反汇编上的BUG很难即时修复。 不过这些也可以理解,因为在当时作者的开发目的是进行文本汇编\反汇编,所以没有为解码出的信息建立结构体以及接口。总的来说,如今再使用这个反汇编引擎,已经落后于时代了。 2. BeaEngine BeaEngine是我用的第二个库,当时使用OD库已经不能满足我的需求了。在做反编译器的时候,需要一个能够解码信息越多越好的库,于是我找到了BeaEngine,这个库我记得以前的版本不支持高8位寄存器识别,现在的版本也支持了。 在使用过程中基本上没有发现什么明显的缺点,不常用的新的扩展指令集也实现了不少。 目前实现的扩展指令集有:
Aliyun Linux 2 是为云上应用程序特别优化的开源操作系统,上游包括 4.19 LTS 内核、CentOS 7.6 软件包,为阿里云基础设施深度优化,致力于为云上用户提供最佳体验。
系统调用 跟用户自定义函数一样也是一个函数,不同的是 系统调用 运行在内核态,而用户自定义函数运行在用户态。由于某些指令(如设置时钟、关闭/打开中断和I/O操作等)只能运行在内核态,所以操作系统必须提供一种能够进入内核态的方式,系统调用 就是这样的一种机制。
现在windows系统都是64位了,那么对应的汇编也就是说已经升级到64位了. 一直没有时间写博客将64位汇编写出来.所以现在细心整理一下. 首先我们先配置好开发环境,然后我们才能进行开发.
这是一个系列的文章,会逐步带大家去实现一个PHP协程扩展。我们把这个扩展叫做study。
我仔细回忆了一下,Go竟然是我知道的第一门编译型带GC的语言(IL2CPP不算),这里的编译不是将代码编译成字节码然后解释的那种,是真正编译成能在CPU上执行的native code。
ROPgadget是一款可以在二进制文件中搜索Gadget的强大工具,本质上来说,ROPgadget 是一个小工具查找程序和自动操作程序。在该工具的帮助下,广大研究人员可以在二进制文件中搜索Gadget,以方便我们实现对 ROP 的利用。ROPgadget 支持 x86,x64,ARM,PowerPC,SPARC 和 MIPS 体系结构,并支持 ELF / PE / Mach-O 格式。
TLB 是页表项的物理 cache,用于加速虚拟地址到物理地址的转换。CPU 在访问一个虚拟地址时,首先会在 TLB 中查找,如果找不到对应的表项,那么就称之为 TLB miss,此时就需要去内存里查询页表,如果页表项是合法的,那么就会把它添加到 TLB 中。如果内核修改了页表,那么就需要主动的去清空一下当前的 TLB。
Maat是一款功能强大的开源动态符号执行和二进制源码分析框架,在该工具的帮助下,广大研究人员可以轻松实现符号执行、污染分析、约束求解、二进制加载和环境模拟等操作,并利用Ghidra的sleigh库进行汇编操作。
开发后端有很多的编程语言,目前比较流行的就是python ,c,cpp,java,js,php,rust,golang ..
Lunix是一套操作系统,它提供了一个完整的操作系统当中最底层的硬件控制与资源管理的完整架构, 这个架构是沿袭Unix 良好的传统来的,所以相当的稳定而功能强大!Lunix具有核心和系统呼叫两层。Torvalds 先生在 1991 年写出 Linux 核心的时候,其实该核心仅能『驱动 386 所有的硬件』而已, 所谓的『让 386 计算机开始运作,并且等待用户指令输入』。
内联汇编(Inline assembly):目前,对内联汇编方面来讲,Rust 非常接近于 LLVM,这是一种不同于 gcc 的格式,因此,我们必须解决这种不匹配的问题。我们期待将来有一天,Rust 能够为内联汇编提供稳定的支持。
在微指令架构的 CPU 里面,编译器编译出来的机器码和汇编代码并没有发生什么变化。但在指令译码的阶段,指令译码器“翻译”出来的,不再是某一条 CPU 指令。译码器会把一条机器码,“翻译”成好几条“微指令”。这里的一条条微指令,就不再是 CISC 风格的了,而是变成了固定长度的 RISC 风格的了。
SRS是一个单进程多协程的服务器,保持高并发同时还能利用ST协程避免异步回调的问题,这也导致新的平台需要移植ST,而且是汇编代码。 其实,移植ST比想象的要简单很多,最关键的就是实现setjmp/longjmp,也就是保存寄存器和恢复寄存器,所以步骤如下: 1.分析你的平台的寄存器使用,也就是函数调用规范。一般是由系统(Linux/OSX/Windows)和CPU(x86/ARM/MIPS)决定的。有个小工具打印这些信息,参考porting.c[1]。2.使用汇编实现寄存器的保存和恢复,不同系统的汇编语法有
汇编出来的东西里面有 很多 .size mul… .ident “GCC:Ubuntu”… 点开头的信息不用管 都是给汇编器和链接器的伪指令
• 它要适用于所有实现技术,包括 FPGA(Field-Programmable Gate Array,现场可编程逻辑门阵列)、ASIC(Application-Specific Integrated Circuit,专用集成电路)、全定制芯片,甚至未来的制造元件技术。
领取专属 10元无门槛券
手把手带您无忧上云