Tencent2016A安卓静态逆向分析

安卓静态逆向分析——Tencent2016A

引入

本文是我在学习安卓逆向时的一些步骤、心得,逆向的是2016年腾讯游戏安全技术竞赛提供的文件,因为文件比较简单仅仅从静态分析便能找到对应的注册码。
所用到的工具有: IDA、CodeBlocks。

逆向步骤

首先先看下程序运行结果,如下图所示:
在这里插入图片描述
这是一个输入name和password的程序,我们输入后会出现check failed的提示,那么问题就简单了,猜想:是把验证放到了native层,下面通过静态分析来验证。
将apk文件中的libCheckRegister.so拖入到ida中,打开的图片如下所示。
在这里插入图片描述随便在函数列表翻翻,便可发现一个奇怪的函数Java_com_tencent_tencent2016a_MainActivity_NativeCheckRegister,它的命名规则刚好符合Android Native层命名规则,之前的猜想成立,真的就是把验证放到了native层,这个就是我们要分析的函数。
双击函数跳转到相应的ARM汇编代码如下图所示
在这里插入图片描述按F5反编译得到对应C代码,如下图所示。
在这里插入图片描述发现传进去的参数有点不太对,第一个应该是JNIEnv,第二个是jobject或者jclass,因此我们在Structures视图中加载并修改下数据类型,修改后结果如下图所示:
在这里插入图片描述然后返回到C代码中在相应参数上按Y修改参数类型,可以发现下面函数中对应的函数名已经找到,修改四个参数类型以及名字以便阅读,如下图所示:
在这里插入图片描述
很显然,sub_1634(v7, v8)这个函数就是调用验证的函数, 点进去。分析这个函数,显然返回0为失败,返回1为成功,返回结果放在result变量中。

bool __fastcall sub_1634(char *cname, char *cpw)
{
  char *v2; // r6
  int v3; // r5
  _BOOL4 result; // r0
  int v5; // r4
  char *v6; // r7
  int v7; // r3
  int v8; // r4
  int v9; // r4
  int v10; // r1
  char *v11; // [sp+Ch] [bp-464h]
  int v12; // [sp+18h] [bp-458h]
  int v13; // [sp+1Ch] [bp-454h]
  int v14; // [sp+20h] [bp-450h]
  int v15; // [sp+24h] [bp-44Ch]
  int v16; // [sp+28h] [bp-448h]
  char v17[4]; // [sp+2Ch] [bp-444h]
  int v18; // [sp+30h] [bp-440h]
  int v19; // [sp+34h] [bp-43Ch]
  int v20; // [sp+38h] [bp-438h]
  int v21; // [sp+3Ch] [bp-434h]
  char v22[20]; // [sp+40h] [bp-430h]
  char v23[936]; // [sp+54h] [bp-41Ch]

  v2 = cpw;
  v11 = cname;
  v3 = j_strlen();
  if ( (unsigned int)(v3 - 6) > 0xE )
    return 0;
  j_memset(v22, 0, 20);
  v5 = 0;
  do
  {
    v6 = &v22[v5];
    v7 = (unsigned __int8)v11[v5 % v3] * (v5 + 20160126) * v3;
    ++v5;
    *(_DWORD *)v6 += v7;
  }
  while ( v5 != 16 );
  j_memset(v23, 0, 1024);
  if ( sub_146C(v2) > 1024 )
    return 0;
  v8 = sub_1498(v23, v2);
  if ( v8 != 20 )
    return 0;
  j_memset(&v12, 0, 20);
  j_memset(v17, 0, 20);
  v9 = 0;
  do
  {
    v10 = *(_DWORD *)&v23[v9];
    *(int *)((char *)&v12 + v9) = *(_DWORD *)&v22[v9] / 10;
    *(_DWORD *)&v17[v9] = v10;
    v9 += 4;
  }
  while ( v9 != 20 );
  result = 0;
  if ( v21 + v12 == v19 && v21 + v12 + v13 == 2 * v21 && v14 + v20 == *(_DWORD *)v17 && v14 + v20 + v15 == 2 * v20 )
    result = (unsigned int)(v16 + v18 - 3 * v14) <= 0;
  return result;
}

从(cname_length - 6) > 0xE 中可以看出名字的长度需要在[6, 20]间,将函数变量稍微处理处理得到以下代码:

