IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【嵌入式】NXP/LPC的CRP功能的使用(代码加密/解密) -> 正文阅读

[嵌入式]【嵌入式】NXP/LPC的CRP功能的使用(代码加密/解密)

目录

一 J-Flash读取MCU内部程序

二 程序加密

三 程序解密


一 J-Flash读取MCU内部程序

? ? ? ? 通过J-Flash可以读取到MCU内部的程序,步骤如下:

(1)进入J-Flash,选择指定的芯片之后,点击连接Target-Connect;

(2)根据需要选择Read back中的选项,分别是回写Project settings中预设的扇区区间(Selected sectors)、回写芯片全部的扇区(Entire chip)、回写指定范围的扇区(Range)。选择之后J-Flash会回写内存中的数据

(3)可以保存读取到的数据,建议选择HEX格式。这样就可以把回写得到的程序纳为己用,进行重复烧写。

二 程序加密

? ? ? ? 经过上一章,如此简单就可以获得MCU中的程序,那有效地把自己的程序保护起来就显得尤为重要。以所使用的LPC1857为例,关于CRP,其说明书如下:

? ? ? ? 总结概括为以下几点:

(1)LPC1857有三个CRP权限以及对应的安全码,分别为CRP1(0x12345678)、CRP2(0x87654321)、CRP3(0x43218765)。从这三个安全权限中选择所需的设置值写入到0x1A0002FC或者0x1B0002FC,即可实现ROM1或者ROM2的加密。

(2)无论设置哪一种权限,JTAG都是禁用的。谨慎选择CRP3,我这边选用的是CRP1级别。

(3)加密的时候,需要确认keil的option中,没有定义NO_CRP宏,否则加密失效:

????????程序加密的方法如下:

(1)在main.c中加入下面的语句,作用在于预开辟出0x1A0002FC处的空间用作CRP功能:

const unsigned crp __attribute__((section(".ARM.__at_0x1A0002FC"))) = 0x12345678;

?(2)startup_LPC18xx.s中,关于CRP的部分修改如下:

;CRP address at offset 0x2FC relative to the BOOT Bank address
                IF      :LNOT::DEF:NO_CRP
                AREA    |.ARM.__at_0x1A0002FC|, CODE, READONLY
;                EXPORT  CRP_Key
CRP_Key         DCD     0x12345678
;                       0xFFFFFFFF => CRP Disabled
;                       0x12345678 => CRP Level 1
;                       0x87654321 => CRP Level 2
;                       0x43218765 => CRP Level 3 (ARE YOU SURE?)
;                       0x4E697370 => NO ISP      (ARE YOU SURE?)
                ENDIF

                AREA    |.text|, CODE, READONLY

?这样,即可以对程序进行CRP1级别加密,烧写MCU,重启之后代码保护生效,再通过JTAG烧写程序,或者通过J-Flash回写内存均不能成功。

三 程序解密

? ? ? ? 程序加密之后,需要通过擦除或者修改0x1A0002FC处的值,来实现解密。主要分为下面两种方式。

(1)加密之后,程序不能通过JTAG口进行烧写,但是可以进入ISP模式,通过Flash Magic软件进行下载或者擦除操作(外部硬件进入ISP模式只对CRP1和CRP2有效;而IAP指令进入ISP模式对CRP1、CRP2、CRP3均有效);

(2)可以通过程序执行IAP指令擦除扇区0整块扇区,来清除0x1A0002FC处的加密值,重新上电之后,就可以恢复未加密的状态(加密或者解密程序下载到MCU之后,都必须重新上电才能生效);

? ? ? ? 我这边采用的第二种方法,思路是通过串口接收特定的通讯指令(例如XX XX 12 34),当串口数据接收函数收到该指令时,则执行扇区清除

void exBufRcv(unsigned char *p_rcv_buf)
{
    int i = 0;
	int j = 0;

    //修改IAP与APP切换的标志位
    if((p_rcv_buf[2] == APP_CONFIG_SET_VALUE) || (p_rcv_buf[2] == APP_CONFIG_CLEAR_VALUE))
    {
        iap_init(BANK0);
        Iap_Write_Config_Value(p_rcv_buf[2]);

        __set_FAULTMASK(1);
        NVIC_SystemReset();
    }
    
    //收到解锁命令码之后,执行扇区清除操作
    if((p_rcv_buf[2] == 0x12) && (p_rcv_buf[3] == 0x34))
    {
        iap_init(BANK0);
        iap_erase_flash(0x1A0002FC, 4);
    }
}
/******************************************************************************************************  
** 函数名称:iap_erase_flash()  
** 函数功能:flash 擦除操作  
** 入口参数:addrDst       要擦除flash的起始地址  
**           length        要擦除flash的长度   
** 出口参数:IAP操作状态码  
**           IAP返回值(paramout缓冲区)  
*******************************************************************************************************/ 
uint32_t iap_erase_flash(uint32_t addrDst, uint32_t length)
{
	uint32_t state;
	uint32_t baseAddr;
	
	if (length == 0)
	{
		return 101;
	}
	
	if (g_bank_num)
	{
		baseAddr = 0x1B000000;
	} else
	{
		baseAddr = 0x1A000000;
	}
	
	if ((addrDst < baseAddr) || ((addrDst + length) > (0x7FFFF + baseAddr)))
	{
		return 100;
	}

	// 计算起始扇区号
	if (addrDst < (0x10000 + baseAddr))
	{
		gSecStart = (addrDst - baseAddr) / (8 << 10);
		if ((addrDst + length) < (0x10000 + baseAddr))
		{
			gSecEnd = (addrDst - baseAddr + length) / (8 << 10);
		} else
		{
			gSecEnd = 8 + (addrDst - baseAddr - 0x10000 + length) / (64 << 10);
		}
	} else
	{
		gSecStart = 8 + (addrDst - baseAddr - 0x10000) / (64 << 10);
		gSecEnd = 8 + (addrDst - baseAddr - 0x10000 + length) / (64 << 10);
	}

//	debugPrint("bank %d, len %d,sector start %d, end %d\r\n", g_bank_num, length, gSecStart, gSecEnd);
		 
	CLOSE_CORE_INT();	

	state = pre_sector(gSecStart, gSecEnd, g_bank_num);

	if (state == CMD_SUCCESS) 
	{
		state =  erase_sector(gSecStart, gSecEnd, g_bank_num);		
	
		if (state == CMD_SUCCESS) 
		{
			state = blank_check_sector(gSecStart, gSecEnd, g_bank_num);
		}  
	}		   
	OPEN_CORE_INT();

	return state;
}

? ? ? ? 如果程序中IAP部分程序和APP部分程序是分开的话【嵌入式】基于串口的IAP在线升级详解与实战1----IAP功能设计),需要对IAP程序和APP程序分开处理,在IAP程序中,初始化设置0x1A0002FC加密。在APP中,串口收到特定码解密

? ? ? ? 总的来说,给程序加密,尽管可能会带来程序调试或者debug的不便,但是对于保护自己的劳动成果是非常重要的。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:57:52  更:2021-07-23 10:58:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:15:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码