首页
学习
活动
专区
圈层
工具
发布

逆向工程——栈

PUSH指令会对ESP/RSP/SP寄存器的值进行减法运算,使之减去4(32位)或8(64位),然后将操作数写到上述寄存器里的指针所指向的内存中。...POP指令是PUSH的逆操作:他先从栈指针(Stack Pionter,上面三个寄存器之一)指向的内存中读取数据,用以备用(通常是写到其他寄存器里面),然后再将栈指针的数值加上4或8....call指令等价于“PUSH返回地址”和“JMP函数地址”的指令对 被调用函数里的RET指令,会从栈中读取返回地址,然后跳转到这个这个地址,就相当于“POP返回地址”+“JMP返回地址”指令。...参数处理方面并没有相关的硬性规定。 例如,程序员可以在堆(heap)中分配内存并用之传递参数。在堆中放入参数之后,可以利用EAX寄存器为函数传递参数。这种做法确实行得通。...典型的栈的内存存储格式 在 32 位系统中,在程序调用函数之后、执行它的第一条指令之前,栈在内存中的存储格式一般如下表所示。

1.1K31

c++ 寄存器 缓存 cpu 内存之间的关系

CPU内部结构与寄存器(了解) cpu > 寄存器 > 缓存 > 内存 64位和32位系统区别 寄存器是CPU内部最基本的存储单元 CPU对外是通过总线(地址、控制、数据)来和外部设备交互的...位 在64位的CPU构架上,运行了32位的软件操作系统,那么这个系统就是32位 64位的软件不能运行在32位的CPU之上 寄存器名字(了解) 8位 16位 32位 64位 A AX EAX...RAX B BX EBX RBX C CX ECX RCX D DX EDX RDX 寄存器、缓存、内存三者关系 按与CPU远近来分,离得最近的是寄存器,然后缓存(CPU缓存),最后内存。...CPU计算时,先预先把要用的数据从硬盘读到内存,然后再把即将要用的数据读到寄存器。于是 CPU寄存器内存,这就是它们之间的信息交换。 那为什么有缓存呢?...因为如果经常操作内存中的同一址地的数据,就会影响速度。于是就在寄存器与内存之间设置一个缓存。 因为从缓存提取的速度远高于内存。当然缓存的价格肯定远远高于内存,不然的话,机器里就没有内存的存在。

