一、指針
& 取地址操作符。運用在內存中的對象上面,即變量與數組元素
* 間接尋址或者引用運算符。
指針:指針變量存儲的是 變量類型的對應的變量的地址
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個字節(jié)
//為什么結果是4? fp 是一個變量,指向double類型的數據的變量
//fp 是存儲的地址, 地址是占用4個字節(jié)的。32位 4*8
//指針變量所占用的字節(jié)的大小是確定的 4個字節(jié)。
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.將工程屬性修改成動態(tài)鏈接庫

3.外掛代碼(生成動態(tài)鏈接庫)
_declspec(dllexport) go(){
int *p; //定義一個指針變量
p = (int *)0x4ffca4 //拿到想要修改的變量的內存地址int值并強制轉換為地址值,
*p = 100000; //手動修改其指向的值
}
4.使用注冊器,找到想要修改的程序進程

5.使用自己寫的dll外掛,執(zhí)行go函數,注入動態(tài)鏈接庫

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 三目運算符(三個變量共同起作用)