百度语音离线合成授权破解

1 研究背景

1.1 研究现状

百度语音合成(Text to Speech)目前已能正常语音合成或停止合成功能,但因临时授权文件的初始日期会与设备系统的日期比较,若设备系统时间超过授权文件初始日期30天即为过期无法进行语音合成,存在缺陷。

1.2研究目的和意义

设备使用百度语音合成来进行语音提示时能正常播放。

 

2 项目主要研究内容

2.1 主要工作内容

       ①分析临时授权文件和百度语音so动态库,寻找突破口

       ②研究所有so动态库授权相关内容

③修改so动态库

       ④真机测试

2.2 具体实施方案

2.2.1 分析现有文件,寻找突破口

       2.2.1.1 分析授权文件,尝试破解加密内容(RSA加密)没成功,转从修改so动态库入手。

 

       2.2.1.2查找所有与授权相关内容的动态库

libbd_etts.so包含获取当前日期和获取授权文件、及二者日期比较

  

 

libbdtts.so  包含获取授权文件和验证授权文件有效函数

 

libgnustl_shared.so  包含处理时间等函数

 

2.2.1.3 分析相关函数,初步确认方案有:

①将获取到的授权文件日期更改

②授权文件日期与系统日期比较判断结果都改为可语音合成

③获取系统日期时返回值更改为自己设定日期

因方案①、②中的获取授权文件和日期比较函数中寄存器较多,同时不同so中皆有包含,修改复杂,最终采用方案③。

 

2.2.2 授权破解

2.2.2.1获取系统时间函数研究

  通过IDA破解出来的汇编源码,研究程序结构及寄存器作用。

       分析上图汇编源码,函数的程序流程大概为:

①time函数获取系统时间给寄存器R0

②使用gmtime函数将日期时间转为GMT时间,寄存器R5赋值为年份,R6为月份,R7为天数;

③memset给一字符串变量内存空间清零

④sprintf将字符串变量日期格式化,年份需加1900,月份日期各加1.

⑤返回字符串变量

 

将其复原为程序代码即为:

void *__fastcall etts::GetCurrTime(etts *this)

{

  struct tm *SysDate; //r0寄存器

  int year; // r5

  int month; // r6

  int day; // r7

  time_t SysTime;

 

  SysTime = time(0);

  SysDate = gmtime(&SysTime);

  year = SysDate->tm_year;

  month = SysDate ->tm_mon;

  day = SysDate ->tm_mday;

  memset(&unk_128958,0, 0x80);

  sprintf((char*)&unk_128958, "%d-%d-%d", year + 1900, month + 1, day + 1);

  return &unk_128958;

}

 

2.2.2.2 修改so程序文件

刚开始打算将time函数获取系统时间改为一个常数,但汇编转为机器码时不符合导致出错,最后考虑把sprintf格式化日期字符串时的年份需加的1900做修改。

 

定位到代码段地址为000DD440处,目的为修改立即数0x760。

 

查看汇编代码二进制格式指令,高亮处即为地址000DD440的指令:

 

因指令集ADD.W比较特殊导致汇编转为机器码的工具无法正常转换

 

自己手动改所以无法凑整,修改后的汇编代码二进制格式指令为

 

在代码段源码中变为:

 

所以最终sprintf将字符串变量日期格式化时,年份加上的值为0x200 + 0xC = 512 + 12 = 524,程序源码修改后为:

void *__fastcall etts::GetCurrTime(etts *this)

{

  struct tm *SysDate; //r0寄存器

  int year; // r5

  int month; // r6

  int day; // r7

  time_t SysTime;

 

  SysTime = time(0);

  SysDate = gmtime(&SysTime);

  year = SysDate->tm_year;

  month = SysDate->tm_mon;

  day = SysDate->tm_mday;

  memset(&unk_128958,0, 0x80);

  sprintf((char*)&unk_128958, "%d-%d-%d", year + 524, month + 1, day + 1);

  return &unk_128958;

}

综上,虽然仍然会获取系统的时间与授权文件时间进行比较,但有效年份多余出了 1900 – 524 = 1376 年。

 

2.2.2.3 真机测试

通过设置设备系统日期,发现其系统可设置日期范围为1970 ~ 2038年。

   在设备上测试,设置任意系统时间,语音都能正常合成,同时当正在语音播放时调整音量,播放的音量能够立即改变。

 

 

3 结论

3.1 研究成果总结

       设备在无法联网条件下,能够离线进行语音合成,不存在过期风险。

 

3.2 使用说明

①安装SpeakService.apk应用(即服务端)到设备。

②客户端程序加载SpeechService.jar包到工程,并调用其接口。

jar包中封装的语音合成接口函数:

    public static void startSpeech(Context baseContext,Stringtext,int AudioType);

        参数baseContext:客户端Activity的上下文;

        参数text:需要语音合成的字符串

        参数AudioType:语音合成类型(值为1-6)

            1:STREAM_VOICE_CALL  (A10设备的系统音量)

            2:STREAM_ALARM       (A10设备的按键音量)

            3:STREAM_MUSIC       (A10设备的多媒体音量)

            4:STREAM_NOTIFICATION

            5:STREAM_RING

            6:STREAM_SYSTEM

jar包中封装的停止语音合成接口函数:

    public static void stopSpeech();

 

③客户端Activity添加import com.speech.SpeechClass;

 详情请下载:

http://download.csdn.net/download/p876643136/10270199


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值