前言
正向開發,是先寫代碼,再編譯成軟件。而逆向分析,到手的只有軟件。從軟件入手,推測對應的代碼,需要了解一下編譯之后的軟件是怎么跑起來的。
軟件運行過程
1、軟件加載到內存。
2、CPU讀取內存的指令。
3、根據指令,再讀取數據,進行運算。
4、運算的過程,數據是存在CPU里面的寄存器。
5、運算過程,用到另一個功能,需要保存當前環境,存到堆棧。
(這里涉及操作系統和計算組成原理,大概了解,心里有底就好)
代碼語言的變化
1、C/C++語言:高級語言,給人看的
2、匯編語言 :低級語言,給機器用的
(逆向分析,接觸多是匯編語言, 需要自行學習下)
軟件加載過程
磁盤 >>內存>>寄存器
1、代碼編譯成軟件,先放在磁盤(C盤,D盤這些)
2、開始運行的時候,就會加載進內存(平時說的內存條)
3、真正運行的是在CPU(也就是所謂的芯片),里面存數據的地方叫寄存器。
軟件的構成
軟件的外部
包含:一個主要程序(exe后綴),多個獨立庫(dll后綴)。
內存一開始加載exe,有必要的時候,exe再把dll加載進內存來。
exe或者dll在內存的開始位置,叫做基址。(每次加載,隨機放置,基址不固定)
exe或者dll里面和基址的距離,叫做偏移。(每次加載,內部不變,偏移固定)
打個比喻:exe和dll相當小尺子,要放在內存這個大尺子上。
大尺子上只要有空位,小尺子就可以隨便放。
小尺子不管怎么放,里面的刻度固定的。
軟件的內部
軟件 = 代碼 + 數據
數據 = 靜態數據 (數據不會變)+ 動態數據 (數據會改變)
動態數據 = 全局數據 (多個函數共用)+ 局部數據(單個函數私有)
代碼和靜態數據在軟件運行過程不會改變,位置固定,可以方便使用。
全局數據,因為是共用的,位置固定,也可以方便使用。
所以這三種的偏移是不變的。
內存地址 = 基址 + 偏移。
基址可以用GetModuleHandle得知。
偏移又是不變的,內存地址也就可以算出來了 。
而偏移會變化的局部數據,就不能直接算出來了。
局部數據,是軟件運行過程中,臨時生成又銷毀的。
所以要獲取局部數據,只能在軟件的運行過程進行攔截。(也就是所謂的HOOK)
逆向分析目的
逆向分析的兩個目的
1、調用功能
2、獲取數據
通過上面的原理可以知道
1、調用功能
代碼是固定的,找到偏移,就可以調用。
2、獲取數據
對於全局數據,找到偏移,就可以得到。
對於局部數據,需要攔截,才可以得到 。
(攔截的是代碼,所以要找代碼的偏移)
所以,逆向的核心點,是找固定的偏移。
下一篇,找偏移的方法。
參考資料(下功夫,基礎扎實,逆向才順手)
匯編:http://c.biancheng.net/asm/
反匯編:《C++反匯編與逆向分析技術揭秘》
函數調用:https://blog.csdn.net/zhongguoren666/article/details/7586074?utm_source=blogxgwz6