-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[add] 1、拦截 glide 图片加载框架函数,捕捉部分图片;2、拦截webView资源加载函数,捕抓app中的网页图片
- Loading branch information
1 parent
a5f0498
commit 8dfda0e
Showing
7 changed files
with
392 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
app/src/main/java/com/pic/catcher/plugin/GlideCatcherPlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package com.pic.catcher.plugin; | ||
|
||
|
||
import android.content.Context; | ||
import android.webkit.MimeTypeMap; | ||
|
||
import com.lu.lposed.api2.XC_MethodHook2; | ||
import com.lu.lposed.api2.XposedHelpers2; | ||
import com.lu.lposed.plugin.IPlugin; | ||
import com.lu.magic.util.IOUtil; | ||
import com.lu.magic.util.log.LogUtil; | ||
import com.pic.catcher.ClazzN; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.File; | ||
import java.io.InputStream; | ||
import java.lang.reflect.InvocationHandler; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Proxy; | ||
|
||
import de.robv.android.xposed.XC_MethodHook; | ||
import de.robv.android.xposed.callbacks.XC_LoadPackage; | ||
|
||
/** | ||
* @author Lu | ||
* @date 2024/10/13 15:18 | ||
* @description | ||
*/ | ||
public class GlideCatcherPlugin implements IPlugin { | ||
@Override | ||
public void handleHook(Context context, XC_LoadPackage.LoadPackageParam loadPackageParam) { | ||
LogUtil.d("GlideCatcherPlugin", "handleHook", ClazzN.from("com.bumptech.glide.load.resource.gif.StreamGifDecoder")); | ||
XposedHelpers2.findAndHookMethod(ClazzN.from("com.bumptech.glide.load.resource.gif.StreamGifDecoder"), "inputStreamToBytes", InputStream.class, new XC_MethodHook2() { // from class: com.pic.catcher.plugin.GlideCatcherPlugin.1 | ||
@Override // com.lu.lposed.api2.XC_MethodHook2 | ||
public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { | ||
Object result = param.getResult(); | ||
LogUtil.d("GlideCatcherPlugin", "inputStreamToBytes", result); | ||
if (result != null) { | ||
PicExportManager.getInstance().exportByteArray((byte[]) result, ".gif"); | ||
} | ||
} | ||
}); | ||
XposedHelpers2.hookAllMethods(ClazzN.from("com.bumptech.glide.load.model.FileLoader"), "buildLoadData", new XC_MethodHook2() { // from class: com.pic.catcher.plugin.GlideCatcherPlugin.2 | ||
@Override // com.lu.lposed.api2.XC_MethodHook2 | ||
public void beforeHookedMethod(XC_MethodHook.MethodHookParam param) { | ||
Object arg = param.args[0]; | ||
if (arg instanceof File) { | ||
PicExportManager.getInstance().exportBitmapFile((File) arg); | ||
} | ||
} | ||
}); | ||
XposedHelpers2.hookAllMethods(ClazzN.from("com.bumptech.glide.load.data.HttpUrlFetcher"), "loadData", new XC_MethodHook2() { // from class: com.pic.catcher.plugin.GlideCatcherPlugin.3 | ||
@Override // com.lu.lposed.api2.XC_MethodHook2 | ||
public void beforeHookedMethod(XC_MethodHook.MethodHookParam param) { | ||
Object glideUrl; | ||
Object callMethod; | ||
Object callback = param.args[1]; | ||
if (Proxy.isProxyClass(callback.getClass())) { | ||
return; | ||
} | ||
glideUrl = XposedHelpers2.getObjectField(param.thisObject, "glideUrl"); | ||
String lastName = null; | ||
if (glideUrl != null) { | ||
callMethod = XposedHelpers2.callMethod(glideUrl, "toStringUrl", new Object[0]); | ||
String url = (String) callMethod; | ||
lastName = MimeTypeMap.getFileExtensionFromUrl(url); | ||
} | ||
final String url2 = lastName; | ||
Object callback2 = Proxy.newProxyInstance(callback.getClass().getClassLoader(), callback.getClass().getInterfaces(), new InvocationHandler() { // from class: com.pic.catcher.plugin.GlideCatcherPlugin.3.1 | ||
@Override // java.lang.reflect.InvocationHandler | ||
public Object invoke(Object o, Method method, Object[] objects) throws InvocationTargetException, IllegalAccessException { | ||
if ("onDataReady".equals(method.getName())) { | ||
Object iStream = objects[0]; | ||
if (iStream instanceof InputStream) { | ||
byte[] data = IOUtil.readToBytes((InputStream) iStream); | ||
PicExportManager.getInstance().exportByteArray(data, url2); | ||
ByteArrayInputStream iStream2 = new ByteArrayInputStream(data); | ||
objects[0] = iStream2; | ||
} | ||
} | ||
return method.invoke(o, objects); | ||
} | ||
}); | ||
param.args[1] = callback2; | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
app/src/main/java/com/pic/catcher/plugin/WebViewCatcherPlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.pic.catcher.plugin; | ||
|
||
import android.content.Context; | ||
import android.util.Log; | ||
import android.webkit.WebView; | ||
import android.webkit.WebViewClient; | ||
|
||
import com.lu.lposed.api2.XC_MethodHook2; | ||
import com.lu.lposed.api2.XposedHelpers2; | ||
import com.lu.lposed.plugin.IPlugin; | ||
import com.lu.magic.util.log.LogUtil; | ||
|
||
import de.robv.android.xposed.callbacks.XC_LoadPackage; | ||
|
||
/** | ||
* @author Lu | ||
* @date 2024/10/13 14:48 | ||
* @description webview 网页图片加载获取 | ||
*/ | ||
public class WebViewCatcherPlugin implements IPlugin { | ||
|
||
@Override | ||
public void handleHook(Context context, XC_LoadPackage.LoadPackageParam loadPackageParam) { | ||
XposedHelpers2.findAndHookMethod( | ||
WebViewClient.class, | ||
"onLoadResource", | ||
WebView.class, | ||
String.class, | ||
new XC_MethodHook2() { | ||
@Override | ||
protected void afterHookedMethod(MethodHookParam param) throws Throwable { | ||
WebView webView = (WebView) param.args[0]; | ||
String url = (String) param.args[1]; | ||
LogUtil.d("WebViewClient.onLoadResource", "url=" + url); | ||
PicExportManager.getInstance().exportUrlIfNeed(url); | ||
} | ||
} | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package com.pic.catcher.util; | ||
|
||
|
||
import com.lu.magic.util.IOUtil; | ||
import com.lu.magic.util.log.LogUtil; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileNotFoundException; | ||
import java.io.InputStream; | ||
import java.nio.ByteBuffer; | ||
|
||
|
||
public abstract class PicUtil { | ||
public static String detectImageType(File file, String fallback) { | ||
if (!file.exists()) { | ||
return fallback; | ||
} | ||
String result = fallback; | ||
FileInputStream inputStream = null; | ||
try { | ||
inputStream = new FileInputStream(file); | ||
result = detectImageType(inputStream, fallback); | ||
} catch (FileNotFoundException e) { | ||
LogUtil.d(e); | ||
} finally { | ||
IOUtil.closeQuietly(inputStream); | ||
} | ||
return result; | ||
} | ||
|
||
public static String detectImageType(InputStream inputStream, String fallback) { | ||
byte[] headerBytes = null; | ||
try { | ||
headerBytes = new byte[12]; | ||
inputStream.read(headerBytes); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
if ((headerBytes[0] & 0xFF) == 0xFF && (headerBytes[1] & 0xFF) == 0xD8) { | ||
return "jpg"; | ||
} else if (headerBytes[0] == (byte) 0x89 && headerBytes[1] == (byte) 0x50 && headerBytes[2] == (byte) 0x4E && headerBytes[3] == (byte) 0x47) { | ||
return "png"; | ||
} else if (headerBytes[0] == (byte) 0x47 && headerBytes[1] == (byte) 0x49 && headerBytes[2] == (byte) 0x46 && headerBytes[3] == (byte) 0x38) { | ||
return "gif"; | ||
} else if (isWebP(headerBytes)) { | ||
return "webp"; | ||
} | ||
return fallback; | ||
} | ||
|
||
public static String detectImageType(byte[] data, String fallback) { | ||
if (data == null || data.length < 8) { | ||
return fallback; | ||
} | ||
return detectImageType(new ByteArrayInputStream(data), fallback); | ||
} | ||
|
||
public static boolean isWebP(byte[] data) { | ||
if (data == null || data.length < 12) { | ||
return false; | ||
} | ||
|
||
// 检查前4个字节是否为 "RIFF" | ||
if (data[0] != 'R' || data[1] != 'I' || data[2] != 'F' || data[3] != 'F') { | ||
return false; | ||
} | ||
|
||
// 检查第8到第11个字节是否为 "WEBP" | ||
if (data[8] != 'W' || data[9] != 'E' || data[10] != 'B' || data[11] != 'P') { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.pic.catcher.util; | ||
|
||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* @author Lu | ||
* @date 2024/10/13 15:03 | ||
* @description 正则 | ||
*/ | ||
public interface Regexs { | ||
/** | ||
* 图片后缀 | ||
*/ | ||
Pattern PIC_EXT = Pattern.compile("jpg|jpeg|png|gif|webp|png|tif|ico|bmp|jng"); | ||
} |
Oops, something went wrong.