zoukankan      html  css  js  c++  java
  • 汇编语言10堆栈平衡

    #include <stdio.h>
    #include <Windows.h>
    //堆栈平衡原理
    //如果要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址。

    //当执行call dword ptr[fun1]语句, esp=esp-4, push eip到堆栈
    void fun1()
    {
    __asm
    {
    mov eax, 1111h
    push eax // esp=esp-4
    mov eax, 3333h
    pop eax //pop eax执行后esp=esp+4,堆栈平衡, 如果不pop eax, pop ebp 然后ret以后堆栈就会溢出
    }
    printf("22222222 ");
    }
    /*--------------------------------------------------------------------------*/
    以下是esp变化的时序代码
    11: void fun1()
    12: { //esp=esp-4
    push ebp //esp=esp-4
    mov ebp,esp
    13: __asm
    14: {
    mov eax,1111h
    push eax //esp=esp-4
    mov eax,3333h
    pop eax //esp=esp+4 esp减了3次 就要加3次,只要这样ret后eip才是call语句push的
        //CPU只认识esp, esp是的地址是否正确需要我们自己去平衡
    19: }
    20: printf("22222222 ");
    21: }
    pop ebp //esp=esp+4
    ret //esp=esp+4
    /*--------------------------------------------------------------------------*/

    源码

    void main()

    {
    char ps[20] = "111111111 ";
    char *p1 =ps;
    HMODULE hmod =GetModuleHandle("msvcr90.DLL");
    if (hmod)
    {
    PVOID pfun =GetProcAddress(hmod, "printf");
    if (pfun)
    {
    HMODULE h = GetModuleHandle(NULL);
    DWORD dd=(DWORD)h;
    dd+=0x1000;//0x1000是fun1函数的偏移,dd表示fun1函数的地址
    __asm
    {
    mov byte ptr [ps+3],0x62
    push dword ptr[p1]
    call pfun
    //下面句话的调用,编译器会把fun1()函数编译进PE文件,去掉这句话dd就不是fun1()函数的地址了
    call dword ptr[fun1]
    call dd
    }
    }
    FreeLibrary(hmod);
    }
    }

     
    1.call和ret指令都是转移指令,它们都修改IP的值,或同时修改CS和IP的值。它们经常共同用语实现子程序的设计。
    2.ret指令用栈中的数据,修改IP的内容,从而实现近转移
    3.retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
    4.CPU执行ret指令时,相当于进行:
      pop IP
      执行retf指令时,相当于进行:
      pop IP
      pop CS
    5.CPU执行call指令时,进行两步操作:
      (1)将当前的IP或CS和IP压入栈中;
      (2)转移
    6.call指令不能实现短转移,call指令实现转移的方法和jmp指令的原理相同
    7.call 标号(将当前的IP压栈后,转到标号处执行指令)
     call执行"call标号"时,相当于进行:
      push IP
      jmp near ptr 标号
    8."call far ptr 标号"实现的是段间转移.
        CPU执行"call far ptr 标号"时,相当于进行:
       push CS
       push IP
       jmp far ptr 标号
    9.指令格式:call 16位 reg
      CPU执行"call 16位 reg"时,相当于:
       push IP
       jmp 16 位 reg
    10.转移地址在内存中的call指令有两种格式.
       (1)call word ptr 内存单元地址
          CPU执行"cakk word ptr 内存单元地址"时,相当于:
          push IP
          jmp word ptr 内存单元地址
       (2)call dword ptr 内存单元地址
          CPU执行"calldword ptr 内存单元地址"时,相当于:
          push CS
          push IP
          jmp dword ptr 内存单元地址
  • 相关阅读:
    存储过程
    需要再研究的题目
    sql(SqlServer)编程基本语法
    sql查询语句
    SQL常用增删改查语句
    SQLserver
    三大范式
    四种约束
    数据库
    学习实践:使用模式,原则实现一个C++自动化测试程序
  • 原文地址:https://www.cnblogs.com/mayingkun/p/4633691.html
Copyright © 2011-2022 走看看