-
不root怎么将FDex2反编译的dex文件拷出来
2019-11-10 14:10:02这里要说的是怎么把反编译后的dex拷出来。 dex输出目录是这样的: /data/user/0/io.va.exposed/virtual/data/user/0/com.xx.xxx 这个目录需要root权限才能打开的,但是我们不root也有办法打开。 ...环境简述
首先,即然不想root,您肯定使用的是VirtualXposed+FDex2之类的工具做的反编译。
反编译肯定已经成功了,这是前提。这里要说的是怎么把反编译后的dex拷出来。dex输出目录是这样的:
/data/user/0/io.va.exposed/virtual/data/user/0/com.xx.xxx
这个目录需要root权限才能打开的,但是我们不root也有办法打开。
下载Total Commander工具
下载地址
https://download.csdn.net/download/weixin_36001685/11782914
安装在手机上
然后在VirtualXposed里也安装上TotalCommander。使用Total Commander
- 通过VirtualXposed打开TotalCommander
- 添加书签,书签地址为/data/user/0/io.va.exposed/virtual
- 回到TotalCommander首页,点击这个书签,发现可进去/data/user/0/io.va.exposed/virtual目录了。接着再打开data/user/0,这下面就是一个一个的包名啦,包含你反编译的apk的包名。
- 进入你反编译的包的文件夹,长按dex文件,点击“发送到”,是不是发现有qq、微信?但是实践证明发送qq和微信总是失败的。我选择发送到Total Commander,然后就是另存为,选择sd卡目录就好啦,现在可以直接拷贝到电脑上了。
-
关于android使用dexjar反编译后的classes.dex.dex2jar.jar为什么jd gui打不开?
2013-06-06 16:26:08运行 dex2jar.bat classes.dex ,生成classes.dex.dex2jar.jar然后运行JD-GUI工具,打开jar文件,看不到源代码,窗口是空白的……怎么破?? 在网上搜了一些办法,有些说换个反编译工具,或者其他的 其实解决这...运行 dex2jar.bat classes.dex ,生成classes.dex.dex2jar.jar然后运行JD-GUI工具,打开jar文件,看不到源代码,窗口是空白的……怎么破??
在网上搜了一些办法,有些说换个反编译工具,或者其他的
其实解决这个问题很简单,问题就是因为生成jar的时候就失败了, dex2jar.bat classes.dex 这一步没有成功,
那是因为我的dex2jar工具版本太低,下载一个最新的来编译,就OK了
http://code.google.com/p/dex2jar/
下载地址: -
unable to execute dex multiple dex files define
2016-03-15 10:31:14怎么出现? Eclipse 项目中导入了多个类库工程 并且每个工程都有自己的 v4 包 每个 v4 包的版本不一致(MD5 sha1) 为什么出现?同上解决方法?非常的简单,只需要打开主工程的 build path->configure build path, ...怎么出现?
- Eclipse 项目中导入了多个类库工程
- 并且每个工程都有自己的 v4 包
- 每个 v4 包的版本不一致(MD5 sha1)
为什么出现?
v4包冲突
解决方法?
非常的简单,只需要打开主工程的 build path->configure build path, 会看到多个 v4 包源,删除或者统一 jar 包即可。
附录
-
dex2jar.rar
2010-11-13 00:51:27参考一下别人怎么实现的吧! 可是Android用的Dalvik压根不是标准的Java VM的Jar,而是DEX格式的,怎么办? 附件是dxe2jar和JD,两个工具都是open source的,我已经全部放在一个压缩包了。 别着急,有办法: 1. ... -
性能优化专题七--Apk加固之Dex文件的加密与解密
2020-05-17 17:46:531、我们一般的apk是这样的,直接打开apk是可以看到里面的...上图中左边是我们未加密的apk打开之后显示的文件结构,我们需要一个proxy代理application以及一个 加密所用的Tools ,用tools来给左边的两个dex进行加密..1、我们一般的apk是这样的,直接打开apk是可以看到里面的源码的,如下图所示
这样对大家来说就不安全,我们所要做的就是把我们的apk中的dex文件加密,让别人就算拿到我们的apk里面啥也看不到。如下图所示,点击加密之后的apk,里面啥也没有,一个代码都看不到,这就是我们要做的:
2、具体怎么做呢?请看下图介绍
上图中左边是我们未加密的apk打开之后显示的文件结构,我们需要一个proxy代理application 以及一个 加密所用的Tools ,用tools来给左边的两个dex进行加密,然后在把加密之后的文件和左边其它的文件一起打包成apk 这样别人就看不到我们的源码了,但是新的文件的dex文件用户是无法运行的,这个时候,我们就需要一个proxy 的application,把我们新打包的apk所有内容交给代理application,然后让代理application去和Android系统对接,因为系统可以加载dex文件的,所以这个时候,我们的代理application要做的就是把拿到的加密的apk中的dex文件进行解密,然后在交给系统处理。
3、我们要先了解自己写的代码是如何被加载到内存的,可以在MainActivity中用以下代码查看:
Log.d("wwy",getClassLoader().toString()); 经过运行发现打印信息为:dalvik.system.PathClassLoader
我们在系统源码中查找这个PathClassLoader ,查看父类 BaseDexClassLoader:
我们通过Android系统源码找到 PathClassLoader 类 ------> BaseDexClassLoader -----> findClass()方法 -----> pathList.findClass() 方法 ,接着查看 pathList 类中都是什么,发现这个类中的方法 就是 findClass(String name,List<Throwable> suppressed) ;它通过循环遍历DexFile ,其实这就是获取dex文件,其实系统所有的dex文件都是要经过这里处理的
所以关键来了,既然所有的dex文件都是通过这里处理,也就是 dexElements , 它本身就是一个数组,我们只需要通过反射拿到这个数组,接着我们通过代码把我们自己的解密之后的dex文件放到我们定义的一个数组中,然后把我们的数组和系统的dex文件数组合并在一起,交给系统去处理。
这里我们在看系统的dex文件数组 dexElements 是怎么初始化的呢?通过查看系统源码,发现如下,
那么我们通过反射拿到这个方法,就可以拿到系统的dex文件数组了,然后再把我们的数据和系统合并后在赋给系统里面的dexElements 这样就把dexElements更新后,这样我们的dex文件就加载到android里面运行了。
好了具体的思路上面就介绍到这里,下面开始实现这个功能。
4、我们新建一个android project ,然后,在项目里面Create New Module 选择 Android Library ,这就是给我们代理的application ,命名为:proxy_core ;然后还需要一个加密工具,在项目中 Create New Module 选择 Java Library 这个java library不需要我们运行时处理,它直接在我们编译的时候就进行加密,这就是为什么创建的是java library ,这命名为:proxy_tools 建好之后,记得把这个proxy_tools 添加到项目中,如下:
添加编译完之后,在app的build.gradle中会自动如下所示:
好了,下面就开始写代码了!
1、代码中需要用到几个类,AES加解密类,Zip压缩解压类等工具类
首先我先proxy_core代理module下写一个代理application ,然后继承至Application,代码目录结构请看:
接着把我们这个代理的application加到我们最常写的配置文件中AndroidManifest.xml 中,我们是不是每个App都有一个application,然后把它配置到AndroidManifest.xml中,这里唯一不同的是,不是把我们项目中的那个application写到AndroidManifest.xml中,而是把我们在代理的写上。然后把我们app自己用到的application也加上,自己的application写在meta-data中,另一个meta-data按照下面的写就行,写法和位置如下
这个是我们自己项目用到的初始化application,上面的代理只是处理代理操作的。
我们自己的MyApplication里面目前啥也没写,这个使我们项目中用于初始化的,这里先不写东西。
这里开始写代理了,在ProxyApplication 中:
public class ProxyApplication extends Application { //定义好的加密后的文件的存放路径 private String app_name; private String app_version; /** * ActivityThread创建Application之后调用的第一个方法 * 可以在这个方法中进行解密,同时把dex交给Android去加载 * @param base */ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); //获取用户填入的metaData getMetaData(); //得到当前apk文件 File apkFile = new File(getApplicationInfo().sourceDir); //把apk解压 这个目录中的内容需要root权限才能使用 File versionDir = getDir(app_name+"_" + app_version,MODE_PRIVATE); File appDir = new File(versionDir,"app"); File dexDir = new File(appDir,"dexDir"); //得到我们需要加载的dex文件 List<File> dexFiles = new ArrayList<>(); //进行解密 (最好做md5文件校验) if (!dexDir.exists() || dexDir.list().length == 0){ //把apk解压到appDir Zip.unZip(apkFile,appDir); //获取目录下所有的文件 File[] files = appDir.listFiles(); for (File file:files){ String name = file.getName(); if (name.endsWith(".dex") && !TextUtils.equals(name,"classes.dex")){ try{ AES.init(AES.DEFAULT_PWD); //读取文件内容 byte[] bytes = Utils.getBytes(file); //解密 byte[] decypt = AES.decrypt(bytes); //写到指定的目录 FileOutputStream fos = new FileOutputStream(file); fos.write(decypt); fos.flush(); fos.close(); dexFiles.add(file); }catch (Exception e){ e.printStackTrace(); } } } }else { for (File file:dexDir.listFiles()){ dexFiles.add(file); } } try { loadDex(dexFiles,versionDir); }catch (Exception e){ e.printStackTrace(); } } private void loadDex(List<File> dexFiles,File versionDir) throws Exception{ //1、获取pathList Field pathListField = Utils.findField(getClassLoader(), "pathList"); Object pathList = pathListField.get(getClassLoader()); //2、获取数组dexElements Field dexElementsField = Utils.findField(pathList,"dexElements"); Object[] dexElements = (Object[]) dexElementsField.get(pathList); //3、反射到初始化makePathElements的方法 Method makeDexElements = Utils.findMethod(pathList,"makePathElements",List.class,File.class,List.class); ArrayList<IOException> suppressedException = new ArrayList<>(); Object[] addElements = (Object[]) makeDexElements.invoke(pathList, dexFiles, versionDir, suppressedException); Object[] newElements = (Object[]) Array.newInstance(dexElements.getClass().getComponentType(), dexElements.length + addElements.length); System.arraycopy(dexElements,0,newElements,0,dexElements.length); System.arraycopy(addElements,0,newElements,dexElements.length,addElements.length); //替换classloader中的element数组 dexElementsField.set(pathList,newElements); } private void getMetaData(){ try { ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo( getPackageName(), PackageManager.GET_META_DATA); Bundle metaData = applicationInfo.metaData; if (null != metaData){ if (metaData.containsKey("app_name")){ app_name = metaData.getString("app_name"); } if (metaData.containsKey("app_version")){ app_version = metaData.getString("app_version"); } } }catch (Exception e){ e.printStackTrace(); } } /** * 开始替换application */ @Override public void onCreate() { super.onCreate(); try { bindRealApplication(); }catch (Exception e){ e.printStackTrace(); } } /** * 让代码走入if的第三段中 * @return */ @Override public String getPackageName() { if (!TextUtils.isEmpty(app_name)){ return ""; } return super.getPackageName(); } @Override public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException { if (TextUtils.isEmpty(app_name)){ return super.createPackageContext(packageName, flags); } try { bindRealApplication(); } catch (Exception e) { e.printStackTrace(); } return delegate; } boolean isBindReal; Application delegate; //下面主要是通过反射系统源码的内容,然后进行处理,把我们的内容加进去处理 private void bindRealApplication() throws Exception{ if (isBindReal){ return; } if (TextUtils.isEmpty(app_name)){ return; } //得到attchBaseContext(context) 传入的上下文 ContextImpl Context baseContext = getBaseContext(); //创建用户真实的application (MyApplication) Class<?> delegateClass = null; delegateClass = Class.forName(app_name); delegate = (Application) delegateClass.newInstance(); //得到attch()方法 Method attach = Application.class.getDeclaredMethod("attach",Context.class); attach.setAccessible(true); attach.invoke(delegate,baseContext); //获取ContextImpl ----> ,mOuterContext(app); 通过Application的attachBaseContext回调参数获取 Class<?> contextImplClass = Class.forName("android.app.ContextImpl"); //获取mOuterContext属性 Field mOuterContextField = contextImplClass.getDeclaredField("mOuterContext"); mOuterContextField.setAccessible(true); mOuterContextField.set(baseContext,delegate); //ActivityThread ----> mAllApplication(ArrayList) ContextImpl的mMainThread属性 Field mMainThreadField = contextImplClass.getDeclaredField("mMainThread"); mMainThreadField.setAccessible(true); Object mMainThread = mMainThreadField.get(baseContext); //ActivityThread -----> mInitialApplication ContextImpl的mMainThread属性 Class<?> activityThreadClass = Class.forName("android.app.ActivityThread"); Field mInitialApplicationField = activityThreadClass.getDeclaredField("mInitialApplication"); mInitialApplicationField.setAccessible(true); mInitialApplicationField.set(mMainThread,delegate); //ActivityThread ------> mAllApplications(ArrayList) ContextImpl的mMainThread属性 Field mAllApplicationsField = activityThreadClass.getDeclaredField("mAllApplications"); mAllApplicationsField.setAccessible(true); ArrayList<Application> mApplications = (ArrayList<Application>) mAllApplicationsField.get(mMainThread); mApplications.remove(this); mApplications.add(delegate); //LoadedApk -----> mApplicaion ContextImpl的mPackageInfo属性 Field mPackageInfoField = contextImplClass.getDeclaredField("mPackageInfo"); mPackageInfoField.setAccessible(true); Object mPackageInfo = mPackageInfoField.get(baseContext); Class<?> loadedApkClass = Class.forName("android.app.LoadedApk"); Field mApplicationField = loadedApkClass.getDeclaredField("mApplication"); mApplicationField.setAccessible(true); mApplicationField.set(mPackageInfo,delegate); //修改ApplicationInfo className LoadedApk Field mApplicationInfoField = loadedApkClass.getDeclaredField("mApplicationInfo"); mApplicationInfoField.setAccessible(true); ApplicationInfo mApplicationInfo = (ApplicationInfo) mApplicationInfoField.get(mPackageInfo); mApplicationInfo.className = app_name; delegate.onCreate(); isBindReal = true; } }
2、下面在proxy_tools中写一个Main类,和一个main方法,直接运行处理,代码如下:
public class Main { public static void main(String[] args) throws Exception{ /** * 1、制作只包含解密代码的dex文件 */ File aarFile = new File("proxy_core/build/outputs/aar/proxy_core-debug.aar"); File aarTemp = new File("proxy_tools/temp"); Zip.unZip(aarFile,aarTemp); File classesDex = new File(aarTemp,"classes.dex"); File classesJar = new File(aarTemp,"classes.jar"); //dx --dex --output out.dex in.jar E:\AndroidSdk\Sdk\build-tools\23.0.3 Process process = Runtime.getRuntime().exec("cmd /c dx --dex --output " + classesDex.getAbsolutePath() + " " + classesJar.getAbsolutePath()); process.waitFor(); if (process.exitValue() != 0){ throw new RuntimeException("dex error"); } /** * 2、加密apk中所有的dex文件 */ File apkFile = new File("app/build/outputs/apk/debug/app-debug.apk"); File apkTemp = new File("app/build/outputs/apk/debug/temp"); Zip.unZip(apkFile,apkTemp); //只要dex文件拿出来加密 File[] dexFiles = apkTemp.listFiles(new FilenameFilter() { @Override public boolean accept(File file, String s) { return s.endsWith(".dex"); } }); //AES加密 AES.init(AES.DEFAULT_PWD); for (File dexFile:dexFiles) { byte[] bytes = Utils.getBytes(dexFile); byte[] encrypt = AES.encrypt(bytes); FileOutputStream fos = new FileOutputStream(new File(apkTemp,"secret-" + dexFile.getName())); fos.write(encrypt); fos.flush(); fos.close(); dexFile.delete(); } /** * 3、把dex放入apk解压目录,重新压成apk文件 */ classesDex.renameTo(new File(apkTemp,"classes.dex")); File unSignedApk = new File("app/build/outputs/apk/debug/app-unsigned.apk"); Zip.zip(apkTemp,unSignedApk); /** * 4、对其和签名,最后生成签名apk */ // zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk File alignedApk=new File("app/build/outputs/apk/debug/app-unsigned-aligned.apk"); process= Runtime.getRuntime().exec("cmd /c zipalign -v -p 4 "+unSignedApk.getAbsolutePath() +" "+alignedApk.getAbsolutePath()); // System.out.println("signedApkprocess : 11111" + " :-----> " +unSignedApk.getAbsolutePath() + "\n" + alignedApk.getAbsolutePath()); process.waitFor(); // if(process.exitValue()!=0){ // throw new RuntimeException("dex error"); // } // apksigner sign --ks my-release-key.jks --out my-app-release.apk my-app-unsigned-aligned.apk // apksigner sign --ks jks文件地址 --ks-key-alias 别名 --ks-pass pass:jsk密码 --key-pass pass:别名密码 --out out.apk in.apk File signedApk=new File("app/build/outputs/apk/debug/app-signed-aligned.apk"); File jks=new File("proxy_tools/proxy1.jks"); process= Runtime.getRuntime().exec("cmd /c apksigner sign --ks "+jks.getAbsolutePath() +" --ks-key-alias wwy --ks-pass pass:123456 --key-pass pass:123456 --out " +signedApk.getAbsolutePath()+" "+alignedApk.getAbsolutePath()); process.waitFor(); if(process.exitValue()!=0){ throw new RuntimeException("dex error"); } System.out.println("执行成功"); } }
我们在写好前面的之后,直接运行这个main方法,就可以在我们的app -> build->outputs->apk->debug下面看到生成的几个apk,分别为 app-debug.apk, app-unsigned.apk, app-unsigned-aligned.apk, app-signed-aligned.apk,最终 app-signed-aligned.apk 才是我们最后安装使用的apk。
这里带多一句嘴,上面的代理ProxyApplication被我们配置到Mainfest的application 标签中,这个位置经常是我们配置项目使用的application的,其实不用担心,代码中已经处理过了,当代理application处理完之后,会自动把我们配置的app里面的项目用到的MyApplication 类替换过来,所以项目在第一次运行完之后,正式运行还是以我们自己的MyApplication为主,大可放心。
-
python写的软件怎么逆向_App逆向|一个案例教你如何进行APP逆向
2021-03-05 22:22:18今天有个好兄弟找我,因为抢不到票,很生气,直接想...接下来,想直接打开jadx开搜了。发现被数字壳加固了。上!FRIDA-DEXDump! 直接脱掉。 搜索一波 发现就在这个dex里面,jadx启动! 那岂不是hook Security.INSTAN... -
反编译工具.zip
2019-06-01 21:05:04操作说明:1、下载完成解压dex2jar-2.0压缩包,然后把apk文件解压,不知道怎么解压的先把apk压缩在打开把classes.dex文件拷贝到dex2jar-2.0 2.在dex2jar-2.0文件中打开命令行输入d2j-dex2jar classes.dex命令会生成... -
查看安卓APK源码破解
2015-03-12 11:47:30工具准备:<1>.android4me的AXMLPrinter2工具 ...其中解压后的xml文件打开时乱码,改怎么查看呢? 第二步:打开cmd.exe进入到解压后的文件夹中。输入:java -jar AXMLPrinter2.jar showtimes_list.xml > h.xml其中 -
2020-03-23
2020-03-23 21:37:22点进classes.dex用dex++打开 怎么样在手机上弄,各位大神!求解! 拜托????????????了! -
腾讯4.1脱壳修复
2019-06-22 12:09:41最近,腾讯出了4.1版本 ,我自己也很好奇...修复好了后,dex放一边,记住:此时,原来的包,也就是加固包,千万不能删除,我们要找入口信息,不然修复dex也是闪退怎么找呢,打开原包,查看apk,查看classes.dex 点击... -
利用无效字节码指令引发逆向工具崩溃(二)
2015-05-28 09:56:52上一节我们介绍了一种利用无效字节码指令引发逆向工具崩溃的方法。...但是如果我们插入有效的字节码指令,但是后跟无效的数据引用,结果会是怎么样呢? 使用C32asm,以十六进制的方式打开dex文件。按快捷键“Ctrl+... -
(爱加密系列教程十五) 利用无效字节码指令引发逆向工具崩溃(二)
2013-11-25 09:26:00上一节我们介绍了一种利用无效字节码指令引发逆向工具崩溃的方法。可惜的是大部分反编译... 使用C32asm,以十六进制的方式打开dex文件。按快捷键“Ctrl+G”,定位到“0003A2A4” 把“620002041A018E076E20191010... -
浅谈 apk 分析器
2020-06-07 23:10:54Android studio 自身提供了一个apk分析器,作用不是很大,但有比没有强吧,操作很简单,这里不做介绍,只说一下他大概可以做什么,怎么打开它~~ APK 分析器可以做以下事情: 查看 APK 中的文件(如 DEX 和 Android... -
android逆向之路七
2018-05-05 23:00:02好了,我们来说一下,怎么去破解积分我们先使用一下软件,看到软件有什么的提示的关键字,然后打开软件的dex文件,搜索关键字,通过smail反编译找出java的调用关系,然后进行分析的函数的调用或者是一些条件的... -
APK反编译指南
2019-07-20 17:11:56APK反编译踩坑指南 我们在开发过程中我们经常致敬别人的某一块功能或者页面,此时我们只有别人的APK包,该如何使用别人的代码呢?...1、dex2jar :将解压缩出来的dex文件转为jar文件 2、jd-gui : 打开j... -
在created调用点击方法_Python调用Java代码抓取APP数据
2020-12-24 06:08:55打开APP我们向下滑可以看到它在发送请求,通过Fiddler可以看到已经抓到请求了多请求几次可以发现,只要知道signature怎么来的,我们就能模仿它的头部信息了。这时候打开jadx,导入我们上次脱壳出来的源dex文件,按... -
android 反编译apk文件
2013-05-22 21:33:48一般的apk文件如果后缀改为rar并解压的话,可以得到一些图片资源,和一堆打开乱码的文件。但我们往往想要的是得到它的xml文件学习下怎么布局的,或者看看它的源码学习下优秀程序的思路。这时就要借助以下工具对apk... -
Eclipse android sdk打不开AndroidSDKManager
2012-11-20 06:10:53然后打开以前的文件,就出现了一些关于API的错误,说需要在SDKmanager中修复的,但是SDKmanager打不开。显示下面错误: [2555-11-20 10:27:27 - Dex Loader] SecurityException: Unable to find field for dex.... -
Android菜鸟日记25-android反编译
2011-10-23 18:43:11写在最前面的话:之所以写这个是感觉目前市场上的书写的内容都不够,那么有很多大公司的android apk写的不错,教下师弟们反编译去看看人家怎么写的,加以学习,请勿用于抄袭或者任何形式的不正确的行为,这样违背了我... -
Python调用Java代码抓取APP数据
2020-11-02 23:16:44需要用到的包: ...这时候打开jadx,导入我们上次脱壳出来的源dex文件,按Ctrl+Shift+F输入signature进行搜索,找到这可以发现其他的头部信息在这,点进去看下 可以发现这就是我们要的, 点击生成s... -
apk反编译
2016-08-19 16:32:35最近在开发一个功能,功能已经实现了,但是性能相当的差,网上找了一些原因,也需要逐一验证,所以想看看别人都是怎么做的,就想到了反编译来试试。...打开apk2java目录下的dex2jar-0.0.9.9文件夹,包含apk反编译 -
APK瘦身
2018-05-08 14:59:34准备瘦身~~~~先分析一下打包的APK的资源是怎么分布的:1、打开ANDROID STUDIO——BUILD——Analyze APK...——找到你打包的APK的位置,选中 然后,就会看到APK的大小分布了——以上图为例,classex.dex是代码占用的... -
Android APK反编译
2012-09-04 12:22:38有些应用反编译后java代码用jd-ui根本都无法打开,连混淆的代码都看不到的,本人尝试多次都做不到(网上有说是混淆工具针对反编译工具的), 希望知道的告知下怎么处理 的。 --注:上面的问题经过本人多次... -
-
Android应用程序开发教程PDF电子书完整版、Android开发学习教程
2011-03-30 22:26:35不知道 34 家厂商的硬件开发商们是怎么样想的);上面是类库和 Runtime,绿色的类库部分可以看 到大名鼎鼎的 SQLite,这个软件甚至声称自己属于公共领域(比 MIT License 还要强 @@),字体 FreeType 是 BSD-style ... -
新版Android开发教程.rar
2010-12-14 15:49:11----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...