对某APP的逆向之旅(2)
来源:互联网 发布:mysql破解教程 编辑:程序博客网 时间:2024/06/05 06:46
接着上面的分析过程,继续
本次分析下java层和ndk通信的框架
首先,执行上一节分析中解密的文件,如下:
继续分析:
private static int a(Context context, String arg13) { int v9 = 3; int v4 = -1; int v1 = 0; Runtime.getRuntime().exec("chmod 755 " + arg13); String[] v0 = new String[v9]; v0[0] = "su"; v0[1] = "-c"; v0[2] = arg13; Log.d("TAG", Build.CPU_ABI + " - -" + Build.CPU_ABI2 + " -- " + System.getProperty("os.arch")); Process decodeExe = Runtime.getRuntime().exec(v0); q ServerSocketThread = new q(); ServerSocketThread.start(); RootManager.waitThread(((Thread)ServerSocketThread)); int v2 = decodeExe.getErrorStream().read(); if(v2 != 120) { Log.d("TAG", "RE:" + v2); return v4; } ServerSocketThread.getPort(); q serverSocket_1 = ServerSocketThread; int v0_2 = 0; label_51: if(!serverSocket_1.isAlive()) { serverSocket_1 = new q(); serverSocket_1.start(); } RootManager.waitThread(((Thread)serverSocket_1)); int localPort = serverSocket_1.getPort(); if(v0_2 > v9 && localPort == 0) { v0_2 = 1; goto label_60; } long v7 = 100; try { Thread.sleep(v7); } catch(InterruptedException v7_1) { v7_1.printStackTrace(); } ++v0_2; if(localPort == 0) { goto label_51; } v0_2 = 0; label_60: OutputStreamWriter v3 = new OutputStreamWriter(decodeExe.getOutputStream()); v3.write(String.valueOf(localPort) + "\n"); v3.flush(); if(v0_2 != 0) { g.a(context).setProcess(decodeExe); g.a(context).initStream(decodeExe.getInputStream(), decodeExe.getOutputStream()); return v1; } try { serverSocket_1.join(); long v6_1 = SystemClock.uptimeMillis(); label_89: Socket receiveSocket = serverSocket_1.getReceiveSocket(); if(receiveSocket == null) { if(SystemClock.uptimeMillis() - v6_1 > 32000) { return -3; } serverSocket_1.run(); Log.d("TAG", "Check alive2"); goto label_89; } g.a(context).setProcess(decodeExe); g.a(context).initStream(receiveSocket.getInputStream(), receiveSocket.getOutputStream()); } catch(InterruptedException v0_3) { Log.d("TAG", "InterruptedExceptioned"); decodeExe.destroy(); v1 = v4; } return v1; }
里面函数名我已经改成了容易识别的名字。该函数的流程如下:
1、修改执行文件的权限,执行文件。
2、创建socket服务端,监听socket连接数据。
3、通过检查socket服务端的本地端口,检查创建是否成功,成功,则通过socket通信(receiveSocket.getInputStream()、 receiveSocket.getOutputStream()),否则直接通过进程通信(decodeExe.getInputStream(), decodeExe.getOutputStream())。
下面看下通信框架,主要在下面的两个函数中
1、g.a(context).setProcess()
2、g.a(context).initStream(,)
第一个函数比较简单,就是将子进程传递进去。如下:
public void setProcess(Process arg1) { this.c = arg1; }
主要看第二个函数,如下:
public void initStream(InputStream arg3, OutputStream arg4) { this.d = new BufferedReader(new InputStreamReader(arg3)); this.e = new DataOutputStream(arg4); new p(this, null).start(); }
初始化了输入输出流,然后执行了一个线程,来到线程p看看,
public void run() { long v1_1; String v0_3; Object v1; BufferedReader v5 = null; if(g.a(this.a) != null) { try { while(true) { label_5: v1 = g.a; __monitor_enter(v1); break; } } catch(InterruptedException v0) { goto label_40; } catch(IOException v0_1) { goto label_29; } try { Log.w("xltest", "get lock mReader"); v0_3 = g.a(this.a).readLine(); Log.w("xltest", "release lock..mReader,=" + v0_3); __monitor_exit(v1); v1_1 = 10; } catch(Throwable v0_2) { goto label_37; } try { Thread.sleep(v1_1); if(v0_3 == null) { goto label_5; } g.a(this.a, v0_3); goto label_5; } catch(InterruptedException v0) { goto label_40; } catch(IOException v0_1) { goto label_29; } try { label_37: __monitor_exit(v1_1); } catch(Throwable v0_2) { goto label_37; } try { throw v0_2; } catch(InterruptedException v0) { label_40: v0.printStackTrace(); } catch(IOException v0_1) { label_29: Log.w("GameSpeed", "reader thread", ((Throwable)v0_1)); g.a(this.a, v5); g.a(this.a, ((DataOutputStream)v5)); } super.run(); } }
看起来比较复杂,其实实质的内容很少,主要逻辑如下:
v0_3 = g.a(this.a).readLine();Thread.sleep(v1_1);g.a(this.a, v0_3);
我们再来看最后一个函数,这个函数主要是用来接收socket消息的,函数名已经修改过:
static boolean a(g arg1, String arg2) { return arg1.sendLocalBroadcast(arg2); } private boolean sendLocalBroadcast(String arg6) { boolean v0 = true; if(!arg6.startsWith("key")) { goto label_24; } if(as.b(this.h, "setting_volume", false)) { String v1 = arg6.split(":")[1]; c v2 = c.a(this.h); Intent v3 = new Intent(); v3.setAction("sb.key.pressed"); v3.putExtra("key", v1); v2.a(v3); // 发送本地广播 } else { Log.d("key", arg6); return v0; label_24: Log.d("xltest", "update=" + arg6); v0 = false; } return v0; }
发送消息的函数为(只列举设置和停止):
public void sendMsg(int arg4) { try { this.e.writeBytes("t set " + arg4 + "\n"); this.e.flush(); } catch(IOException v0) { v0.printStackTrace(); this.b(); } } public void a() { Log.d("xltest", "resetSystemTime"); try { this.e.writeBytes("t stop\n"); this.e.flush(); } catch(IOException v0) { v0.printStackTrace(); this.b(); } }
就是通过本地广播,实现java层和ndk层的通信。
NDK层的分析,有时间再写吧!
0 0
- 对某APP的逆向之旅(2)
- 对某APP的逆向之旅(1)
- 对某APP的逆向之旅(3)
- 对某游戏发包流程的一次逆向之旅
- 对恶意APP"Roidsec"的逆向分析
- 对一个免费通话恶意APP的逆向分析
- 对恶意APP"淘宝宝贝分享图"的逆向分析
- Android逆向之旅---分析某直播App的协议加密原理以及调用加密方法进行协议参数构造
- Android逆向之旅---某直播APP的协议加密原理分析以及调用加密方法进行协议参数构造
- APP逆向(上)
- APP逆向(中)
- Android逆向之旅---获取加固后应用App的所有方法信息
- 逆向实战之对某航软件URL参数的解密
- 一次函数调用过程对堆栈的逆向分析之旅
- 对深蓝少年之机甲勇士的逆向分析
- 对好搜小说app哈希算法的一次逆向
- 逆向某停车app(原创)
- apktool(android app逆向)
- 《twitter:从荒野到IPO》读后感
- MyEclipse创建第一个Servlet程序
- if 与 while
- C语言的指针(进阶篇章之二)
- ssh 连接异常解决纪实(Shared connection to xxx.xxx.xxx.xxx closed.)
- 对某APP的逆向之旅(2)
- PHP实现公钥加密机制
- Android疯狂ListView之旅 第一季 《侧滑删除条目》
- mybatis中数组传递注意事项--简
- Java中的泛型方法
- css实现div高度填满整个空间
- Android 远程调试工具STF——开源项目
- PPT插入可编辑的表格技巧
- android传感器学习之采样率和属性