Jlink使用技巧之讀取STM32內(nèi)部的程序
Jlink可以將Hex文件下載到單片機(jī)內(nèi),也可以將未加密單片機(jī)內(nèi)部的程序文件讀出。本篇文章介紹,如何使用JFlash來(lái)讀取單片機(jī)的程序,學(xué)習(xí)單片機(jī)程序文件的讀取,不是為了破解別人的程序,而是學(xué)習(xí)破解的原理,從而更好保護(hù)自己的程序不被破解,希望大家也能尊重他人的勞動(dòng)成果。
JFlash的下載和安裝
首先,安裝JFlash軟件,安裝完成后,會(huì)默認(rèn)安裝JLink驅(qū)動(dòng)程序,主要包含以下幾個(gè)工具:- JFlash,主要用于程序下載和讀取。
- JFlashLite,JFlash的Mini版
- JFlashSPI,用于給SPI存儲(chǔ)器下載程序,如W25Q128。
- JLinkGDBServer,用于第三方軟件的調(diào)試器,如使用Eclipse搭建STM32開發(fā)環(huán)境時(shí),就要使用GDB Server來(lái)進(jìn)行調(diào)試。
- JLink Command,命令操作窗口,輸入指令執(zhí)行連接,擦除、下載、運(yùn)行等操作。
軟件準(zhǔn)備
- Jlink軟件,J-Flash
- Jlink調(diào)試器,如Jlink V9
- 單片機(jī)開發(fā)板,如STM32F103RET6
1.打開JFlash
2.創(chuàng)建新工程
點(diǎn)擊 File->NewProject3.選擇芯片的型號(hào)
這里支持很多ARM Cortex內(nèi)核的芯片,選擇要讀取單片機(jī)對(duì)應(yīng)的芯片型號(hào),我這里選擇的是STM32F103RE系列。4.連接芯片
如果選擇的是SWD模式,就要連接SWDIO、SWCLK、GND這三根線,連接好之后,點(diǎn)擊Target->Connect,如果連接成功,在下面的LOG窗口會(huì)顯示連接成功。5.讀取單片機(jī)內(nèi)的程序
重點(diǎn)來(lái)了!選擇Target->Manual Programming ->Read Back,一共有三個(gè)選項(xiàng),用于讀取不同的Flash地址范圍。- Selected sectors
- Entire chip
- Range
6.保存讀取到的程序
選項(xiàng)File-> Save data file或者是Save data file as,保存類型根據(jù)需要選擇,建議選擇Hex格式,已經(jīng)包含了地址信息。7.程序的驗(yàn)證。
怎么驗(yàn)證讀取到的程序是正確的呢?很簡(jiǎn)單,重新燒寫進(jìn)去,看運(yùn)行現(xiàn)象和原來(lái)的是不是一樣就行了。具體操作方法查看上一篇Jlink系列文章:Jlink使用技巧之單獨(dú)下載HEX文件到單片機(jī)總結(jié)
既然能這么簡(jiǎn)單的讀取到單片機(jī)的程序,那么我們自己的程序應(yīng)該如何保護(hù)起來(lái)呢?很顯然,我們可以對(duì)Flash設(shè)置讀保護(hù)功能,即大家說(shuō)的“加密”功能,可以防止對(duì)Flash的非法訪問(wèn),這里的加密是針對(duì)整個(gè)Flash區(qū)域的,如果設(shè)置了讀保護(hù)功能,那么程序只能正常的從RAM中加載運(yùn)行,而不能通過(guò)調(diào)試器讀出來(lái),那么別人就不能破解了。哈哈!具體怎么實(shí)現(xiàn)呢?這里先介紹幾個(gè)關(guān)于Flash保護(hù)操作的幾個(gè)庫(kù)函數(shù):FLASH_Unlock(); ? //Flash解鎖
FLASH_ReadOutProtection(DISABLE); ?//Flash讀保護(hù)禁止 ?
FLASH_ReadOutProtection(ENABLE); ? //Flash讀保護(hù)允許
void Set_Protect(void)
{
? ?if(FLASH_GetReadOutProtectionStatus() != SET)
? ?{
? ? ? ?FLASH_Unlock();
? ? ? ?FLASH_ReadOutProtection(ENABLE);
? ? ? ?FLASH_Lock();
? ?}
}
- 啟動(dòng)讀保護(hù)后,就不能讀寫程序了,如使用JLink讀取程序,或者是重新下載程序。
- 所以,在下載程序之前,需要通過(guò)程序內(nèi)部調(diào)用關(guān)閉讀保護(hù),關(guān)閉讀保護(hù)之后,會(huì)自動(dòng)清空Flash
- 另外,當(dāng)?shù)谝淮握{(diào)用SetProtect()函數(shù)啟動(dòng)讀保護(hù)之后,不能再次調(diào)用OffProtect()函數(shù)關(guān)閉讀保護(hù),需要重新斷電才能關(guān)閉讀保護(hù)
void Off_Protect(void)
{
? ?if(FLASH_GetReadOutProtectionStatus() != RESET)
? ?{
? ? ? ?FLASH_Unlock();
? ? ? ?FLASH_ReadOutProtection(DISABLE);
? ? ? ?FLASH_Lock();
? ?}
}
int main(void)
{
? ?/*用戶代碼*/
? ?if(KEY == 0) ? ? ? ?//按鍵按下
? ?{
? ? ? ?Off_Protect();
? ?}
? ?else
? ?{
? ? ? ?Set_Protect();
? ?}
? ?/*用戶代碼*/
? ?while(1)
? ?{
? ?/*用戶代碼*/
? ?}
}