使用有license声明的代码,即使是二进制文件也可判断

上一篇微头条中说道:

如果我们将ST提供的代码编译成二进制文件下载到国厂替换芯片中,

可以芯片内的二进制代码被读出,并与用完全一样的编译器编译出的代码进行二进制文件的比较。

应该会有大块二进制数据相同,根据相似性可以判断出使用了ST声称了版权的代码。

为了证实这一点,我找了两套软件代码进行比较。

一套是6年前编写的雷电预警的代码,没有bootloader,

启动文件startup_stm32f0xx.s以及系统初始化文件system_stm32f0xx.c与应用程序混在一起;

另一套是前几年编写的bootloader的代码,除了启动文件startup_stm32f0xx.s以及系统初始化文件system_stm32f0xx.c之外,仅有一些flash操作的代码。

一、比对bin文件

如下图,在keil的options中,设置编译之后运行程序生成bin文件。

使用有license声明的代码,即使是二进制文件也可判断

设置生成bin文件

通过compare it软件比对两套代码生成的bin文件,可以发现有大块二进制数据相同。

使用有license声明的代码,即使是二进制文件也可判断

大量二进制数据相同

那么这些相同的二进制数据是否就是ST声称版权的代码?

二、反汇编分析

打开keil的反汇编窗口(disassembly window),

在bootloader的项目中,找到SystemInit 函数的前面两条语句:

RCC->CR |= (uint32_t)0x00000001;

RCC->CFGR &= (uint32_t)0xF0FF0000;

我们可以看到这两条指令编译出来的机器码放置在地址为0x80002E6-0X80002F之间的存储空间。

使用有license声明的代码,即使是二进制文件也可判断

反汇编窗口

对应的机器码为(考虑存储的大小端问题):

36 48 00 68 40 F0 01 00 34 49 08 60...

在生成的bin文件中找到了对应的代码块:

使用有license声明的代码,即使是二进制文件也可判断

汇编生成的代码

再打开两个bin文件的比较窗口,果然看到该地址段的数据大量相同。

而相同的数据也就是ST提供的代码所编译生成的二进制数据。

使用有license声明的代码,即使是二进制文件也可判断

画线部分的数据为ST提供系统初始化函数代码生成的二进制数据

三、该怎么做

为了防止二进制数据从芯片中被读出比对,我们可以使用芯片提供的读保护功能(国产替代芯片号称功能与ST完全一致,想必也有此功能)。

开启了读保护功能之后,用正当手段仅能读上来全为0xff的数据。

我们可以在代码中加上自动开启写保护功能的代码,如下:

void ReadProtect(void)
{
	if(FALSE == FL_GetReadOutProtectionStatus())
	{ 
		FL_Unlock(); 
		FL_ReadOutProtection(TRUE);
		FL_Lock();
	} 
}
void FL_Unlock(void)
{
	if((FLASH->CR & FLASH_CR_LOCK) != RESET)
    {
    	FLASH->KEYR = FLASH_KEY1;
  		FLASH->KEYR = FLASH_KEY2;
    }
}
void FL_Lock(void)
{
	if((FLASH->CR & FLASH_CR_LOCK) == RESET){
		FLASH->CR |= CR_LOCK_SET;
	}
}
FLASH_Status FL_ReadOutProtection(U8 enable)
{
	FLASH_Status status = FLASH_COMPLETE;
	status = fnFL_Wait();
	if(status == FLASH_COMPLETE)
	{
		/* Authorizes the small information block programming */
		FLASH->OPTKEYR = FLASH_KEY1;
		FLASH->OPTKEYR = FLASH_KEY2;
		FLASH->CR |= CR_OPTER_Set;
		FLASH->CR |= CR_STRT_Set;
		/* Wait for last operation to be completed */
		status = FL_Wait();
		if(status == FLASH_COMPLETE)
		{
			/* if the erase operation is completed, disable the OPTER Bit */
			FLASH->CR &= CR_OPTER_Reset;
			/* Enable the Option Bytes Programming operation */
			FLASH->CR |= CR_OPTPG_Set; 
			if(enable)
			{
				OB->RDP = 0x00;
			}
			else
			{
				OB->RDP = RDP_Key;  
			}
			/* Wait for last operation to be completed */
			status = FL_Wait();

			if(status != FLASH_TIMEOUT)
			{
			/* if the program operation is completed, disable the OPTPG Bit */
			FLASH->CR &= CR_OPTPG_Reset;
			}
		}
		else 
		{
			if(status != FLASH_TIMEOUT)
			{
			/* Disable the OPTER Bit */
				FLASH->CR &= CR_OPTER_Reset;
			}
		}
	}
	/* Return the protection operation Status */
	return status;       
}

#define RDPRT_Mask ((U32)0x00000002)
U8 FL_GetReadOutProtectionStatus(void)
{
	U8 read = FALSE; 
	if ((FLASH->OBR & RDPRT_Mask) != 0)
	{
		read = TRUE;
	}
	return read;;
}
展开阅读全文

页面更新:2024-05-08

标签:机器码   代码   二进制文件   相似性   这一点   初始化   函数   芯片   声明   版权   窗口   地址   功能   文件   数据   系统   科技

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top