对apk进行反编译时,很多混淆的代码我们都能够在 .source 看到真正的类名。
Paste_Image.png利用smali文本替换,可以还原出一部分类名。
static void PatchSmali(string smaliPath)
{
var classDictionary = new Dictionary<string, string>();
var files = Directory.GetFiles(smaliPath, "*", SearchOption.AllDirectories);
foreach (var path in files)
{
var lines = File.ReadAllLines(path);
if (lines.Length < 3)
continue;
var classLine = lines[0];
var sourceLine = lines[2];
if (!classLine.StartsWith(".class") || !sourceLine.StartsWith(".source"))
continue;
var match = Regex.Match(classLine, "(L.*/)([^$]*)(\\$*.*;)");
var className = match.Value;
if (className.StartsWith("Landroid/support/"))
continue;
var sourceName = Regex.Match(sourceLine, "\"(.+)\"").Groups[1].Value;
if (!sourceName.EndsWith(".java"))
continue;
sourceName = Path.GetFileNameWithoutExtension(sourceName);
var sourceClassName = match.Groups[1].Value + sourceName + match.Groups[3].Value;
if (sourceClassName == className)
continue;
var newPath = Path.GetDirectoryName(path) + Path.AltDirectorySeparatorChar + sourceName + ".smali";
if (File.Exists(newPath))
continue;
if (classDictionary.ContainsKey(sourceClassName))
{
classDictionary[sourceClassName] = null;
continue;
}
classDictionary.Add(sourceClassName, className);
}
Console.WriteLine(string.Format("总共{0}个文件需要处理", files.Length));
var count = 0;
foreach (var path in files)
{
Console.WriteLine(string.Format("正在处理第{0}个文件。。。", ++count));
var text = File.ReadAllText(path);
foreach (var item in classDictionary)
{
if (item.Value == null)
continue;
text = text.Replace(item.Value, item.Key);
}
File.WriteAllText(path, text);
}
}
网友评论