bool __fastcall sub_1634(char *cname, char *cpw)
{
  char *pw_copy; // r6
  signed int cname_length; // r5
  _BOOL4 result; // r0
  int i; // r4
  char *tmp; // r7
  int v7; // r3
  int pw_encode_length; // r4
  int j; // r4
  int *temp; // r1
  char *name_copy; // [sp+Ch] [bp-464h]
  int *v12; // [sp+18h] [bp-458h]
  int v13; // [sp+1Ch] [bp-454h]
  int v14; // [sp+20h] [bp-450h]
  int v15; // [sp+24h] [bp-44Ch]
  int v16; // [sp+28h] [bp-448h]
  int *v17; // [sp+2Ch] [bp-444h]
  int v18; // [sp+30h] [bp-440h]
  int v19; // [sp+34h] [bp-43Ch]
  int v20; // [sp+38h] [bp-438h]
  int v21; // [sp+3Ch] [bp-434h]
  char name_encode[20]; // [sp+40h] [bp-430h]
  char pw_encode[936]; // [sp+54h] [bp-41Ch]

  pw_copy = cpw;
  name_copy = cname;
  cname_length = j_strlen(cname);
  if ( (cname_length - 6) > 0xE )
    return 0;
  j_memset(name_encode, 0, 20);
  i = 0;
  do
  {
    tmp = &name_encode[i];
    v7 = name_copy[i % cname_length] * (i + 20160126) * cname_length;
    ++i;
    *tmp += v7;
  }
  while ( i != 16 );
  j_memset(pw_encode, 0, 1024);
  if ( sub_146C(pw_copy) > 1024 )
    return 0;
  pw_encode_length = sub_1498(pw_encode, pw_copy);
  if ( pw_encode_length != 20 )
    return 0;
  j_memset(&v12, 0, 20);
  j_memset(&v17, 0, 20);
  j = 0;
  do
  {
    temp = *&pw_encode[j * 4];
    (&v12)[j] = (*&name_encode[j * 4] / 10);
    (&v17)[j] = temp;
    ++j;
  }
  while ( j != 5 );
  result = False;
  if ( (v12 + v21) == v19 && (v12 + v21 + v13) == (2 * v21) && (v14 + v20) == v17 && v14 + v20 + v15 == 2 * v20 )
    result = (v16 + v18 - 3 * v14) <= 0;
  return result;

那么问题就变得简单了,知道name怎么转化成name_encode,通过最后的if判断将name_endoce转化成pw_encode再将pw_encode转化成pw就行了。前面的转化通过代码可简单实现,最后一步需关注sub_146C(pw_copy)和sub_1498(pw_encode, pw_copy)函数,在代码中可以很清楚的看到加载一个表, 因此在逆向时需要将这个表写入到代码中,如下图所示。

在这里插入图片描述
通过简单的打印输出便可找到相应的对应关系。如下图所示。
在这里插入图片描述
(因时间有限,我写的C++逆向代码还有bug就不贴了,下周补上。未完待续…)

### 回答1: MATLAB 2016a中的小波分析功能包括22个算法,以下是对每个算法的简要介绍: 1. 小波变换(Wavelet Transform):对信号进行小波分解和重构,并返回系数。 2. 小波包分解(Wavelet Packet Decomposition):将信号进行进一步的分解,提供更详细的频率信息。 3. 双尺度分解(Double-Density Wavelet Analysis):对信号进行不规则分解,适用于非平稳信号。 4. Hilbert-Huang变换(Hilbert-Huang Transform):将信号分解成本征模态函数和频率包络。 5. 向上采样(Upsampling):将信号插值,并使用小波基函数构建高分辨率信号。 6. 向下采样(Downsampling):对信号进行下采样,减少采样率。 7. 小波包重构(Wavelet Packet Reconstruction):根据小波包系数重构信号。 8. 持续小波变换(Continuous Wavelet Transform):对连续时间信号进行小波分析。 9. 离散小波变换(Discrete Wavelet Transform):对离散时间信号进行小波分析。 10. 离散小波包分解(Discrete Wavelet Packet Decomposition):对离散信号进行小波包分解。 11. 1维小波多分辨率分析(1-D Wavelet Multiscale Analysis):对1维信号进行多尺度分析。 12. 2维小波多分辨率分析(2-D Wavelet Multiscale Analysis):对2维图像进行多尺度分析。 13. 小波阈值去噪(Wavelet Threshold Denoising):应用小波阈值去噪算法对信号进行降噪处理。 14. 小波重构(Wavelet Reconstruction):根据小波系数进行信号重构。 15. 二维离散小波变换(2-D Discrete Wavelet Transform):对2维图像进行小波分析。 16. 小波震荡(Wavelet Scattering):对信号进行非线性变换和分解。 17. 小波包阈值去噪(Wavelet Packet Threshold Denoising):应用小波包阈值去噪算法对信号进行降噪处理。 18. 周期小波变换(Periodic Wavelet Transform):对周期信号进行小波分析。 19. 压缩感知(Compressed Sensing):利用稀疏性和小波变换进行信号压缩。 20. 小波分割(Wavelet Segmentation):利用小波分析进行信号分割。 21. 远程传感(Remote Sensing):应用小波分析进行遥感图像处理。 22. 功率谱密度估计(Power Spectral Density Estimation):使用小波分析对信号的功率谱密度进行估计。 这些算法提供了对不同类型信号和图像进行小波分析和处理的功能,可以根据具体需求选择相应的算法进行分析和处理。 ### 回答2: MATLAB 2016a中提供了22种小波分析算法。小波分析是一种在信号和图像处理中常用的方法,它能够将信号分解成不同频率的小波子信号,从而实现多尺度分析和特征提取。 在MATLAB 2016a中,可以使用以下算法进行小波分析: 1. Daubechies小波变换(db) 2. Symlet小波变换(sym) 3. Coiflet小波变换(coif) 4. Biorthogonal小波变换(bior) 5. Reverse Biorthogonal小波变换(rbio) 6. Discrete Meyer小波变换(dmey) 7. Gaussian小波变换(gaus) 8. Mexican Hat小波变换(mexh) 9. Morlet小波变换(morl) 此外,还提供了一些特殊小波变换: 10. Discrete Haar小波变换(haar) 11. DIII-D小波变换(d2) 12. FSF小波变换(fsf) 13. Walsh-Hadamard小波变换(wvtool) 除了这些传统小波变换算法外,MATLAB还提供了以下扩展算法: 14. Nondecimated小波变换(wdenoise):用于去噪信号 15. Stationary小波变换(swt):用于时频分析 16. 二维小波变换(dwt2):用于图像处理 17. 二维非下采样小波变换(swtn):用于图像去噪 18. 分层小波变换(lwt):用于多尺度分析 19. 小波包分析(wpdec):用于特征提取 20. 小波压缩(waverec2):用于信号和图像压缩 MATLAB 2016a中的所有小波分析算法提供了丰富的函数库和工具箱,可以帮助用户实现各种小波分析任务,并且支持不同尺度、频率和分辨率的定制和调整,以适应不同应用领域的需求。 ### 回答3: Matlab 2016a中,提供了22个小波分析算法。小波分析是一种信号处理技术,能够将信号分解成不同频率的子波,并提供了更好的时间频率分析方法。 这22个算法包括了一维和二维的小波分析方法。其中,一维小波分析算法主要用于处理一维信号,如声音,心电图等。例如,discrete wavelet transform (DWT) 离散小波变换是最常用的一维小波分析算法。其他的一维小波分析算法还包括stationary wavelet transform (SWT),wavelet packet decomposition (WPD)等。 而二维小波分析算法主要用于处理图像和视频等二维信号。例如,二维离散小波变换(DWT2)可以将一个二维图像分解成不同频率的小波系数。其他的二维小波分析算法还包括stationary wavelet transform (SWT2),三维小波变换等。 除了以上提到的算法之外,Matlab 2016a还提供了更多的小波分析算法,如一维和二维离散小波包变换、一维和二维整弦小波变换、二维二进小波变换等等。这些算法可以根据不同问题的需求选择使用,从而得到更好的信号分析结果。 总的来说,Matlab 2016a提供了丰富的小波分析算法,可以用于一维和二维信号的处理,包括声音、图像和视频等。这些算法能够提供更好的时间频率分析方法,可以在信号处理和图像处理等领域发挥重要作用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值