ThingsBoard是一款开源的IOT平台,有CE,PE两个版本,PE版需要付费,功能也更加丰富。为了体验下PE版的功能,尝试着对
PE版进行破解。
按照官方文档进行安装,跳过步骤中的填写license部分
启动服务,当然此时是无法访问的。查看日志thingsboard.log发现最后有如下提示
2019-12-24 09:14:50,056 [main] ERROR o.t.s.d.s.BasicSubscriptionService - License secret is not provided! 2019-12-24 09:14:50,057 [main] ERROR o.t.s.d.s.BasicSubscriptionService - Please provide license.secret property value in thingsboard.yml or set TB_LICENSE_SECRET environment variable! 2019-12-24 09:14:50,156 [Shutdown Thread] INFO o.t.s.d.s.BasicSubscriptionService - Terminating application due to critical License Error GENERAL_ERROR(300), exit code [-1]...
这里提示
BasicSubscriptionService
这个类中进行了license的检验,但是上面没有显示改类包路径,无法精确定位到改类的位置。为了精确定位
BasicSubscriptionService
这个类的位置,对conf/logback.xml
进行修改,将日志长度改大一点<encoder> <pattern>%d{ISO8601} [%thread] %-5level %logger{255} - %msg%n</pattern> </encoder>
再次重启服务,查看日志
2019-12-24 09:32:58,495 [main] ERROR org.thingsboard.server.dao.subscription.BasicSubscriptionService - License secret is not provided! 2019-12-24 09:32:58,497 [main] ERROR org.thingsboard.server.dao.subscription.BasicSubscriptionService - Please provide license.secret property value in thingsboard.yml or set TB_LICENSE_SECRET environment variable! 2019-12-24 09:32:58,504 [Shutdown Thread] INFO org.thingsboard.server.dao.subscription.BasicSubscriptionService - Terminating application due to critical License Error GENERAL_ERROR(300), exit code [-1]...
发现
org.thingsboard.server.dao.subscription.BasicSubscriptionService
这个类是再dao包下,解压lib/thingsboard.jar
,找到依赖的dao-2.4.2PE.jar
,解压找到BasicSubscriptionService
最后发现检查license的地方在这里:@PostConstruct public void init() { if (StringUtils.isEmpty(this.licenseSecret)) { log.error("License secret is not provided!"); log.error("Please provide license.secret property value in thingsboard.yml or set TB_LICENSE_SECRET environment variable!"); this.doExit(-1, LicenseErrorCode.GENERAL_ERROR, false); } else { try { this.tbLicenseClient = TbLicenseClient.builder().listener(this).licenseSecret(this.licenseSecret).releaseDate((new SimpleDateFormat("yyyy-MM-dd")).parse("2019-09-13").getTime()).build(); this.tbLicenseClient.init(); } catch (Exception var3) { log.error("Failed to init license client", var3); LicenseErrorCode licenseErrorCode = var3 instanceof LicenseException ? ((LicenseException)var3).getErrorCode() : LicenseErrorCode.GENERAL_ERROR; this.doExit(-1, licenseErrorCode, false); } } }
尝试重写该类中方法,将验证license那部分去掉。然后将新的
BasicSubscriptionService.class
替换掉之前的代码。
打开CE版的源码,在dao
模块下新建subscription
包,对照dao-2.4.2PE.jar
中的内容,将SubscriptionService
,InstallSubscriptionService
,BasicSubscriptionService
这3个类中的内容完全复制过来,
再重写BasicSubscriptionService
中的方法,最后内容如下:import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.subscription.SubscriptionException; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @Service @Profile({"!install"}) public class BasicSubscriptionService implements SubscriptionService { private static final Logger log = LoggerFactory.getLogger(BasicSubscriptionService.class); private static final String MAX_DEVICES_KEY = "maxdevices"; private static final String MAX_ASSETS_KEY = "maxassets"; private static final String WHITELABELING_KEY = "whitelabeling"; @Value("${license.secret}") private String licenseSecret; public BasicSubscriptionService() { } @PostConstruct public void init() {
}
@PreDestroy
public void stop() {
}
@Override
public void createDeviceAllowed(TenantId tenantId) throws SubscriptionException {
}
@Override
public void createAssetAllowed(TenantId tenantId) throws SubscriptionException {
}
@Override
public void whiteLabelingAllowed(TenantId tenantId) throws SubscriptionException {
}
@Override
public boolean whiteLabelingEnabled(TenantId tenantId) throws SubscriptionException {
return true;
}
}
(这步过程中`SubscriptionService`类中有个异常类`SubscriptionException`是在`common`模块下的,CE版中也没有这个类,需要按照路径在CE版中生成,然后重新编译`common`模块)
6. 编译`dao`模块,拿到`BasicSubscriptionService.class`
7. 重新生成`dao-2.4.2PE.jar`,使用jar命令替换,在`dao-2.4.2PE.jar`同目录下新建目录`org\thingsboard\server\dao\subscription`,将`BasicSubscriptionService.class`放到该目录下,
执行`jar uf dao-2.4.2PE.jar org\thingsboard\server\dao\subscription\BasicSubscriptionService.class`此时`dao-2.4.2PE.jar`已经更新完。
8. 重新生成`thingsboard.jar`,解压之间的`thingsboard.jar`,得到3个目录`BOOT-INF`,`META-INF`,`org`,将上一步生成的`dao-2.4.2PE.jar`放入`BOOT-INF\lib`中,
执行`jar cf0M thingsboard.jar *`生成新的jar包
9. 用新的thingsboard.jar替换掉lib中的jar包重新install或者直接执行都可以(java -jar thingsboard.jar,需要修改jar包中的yml配置文件)。