共2条
1/1 1 跳转至页
LPCARM,FLASH 在LPCARM上实现FLASH二次写入
问
众所周知,EPROM/FLASH ROM是可以进行"二次写入"的.
所谓"二次写入",就是在对EPROM/FLASH ROM某字节不进行擦除而多次改写其内容,这个本人已在多种MCU和EPROM/FLASH ROM中成功地应用过.
原则为'1'可写入'0',但'0'不可再写回'1'.
尤其在OTP的MCU中,可实现"多次写入".
这种"二次写入技术"可以实现对下载的代码进行"动态解密","动态自毁"...
而且对于无真正的EEPROM的MCU/ARM/DSP等,都可实现"伪EEPROM",使用价值较高.
当然,本帖是个"小儿科的东东",可能是菜农吃饱了没事干...
在当ARM菜鸟时就对LPCARM无EEPROM而"失望",但预感到"二次写入技术"应该在LPCARM能实现,今天做IAP类时,干脆就将其封装起来.
以下是部分测试代码和截图:
void IapObj::IapWriteTest(void)
{
char str[64];
unsigned char a[256];//ram
unsigned char *ptr;
int i;
ptr = (unsigned char *)0x000010000;//flash
Uart.puts("");
if (EraseSector(ptr, (void *)0x000100ff)) {
Uart.puts("擦除成功!!!");
}
else {
Uart.puts("擦除失败!!!");
}
for (i = 0; i < 256; i ++) {
a[i] = *(ptr + i);
}
// for (i = 128; i < 256; i ++) {
// a[i] = (unsigned char)i;
// }
Uart.puts("");
for (i = 0; i < 256; i ++) {
a[i] = (unsigned char)i;
if (ProgramPage(ptr, (void *)&a[0], 256)){
sprintf(str, "%02X -->一次写入成功!!!", i);
Uart.puts(str);
}
else {
sprintf(str, "%02X -->一次写入失败!!!", i);
Uart.puts(str);
}
}
Uart.puts("");
for (i = 0; i < 256; i ++) {
sprintf(str, "%02X: %02X", i, *(ptr + i));
Uart.puts(str);
}
Uart.puts("");
for (i = 0; i < 4; i ++) {//对0xfe进行二次写入,写4遍后为0xaa
a[254] &= ~(1 << (i * 2));
if (ProgramPage(ptr, (void *)&a[0], 256)){
sprintf(str, "%02X -->二次写入成功!!!", a[254]);
Uart.puts(str);
}
else {
sprintf(str, "%02X -->二次写入失败!!!", a[254]);
Uart.puts(str);
}
}
Uart.puts("");
for (i = 0; i < 8; i ++) {//对0xff进行二次写入,写8遍后为0x00
// a[255] &= ~(1 << i);//等效为下句
a[255] <<= 1;
if (ProgramPage(ptr, (void *)&a[0], 256)){
sprintf(str, "%02X -->二次写入成功!!!", a[255]);
Uart.puts(str);
}
else {
sprintf(str, "%02X -->二次写入失败!!!", a[255]);
Uart.puts(str);
}
}
}
bool IapObj::IapExec(void)
{
unsigned int save_VicInt; // for saving of interrupt enable register
bool result;
save_VicInt = VIC->IntEnable; // save interrupt enable status
VIC->IntEnClr = 0xFFFFFFFF; // disable all interrupts
iap_execute(IAPDR);// 调用IAP服务程序
VIC->IntEnable = save_VicInt; // enable interrupts
result = (IAPDR.stat == CMD_SUCCESS);
return result;
}
bool IapObj::EraseSector(void* start, void* end)
{
bool result;
IAPDR.cmd = IAP_SELECTOR;//选择扇区
IAPDR.par[0] = GetSecNum(start);//开始扇区
IAPDR.par[1] = GetSecNum(end); //结束扇区
IapExec();// 调用IAP服务程序
result = (IAPDR.stat == CMD_SUCCESS);
if (result) {
IAPDR.cmd = IAP_ERASESECTOR;//擦除扇区
IAPDR.par[2] = IAP_FCCLK;
IapExec();// 调用IAP服务程序
result = (IAPDR.stat == CMD_SUCCESS);
}
return result;
}
答 1: 这个...好象不大好玩啊~~~~~~~~` 答 2: 放心用吧...5年前就在PIC上玩过了,这次移植到ARM来玩没想到00胆子也够小的...
哈哈,以前用PIC/AVR都有EEPROM,这次3个LPCARM产品我根本就没排EEPROM!!!
不这么玩就只有跳楼了... 答 3: 我宁愿挂一个24xx上去应付一下。。。反正要不了几个毫子~~~~~~~~ 答 4: 晕菜~~~主要为了远程下载时的加密和解密最简单的是将有效数据都初始化为0xff...再通过每个不同的授权解密这些数据...
同理,将函数指针也强写为0xffffffff,再...
哈哈...好玩否??? 答 5: 原来是这样玩法。。。 答 6: 哈哈,一张白纸可画的东西很多,00不会只喜欢美人头吧假使程序正确时应该跳入0x80000000,你先搞个她到0x88888888.
看她晕不晕!!!想不晕---拿菜来!!!
通过她的硬盘或ID等(唯一)信息,解出密钥0x08888888.
将其异或即为0x80000000.
这样做的结果是可以"明码下载",程序可以"公开"!!!
要想真正运行程序,需要"二次注册下载"才能"解密展开程序".
这种手段对付一般的"高手"基本就足够了... 答 7: 只能对付加引号的“高手”~~~~~~~~~~~` 答 8: 这是密码学的问题,至少让他破译250天才晕菜哈哈... 答 9: 还是菜农够晕菜俺还没想过在LPCARM上用这些加密技术呢,不过这样考虑倒是蛮有些可行性,就算只是对付带引号的高手 答 10: 哈哈,高手不用破译密码先反汇编,再删除你的密码验证程序 答 11: FLASH变量和FLASH计"次"器的构成由于FLASH写入次数和写入擦除等待时间等方面的约束,FLASH变量和FLASH计数器很难构成.
因为有'0'不能变'1'的束缚,所以FLASH变量不可以定位到某个存储单元地址上.
同理FLASH计数器也一样.
仔细分析"FLASH二次写入技术"后不难看出,若稍做变通,就可实现真正的FLASH变量和FLASH计数器.
计数器是每次遇到它都+/- 1,那么为什么不能每次清除1位变成"计次器"呢???
FLASH一般空间很大,而且几乎都是以扇区为单位擦除的.
那么假定FLASH计数器为8位,即0~255,那么就可分配256/8=32个字节作为"FLASH计次器",即:
0xff,0xff.....,0xff表示0x00
0xfe,0xff.....,0xff表示0x01
0xfc,0xff.....,0xff表示0x02
...........................
0x00,0xff.....,0xff表示0x07
0x00,0xfe.....,0xff表示0x08
0x00,0xfc.....,0xff表示0x09
...........................
0x00,0x00.....,0xff表示0x0f
...........................
0x00,0x00.....,0x00表示0xff
对于FLASH变量则必须采用每次改写地址+1的原则,还需要限制"写入次数".
故一般与FLASH计次器联合使用,即FLASH计次器实际为FLASH变量的"写入指针".
当"写入次数"满时才清除FLASH计次器和FLASH变量所在的扇区.
注意,FLASH计次器在初始化完成后就应该读到RAM中!!!
写入FLASH变量的同时也要更新FLASH计次器以备掉电后再将FLASH计次器的值读入RAM中.
一般FLASH变量是用于不频繁改写时,若需频繁改写,则再需要将FLASH变量读入RAM中.
即运行时在RAM中,掉电或上电时在FLASH中. 答 12: 哈哈,菜农对密电码还是有研究的,如果采用菜农理论高手也歇菜我在十几年前就对当今的密码验证机制存在异议!!!
我认为软件被破译的最大BUG就出在密码验证机制上面!!!
例如:word软件,它最大的功能就是文字处理.
假定没有密码验证机制,则word软件可以任意使用!!!
但是如果每个文字即字符都通过解码,则对不上密码的就显示乱码!!!
哈哈,这比不运行word软件更晕菜!!!
密码验证机制实际就是给解密者留了后门,打通这道门就见阳光了!!!
如果废除密码验证机制,则使解密者"无门无路"!!!老老实实解密!!!
2^N将是解密者的地狱之门!!! 答 13: 哈哈,最好还是别推广菜农的加密理念了,否则大家用的工具软件就.. 答 14: 晕菜~~~主题的插图也被删除!!!看来以后的帖图还是存在水潭里更安全些...
答 15: 终于实现"我一定要先下地狱后升天堂"在设计是我就没给自己留退路...
哈哈~~~置死地而后生!!!
所谓"二次写入",就是在对EPROM/FLASH ROM某字节不进行擦除而多次改写其内容,这个本人已在多种MCU和EPROM/FLASH ROM中成功地应用过.
原则为'1'可写入'0',但'0'不可再写回'1'.
尤其在OTP的MCU中,可实现"多次写入".
这种"二次写入技术"可以实现对下载的代码进行"动态解密","动态自毁"...
而且对于无真正的EEPROM的MCU/ARM/DSP等,都可实现"伪EEPROM",使用价值较高.
当然,本帖是个"小儿科的东东",可能是菜农吃饱了没事干...
在当ARM菜鸟时就对LPCARM无EEPROM而"失望",但预感到"二次写入技术"应该在LPCARM能实现,今天做IAP类时,干脆就将其封装起来.
以下是部分测试代码和截图:
void IapObj::IapWriteTest(void)
{
char str[64];
unsigned char a[256];//ram
unsigned char *ptr;
int i;
ptr = (unsigned char *)0x000010000;//flash
Uart.puts("");
if (EraseSector(ptr, (void *)0x000100ff)) {
Uart.puts("擦除成功!!!");
}
else {
Uart.puts("擦除失败!!!");
}
for (i = 0; i < 256; i ++) {
a[i] = *(ptr + i);
}
// for (i = 128; i < 256; i ++) {
// a[i] = (unsigned char)i;
// }
Uart.puts("");
for (i = 0; i < 256; i ++) {
a[i] = (unsigned char)i;
if (ProgramPage(ptr, (void *)&a[0], 256)){
sprintf(str, "%02X -->一次写入成功!!!", i);
Uart.puts(str);
}
else {
sprintf(str, "%02X -->一次写入失败!!!", i);
Uart.puts(str);
}
}
Uart.puts("");
for (i = 0; i < 256; i ++) {
sprintf(str, "%02X: %02X", i, *(ptr + i));
Uart.puts(str);
}
Uart.puts("");
for (i = 0; i < 4; i ++) {//对0xfe进行二次写入,写4遍后为0xaa
a[254] &= ~(1 << (i * 2));
if (ProgramPage(ptr, (void *)&a[0], 256)){
sprintf(str, "%02X -->二次写入成功!!!", a[254]);
Uart.puts(str);
}
else {
sprintf(str, "%02X -->二次写入失败!!!", a[254]);
Uart.puts(str);
}
}
Uart.puts("");
for (i = 0; i < 8; i ++) {//对0xff进行二次写入,写8遍后为0x00
// a[255] &= ~(1 << i);//等效为下句
a[255] <<= 1;
if (ProgramPage(ptr, (void *)&a[0], 256)){
sprintf(str, "%02X -->二次写入成功!!!", a[255]);
Uart.puts(str);
}
else {
sprintf(str, "%02X -->二次写入失败!!!", a[255]);
Uart.puts(str);
}
}
}
bool IapObj::IapExec(void)
{
unsigned int save_VicInt; // for saving of interrupt enable register
bool result;
save_VicInt = VIC->IntEnable; // save interrupt enable status
VIC->IntEnClr = 0xFFFFFFFF; // disable all interrupts
iap_execute(IAPDR);// 调用IAP服务程序
VIC->IntEnable = save_VicInt; // enable interrupts
result = (IAPDR.stat == CMD_SUCCESS);
return result;
}
bool IapObj::EraseSector(void* start, void* end)
{
bool result;
IAPDR.cmd = IAP_SELECTOR;//选择扇区
IAPDR.par[0] = GetSecNum(start);//开始扇区
IAPDR.par[1] = GetSecNum(end); //结束扇区
IapExec();// 调用IAP服务程序
result = (IAPDR.stat == CMD_SUCCESS);
if (result) {
IAPDR.cmd = IAP_ERASESECTOR;//擦除扇区
IAPDR.par[2] = IAP_FCCLK;
IapExec();// 调用IAP服务程序
result = (IAPDR.stat == CMD_SUCCESS);
}
return result;
}
答 1: 这个...好象不大好玩啊~~~~~~~~` 答 2: 放心用吧...5年前就在PIC上玩过了,这次移植到ARM来玩没想到00胆子也够小的...
哈哈,以前用PIC/AVR都有EEPROM,这次3个LPCARM产品我根本就没排EEPROM!!!
不这么玩就只有跳楼了... 答 3: 我宁愿挂一个24xx上去应付一下。。。反正要不了几个毫子~~~~~~~~ 答 4: 晕菜~~~主要为了远程下载时的加密和解密最简单的是将有效数据都初始化为0xff...再通过每个不同的授权解密这些数据...
同理,将函数指针也强写为0xffffffff,再...
哈哈...好玩否??? 答 5: 原来是这样玩法。。。 答 6: 哈哈,一张白纸可画的东西很多,00不会只喜欢美人头吧假使程序正确时应该跳入0x80000000,你先搞个她到0x88888888.
看她晕不晕!!!想不晕---拿菜来!!!
通过她的硬盘或ID等(唯一)信息,解出密钥0x08888888.
将其异或即为0x80000000.
这样做的结果是可以"明码下载",程序可以"公开"!!!
要想真正运行程序,需要"二次注册下载"才能"解密展开程序".
这种手段对付一般的"高手"基本就足够了... 答 7: 只能对付加引号的“高手”~~~~~~~~~~~` 答 8: 这是密码学的问题,至少让他破译250天才晕菜哈哈... 答 9: 还是菜农够晕菜俺还没想过在LPCARM上用这些加密技术呢,不过这样考虑倒是蛮有些可行性,就算只是对付带引号的高手 答 10: 哈哈,高手不用破译密码先反汇编,再删除你的密码验证程序 答 11: FLASH变量和FLASH计"次"器的构成由于FLASH写入次数和写入擦除等待时间等方面的约束,FLASH变量和FLASH计数器很难构成.
因为有'0'不能变'1'的束缚,所以FLASH变量不可以定位到某个存储单元地址上.
同理FLASH计数器也一样.
仔细分析"FLASH二次写入技术"后不难看出,若稍做变通,就可实现真正的FLASH变量和FLASH计数器.
计数器是每次遇到它都+/- 1,那么为什么不能每次清除1位变成"计次器"呢???
FLASH一般空间很大,而且几乎都是以扇区为单位擦除的.
那么假定FLASH计数器为8位,即0~255,那么就可分配256/8=32个字节作为"FLASH计次器",即:
0xff,0xff.....,0xff表示0x00
0xfe,0xff.....,0xff表示0x01
0xfc,0xff.....,0xff表示0x02
...........................
0x00,0xff.....,0xff表示0x07
0x00,0xfe.....,0xff表示0x08
0x00,0xfc.....,0xff表示0x09
...........................
0x00,0x00.....,0xff表示0x0f
...........................
0x00,0x00.....,0x00表示0xff
对于FLASH变量则必须采用每次改写地址+1的原则,还需要限制"写入次数".
故一般与FLASH计次器联合使用,即FLASH计次器实际为FLASH变量的"写入指针".
当"写入次数"满时才清除FLASH计次器和FLASH变量所在的扇区.
注意,FLASH计次器在初始化完成后就应该读到RAM中!!!
写入FLASH变量的同时也要更新FLASH计次器以备掉电后再将FLASH计次器的值读入RAM中.
一般FLASH变量是用于不频繁改写时,若需频繁改写,则再需要将FLASH变量读入RAM中.
即运行时在RAM中,掉电或上电时在FLASH中. 答 12: 哈哈,菜农对密电码还是有研究的,如果采用菜农理论高手也歇菜我在十几年前就对当今的密码验证机制存在异议!!!
我认为软件被破译的最大BUG就出在密码验证机制上面!!!
例如:word软件,它最大的功能就是文字处理.
假定没有密码验证机制,则word软件可以任意使用!!!
但是如果每个文字即字符都通过解码,则对不上密码的就显示乱码!!!
哈哈,这比不运行word软件更晕菜!!!
密码验证机制实际就是给解密者留了后门,打通这道门就见阳光了!!!
如果废除密码验证机制,则使解密者"无门无路"!!!老老实实解密!!!
2^N将是解密者的地狱之门!!! 答 13: 哈哈,最好还是别推广菜农的加密理念了,否则大家用的工具软件就.. 答 14: 晕菜~~~主题的插图也被删除!!!看来以后的帖图还是存在水潭里更安全些...
答 15: 终于实现"我一定要先下地狱后升天堂"在设计是我就没给自己留退路...
哈哈~~~置死地而后生!!!
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |