apktool反编译与重新打包学习,apk反编译与重新签名学习,keytool-jarsigner

有个玩无线电的朋友问我会不会破解软件,我说太难的搞不了,有些是混淆过的;他说有个好像是测无线电天线的设备(天调?)是绑定蓝牙mac的让我给搞定下,安卓的app。

于是完成之后记录下。之前没事时候用过apktool,jd-gui,dex2jar等工具还有在线的,不过玩着玩着就扔掉了,这次答应了人家,起码弄出个123吧。

本次用到的工具:

1.apktool2.2

2.keytool,位于jdk/bin目录

3.jarsigner,位于jdk/bin目录

最初使用的直接apk包改扩展名zip,拿出classex.dex,然后dex2jar,拿到java文件之后想把源码直接拿出来复制到一个新工程里去,跟重新做差不多,因为看到里面只有四个Activity :

DeviceListActivity.java

DrawChart.java

MainActivity.java

MyApplication.java

比较简单,字面意思都能猜出是干嘛的,设备列表Activity,显示匹配/未匹配的蓝牙设备吧?DrawChart绘制曲线的吧?MainActivity和MyApplication都不用说了,主界面和入口,哇塞我敏锐的直觉囧。。。然后软件运行截图是这样的:

Mini60X APP运行截图
Mini60X APP运行截图

玩无线电的就是高大上,直接看不懂。。。

打开设备列表Activity之后就能看到写死的蓝牙地址,于是数组里再加入一个

但是复制到新工程之后就各种报错,比如do{ return;xxx;xxx; }while(1);这种,do里面直接return,肯定是不对的,然后各种重新反编译最后都不能直接拿来用,是不是我想的太简单了。。。虽然拿到了源码,但是有错误,尤其DrawChart里面的代码,gdi编程的错误真心搞不了。

然后又使用apktool d xxx.apk反编译得到smali文件列表(smali语法也玩不转)找到DeviceListActivity直接替换掉数组里面的蓝牙mac地址,ok第一步算完成了;

接着使用apk b xxx(xxx代表刚才反编译得到的文件路径),重新打包,在xxx/dist目录下会生成新的apk文件;这个时候apk是没有签名的,也不能安装到安卓手机中,需要对apk文件进行签名,过程如下:

1.首先生成签名文件,直接切换至%JAVA_HOME%/bin目录,使用
keytool -genkey -alias new.keystore -keyalg RSA -validity 20000 -keystore new.keystore
命令生成文件,中间不断下一步,输入密码填信息什么的,上面的语句就会在当前目录生成的签名文件new.keystore

2.使用jarsigner签名apk,将apk拷贝至%JAVA_HOME%/bin目录,输入命令:
jarsigner -verbose -keystore new.keystore -signedjar Mini60X-signed.apk Mini60X.apk new.keystore

new.keystore就是1步生成的签名文件,Mini60X-signed.apk就是要生成的签名之后的文件名,Mini60X.apk是你的apk文件名,运行结果如下:

jarsigner签名apk运行结果

就会在当前目录生成Mini60X-signed.apk,下面的Warning我没管它,然后就安装到手机上吧。

声明:本文只为学习安卓打包与签名机制使用,不针对任何app生产厂商,本文及作者不承担任何法律内外责任。

java byte[] 字节数组按份分割拆分成多个数组

java byte[] split

简单的字节数组分割方法,输入要拆分的数组及要按几个拆成一份即可,返回二维数组byte[],做记录直接上代码了。

测试代码:

 

输出结果:

8
==========================================
23 4 23 42
34 2 34 2
34 2 54 3
4 56 4 7
56 7 8 5
15 2 34 2
41 2 32 3
3 3 33

使用Netty进行Android与Server端通信实现文字发送接收与图片上传 – 原创

ANOTHER TITLE:

Let’s use netty to achieve text send and receive and  image transfer to server based on android and jdk1.7

就让我来Rap<MC Hotdog>,使用netty进行安卓端发送接收文字,并且附带发送图片功能,折腾了几天的netty总算有点眉目了,做下记录。

需求是安卓端拍照上传到服务器,服务器返回上传成功或失败bla bla bla,需求比较简单。最初使用的传统的post加multipart/form-data,一般的手机照片大小1-2M,测试没问题,但实际情况是有的用户使用3G网络,有的4G,有的WIFI还有的使用2G,网络环境稍微有点差的上传图片时间持续到十多分钟(我都不好意思说了),然后想到了使用socket,然后google到了netty,有的大神说这样的需求没必要上netty啊,其实我就是想通过这个需求学习下关于socket,关于netty,关于channel,关于byte[],关于NIO,多学习点总是没坏处的,后面我也可以牛逼点说玩过高性能基于事件的异步网络框架了。

刚开始直接啃的netty.io的document,照葫芦画瓢抄完了TimeServer之后就满世界的google其他的netty知识,比较零散,然后入手了《Netty权威指南第二版》,啃了几章之后怎么也是TimeServer,不过对NIO一些基本组件有了一个初步的认识。

OK,入正题,我要实现一个Demo,就说是个Netty的聊天室吧(群聊,没有单聊的功能,demo味儿十足),不过客户端换成了安卓,一个服务器对多个客户端,所有数据经过服务器端,要定义中间信息交换组件。关于Google的Protobuf还有MessagePack和JBoss Marshalling这些编解码中间件都没有玩过,似乎有点看不懂,我的需求很简单,如下图(抱歉键盘党多年手已废掉,可能只有我自己看得懂):

Echo-Server、Echo-Pojo、Lets's Chat Relationship

一共包含三个对象:

Echo-Pojo,信息交换中间对象,用于Android端与Server端封装byte[]之后的序列化对象。

Let’s Chat,安卓客户端,构建EchoMessage或EchoFile对象,然后发送到channel;EchoMessage与EchoFile用于服务端判断信息对象的类别。

Echo-Server,服务端。ChannelRead时判断信息对象类型,决定是广播到所有用户还是保存文件。

对于ByteBuf对象一直没有弄很明白,所以上述也就没有使用。

来张安卓端(小米PAD)Let’s Chat的运行截图:

Let's Chat小米Pad运行截图
Let’s Chat小米Pad运行截图

三星手机Let’s Chat运行截图:

Let's Chat三星手机运行截图
Let’s Chat三星手机运行截图

服务端(Echo-Server)的运行截图:

Echo-Server输出日志与说明截图
Echo-Server输出日志与说明截图

上传的文件:

QQ截图20160518132859

文件名格式为:Build.MANUFACTURE+UUID.randomUUID()+”.jpg”,第二张图片为12.9M,上传时间六七秒钟,应该还有优化的空间。

Echo-Pojo的代码就不截图了,直接下载查看就可以,或者也可以继续扩展,目前只是图片跟文字。

上述功能一共分为三个程序,Echo-Pojo信息交换对象使用eclipse-Mars2开发,Echo-Server使用Intellij idea开发,Let’s Chat使用Android Studio2,有点蛋疼,但好在实现了功能,中间折腾的很多,尤其公司电脑跟家里电脑jdk不一致,一个1.8,一个1.7,因为这个出了很多莫名的错误,也浪费了很多时间,中间的各种折腾各种烦躁就不记录了。

代码注释比较少,也有很多废弃的没有删掉,只是实现了功能可以运行,没有做完全整理,有问题可以直接回复或者@EMAIL ME

借鉴刘源的NettyFileTransfer,只是我把客户端修改成了Android,然后Netty版本我用的是4.0.36Final,感谢大神。

剩下的就是把功能揉进项目里了,Keep Fighting !

项目开源地址:https://github.com/LisonLiou/netty-learning.git

java中的观察者/订阅者模式实践 – Observable、Observer

这方面的资料搜索一下很多,但是自己一直没有实践过。今天用到了,做下记录。名词解释:

观察者,Observer
被观察者,Observable

举例,过年放烟花,烟花放在中间一直燃烧,就是被观察者;
而大家在周围看,就是观察者(哇~~~猴赛雷)
直接上代码:

测试一下:

输出:

I am fired, check on that
XiaoLi watched: qiu…qiu…qiu…
XiaoHong watched: qiu…qiu…qiu…
XiaoQiang watched: qiu…qiu…qiu…
XiaoMing watched: qiu…qiu…qiu…

之前使用的是直接new一个Observable对象,导致无法调用父类的setChanged方法。 Continue reading

Android坑之java.net.SocketException: Permission denied

OK,不知道这算不算是一个坑,记录一下吧,一上午都过去了。。。

先上代码,简单的网路请求上传图片,做了精简,只留关键部分。
HttpURLConnection请求
一执行到con.getOutputStream()就报错:java.net.SocketException Permission denied刚开始以为代码抄的不好,各种百度,发现没有加权限:

<uses-permission android:name=”android.permission.INTERNET” />

结果加上也不好使,又陆续加了
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

都不好使。。。后来单开线程请求也不好使(代码已省略)。

然后各种百度找到的都是那几篇文章, 要么是模拟器忘了开sd卡,可是我用的真机啊。。。
然后各种胡思乱想,难道是因为我的手机没root?这倒是跟没有权限的用户执行命令的时候没权限是同样的提示啊。。。难道我的内存卡没有mount?难道我的图片存到了系统空间,我没有权限读?bla bla bla

后来找大神要了段代码,发现跟我写的一样,同样报错。。。
知道后来又搜到了这篇文章:
《Android之EACCES (Permission denied)与Permission denied异常探密》
当中的第二条,permission写的地方不对,检查了我的manifest发现我的permission节写在了application里面(为什么当初我要这么做?我也不知道,为什么别的permission没有报错,我tm怎么知道),然后把所有permission拿出来放到与application平级,终于报的错不一样啦。。。。
java.net.ProtocalException Does not support outputOK,另一个坑走起。

 

记@我也来篇eclipse – Maven配置实战-_-

为了实现一个不可告人的秘密,我在github找到了一个maven项目,我以为pull本地或者import之后就能运行看到效果(因为我是典型的windows程序猿),结果发现,我不能run它。。。

Maven到底是什么,百科和度娘上解释的都太大牛话,我是看的云里雾里,什么事情我喜欢用一句话解释:Maven就是以前你引用jar都是拷贝到lib目录,或者从项目属性的Build Path中添加jar包,现在不用,你可以从Maven的中央仓库中添加依赖项(dependencies),适合团队协作,各种项目如果都使用某一个版本的jar包,则可以使用对应的dependency。还是不懂?也难怪,谁让我们都在代码作坊中工作,而且本身又是码畜呢。。。

OK,切正题。怎么玩Maven?

实际上,eclipse中已经嵌入了一个maven,如果你点击Window->Preferences->Maven->Installations可以看到右侧已经有一个Embedded的Maven,OK不管他,我们要自己配置一个。

Maven是apache的项目,主页地址为:http://maven.apache.org
左侧有download选项卡,选择适合自己的下载就ok了。下载完成后解压会得到apache-maven-3.3.3这样一个目录,然后配置环境变量。
M2_HOME指向F:\maven\apache-maven-3.3.3\(这是我本机的目录)
MAVEN_HOME同样指向上述目录|
MAVEN_OPTS设置为:-Xms512m -Xmx1024m(这个好像是运行时分配资源的大小,我猜的)

然后cmd->mvn -v

mvn -v
mvn -v

OK,这一步算完成了。

然后安装eclipse的Maven插件,直接传送门一个吧,ps.我的JUNO版本的eclipse的help中没有marketplace项,那就使用Install New Software,eclipse安装maven插件传送门

接下来,我git下来的项目到底怎么用,比如我git的这个webmagic,首先阅读readme.md,找到如何使用Maven
webmagic使用maven实际上,这就我们项目所要用的依赖项。

OK,eclipse的maven插件安装好以后,eclipse中就可以新建maven项目了,File->New->Project->Maven Project下一步之后等待Catelog从Nexus Indexer选项中Retrive Indexer,之后选择,Group Id为org.apache.maven.archetypes Artifact Id为maven-archetype-quickstart的这一项(这个我也没大弄懂),下一步,为你的项目指定Group Id,Artifact Id及version(这里是在中央仓库注册自己的项目?类似指定package name?)下一步,创建成功。

之后在项目中会找到pom.xml,将上面使用maven的depencency复制到depencencies节点中,然后右键项目Maven->Maven Build,可以看到Console中输出为Build Success
maven build success

如果出现找不到Goles错误的话,就在Goles里填入clean或者test。之后就可以新建class extends或者implements maven项目中的包了,OK,Enjoy it。

借鉴了的几篇文章,感谢互联网上的大神们。
http://www.cnblogs.com/yjmyzz/p/3495762.html
http://www.iteye.com/topic/1123225

从简单的java连接MSSQLSERVER代码中得到的教训

一切都没什么好说的,只有那句:System.out.println(excel.getString(2));

最初写的是getString(0),一直报错,怎么写也报错,getArray,getObject都试了一遍,还是报错:

java.sql.SQLException: [Microsoft][ODBC
at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.SQLColAttributes(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getColAttribute(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getColumnType(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getMaxCharLen(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
at com.lison.practise.Main.main(Main.java:39)

最后是查看了getString的源码,看到了注解:

ResultSet的getString方法注解原来这个index是从1开始的, 瞬间清凉到北极啊。。。尼玛不看注解会折寿啊。。。

其实还是自己少看书,少写代码,少做项目的缘故,java新手被虐的体无完肤。。。

认识java杂记-基础知识(概念)

1. 继承关键字使用extends    而.NET中使用冒号 :

2.抽象类型。使用abstract关键字修饰的class只能new它的衍生类(子类),抽象方法只能在抽象类中创建。继承抽象类后,必须实现抽象方法,或者将方法也修饰为abstract。通过抽象方法,可以将方法置入接口中,而无需编写主体代码。

3. OOP (Object Oriented Programming) 面向对象编程

4.上溯造型 UpCasting,原来是装箱的意思;

下溯造型DownCasting,原来是拆箱的意思。翻译不同的结果吧。

5. 违例(Exception);异常。翻译不同的结果。

6.synchronized 内存锁关键字(多线程),一般修饰对象(方法);其他类型的锁一般为创建一个对象,用它代表一把锁,所有线程在访问那个资源时都必须检查这把锁。

7. Servlet & Applet

8.javadoc,注释提取工具(生成html)

9.关于protected关键字:基类的创建者会希望有某个特定成员,把对它的访问权限赋予派生类而不是所有类。

10.关于public关键字:每个编译单元(文件)都只能有一个public类。这表示,每个编译单元都有单一的公共接口,用public类来实现。public类的名称必须完全与含有该编译单元的文件名相匹配,包括大小写。

11.关于this关键字:

由于increment()通过this关键字返回了对当前对象的引用,所以很容易在一条语句里对同一个对象执行多次操作。