99010
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【汇编语言】寄存器(内存访问)(一)—— 内存中字的存储

    前面的部分,我们主要从CPU如何执行指令的角度讲解了8086CPU的逻辑结构、形成物理地址的方法、相关的寄存器以及一些指令。这一部分中,我们从访问内存的角度继续学习几个寄存器。 1....内存中字的存储 CPU中,用16位寄存器来存储一个字。高8位存放高位字节,低8位存放低位字节。...✍字单元的概念:字单元,即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。...问题 对于上图: (1)0地址单元中存放的字节型数据是多少? (2)0地址字单元中存放的字型数据是多少? (3)2地址单元中存放的字节型数据是多少? (4)2地址字单元中存放的字型数据是多少?...问题分析与解答 (1)0地址单元中存放的字节型数据:20H; (2)0地址字单元中存放的字型数据:4E20H; (3)2地址单元中存放的字节型数据:12H; (4)2地址字单元中存放的字型数据:0012H

    27110

    __asm__ volatile 之 C语言嵌入式汇编

    cr0被放在内存-4(%ebp)的位置,所以指令mov %eax, -4(%ebp)即表示将%eax的内容输出到变量cr0中。...u I,O 表示使用第二个浮点寄存器 2、内存约束 如果一个Input/Output操作表达式的C/C++表达式表现为一个内存地址,不想借助于任何寄存器,则可以使用内存约束。...通用约束g是一个非常灵活的约束,当程序员认为一个C/C++表达式在实际的操作中,究竟使用寄存器方式,还是使用内存方式或立即数方式并无所谓时,或者程序员想实现一个灵活的模板,让GCC可以根据不同的C/C+...的 & O 表示此Output操作表达式独占为其指定的寄存器 % I 表示此Input操作表达式中的C/C++表达式可以和下一个Input操作表达式中的C/C++表达式互换 4....如果一个内联汇编语句的Clobber/Modify域存在"memory",那么GCC会保证在此内联汇编之前,如果某个内存的内容被装入了寄存器,那么在这个内联汇编之后,如果需要使用这个内存处的内容,就会直接到这个内存处重新读取

    13.4K45

    【C++】拿下! C++中的内存管理

    1 C++ 的内存分布 内存管理是十分重要的内容,企业开发中多有服务器宕机的大事故,比如: B站崩了两次: 2023年3月5日晚20:20左右,许多网友表示在使用B站时,手机和电脑端都无法访问视频详情页...最重要的栈是向下增长的!空间有限但效率较高。 内存映射段是高效的 I/O映射方式,用于装载一个共享的动态内存库。用户可以使用系统接口创建共享内存,叫做进程间通信。...realloc 扩容 free 释放 接下来我们来看C++ 的内存管理,来欣赏祖师爷的绝妙手笔~ 3 C++的内存管理 首先C语言的内存管理可以在C++中使用,但是有些地方就显得比较复杂,因此我们需要...C++的内存管理 C++的内存管理是通过new 操作符 和 delete 操作符来实现的。...lete[]的原理 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete

    39110

    一行代码,揭开CPU执行原理!

    我们以x86架构的CPU为研究对象,从一个例子出发,来尝试解答这个问题。..., a : 将变量a的值存入eax寄存器中 add eax, b : 把变量b的值和eax寄存器的值相加,并将结果保存在eax寄存器中 mov sum, eax : 将计算结果从eax寄存器写入...下面是x86架构的CPU指令操作码表: CPU中的指令译码模块拿到手一看,呀,不是指令前缀,是个单字节操作码的mov指令,要往eax寄存器里面塞数据,数据从哪来呢?...再往后一看,0x45,再来译码: 好家伙,原来是根据ebp寄存器的值+一个8位的偏移来读取数据。 再往后读取一个字节,就是偏移值:EC。...现在第一条指令就译码出来了:将ebp+0xEC位置处的4个字节的数据取出来,放到eax寄存器中。,这就是这一条指令要干的事情。

    79550

    java与c++内存泄露的问题

    以前用c++,现在用java我发现两种语言用法上区别不太大,但是在编程思路上却又区别,c++什么都要自己做,但是如果做的很严谨是不会出现内存泄露的问题,但是c++太灵活以至于可用性确实降低了...,什么都需要自己考虑,而java在内存回收上有垃圾回收机制,在可用性上比c++要好一点,但是java的内存泄露却更加的隐蔽,今天我来谈谈java与c++内存泄露的区别: 1.c++的内存泄露的概念很简单...但是这种问题很是明显,如果细心查找应该能查找出来 2.java的内存泄露:很多书上对java的内存泄露是这么解释的,内存泄露就是你以后都不会再使用的实例,没有被垃圾回收这样就会发生内存泄露,这个问题其实有点模棱两可...很明显,java中的内存泄露比c++中的内存泄露复杂的多,而且要隐蔽的多,所以现在想起那句话,我才理解,为什么说垃圾回收是一堵高墙,搞java的人想出去,搞c++的人想进去,我认为这就是两种语言有利有弊...,c++太灵活,易用性比较差,但是所展现的问题比较清晰,而java比较规整,并且是真正的oo语言,所以易用性更加好一点,但是它存在的问题也就比较复杂,比较隐蔽的,如果不深究这些问题是很难发现的。

    93110

    GCC在C语言中内嵌汇编-转载

    这里有一个问题:假设eax已经被使用,那怎么办?...由编译器优化或者硬件重新排序引起的问题的解决办法是在从硬件(或者其他处 理器)的角度看必须以特定顺序执行的操作之间设置内存屏障(memory barrier),linux 提供了一个宏解决编译器的执行顺序问题...void Barrier(void) 这个函数通知编译器插入一个内存屏障,但对硬件无效,编译后的代码会把当前CPU寄存器中的所有修改过的数值存入内存,需要这些数据的时候再重新从内存中读出。...Cache 到寄存器中的变量值先写回内存,如果以后又要使用这些变量再重新读取。...当给b赋值时,不是再次读取X内存 地址中的值,而是直接把寄存器中的5赋给b。这一优化对于普通变量没有问题。但如果定义成 volatile int x;则表明x可以被程序代码外的其他代理改变值。

    3.2K20

    UPX脱壳详细分析

    一大堆都是从UPX1中读取数据,做一些处理,并且放入UPX0中。 应该是UPX的解压算法。具体算法比较复杂没有详细的分析。 里面的EBX控制了每一步解压应该做的操作,十分好奇这个数是怎么出来的。...这里有两重循环,分别从UPX1中读取dll名称,使用LoadLibrary加载入内存。 获得句柄后,再从UPX1中读取相应函数名,使用GetProcAddress获得函数地址。...从这段代码中可以获得IAT的RVA,为0x10000。记下来留着以后修复IAT时使用。...character 去除了节表中UPX0和UPX1段的UNINITIALIZED_DATA属性,完成了节表的初始化。...使用ImportREC修复一下IAT IAT的起始地址为刚才记下的0x10000,通过观察那段内存得到IAT大小为0x344 在ImportREC的IAT Infos Needed中填入我们获得的信息,

    70930

    xv6(21) 内联汇编

    内联汇编 内联汇编,顾名思义,一种语言的内部使用汇编,一般的语言是不能直接操作寄存器的,而汇编可以,所以在这种语言内部以某种方式嵌入汇编代码来提升能力,一般来说也就是 c/c++ 使用内联汇编比较多,本文用的...第一个例子中 in_b 使用的内存约束,所以 movl 操作直接操作的是 in_b 所在的内存,将 eax 的值移到 in_b 所在的内存,所以 in_b 本身的值变成 1。...第二个例子中 in_b 也是用的寄存器约束,所以 movl 操作的是寄存器 eax, ebx,将 eax 的值移到 ebx,但 in_b 所在的内存不受影响,所以本身的值不变还是 2。...而这里的 100 通过 i 来约束表整数。 CPU 能够直接使用的数据就存放在三个地点,寄存器中,内存中,还有指令中的立即数,这就与三种约束对应起来。...al/ax/eax 中的数据送到 edi 指向的内存单元 以上指令通常配合 rep 重复指令一起使用,每次执行完后,根据 eflags 寄存器的 DF 位修改 esi 和 edi 的值 cld, std

    43500

    深入理解计算机系统(3.8)------数组分配和访问

    *D[5];   我们可以得到如下信息:注意由于B和D都是声明的数组,在IA32中,指针变量占用4个字节的内存空间。...比如对于上面的 int a[10],我们想访问 a[i],这时候 a 的地址存放在寄存器 %edx 中,而 i 存放在寄存器 %ecx 中。...然后指令计算如下: movl (%edx,%ecx,4), %eax   这会执行地址计算 xa+4i,读取这个存储器位置的值,并把结果存放在寄存器%eax中。...假设整型数组 E 的起始地址和整数索引 i 分别存放在寄存器 %edx 和 %ecx 中,下面是每个表达式的汇编代码实现,结果存放在 %eax 中。 ?   ...之前的C编译器不允许在声明数组时,将长度定义为一个变量,而只能是常量,不过当前的C/C++编译器已经开始支持动态数组,但是C++的编译器依然不支持方法参数。

    1.2K100

    程序员需要了解的硬核知识之汇编语言(全)

    本地代码需要加载到内存后才能运行,内存中存储着构成本地代码的指令和数据。程序运行时,CPU会从内存中把数据和指令读出来,然后放在 CPU 内部的寄存器中进行处理。...而在 mov eax,dword ptr [ebp+8] 这条指令中,ebp 寄存器的值 + 8 后会被解析称为内存地址。...栈(stack)的特性是后入先出,数据在存储时是从内存的下层(大的地址编号)逐渐往上层(小的地址编号)累积,读出时则是按照从上往下进行读取的。...通过(4) 的 add 指令,把当前 eax 寄存器的值同第2个参数相加后的结果存储在 eax 寄存器中。[ebp + 12] 是用来指定第2个参数456的。...跳转到标签行 mov A,B 把 B 的值赋给 A pop A 从栈中读取数值并存入A push A 把A的值存入栈中 ret 无 将处理返回到调用源 xor A,B A和B的位进行亦或比较,并将结果存入

    1.1K20

    2020-09-04:函数调用约定了解么?

    函数结果保存在寄存器EAX/AX/AL中 浮点型结果存放在寄存器ST0中 编译后的函数名前缀以一个下划线字符 调用者负责从线程栈中弹出实参(即清栈) 8比特或者16比特长的整形实参提升为32比特长。..., CS, DS RET指令从函数被调用者返回到调用者(实质上是读取寄存器EBP所指的线程栈之处保存的函数返回地址并加载到IP寄存器) 3....通过使用寄存器解决效率问题。特点: 函数参数部分通过寄存器传递,函数中最左的两个DWORD(寄存器大小是双字)或者更小的参数,通过寄存器传递。剩下的从右到左堆栈传递。...EAX, ECX和EDX不会保留值。参数列表的大小被放置在AL寄存器中(?)。 syscall是32位OS/2 API的标准。 9.optlink 参数也是从右到左被推入堆栈。...函数的返回值在EAX或ST(0)中。保留的寄存器有EBP, EBX, ESI和EDI。 optlink在IBM VisualAge编译器中被使用。 10.

    71810

    muduo网络库学习之Timestamp类、AtomicIntegerT 类封装中的知识点

    x++; (x是共享变量) 从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址 (1)、假设是多核(multiprocessors)的情况,x 的初始值为5: ?...因为每个核都有自己独立的寄存器,两个线程同时访问可能出现只加了一次的情况。...的结果被覆盖掉了,因为Thread2在进行++之前以为x还是0,而不是1(每个线程都保存自己的上下文包括寄存器的值,重新调度回Thread2时eax被加载为原来保存的0)。...当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,而不是使用保存在寄存器中的备份。即使它前面的指令刚刚从该处读取过数据,而且读取的数据立刻被保存。...参考: muduo manual.pdf 《linux 多线程服务器编程:使用muduo c++网络库》

    89800

    程序员必须掌握的 CPU 硬核干货!

    05 计算机语言 人和人之间最古老和直接的沟通媒介是语言。 但是和计算机沟通,就必须按照计算机指令来交换,其中就涉及到语言的问题。 最早,为了解决计算机和人类的交流的问题,出现了汇编语言。...-0Ch] /* 把 eax 的数值和内存的数值相加 */ mov dword ptr [ebp-4], eax /* 把 eax 的数值(上一步的结果)存储在内存中*/ ?...汇编语言可以帮助你理解计算机做了什么工作,机器语言级别的程序通过寄存器来处理, 上面代码中的eax,ebp都是表示的寄存器,它们是CPU内部寄存器的名称。...随后,CPU会根据程序计数器的数值,从内存中读取命令并且执行, 换言之,程序计数器控制着程序的流程。 ?...取指令阶段就是将内存中的指令读取到CPU中寄存器的过程,程序起存起用语存储下一条指令所在的地址; 在取指令完成后,立马进入指令译码阶段, 在指令译码阶段,指令编码器按照预先的指令格式,对取回的指令进行拆分和解释

    63420

    CC++:堆栈面面观

    -24] add edx, eax mov eax, DWORD PTR [rbp+16] add eax, edx pop rbp ret 可以看到函数从6个寄存器和1个栈地址中读取参数...曾几何时,以为面试官也曾经问我,函数的参数是通过什么传递的,我就说寄存器,寄存器不够了,就用栈。然后他接着问我几个寄存器不够了,就用栈了。我有点哑口无言。说了个四五个。其实这种问题是很开放的。...C语言中的malloc,C++中的new完成的都是堆上的操作。堆不会自动释放所以需要free和delete。 还记得经典面试题吗:比较一下malloc和new的不同。...然后new作为C++中动态对象创建的基石,除了完成堆空间的分配操作以外还要完成一些初始化操作,及new的过程中会调用对象的构造函数去初始化,而malloc不会。...实际上关于这个问题,不同的内存管理器有各自的策略,但大致的思想就是将偏移量存储在内存中。

    64920

    C++ std::vector元素的内存分配问题

    来看一个问题: 在使用C++ STL的vector时,下面三种写法有什么不同呢?其内存分配是怎么样的呢?...下面通过实验说说第一种情况和第二种情况的不同吧! 下面代码中声明了一个类A和一个函数IsObjectOnStack()用于监测对象是否在栈上,该函数使用到了Windows的系统API。...可以看到std::vector中的元素A是在栈上创建的。而且是在push_back的时候将栈上对象通过拷贝复制到堆上去的。...这个很明显std::vector中的对象都是在堆上。使用完以后,我们必须手动释放该对象所占内存。...所以,我个人觉得两者的主要区别在于:std::vector和std::vector中元素T都是存储在栈上,而且std::vector不用手动管理内存空间,而std::vector<T

    4K31

    对X86汇编的理解与入门

    下面例子是汇编程序中常见的方式 mov eax, [ebx] ; 将ebx值指示的内存地址中的4个字节传送到eax中 mov [var], ebx ; 将ebx的内容传送到var的值指示的内存地址中...mov eax, [esi-4] ; 将esi-4值指示的内存地址中的4个字节传送到eax中 mov [esi+eax], cl ; 将cl的值传送到esi+eax的值指示的内存地址中...mov指令将第二个操作数(可以是寄存器的内容、内存中的内容或值)复制到第一个操作数(寄存器或内存)。..., 10 — EAX ← EAX + 10 add BYTE PTR [var], 10 — 10与var指示的内存中的一个byte的值相加,并将结果保存在var指示的内存中 sub— Integer...,idiv只有一个操作数,此操作数为除数,而被除数则为EDX:EAX中的内容(一个64位的整数),操作的结果有两部分:商和余数,其中商放在eax寄存器中,而余数则放在edx寄存器中。

    2.2K42
    领券