【技术研究】指针 地址

TEC

Posted by Corax on November 14, 2023

当采用__T

image-20231115151853414

它会变成如下

image-20231115151930679

修改成_T,进行宏替换,实际上解决了宏嵌套的问题。关于宏转换规则的问题。

image-20231115152223656

实际上第二次才转换到了如下

image-20231115152123161

指针

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;

void exchange(int n, int m)
{
    int temp = n;
    n = m;
    m = temp;
}

int main(int argc)
{
    int a = 8;
    int *pa = NULL;
    pa = &a;
    *pa = 999;

    system("pause");
    return 0;
}

如上有一段示例代码,我们单步看看

int a = 8;

令19ff2c为int的8

image-20231115183308582

int *pa = NULL;

定义一个指针就在19ff2c旁边,也就是19ff28的位置。初始值为00 00 00 00。 定义的时候限制了指向的位置 等会的解释类型

image-20231115183449045

pa = &a;

让pa指向a的地址。这里有个取地址符,实际上就是把a的地址,也就是19ff2c,给到了pa的19ff28。

image-20231115183611514

*pa = 999;

间接访问,和去内容是一件事。

定位刚刚19ff28的位置,因为有*,又要再一次解析,解析到19ff2c的位置。然后用刚刚的解释类型把999变成int,存进19ff2c的位置。

image-20231115183914205

不管留多少空,*往右靠近,也就是,只定义一个int型指针pa和一个int数据pb

image-20231115184535226

type *ptr = ...;

int n = ...;

ptr +n = (int)ptr + sizeof(type)*n //运算结果为同类指针的常量
	   = (type *const)((int)ptr + sizeof(type)*n)

数组名是数组第0个元素的指针常量

type ary[M] = ...;
ptr = ary;
ptr[n] = *(type *const)((int)ptr + sizeof(type)*n) //多个取下标,也就是多个读内容
ary[n] = *(type *const)((int)ary + sizeof(type)*n) //其实就变个 ary

红框内生成的汇编代码会多一些,因为实际上是先取指针指向的地址,再做下标运算,而下面的是直接进行下标运算。(两个是一样的)

image-20231115191304407

image-20231115191058960

条数如下

image-20231115191223930

(未被优化版本)

强类型检查 不同类型指针之间不可以相互赋值。

image-20231115192628128

第一个语句 是对同一地址更换解释方式,是告诉编译器flt的这个地址我要把它当作整型地址了,然后把他取出来,就是4048f5c3

而第二个只是数值进行转换 输出3

image-20231115192900952

image-20231115193123176

空类型指针只做函数地址传递。只有箭头指的可以运行。

image-20231115193504612

ctf里面也很常见,对整个数据块进行复制,比较,等等。一般接受三个参数,目标指针 源指针 大小

image-20231115193602778

返回来的是目标的地址

可以看到这里就是void指针 就是上面那个知识点的用处

这个其实是不实际改变内容的,因为没有间接访问,所以没有影响到实参

image-20231115193938438

如下就可以

image-20231115194401393

image-20231115194418575

老生常谈的指针常量常量指针的东西了

image-20231115194631980

所指向的内容是一个常量

const int *

int const *是一样的。只要const在 *左边

如图这样*pn1 = 888 是没有办法过的

如果是如下,那么这个常量只能指向null了,不能改变。

image-20231115194807703

一段简单代码

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;

void exchange(int n, int m)
{
    int temp = n;
    n = m;
    m = temp;
}

int main(int argc)
{
    char szTest[] = "Hello";
    char *pszTest = "Hello";

    szTest[0] = 'h';
    pszTest[0] = 'h';

    puts(szTest);
    puts(pszTest);



    system("pause");
    return 0;
}

这个里面能过编译,但是运行会访问错误

因为szTest[] = “Hello”这个里面是写在栈里面,可以修改的状态,但是*pszTest = “Hello”,其实是指向一个常量字符串,在不可以写入的data区里面,所以pszTest[0] = ‘h’;也是不行的。会直接C05

一个方法

image-20231115201657587

这个位置的值 1f0下面,根据wres 写入 读取 执行 分享

写成1100 也就是C0,这样就可以写入了