分析xx输入法
解包与封包
过签名检验
xx输入法v4.2.1.32
总体思想:
app本身没有做太多的防护,只有一个签名校验。
签名校验的位置在inputcore_20131125 文件中的Java_com_baidu_input_PlumCore_PlInit 函数中。
PlInit为inputcore_20131125 中的原生函数。
注释掉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一致.
注释checkState 函数。
原汇编:
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校验的方法有很多,例如:
- 将
if 条件取反。
- 将
if-else 代码全部删除,在调用sub_38DB8 ,直接给定参数0 。
我这里简单一点,直接修改if 跳转。
重新打包后,安装进手机发现能够正常运行了。
修改原包名
xx输入法v4.2.1.32
总体思想:
修改AndroidManifest.xml和smali汇编中有关包名这部分的内容。
注意:
- 修改完AndroidManifest.xml和smali汇编后封包的时候可能有些错误。这是由于资源中包名的部分没有修改,根据提示进行修改。
- 在so中可能存在反射调用的问题,需要在so中进行同步修改。
这里将原包名com.xxxx.input 修改为com.xxxx.imput 。
AndroidManifest.xml
-
Line 56
<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
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:name=".ImeThemeActivity" android:taskAffinity="com.baidu.imput.theme" android:windowSoftInputMode="adjustPan"/>
-
Line 61
<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
<action android:name="com.xxx.imput.action.INSTALL"/>
res
重新封包时发现以下错误:
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
xmlns:xxx="http://schemas.android.com/apk/res/com.xxx.imput">
-
Line 15
<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
<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
<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
xmlns:xxx="http://schemas.android.com/apk/res/com.baidu.imput">
-
Line 13
<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汇编中包名中的. 被替换成/ 。
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();
}
}
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文件修改
搜索字符串,然后可以把这些字符串进行修改。然后封包发现终于可以正常运行了。
|