zoukankan      html  css  js  c++  java
  • 为什么Fun函数能够执行

    #include<stdio.h>
    #include<windows.h>
    
    void Fun()
    {
    		printf("Kali-Team
    ");
    }
    
    int check()
    {
    	int arr[4] = {0,1,2,3};
    	arr[5] = (int)&Fun;
    	return 0;
    }
    
    void main()
    {
    	_asm{
    		mov eax,eax;
    		mov eax,eax;
    	}
    	check();
    	getchar();
    	return;
    }
    
    • 调用check函数前先把004010F1(call下一条要执行的地址)压入堆栈中,当前的ESP为0012FF30,EBP为0012FF80,check函数的地址为00401005。F11单步跟进函数。
    • 因为压入了call下一步的返回地址,所以ESP减4变为0012FF2C,到下面的push原ebp到堆栈中,esp减4,mov将当前ebp改为esp后提升堆栈50h(十进制的80),再保存ebx,esi,edi三个寄存器的值到栈中,esp减12,最后四行为填充CC到缓冲区。
    00401070 55                   push        ebp
    00401071 8B EC                mov         ebp,esp
    00401073 83 EC 50             sub         esp,50h
    00401076 53                   push        ebx
    00401077 56                   push        esi
    00401078 57                   push        edi
    00401079 8D 7D B0             lea         edi,[ebp-50h]
    0040107C B9 14 00 00 00       mov         ecx,14h
    00401081 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
    00401086 F3 AB                rep stos    dword ptr [edi]
    
    • 下面是给数组arr赋值,局部变量在堆栈中保存。
    00401088 C7 45 F0 00 00 00 00 mov         dword ptr [ebp-10h],0
    0040108F C7 45 F4 01 00 00 00 mov         dword ptr [ebp-0Ch],1
    00401096 C7 45 F8 02 00 00 00 mov         dword ptr [ebp-8],2
    0040109D C7 45 FC 03 00 00 00 mov         dword ptr [ebp-4],3
    
    • 关键代码继续给arr赋值,因为上面已经分配到ebp-4了,下标为4的很明显是越界了,就会覆盖到ebp
    004010A4 C7 45 04 0A 10 40 00 mov         dword ptr [ebp+4],offset @ILT+5(Fun) (0040100a)
    
    • call的返回地址在EBP+4中,所以我们要将下标改为5,即为arr[5] = (int)&Fun;
    004010AD 5F                   pop         edi
    004010AE 5E                   pop         esi
    004010AF 5B                   pop         ebx
    004010B0 8B E5                mov         esp,ebp
    004010B2 5D                   pop         ebp
    004010B3 C3                   ret
    
    • 在恢复寄存器后执行ret指令,将arr[5]的值给了EIP。

    • 现在就会把Check函数的返回地址改为Fun函数的开始地址,所以Fun会被执行。

    0012FECC edi
    0012FED0 esi
    0012FED4 ebx
    esp 0012FED8 提升堆栈后到了这里
    0 Ebp-10
    1 Ebp-C
    2 Ebp-8
    3 Ebp-4
    ebp 0012FF28 保存原ebp 0012FF80
    0012FF2C call下一步的返回地址
    0012FF30
    0012FF80
  • 相关阅读:
    rowkey设计原则和方法
    ubuntu安装及使用
    sqoop数据迁移
    Hive 自定义UDF操作步骤
    hive之数据导入导出
    MySQL优化
    MongoDB、Redis、elasticSearch、hbase的对比
    数据库基本操作
    count(*) 和 count(1)和count(列名)区别
    BigDecimal的运算——加减乘除
  • 原文地址:https://www.cnblogs.com/Kali-Team/p/12181456.html
Copyright © 2011-2022 走看看