一、指针
& 取地址操作符。运用在内存中的对象上面,即变量与数组元素
* 间接寻址或者引用运算符。
指针:指针变量存储的是 变量类型的对应的变量的地址
int *p (int型指针p) p存储的是 int型的变量的地址
int main(){
int i = 10;
int *p; //定义一个指针变量 (p存储的是 int型的变量的地址)
p = &i; //取i的地址值赋给p
printf("i 的地址:%#x \n", &i); //打印结果为 i的地制值
printf("p 的地址:%#x \n",&p); //打印结果为 p的地址值 其实就是i的地址值
printf("sizeof(*p) %d\n ",sizeof(*p));//*p的大小 结果 4
double f = 23.99f;
double * fp;
fp = &f;
printf("f 的内存:%d \n",sizeof(f)); //结果是 8 double占用8个字节
//为什么结果是4? fp 是一个变量,指向double类型的数据的变量
//fp 是存储的地址, 地址是占用4个字节的。32位 4*8
//指针变量所占用的字节的大小是确定的 4个字节。
printf("sizeof(p)%d\n",sizeof(fp)); //结果是4
system("pause");
return 0;
}
二、外挂原理
只要知道一个变量的内存地址,就可以根据地址值更改变量的值,既可以直接根据指针改变他所指向的地址对应的内容。
int main(){
int i = 10;
int * p;
p = &i;
printf("i value:%d\n", i);
printf("p的地址:%#x \n",&p);
printf("i 的地址:%#x \n",&i);
printf("修改*p");
*p = 10000;
printf("i value:%d\n",i);
system("pause");
return 0;
}
三、简易外挂
1.假设有一个正在运行的计数器程序代码是这样的
#include<windows.h>
int main(){
int i = 1000;
printf("i的地址:%#x \n",&i);
while(i>0){
printf("计数器的值: %d\n",i);
i--;
Sleep(1000);
}
return 0;
}
2.将工程属性修改成动态链接库
3.外挂代码(生成动态链接库)
_declspec(dllexport) go(){
int *p; //定义一个指针变量
p = (int *)0x4ffca4 //拿到想要修改的变量的内存地址int值并强制转换为地址值,
*p = 100000; //手动修改其指向的值
}
4.使用注册器,找到想要修改的程序进程
5.使用自己写的dll外挂,执行go函数,注入动态链接库
6.可以看到计数器的值被强行修改了
四、知识要点
1. 关键字:sizeof() 用来计算基本数据类型 所占用的内存大小
(类似java的 instanceof)
//它只是一个操作符并不是一个函数
int i= 1;
printf("int 值:%d,int 类型数据内存大小:%d\n,i,sizeof(int)");
2. 单目 双目 三目运算符
//i++ 单目运算符(作用于一个变量上)
//1+2 1*2 双目运算符(作用在两个变量上)
//bool b = 3>2?true:false 三目运算符(三个变量共同起作用)
网友评论