2016年12月14日 星期三

备忘:Blogger Simple模板缩短订阅按钮用到的css

.subscribe-dropdown-arrow {
    display: none !important;
}
.subscribe {
    width:97px !important;
}
.subscribe .top{
    width:97px !important;
    background:none !important;
}
.subscribe .bottom{
    width:97px !important;
    background:none !important;
}

2016年12月9日 星期五

废物利用老旧安卓平板流水账(二):交叉编译shadowsocks


在上一篇流水账中我已经有了个能用的ROM,然而这个android系统还是太老了,在这个系统上并不能支持最新版的shadowsocks安卓app,而旧版本的shadowsocks没有自带kcptun,不知道为什么也没法通过我手工启动的kcptun连上服务器。所以只好放弃使用app,手工编译一个ARM指令集的native shadowsocks客户端程序。

这篇包含两部分,前一部分是使用NDK交叉编译shadowsocks-libev,后一部分是使用go交叉编译shadowsocks-go

使用NDK交叉编译shadowsocks-libev:

由于这是一次失败的尝试,同时我在写这篇文章的时候也是在回忆了,所以这部分重心放在记述如何使用NDK交叉编译可以运行在androidnative程序而不是ss,有些细节可能略过了。
首先需要去这里下载一份NDK。由于我只是需要交叉编译个native程序而已,并不是要搞app开发,所以只要使用standalone toolchain就好。
按照这里的步骤NDK创建出适用于自己的android平台的standalone toolchain。如果直接使用ndk目录内的toolchain你可能会遇到像这里或者这里还有这里遇到的诸如“fatal error: string: No such file or directory”或者“undefined reference to `std::basic_string”之类的编译错误,由于我们不是android工程没有使用ndk-build所以创建Application.mk文件的办法并不管用。
之后编译opensslpcrelib库,在执行configure之前先设置环境变量让make的时候使用我们的toolchain(将'/my-android-toolchain-path替换为你的toolchain目录):

export ANDROID_TOOLCHAIN='/my-android-toolchain-path/'
export CC=${ANDROID_TOOLCHAIN}/bin/'arm-linux-androideabi-gcc --sysroot='${ANDROID_TOOLCHAIN}/sysroot
export CXX=${ANDROID_TOOLCHAIN}/bin/'arm-linux-androideabi-g++ --sysroot='${ANDROID_TOOLCHAIN}/sysroot
export CCLD=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ld
export AR=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ar
export AS=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-as
export RANLIB=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ranlib

configure的时候记得添加这几项:
--host=arm-linux 指定编译目标系统环境
--with-sysroot=/my-android-toolchain-path/sysroot 指定sysroottoolchain
--prefix=/my-android-toolchain/sysroot/usr 指定安装目录到toolchain

之后编译shadowsocks-libev仍然并不顺利,因为这个工程并没有做好在NDK编译的工作,指定-DANDROID,手工添加编译ancillary和添加-llog引用等一系列工作完成后编译出来的程序并不能正常工作,于是我把视野转向了shadowsocks-go

交叉编译shadowsocks-go:

其实如果COW或者MEOW这种自动化的工具更合你的口味的话,你完全不需要自己去编译shadowsocks-go,因为他们都提供了ARM版本的bin。而对于我来说,他们都不是我的菜。
由于我完全没有go编程经验,所以我这里的一些对go的理解很可能是错误的,请自行思考并有选择的接受我的看法。
Go的交叉编译很简单,按照下面的顺序执行即可:
yum install -y golang
安装go

export GOARCH=arm
指定go编译的指令集

https_server=127.0.0.1:1234 go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-local
因为golang.org被墙了,所以这里指定了https代理服务器127.0.0.1:1234

之后就可以在/lib/golang/bin/linux_arm路径下找到arm版的shadowsocks-go了。

接下来我做了什么?在平版上安装了ssh服务,然后结合kcptun + shadowsocks-go + privoxy搞了个内网公用服务器。这三个组合起来在安卓上搞内网服务并没有啥难度,我不确定会不会单开一篇详述。另外最近才发现privoxy真的很强大呢,完全超越了PAC的灵活性(见这里这里

2016年12月8日 星期四

废物利用老旧安卓平板流水账(一):解决ROM问题


家里有个常年落灰的老旧平板,这两天把他折腾了一番重新废物利用了起来,在此记录一下遇到的问题和解决方案。

老旧平板的安卓系统也已经非常老了, 为了更新系统我从网上找了个最新(多年前)的ROM更新到机器上,然后悲剧的发现触摸时x轴镜像了,原来能用的ROM又找不回来了。
不断下载了各个不同子型号的ROM仍然没有找到合适的ROM的我,决定使用相性最好的一个ROM,并手动解决这个ROMx轴反向像的问题。

要改ROM首先要能解包封包,这个板子是RK2918的方案,对应的解包封包工具在这个帖子有介绍。

我按照国内一个论坛的说法尝试首先尝试了修改build.prop的以下属性:accelerometer.hwrotationinput.hwrotationro.sf.hwrotation。然而这并没有什么卵用。

然后我尝试修改内核驱动,首先通过这个帖子的找到了解包boot.img的办法:打开winhex16进制搜索1f8b08 ,定位到zip头,然后把后面的数据都拷到新的文件。然而看了一圈并没有发现合适下手对象。

于是我把目光转向了system.img,并发现了合适的下手目标:libinput.so
把这东西拖给IDA,根据IDA的分析结果,在github上搜到这个安卓系统对应版本的libinput的相关代码:InputReader.cpp

注意void TouchInputMapper::cookPointerData()这个函数的这段:
switch (mSurfaceOrientation) {
  case DISPLAY_ORIENTATION_90:
    x = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
    y = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
    left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
    right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
    bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
    top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
    orientation -= M_PI_2;
    if (mOrientedRanges.haveOrientation && orientation < mOrientedRanges.orientation.min) {
    orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
    }
    break;
  case DISPLAY_ORIENTATION_180:
    x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
    ...
    break;
  case DISPLAY_ORIENTATION_270:
    ...
    y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
    ...
    break;
  default:
    x = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
    ...
    break;
}
这段代码明显就是安卓应对屏幕的不同旋转方向映射触点坐标系到显示坐标系的代码了,只要在这里做修改即可解决x轴镜像的问题
接下来继续啃ida逆向代码,找到对应的x值和y值计算的部分:
 
实际上只需要把“xTransformed - mRawPointerAxes.x.minValue”和“mRawPointerAxes.x.maxValue - xTransformed”互换即可,这里如何逆向并找到相关汇编代码就不赘述了,这是另一个方向的技术了。光找到相应的汇编其实还不能解决问题,还需要一个ARM汇编器帮我们把想要的ARM汇编转换成我们需要patch的机器码当时在pediy上找到了一个,但是并不好用,这里感谢44同学提供的ARM汇编器帮我解决了patch的最后一步。

之后只需要把修改好的libinput.so替换到ROM里重新刷机即可完美解决x轴反向/镜像。
有了能用的ROM,下一篇流水账就是在ROM上继续折腾了。