タイトル/名前 | 更新者 | 更新日 |
---|---|---|
日記/2011/10/10/Androidアプリから画面キャプチャ | msakamoto-sf | 2011-10-10 16:56:15 |
日記/2011/10/10/AndroidでのHTTPクライアントライブラリの近況 | msakamoto-sf | 2011-10-10 15:21:11 |
日記/2011/10/02/プログラミングと仏教 | msakamoto-sf | 2011-10-03 07:53:11 |
技術/Android/HowToReadSystemLogs | msakamoto-sf | 2011-09-25 20:16:58 |
技術/Android/ProxyDroidとHTTP(S),SOCKSプロキシ | msakamoto-sf | 2011-09-19 14:16:47 |
日記/2011/09/19/Ubuntu10.04にJava入れてみた。 | msakamoto-sf | 2011-09-19 12:32:37 |
技術/Android/ReverseEngineering | msakamoto-sf | 2011-09-18 18:00:16 |
技術/Android/HowToBackupInstalledAPKFiles | msakamoto-sf | 2011-09-18 17:28:01 |
JavaScript/エスケープ時の注意点メモ | msakamoto-sf | 2011-09-12 08:21:58 |
日記/2011/09/11/Mercurialを使い始めた。 | msakamoto-sf | 2011-09-11 17:39:15 |
非rootがベストだけれど、APIとしては用意されてないのでどうしても特殊な方法になってしまうらしい。
framebufferを直接読み込むことでキャプチャを実現しているが、機種によってRGBがRBGになってたりエンディアンが異なったり色々。
2.3.3になってroot不要のキャプチャが可能になった!という話も流れているようだけど、結局システムアプリと同じ署名であれば可能で、サードパーティのアプリからはできないようだ。
逆に言えばメーカ製のアプリであればOKということで、機種によってはその機種専用のボタンショートカットなどでスクリーンキャプチャ出来るようになっていたりするようだ。
個人的にはmalwareの餌食になりそうな気がするので、ADBやDDMS経由で取得できれば十分だと思う。
APIを用意するにしても、専用のpermissionを準備して制限をかけるとか。
他、adbからの画面キャプチャ関連:
AndroidにはApache HTTP Clientが移植されているが、方向性としてはHttpURLConnectionを強化する流れになっているらしい。
上記記事では、4.0と目されるIce Cream SandwichでHTTPレスポンスキャッシュ機能が加えられる予定であると書かれているが、恐らくその対象はApache HTTP Clientではなく、HttpURLConnectionの方になるだろう。
個人的にはタイムアウトとかソケットとか細かい調整が効くApache HTTP Clientの方が好きなんだけどな・・・。POSTとかmultipart form dataとかも分かりやすいメソッドが用意されてて直感的だし・・・。
最初は「アジャイルと仏教」で一席ぶとうと思ったが、どちらも全くのド素人なので語れることは何も無い・・・。タイトル詐欺。
ということで、とりあえずプログラミング・システム開発に関連しそうな偈(経)を取り上げて無理やりITギョーカイにつなげてみます。
本日はこの偈を取り上げます。
法句経277
「一切の形成されたものは無常である」(諸行無常)と明らかな知慧をもって観るときに、ひとは苦しみから遠ざかり離れる。これこそ人が清らかになる道である。
・技術の流行り廃りにかこつけて。
「このプログラミング言語で一生食っていける!」というのはあり得ないようです。
「この会社に就職すれば一生安泰だ!」というのが幻であるのと同じことのようです。
・仕様変更にかこつけて。
同様に、人の心も常ならず。
というわけで、決まった仕様が覆る・変更されるというのはどうも世の中の真理のようです。
「顧客に一度仕様を決めたら絶対変更させないよう徹底する!」と考えないほうが良いようです。
もうちょっと突っ込むと、
「こうでなければならない!」
という理想像自体も絶対ではないようです。
というわけで、「まぁ人間みんな死ぬのだから、あんまり堅苦しく『~でなければならない』なんて考えるの、やめちゃおうよ」という教えですね。
ただ「じゃぁなんでも自由なんだ~!!」と好き勝手し放題がOKですよ、とは一言もかかれてない・・・はず、ですので、その辺はTPOに合わせて柔軟に制限をします。
法句経277、万能すぎるぞ・・・。他にも色々ネタを絡められそうだ・・・。
色々突っ込みどころ満載だと思います。
「仕様変更が真理だとしても、いちいち対応してられない」とか、
「『~でなければならない』のがNGなのは分からないでも無いけど、だからといってコメント無しのソースとか、ぐちゃぐちゃなファイル名やシンボル名にされても困る」とか。
後日その辺りを別の偈を持ちだしたりしてフォローしていきます。
・・・ちょっとこの記事書くのは早すぎたかも。関連箇所だけ切り抜いただけで、すごい物足りない感じがする・・・。後日もう少し書きなおすか、練り直しします・・・。
技術/Android/LogAndLogLevelTips ではログを出力する方法を紹介したが、今度はログを取得する方法についてのメモ。
3行でOK:
多分android-log-collectorをコピペして適当に改造すればお好みのLoggerが作れると思います。
他参考:
"ProxyDroid"はHTTP(S), SOCKS4, SOCKS5に対応したプロキシ設定アプリです。
root化前提ですが、Android端末内のアプリ全てに対して強制的に外部HTTP(S)/SOCKS4,5プロキシを通すように設定できます。
本記事では、その裏舞台を簡単に紹介します。
幸いなことにProxyDroidはソースコードが公開されています。ライセンスはGNU GPL v3です。
早速hgでリポジトリをcloneして中身を確認してみると、"assets"ディレクトリの中に興味深いファイルが見つかりました。
assets/ cntlm iptables proxy.sh redsocks tproxy
これらはインストール時に以下のディレクトリにコピーされます。
/data/data/org.proxydroid/
この辺の処理はorg.proxydroid.ProxyDroidのrecovery(), CopyAssets(), onCreate()辺りを参照してみてください。
では1つずつ見ていきます。
HTTP(S), SOCKS4/5 の透過型Proxyです。
ProxyDroidから起動されるシェルスクリプトで、引数に応じたredsocks用の設定ファイルを生成し、redsocksを起動します。
これ・・・だと思います。多分。NTLM認証用のHTTPプロキシのようです。
"tproxy"で検索すると似たようなのが結構出てくるので、ちょっとアタリがつけづらいのですが・・・多分これかな?
ちょっとコマンドラインオプションが異なるようですが。
いずれにせよ、透過型プロキシの一種であることは確かなようです。
いずれもARM用にコンパイルされているようです。
iptablesと透過型プロキシが同梱されている時点で気づいた人も居ると思いますが、ProxyDroidのやっていることは以下のとおりです。
図にするとこんな感じです:
Androidアプリ <-> Kernel <-> 透過型プロキシ <-> 外部プロキシ <-> インターネット
iptablesのコマンド実行や、上で紹介したツールの実行は org.proxydroid.ProxyDroidService クラスの enableProxy() メソッドで処理されています。実行されるコマンドラインについてはちゃんとログ出力されてますので、LogCatなどで確かめてみてください。
iptablesでroot権限が必要で、例えば org.proxydroid.ProxyDroidService クラスの runRootCommand(String command) メソッドでは以下のように処理しています。
process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getOutputStream()); os.writeBytes(command + "\n"); os.writeBytes("exit\n"); os.flush(); process.waitFor();
ProxyDroidがiptablesで強制的に透過型プロキシにルーティングしているのは、80番や443番など標準的なポート番号を使用している場合に限ります。従って標準以外の独自ポート番号を使用しているHTTP通信の場合は、直接インターネットに出て行ってしまい、外部Proxyを通せない可能性が高いです。
もしそのようなアプリにも透過型プロキシを適用させたいのであれば、ProxyDroidのソースを取得しで独自にビルドすればOKです。
試してないので断言できないのですが、多分 enableProxy() の中でiptablesの設定コマンドを実行してますので、適当にコピペしてポート番号を書き換えればOKだと思います。
あと、バージョン2.0.4ではローカルIPへの通信がProxyに流れない現象が見られました。enableProxy()の中で
if (intranetAddr == null || intranetAddr.equals("")) { // Reference: // http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces if (localIp != null) { String[] prefix = localIp.split("\\."); if (prefix.length == 4) { String intranet = localIp; if (localIp.startsWith("192.168.")) intranet = "192.168.0.0/16"; else if (localIp.startsWith("10.")) intranet = "10.0.0.0/8"; else if (localIp.startsWith("172.")) { int prefix2 = Integer.valueOf(prefix[1]); if (prefix2 <= 31 && prefix2 >= 16) { intranet = "172.16.0.0/12"; } } rules = rules.replace("-p tcp", "-p tcp " + "! -d " + intranet); } } } else { rules = rules.replace("-p tcp", "-p tcp " + "! -d " + intranetAddr); }
この辺の処理だと思います。一応画面上にもintranetAddrを指定する箇所があります。
色々弄ってみたのですが、結局上のifブロクをelseも含めてまるごとコメントアウトして、ローカルIPについても強制的にProxyを通すように修正してビルドしたのを使ってます。
当面の間、Android 2.x系ではHTTPプロキシ設定は公式にはサポートされない状況が続くと思います。
もしもroot化が可能であれば、ProxyDroidを使うことで無料で外部HTTP(S), SOCKS4, 5のプロキシを設定可能です。
しかもオープンソースですので、独自に改造してiptablesや透過型プロキシの設定を修正できます。
以上、ProxyDroidの舞台裏のごく簡単な紹介でした。
Sun・・・じゃなかった、OracleのページからLinux用のバイナリをインストールするというよくあるパターンで特に問題なかった。
参考:
/etc/profileに追加:
JAVA_HOME=/opt/jdk1.6.xxxxx PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME PATH
CLASSPATH設定はまだ。今後使っていく中で怒られたら追加しようと思う。
今回初めてUbuntuをインストールから試してみたが、aptやdpkgの資料が豊富なお陰で特にパッケージ周りで躓くこともなく、すんなりとUbuntuの世界観に入れたと思う。
Androidのリバースエンジニアリング関連メモ。
参考:
インストールされたAPKファイルをバックアップする手法のメモ。
アストロファイルマネージャ独自の「アプリケーションマネージャー」からAPKファイルをSDカード内に保存できる。さらにバックアップしたAPKファイルから再インストールすることも可能。
ファイルマネージャとしても高評価なオススメアプリ。
まずAndroidのshellに入れる環境を用意する。次のいずれかになると思う。
1. パッケージの一覧を取得
$ pm list packages package:com.google.android.location ...
2. パッケージからAPKファイルのフルパスを取得
$ pm path com.google.android.location package:/system/app/NetworkLocation.apk
あとは"adb pull"コマンドなどを使って適当な場所にコピーすれば良い。
adb pull /system/app/NetworkLocation.apk
"/system/app/"以下は"o+r"になっているので、shellユーザでも他のユーザでもread可能となっている。
なお、引数なしで"pm"を実行するとヘルプが表示される.
JavaScriptのエスケープを意識する箇所:
a. document.write(...); b. jQuery : $('#id').text(...); c. jQuery : $('#id').html(...); d. JSON : { "key" : "..." }
まだまとめきれてません:
参考:
document.write()は最近見かけなくなったとはいえ、jQueryの場合だけでも、正直頭が痛くなってきます。
$('#id').text('<?php echo htmlspecialchars($_GET['data'], ENT_QUOTES); ?>');
とすると二重エスケープになってしまいます。なので
$('#id').text('<?php echo $_GET['data']; ?>');
としてしまいますと、"</script>"などの閉じタグが入り込んでしまうとブロックが閉じてしまいます。
結果、
$('#id').html('<?php echo htmlspecialchars($_GET['data'], ENT_QUOTES); ?>');
としないと安心できません(=安全、と断言できるレベルではまだ無い)。
しかしそうなってくると、そもそもjQueryのhtml()でHTMLブロックをごそっと突っ込む機能自体が要らないのではないか、という気もしてきます。
つまり入力に含まれるHTMLタグは、エスケープされて表示されるべきということを徹底し、HTML要素を組み立てる必要があれば、DOM要素を1つずつ組み立てていく方が安心できます。とはいえ、過剰エスケープを抑制するためにわざわざ「エスケープをしない」jQuery.html()を使う、というのも混乱を招きそうです。
hiddenタグに出力してそれを参照すれば、少しわかりやすくなります。
<?php function h($s) { echo htmlspecialchars($s, ENT_QUOTES); } ?> <html> <head> <title>jQuery Escape Test</title> <script type="text/javascript" src="../jquery-1.6.1.min.js"></script> </head> <body> <div id="msg">dummy</div> <input type="button" value="act1" onclick="act1()" /> <input type="button" value="act2" onclick="act2()" /> <input type="hidden" name="data" id="data" value="<?php h('<b>bold</b>'); ?>" /> <script type="text/javascript"> function act1() { $('#msg').text($('#data').val()); } function act2() { $('#msg').html($('#data').val()); } </script> </body> </html>
これならばjQuery.text()で過剰エスケープはされませんでした。jQuery.html()ではちゃんと<b>が効いて太字になってくれます。
ユーザ入力を(なんのチェックも無しに)jQuery.html()に渡すことは無いと思いますので("<script>とか含まれてたら動いてしまう)、hiddenに出力してjQuery.text()で出力、という方式は比較的安定していると思います。エスケープを考慮するレイヤーがHTMLレイヤーだけにとどまり、JavaScriptの構文解析レイヤーを気にしなくて良いのでわかりやすいです。
Mercurialで管理されてるOSSを調べようと思って、Mercurialを使い始めた。
感想:思ってたよりも難しくはなかった。
ぶっちゃけpullとかpushに対して「めんどくさそう」で手を付けなかったのがあるのだけれど、Mercurialのガイドとかの構成が練られているのだろうか、結構すんなりとMercurialの世界観に馴染むことが出来た。
Windows用のバイナリが、コマンドラインツールであってもMSYSとかCygwin無しで使えるのが助かる。TortoiseHGはまだ触ってない。
Subversionに慣れていれば、バージョン管理系のコマンドはよく似てるので違和感を感じない。あとは分散型ならではのpull/push/mergeについて慣れるだけ。
それと、Subversionでは明示的に"tags"とか"branches"とかディレクトリ作ってツリーを管理しないとだったんだけれど、Mercurialではそんな必要無くてbranchやtagをバンバン作れるようになってる。
とりあえず今日一日の練習で大分手に馴染んだ。