关于app逆向工程的一些方法

本屌是一个苦逼的爬虫,从入行到现在一年多,接触过各种反爬,什么检测自动化之类的都常见了,碰到js加密、app逆向的采集基本都是歇菜了,不过慢慢的还是接触这个,慢慢的学了很多。关于js解密的已经有一篇文章了,如果我说的不明确的话可以留言给我,我会回复的.

首先说一下做app逆向的几个工具,

1.  dex2jar 这是个jar包,版本没啥限制选一个合适的版本就好

2.jd-gui这个可以将你反解出来的jar包打开,看里面的代码和结构

3.一台装有xposed框架的root手机,本人用的华为的nexus 6p  (市面上都是二手的,最好买的时候换个电池,不然一直重启啥的)

4.android studio 编译你的apk,将你的xposed 插件装到手机上。

5.一定版本的app apk文件

由于工作的需求,破解了某鱼和某夕夕的apk。

首先将你的apk后缀改成  .zip,然后将你的包进行解压,有的解压工具可能是解不了的,换一个工具 或者用 unzip命令去解包,解了包 里面会出现很多文件 ,我们需要的就是 classes.dex  可能会存在多个类似的文件,我们只要这一个就好,将这个文件拷贝到下载好的 dex2jar 文件中,将你这个文件中的  d2j-dex2jar.sh     d2j_invoke.sh  修改权限为可执行,然后执行  

sh d2j-dex2jar.sh ./classes.dex

他会将你的包改成一个jar包,classes-dex2jar.jar,ok  你拿到这个jar包 就可以放到jd-gui中 了,里面会看到他所有的类和方法(有可能是混淆过的哦),这就该用到了这个工具的搜索功能了,搜你想hook的关键词,除非所有的类和方法都混淆过,不然你一定可以找到你想要的东西。

 

我想要的就是列表页的数据,搜索一下goods  respoinse 等关键词,轻松的找到 

com.xunmeng.pinduoduo.ui.fragment.search.entity.SearchResponse  这个类下面是我想要的方法。

既然找到了 接下来就是 在android studio中写hook代码咯

public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable{

        if (loadPackageParam.packageName.equals("com.taobao.idlefish")){
            XposedBridge.log("PackageName====>"+loadPackageParam.packageName);
            XposedBridge.log("ProcessName====>"+loadPackageParam.processName);
            XposedBridge.log("AppInfo====>"+loadPackageParam.appInfo);
              XposedBridge.log("闲鱼");
        }else if (loadPackageParam.packageName.equals("com.xunmeng.pinduoduo")){
            XposedBridge.log("PackageName====>"+loadPackageParam.packageName);
            XposedBridge.log("ProcessName====>"+loadPackageParam.processName);
            XposedBridge.log("AppInfo====>"+loadPackageParam.appInfo);
            pddhook(loadPackageParam);
        }

    }

这几行代码可以在xposed中输出你选中的包的一些相关的属性,没什么用 不过用来玩耍 还是不错的

private void pddhook(final XC_LoadPackage.LoadPackageParam lppam) throws JSONException, MalformedURLException {

        Class aClass = XposedHelpers.findClass("com.xunmeng.pinduoduo.constant.HttpConstants",lppam.classLoader);
        List listMember = new ArrayList();
        for (Method method: aClass.getDeclaredMethods()){
           XposedBridge.log("【当前类中的方法】=====>{}"+method);
              listMember.add(method);
        }

        for (final Member member : listMember) {
            XposedBridge.hookMethod(member, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    String result = param.getResult().toString();
                    XposedBridge.log("【方法名称】=====>" + member.toString());
                    XposedBridge.log("【每个方法中的返回值】=====>" + result);
                }
            });
            if (member.toString().contains("buildQuery")) {
                XposedBridge.hookMethod(member, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        String result = param.getResult().toString();
                        if (result.length() > 20){
                            keyUrl = result;

                            XposedBridge.log("【请求的url】=====>" + result);
                        }

                    }
                });
            }
        }

上面第一个hookmethod  是穷举了HttpConstants 这个类下面所有的方法和每个方法执行完毕后的所有结果,第二个methodhook其实就是筛选了一下制定的方法名获取他的结果

Class bClass = XposedHelpers.findClass("com.xunmeng.pinduoduo.ui.fragment.search.entity.SearchResponse",lppam.classLoader);
        List listMemberb = new ArrayList();
        for (Method method: bClass.getDeclaredMethods()){
            XposedBridge.log("【当前SearchResponse类中的方法】=====>{}"+method);
            XposedBridge.hookMethod(method, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    XposedBridge.log("【每个方法的结果】=====>" + param.getResult());
                }
            });
            listMemberb.add(method);
        }
        for (final Member member1 : listMemberb){
                    if (member1.toString().contains("getItems")){
                        XposedBridge.hookMethod(member1, new XC_MethodHook() {
                            @Override
                            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                super.afterHookedMethod(param);
                                String result = param.getResult().toString();
                                goodsList = result;
                                XposedBridge.log("【result】=====>"+result +"$"+keyUrl);
//                                URL url = new URL("");
                                URL url = new URL("");
                                try{
                                    String str = goodsList + keyUrl;
                                    try {
                                        HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
                                        httpURLConnection.setConnectTimeout(2000);
                                        httpURLConnection.setReadTimeout(5000);
                                        httpURLConnection.setDoOutput(true);//设置允许输出
                                        httpURLConnection.setRequestMethod("POST");//设置请求的方式
                                        httpURLConnection.setRequestProperty("ser-Agent", "Fiddler");
                                        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                                        StrictMode.setThreadPolicy(policy);
                                        PrintWriter out = new PrintWriter(httpURLConnection.getOutputStream());
                                        out.print(str);
                                        out.flush();
                                        out.close();

                                        int code = httpURLConnection.getResponseCode();
                                        if (code == 200){
                                            XposedBridge.log("发送成功");
                                        }else{
                                            XposedBridge.log("发送失败");
                                        }

                                    }catch (Exception e2){
                                        XposedBridge.log("pddPost请求异常"+e2);
                                    }



                                }catch (Exception e1){
                                    XposedBridge.log("urlencode 异常"+e1);
                                }

                            }
                        });
                    }
                }

    }

这些代码是hook了他列表页搜索的结果 并且将数据转发到我的服务器,其实你如果只是想hook一些数据没什么难度的。

整个的流程就是这些,其中比较耗时的就是一个包的查找和hook,有许多的方法是hook不到的,需要用别的方法去处理。

hook的强大之处在于 可以在你目标方法之前执行也可以在你目标方法之后执行,可以获取他传入的参数也可以获取他返回的参数。

听说阿里下面的app都是有反hook机制,所以需要先破解这个,这个就比较高深了需要大神去解决。

这个逆向就说到这,需要了解的同学,留言~本博客纯属技术交流~

你可能感兴趣的:(java,xposed,爬虫,app逆向,xposed,hook,java)