實(shí)驗(yàn)環(huán)境為VS2015
#include <stdio.h>
void decodeOprand()
{
/*
00C91650 push ebp
00C91651 mov ebp,esp
00C91653 sub esp,0C0h // 默認(rèn)提高堆棧的大小為C0h;在x86系統(tǒng)中,內(nèi)存是小端存儲方式
00C91659 push ebx
00C9165A push esi
00C9165B push edi
00C9165C lea edi,[ebp-0C0h]
00C91662 mov ecx,30h
00C91667 mov eax,0CCCCCCCCh // 填充為0CCCCCCCCh,防止中間出現(xiàn)問題,如果出現(xiàn)問題則可以及時的產(chǎn)生中斷,以便調(diào)試器可以接收到中斷
00C9166C rep stos dword ptr es:[edi]
*/
// 防止被和諧
// 00C9166E mov dword ptr [i],0
// 去掉 右鍵->顯示符號名后可以看到
// 00C9166E mov dword ptr [ebp-8],0
// 可以證明i <=> ebp-8;即我們聲明的變量符號i,在匯編中代表的是地址ebp-8;也可以看出來是棧變量;即局部變量為棧變量
// 第一個變量的起始地址為ebp-8;
// int i = 0;
// 00F41A75 mov dword ptr [ebp - 14h], 2
// 增長的幅度為 0x14h - 0x08h = 0Ch;
// int b = 2;
// int c = 3;
char a = 1;
// char d = 4;
// short b = 2;
int c = 3;
// short e = 5;
// 相同的差0Ch,不同之間差0Fh
// short和int之間是一樣的,只是對地址的解釋不一樣
// short是將從[]地址解釋為word大小;int是將從[]地址解釋為dword大小
// 以有符號整數(shù)進(jìn)行解釋
// 在分析過程中其實(shí)無需知道到底是哪個,只需要知道每個內(nèi)存單元的功能,以及怎么解釋的即可
}
void decodePointer()
{
int nVar = 0x12345678;
int* pnVar = &nVar;
char* pcVar = (char*)&nVar;
short* psnVar = (short*)&nVar;
printf("%08x \r\n", *pnVar);
printf("%08x \r\n", *pcVar);
printf("%08x \r\n", *psnVar);
}
void decodePointerOperator()
{
// cVar 代表的是數(shù)組的第一個數(shù)據(jù)的首地址
// __cdecl調(diào)用約定,參數(shù)傳遞為從右到左;調(diào)用方負(fù)責(zé)清理堆棧
// 00834B48 mov byte ptr [ebp-10h],1
char cVar[5] = { 0x01,0x23,0x45,0x67,0x89 };
// 01194B5C lea eax,[ebp-10h]
// 01194B5F push eax
printf("%x\r\n", cVar);
int* pnVar = (int*)cVar;
char* pcVar = (char*)cVar;
short* psnVar = (short*)cVar;
/*
00C34B6E mov eax,dword ptr [ebp-1Ch]
00C34B71 add eax,4
00C34B74 mov dword ptr [ebp-1Ch],eax
00C34B77 mov eax,dword ptr [ebp-28h]
00C34B7A add eax,1
00C34B7D mov dword ptr [ebp-28h],eax
00C34B80 mov eax,dword ptr [ebp-34h]
00C34B83 add eax,2
00C34B86 mov dword ptr [ebp-34h],eax
*/
// 首地址 + sizeof(指針type) * n;
pnVar += 1;
pcVar += 1;
psnVar += 1;
// 每加一個*就是在這個指針的type上減掉一個星
int a = 1;
int* i = &a;
int** pI = &i;
int*** pPi = &pI;
int**** p = &pPi;
/*
01054C89 mov eax,dword ptr [ebp-70h]
// 下面是*的操作,有幾句就是幾顆*
01054C8C mov ecx,dword ptr [eax]
01054C8E mov edx,dword ptr [ecx]
01054C90 mov eax,dword ptr [edx]
01054C92 mov ecx,dword ptr [eax]
*/
printf("%x\r\n",****p);
// * 的運(yùn)用:假設(shè)int**** p = (int****)&nVar; 那么***p == nVar;
}
void usePointer()
{
// 要修改被const限制的局部變量i
const int i = 10;
int* pnI = (int*)&i;
*pnI = 20;
// 在內(nèi)存中其實(shí)已經(jīng)改了,但是為什么輸出的還是10呢
// 答案是常量傳播,看反匯編即可明確
/*
008B4B64 push 0Ah
008B4B66 push 8B6C0Ch
008B4B6B call 008B1352
*/
// 經(jīng)由常量傳播,直接吧0Ah傳遞給了printf函數(shù)
printf("%d %d\r\n",i,*pnI);
}
int main()
{
decodeOprand();
decodePointer();
decodePointerOperator();
usePointer();
getchar();
return 0;
}
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。