分析xx输入法
# 分析xx输入法## 解包与封包
- **解包**
```sh
java -jar apktool_2.6.0.jar d xxx_lastold.apk -o bdold
```
!(https://gitee.com/koifishly/pb/raw/master/img/2022/02/11/21-24-902.png)
- **封包**
```sh
java -jar apktool_2.6.0.jar b bdold -o xxx.apk
```
> 封包后发现执行会崩溃。
>
> 经过调试后发现存在反调试,删除掉反调试的代码。
>
## 过签名检验
### xx输入法v4.2.1.32
> 总体思想:
> app本身没有做太多的防护,只有一个签名校验。
> 签名校验的位置在`inputcore_20131125`文件中的`Java_com_baidu_input_PlumCore_PlInit`函数中。
!(https://gitee.com/koifishly/pb/raw/master/img/2022/02/11/21-31-073.png)
!(https://gitee.com/koifishly/pb/raw/master/img/2022/02/11/21-50-615.png)
!(https://gitee.com/koifishly/pb/raw/master/img/2022/02/11/21-54-984.png)
> PlInit为`inputcore_20131125`中的原生函数。
!(https://gitee.com/koifishly/pb/raw/master/img/2022/02/11/22-01-707.png)
> 注释掉`checkState`函数。
> **原来的汇编指令:**
> `03 F0 DD F9 BL _Z10checkStatei ; checkState(int)`
> **将这句话注释掉,修改为:**
> `00 00 MOVS R0, R0`
> `00 00 MOVS R0, R0`
### xx输入法v5.0.1.6
和v4一致.
![修改前](https://gitee.com/koifishly/pb/raw/master/img/2022/02/17/23-07-560.png)
![修改后](https://gitee.com/koifishly/pb/raw/master/img/2022/02/17/23-12-453.png)
注释`checkState`函数。
```assembly
原汇编:
03 F0 41 F9 BL _Z10checkStatei ; checkState(int)
修改为:
00 00 MOVS R0, R0
00 00 MOVS R0, R0
```
### 最新版xx输入法v10.9.5.25
主要过程和v4差不多。在`lib`中分析`libiptcore.so`。
搜索字符串`signature`很容易定位到下面的代码。
![计算Hash](https://gitee.com/koifishly/pb/raw/master/img/2022/02/20/20220220175316.png)
![调用计算Hash](https://gitee.com/koifishly/pb/raw/master/img/2022/02/20/20220220175622.png)
这里的代码逻辑非常的清晰,想要去除Hash校验的方法有很多,例如:
- 将`if`条件取反。
- 将`if-else`代码全部删除,在调用`sub_38DB8`,直接给定参数`0`。
我这里简单一点,直接修改`if`跳转。
![修改前](https://gitee.com/koifishly/pb/raw/master/img/2022/02/20/20220220185224.png)
![修改后](https://gitee.com/koifishly/pb/raw/master/img/2022/02/20/20220220185439.png)
重新打包后,安装进手机发现能够正常运行了。
## 修改原包名
###xx输入法v4.2.1.32
> 总体思想:
>
> 修改AndroidManifest.xml和smali汇编中有关包名这部分的内容。
>
> 注意:
>
> 1. 修改完AndroidManifest.xml和smali汇编后封包的时候可能有些错误。这是由于资源中包名的部分没有修改,根据提示进行修改。
> 2. 在so中可能存在反射调用的问题,需要在so中进行同步修改。
**这里将原包名`com.xxxx.input`修改为`com.xxxx.imput`。**
#### AndroidManifest.xml
- Line 1
```xml
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.xx.imput">
```
- Line 56
```xml
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:name=".ImeCellManActivity" android:taskAffinity="com.xxx.imput.cell" android:theme="@android:style/Theme.NoTitleBar"/>
```
- Line 57
```xml
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:name=".ImeThemeActivity" android:taskAffinity="com.baidu.imput.theme" android:windowSoftInputMode="adjustPan"/>
```
- Line 61
```xml
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:name=".ImeListEditorActivity" android:noHistory="true" android:taskAffinity="com.baidu.imput.listeditor" android:theme="@android:style/Theme.Dialog"/>
```
- Line 78
```xml
<action android:name="com.xxx.imput.action.INSTALL"/>
```
#### res
重新封包时发现以下错误:
```sh
W: G:\nom\bd_bugai\res\layout\emoji_detail.xml:17: error: No resource identifier found for attribute 'textSize' in package 'com.baidu.input'
W:
W: G:\nom\bd_bugai\res\layout\emoji_item.xml:13: error: No resource identifier found for attribute 'textSize' in package 'com.baidu.input'
```
##### emoji_detail.xml
- Line 4
```xml
xmlns:xxx="http://schemas.android.com/apk/res/com.xxx.imput">
```
- Line 15
```xml
<com.xxx.imput.layout.widget.PageGalleryView android:id="@id/gallery" android:layout_width="0.0dip" android:layout_height="0.0dip" android:layout_marginLeft="32.0dip" android:layout_marginRight="32.0dip" />
```
- Line 16
```xml
<com.xxx.imput.layout.widget.HintSelectionView android:id="@id/hint" android:layout_width="fill_parent" android:layout_height="6.0dip" android:layout_marginLeft="82.0dip" android:layout_marginTop="12.0dip" android:layout_marginRight="82.0dip" android:layout_marginBottom="24.0dip" />
```
- Line 17
```xml
<com.xxx.imput.layout.widget.DownloadButton android:id="@id/button" android:background="@drawable/guide_btef" android:layout_width="fill_parent" android:layout_height="34.0dip" android:layout_marginLeft="36.0dip" android:layout_marginRight="36.0dip" baidu:textSize="14.0dip" />
```
##### emoji_item.xml
- Line 4
```xml
xmlns:xxx="http://schemas.android.com/apk/res/com.baidu.imput">
```
- Line 13
```xml
<com.xxx.imput.layout.widget.DownloadButton android:id="@id/button" android:background="@drawable/guide_btef" android:layout_width="fill_parent" android:layout_height="26.0dip" android:layout_marginTop="20.0dip" android:layout_below="@id/thumb" android:layout_alignLeft="@id/thumb" android:layout_alignRight="@id/thumb" baidu:textSize="12.0dip" />
```
#### smali汇编
- 需要修改的smali文件的数量特别多,采用代码修改。
- 在smali汇编中包名中的`.`被替换成`/`。
```java
public class Main {
public static void main(String[] args) {
UpdateFile updateFile = new UpdateFile("G:\\nom\\bd_bugai\\smali\\com", "Lcom/xxx/input", "Lcom/xxx/imput");
updateFile.updateFiles();
}
}
```
```java
import java.io.*;
import java.util.List;
public class UpdateFile {
private String mCWD;
private String mOldPkgName;
private String mNewPkgName;
UpdateFile(String cwd, String oldPkg, String newPkg) {
mCWD = cwd;
mOldPkgName = oldPkg;
mNewPkgName = newPkg;
}
public void updateFiles() {
updateFiles(mCWD);
}
private void updateFiles(String dir) {
File file = new File(dir);
File[] files = file.listFiles();
for (File f : files) {
if (f.isDirectory()) {
updateFiles(f.getAbsolutePath());
} else {
System.out.println(f.getAbsolutePath());
update(f.getAbsolutePath());
}
}
}
private void update(String filePath) {
BufferedReader br = null;
String line = null;
StringBuffer buf = new StringBuffer();
try {
// 根据文件路径创建缓冲输入流
br = new BufferedReader(new FileReader(filePath));
// 循环读取文件的每一行, 对需要修改的行进行修改, 放入缓冲对象中
int lineNum = 1;
while ((line = br.readLine()) != null) {
// 此处根据实际需要修改某些行的内容
if (line.contains(mOldPkgName)) {
String update = line.replaceAll(mOldPkgName, mNewPkgName);
buf.append(update);
System.out.println(" ["+lineNum+"]"+line);
System.out.println(" ["+lineNum+"]"+update);
System.out.println();
}
// 如果不用修改, 则按原来的内容回写
else {
buf.append(line);
}
buf.append("\n");
lineNum++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭流
if (br != null) {
try {
br.close();
} catch (IOException e) {
br = null;
}
}
}
BufferedWriter bw = null;
try {
// 根据文件路径创建缓冲输出流
bw = new BufferedWriter(new FileWriter(filePath));
// 将内容写入文件中
bw.write(buf.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭流
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
bw = null;
}
}
}
}
}
```
#### so文件修改
!(https://gitee.com/koifishly/pb/raw/master/img/2022/02/11/22-10-126.png)
搜索字符串,然后可以把这些字符串进行修改。然后封包发现终于可以正常运行了。 小白问题:这是修改了什么呢?
对于小白的我来说,看天书。。。感谢分享!! 截图里面大大的“百度”显得很XX... 牛啊牛啊{:301_1003:} 学习学习,关键是思路 小白啥也没看懂!!! 学习了,感谢大牛 思路非常好 hhuan 发表于 2022-2-26 12:08
小白问题:这是修改了什么呢?
修改了so过签名校验