本篇文章適用於有一定c語言基礎,但是對c++零基礎的同學看,講解了c++裡的一些概念
c在定義乙個結構體的時候,就是定義乙個新的資料型別
而c++在定義乙個結構體,會有乙個this指標,指向本結構體的位址,傳的this指標的值一般給到了ecx。主要應用如下
typedef struct
}str;
int main()
這樣可以修改結構體裡的變數值
在c++中,如果有一些struct的東西是重複的,那我們就懶得再寫,直接copy過來,c++提供乙個很方便的東西繼承
struct person
;struct a
struct a:person
兩種方式都差不多,person就是a的爹,稱為父類,父類指標可以用來訪問子類裡父類的東西。
再說一點,如果子類和父類有定義相同的變數,那麼需要在子類變數前加入乙個類名加兩個冒號才行
建構函式就是宣告類後可以直接啟動的函式,可以過載,可以有引數,無返回值
class test
};int main()
~
析構函式,這個類不用後執行的乙個函式,可以用來free,不能過載,不能有引數,無返回值
有父類子類,先父構造、子構造、子構析,父構析
虛函式表
如果在乙個函式前加virtual,就是虛函式虛函式呼叫:
mov ecx,dword ptr [ebp-10]
mov edx,dword ptr [ecx];虛表位址給到edx
mov esi,esp
mov ecx,dword ptr [ebp-10]
call dword ptr [edx];取虛表位址裡的資料,就是虛表
底層上從this指標處會多存乙個4位元組(32位),這個4位元組就是儲存著虛表的位址
這個虛表是乙個陣列,裡面有函式位址
有乙個父類的話,是直接把父類的虛表拿過來,子類接著寫,如果子類和父類虛函式名重複,子類中copy來的父類虛表上的函式會被改寫,這就是動態繫結。在這個基礎上子類每多繼承乙個父類,就會多乙個虛表,也就是多4位元組(32位)而子類的虛函式放在第一張虛表了,其他虛表放其他父類的虛函式(不推薦使用)
所以取虛表:
class base
........
base b;
printf("虛表的位址是%d",*(int*)&b);
多型
#includeclass base
virtual void print()
};class sub1:public base
virtual void print()
};class sub2:public base
virtual void print()
};void test()
; for(int i = 0;i<3;i++)
}int main()
上面的執行結果
base:1 2
base:4 5
base:7 8//前面沒有加virtual
base:1 2//後面加了virtual
sub1:4 5 6
sub2:7 8 9
這樣也指明了:析構函式最好定義成虛函式.
我們之前寫了乙個函式是這樣傳參的
func(int* a)
我們知道一般而言函式不能更改引數的值,假如傳參進去是ebp+8,然後ebp+8給eax,這樣我們在函式裡修改的值是eax的值,不是引數的值,但我們觀察一下上面的反彙編
*a = 10;
mov eax,dword ptr [ebp+8]
mov dword ptr [eax],0ah
可以看到,假如傳進去的是個位址,直接把位址裡的資料給改了,也就是能修改引數
所以c++裡面有個引用符號
void test(int &x)
int main()
在底層傳參是一樣的
lea eax,[ebp-4]
push eax
call@ilt+0(test)
有什麼不一樣的地方,就是有一種情況指標的值被修改,比如上面的第一行注釋的**,就是指標亂指
如果用引用的話,不能夠進行亂指,比如x = 2,只是普通地把2給到這個變數,編譯器不允許引用指向別的地方,引用中那個x永遠代表a
同樣的資料型別給指標就是指向另乙個,不管原來的,而引用就是把指向的那個東西的值修改一下
還有就是傳結構體的話引數太多,直接傳引用好一點
我們都知道class裡面的成員,資料成員都是私有的
class person
//friend void print(const person& refper);
};void print(person &p)
如果這樣的話是不能打出來的,因為私有的,只有型別的其他成員能訪問,比如自己的方法啥的,但是我們就要訪問咋整(通過指標訪問記憶體可以)
那我們可以把注釋中的**寫出來,告訴這個類,這個print是它的朋友,通過這個函式訪問類就可以訪問私有成員了
在c++中,通常說我們要new乙個物件,在物件不用的時候delete他。其實new是把malloc再封裝一遍的,比malloc多了一層。比如int* pi = new int;
就分配了int大小的空間,所以申請物件person* pa = new person(1,2);
並執行建構函式,也就是說,new乙個物件的目的其實就是把他放到堆裡,不然的話我們只能放到全域性變數(data )或者區域性變數(stack)裡了
要注意delete和new一定配套,如果new int[10];
一定要delete;
往後會用c++做
逆向分析技術總結
好久沒寫過文件了,今天把之前的關於逆向 分析的一些心得總結一下,反正閒著也是閒著 本文不包含什麼新的 技術,只是將 於各方的知識加上自己的心得進行總結而已,高手就不用看了 我認為軟體安全攻防其本質是分析與抗分析之間的鬥爭。因為無論安全技術做的多麼先進,一旦其 意圖被分析者掌握,就不在有安全性可言。想...
逆向分析細節總結
1 函式識別及引數傳遞 call指令 跳轉指令 返回位址 call指令跳轉的位址即被呼叫函式的起始位址 函式引數傳遞方式 1 堆疊傳遞引數 2 暫存器傳遞引數 fastcall thiscall 暫存器傳遞this指標 引數入棧順序,平衡堆疊 1 c c 和mfc程式預設使用 cdecl呼叫約定,引...
遊戲逆向學習 C 共同學習1
這裡要說的就是建立的時候一定要預先宣告。這裡我們發現在指標指向引用變數時,和我們平常指標指向輸出不一樣,乙個輸出真實值,乙個卻輸出了位址,經過又一輪驗證看圖2。這裡我們看的出其實引用的實際含義就是與原始值使用相同位址,引用變數自身為什麼不能賦值的原因就在這裡。類似於寄生的關係。第三個知識點 將引用用...