C++逆アセンブリ学習ノート(二)

7156 ワード

Chinese:
1、アドレスポインタ参照
C++のアドレス番号は16進数で表し、変数アドレスを1つ取って&オペレータを使用し、変数だけがメモリアドレスが存在し、定数にはアドレスがない(const定義の擬似定数を含まない)
ポインタは、メモリ内の様々なデータ型のアドレスを保存するためのデータ型です.ポインタ変数はアドレスを取り出すこともできるので、マルチレベルポインタが表示されます.
C++の参照は単独で定義することはできません.定義するときは初期化する必要があります.参照は変数を表す別名であり、その任意の操作に対して、本質はその表す変数を操作することである.
 
2、ポインタとアドレスの違い
ポインタは変数であり、変数アドレスを保存するために使用されます.アドレスは定数で、メモリ番号です.
ポインタは変更可能で、他の変数アドレスを再保存することができます.アドレスは変更できません.
ポインタは、アドレス取得操作を実行してアドレスを得ることができる.アドレスはアドレス取得操作を実行できません.
ポインタには、保存アドレスの解釈情報が含まれる.アドレスはデータを解釈できません.
 
3、各種類のポインタの働き方
C++の逆アセンブリ命令で説明する
// C++ Code:
int nVar = 0x12345678;

;     4    12345678h
mov dword ptr [ebp-10h], 12345678h

// C++ Code:
int *pnVar = &nVar;

lea ecx, [ebp-10h]
mov dword ptr [ebp-14h], ecx

// C++ Code:
char *pcVar = (char*)&nVar;

lea edx, [ebp-10h]
mov dword ptr [ebp-18h], edx

// C++ Code:
short *psnVar = (short*)&nVar;

lea eax, [ebp-10h]
mov dword ptr [ebp-1Ch], eax

// C++ Code:
printf("%08x", *pnVar);

;  pnVar          ecx 
mov ecx, dword ptr [ebp-14h]
mov edx, dword ptr [ecx]
;printf       

// C++ Code:
printf("%08x", *pcVar);

;  pcVar          eax 
mov eax, dword ptr [ebp-18h]
; eax      , 1        ,  ecx 
movsx ecx, byte ptr [eax]

// C++ Code:
printf(“%08x", *psnVar);

;  psnVar         edx 
mov edx, dword ptr [ebp-1Ch]
; edx      , 2         ,  eax 
movsx eax, word ptr [edx]

表示されるポインタタイプは、ポインタタイプに従ってアドレスデータを解釈します.コンテンツ除去操作は一般的に2つのステップに分けられ、ポインタに保存されているアドレス情報を先に取り出し、その後、このアドレスに対してコンテンツ、すなわち間接アドレスを取るプロセスであり、これもポインタを識別する重要な根拠である.
 
4、引用の内部動作原理を理解する
実際には参照タイプはポインタタイプですが、アドレスを格納するためのメモリ領域はユーザーにとって非表示です.
// C++ Code
 int nVar = 0x12345678;

mov dword ptr [ebp-4], 12345678h

// C++ Code
int &nVarType = nVar;
;    nVar     eax 
lea eax, [ebp-4]
;   nVar       ebp-8 ,  ebp-8       nVarType   
;
mov dword ptr [ebp-8] eax;

//    Add,Add    int    ,   nVar      
Add(nVar);

;    nVar     ecx
lea ecx, [ebp-4]
; ecx      ,       nVar       
push ecx;
;        
call @ILT+15 (Add)  (00401014)
add esp, 4

参照タイプの格納方法はポインタと同じで、メモリ領域を使用してアドレスを格納します.リファレンスはコンパイラによってのみアドレッシングされ、ポインタは手動でアドレッシングする必要があります.
参照タイプは、関数のパラメータタイプと戻りタイプとしても使用できます.参照は実際にはポインタであるため、パラメータの転送時にコピーが生成されます.
// C++ Code
void Add(int &nVar)
{
    nVar++;
}

;    nVar      eax 
mov eax, dword ptr [ebp+8]
; eax       
mov ecx, dword ptr [eax]
add ecx, 1
mov edx, dword ptr [ebp+8]
mov dword ptr [edx], ecx
ret

アセンブリコードから、参照タイプのパラメータもメモリ領域を占め、保存されたデータはアドレス値であることがわかります.このアドレスのデータを取り出して1を加え、+1の結果を戻します.したがって、逆アセンブリでは、このようなデータ型は参照されません.
転載先:https://www.cnblogs.com/maplewan/p/3243785.html