zoukankan      html  css  js  c++  java
  • 对一段有趣代码分析,你确定不来看看吗?

    简介:大家好我是小江,放假的我在家实在是太无聊了,经常看别人博客文章也学到了不少知识,所以呢我决定自己弄了个博客来记录下自己的点点滴滴,在写文章的同时我会

    尽量给大家写的详细点,把一些知识带给初学者,一起学习。

    好了废话不多说了  我们直接进入主题,最近在一个论坛看到一个简单而又有趣的程序

    代码如下:

    #include <stdio.h>

    int main()

    {

      const short int c1 = 49920;

      const int c2 = 1073742008;

      int (*pf)() = (int (*)())&c2;

      printf("%c%c ", *(char*)pf()-19, *((char*)pf()+1)-49);

      return 0;  

    }

    ==========================这是一条华丽的分割线================================

    我相信有大部分人都不理解这段代码的运行原理;

    这段代码丢进VC++里面的运行结果是  :)

    Turbo3.0中 这段代码是显示的结果是 Abnormal program termination(程序异常终止)

    这里每个编译器的字节都是不同的 不如说Turbo3.0 short(短整型) 内存占用字节为:2B

    VC++short 占用的字节为 4B int 的大小是一样的。

    本次分析采用的编译器是VC++6.0

    分析过程:

    我们先从const(限定符) 开始吧;

    const short int c1 = 49920;  

    const int c2 = 1073742008;

    这是两个局部变量 我们将它转换为16进制,用于后面的分析

    C1=0xC300C2=0X400000b8

    我们再来看看它们各自在内存的地址

     

    C1地址为:0019FF3CC2=0019FF38;我们可以很清楚的看到c2c1的字节数为4B

    这两个变量占据了连续的空间,这里给变量赋值后,从0x0019ff38开始内存单元的存储字节码为:B8 00 00 40 00 C3

    对应的汇编码为:0040102E   mov         dword ptr [ebp-8],400000h  看下图

    我们继续分析下一句

    int (*pf)() = (int (*)())&c2;

       (int (*)());这里定义了一个函数指针 参数为NULL 而且返回值为int类型,这里的函数指针pf指向上面的汇编码,这就是这段语句的执行过程

    接着分析下面 printf("%c%c ", *(char*)pf()-19, *((char*)pf()+1)-49);

     *(char*)pf()-19 这段代码分析:刚刚我们函数指针pf() 是指向汇编码0x400000,然后(char*)再把汇编码转换成字符型指针来指向它的地址,最后在用他的地址减去个19然后再取这个地址的值,因为char在内存占用的字节数位1B因此从这个地址取一个字节。*(char*)pf()-19 其实就是从0x400000内存地址取出的字节内容再减去19

    接下来的一句:*((char*)pf()+1)-49代表的意思是从0x400000 + 1的地址取出一个字节内容在减去49

    下面我们打开编译器找到0x400000的地址以及字节内容 如图

     

    熟悉PE文件结构的朋友一定知道,对于exe文件0x400000是内存加载的基地址。

    也就是说,0x400000 字节的内容对应的是0x4D,0x400001 字节的内容对应的是0x5A.

    这是我们常说的pe文件起始的两个字节,"MZ"

    0x400000地址=0x4D

    0x400001地址=0x5A

    刚刚上面说到

    ①:*(char*)pf()-19 其实就是从0x400000内存地址取出的字节内容再减去19

    ②:*((char*)pf()+1)-49代表的意思是从0x400000 + 1的地址取出一个字节内容在减去49

    ①:0x4D-19=58

    ②:0x5A-49=41

    最后按%c输出得到的结果是::)

    别看代码少,这段代码知识点应用还是比较广泛的。

                 这段代码就分析到这里了,不喜勿喷,最后谢谢大家的阅读。

     

     

  • 相关阅读:
    C# using 实现强制资源清理
    MySQL workbench How to create a new model
    无法启动windows audio服务,错误提示126.
    Process of knowledge discovery in databases
    Android 应用程序中资源的引用
    Javadoc使用方法
    Android xml 布局
    load data with matlab
    Android中string.xml使用总结
    Introduction to Indigo
  • 原文地址:https://www.cnblogs.com/c-c-c-c/p/7017589.html
Copyright © 2011-2022 走看看