[Analyzing] Dịch ngược APK để so sánh WeChat và Zalo |
28/05/2013 21:17:34 (+0700) | #1 | 276065 |
|
WinDak
Researcher
|
Joined: 27/01/2002 11:15:00
Messages: 223
Offline
|
|
Gần đây có một người bạn nhờ tôi kiểm tra xem WeChat – một ứng dụng Android (Android App) của tàu khựa có liên hệ gì với Zalo sản phẩm có tính năng tương tự của Việt Nam, do hãng VNG sản xuất hay không. Chưa từng reverse Android App nên tôi cũng mày mò và tranh thủ học hỏi thêm. Bài viết này nhằm 2 mục đích:
- Giới thiệu và thảo luận phương pháp và một số công cụ reverse một Android App
- Thảo luận và so sánh WeChat và Zalo, về các mặt: mã nguồn, vấn đề bảo mật người dùng, các tính năng có thể nguy hại đến người dùng
Phần 1: Dịch ngược:
Để bắt đầu thì trong bài viết này tôi sử dụng 2 file apk sau cho 2 ứng dụng:
- WeChat: http://dl.dropbox.com/u/11027388/WeChat_4.5.apk
- Zalo : http://dl.dropbox.com/u/11027388/Zalo_1.0.8.apk
File APK chính là file thực thi của một ứng dụng Android, nó thực ra là một file đóng gói của ngôn ngữ Java mà hệ điều hành Android có thể đọc được và thực thi trong môi trường HDH Android.
Khi cài đặt 1 ứng dụng từ google play, file apk sẽ nằm trong thư mục /data/app trong máy ( bài tập cho bạn: làm sao lấy được nó ra khỏi máy ? )
Sau khi lấy được 2 file này, chúng ta cần một số công cụ để dịch ngược file apk thành file java ban đầu. Để làm việc này tôi sử dụng 2 công cụ:
- dex2jar : https://code.google.com/p/dex2jar/
- jd-gui : http://java.decompiler.free.fr/?q=jdgui
Công cụ (1) giúp chuyển tập tin apk thành định dạng “jar” (Java Archive) một file đóng gói khác của java.
Code:
dex2jar.sh Zalo_1.0.8.apk
ls
Zalo_1.0.8.jar
Tuy nhiên trong file .jar chỉ toàn là java bytescode gồm các mã lệnh dưới dạng binary của java, rất khó để đọc vì vậy tôi đã sử dụng tiếp chương trình (2).
Code:
Kết quả:
Mã nguồn rất tuyệt và dễ đọc hơn java bytecode gấp 10000 lần
Tuy nhiên ta còn một vấn đề nhỏ. Trong quá trình đóng gói ứng dụng, 1 số thông tin của các hàm, biến v.v... đã bị xóa khỏi ứng dụng, vì mục đích obfuscation (làm cho khó đọc). Chính vì thế ta thấy rất nhiều các file a,b,c,d … .java xuất hiện như trên hình.
Để đỡ rối khi đọc, tạm thời tôi di chuyển các file chưa xác định tên tuổi này vào 1 package gọi là “unk” (nghĩa là chưa biết). Một đoạn ruby script nhỏ sẽ giúp ta làm điều này.
Code:
`mkdir unk 2>/dev/null`
Dir.glob("**/*").select { |f| not File.dirname(f) =~ /^unk/ and File.basename(f) =~ /^[a-z]{0,3}\.java$/}.each do |f|
puts f
content = open(f).read().sub("package ", "package unk.")
open(f,"w").write(content)
`mkdir -p unk/#{File.dirname(f)} 2>/dev/null`
`mv #{f} unk/#{f}`
end
Ngoài ra tôi cũng sử dụng thêm công cụ apktool tại https://code.google.com/p/android-apktool/ để thực hiện việc lấy các thông tin về resources của ứng dụng android. (Apktool cũng sẽ convert các file byte code thành dạng smalli và ta cũng có thể sử dụng để hiểu thêm về ứng dụng)
Toàn bộ quá trình trên sau khi hoàn tất tôi đã đưa kết quả lên github cho các bạn nếu thích thì tìm hiểu cùng:
- WeChat: https://github.com/danghvu/WeChatRE
- Zalo: https://github.com/danghvu/ZaloRE
( Kết quả của apktool nằm trong src/resources/* )
Phần 2: So sánh mã nguồn
Để so sánh mã nguồn 2 chương trình này, tôi sử dụng gói ứng dụng PMD: http://pmd.sourceforge.net/
Gói ứng dụng PMD có kèm theo 1 chương trình cho phép kiểm tra các đoạn code copy & paste của các file source code trong cùng 1 thư mục. Tôi tiến hành copy file source của Zalo và WeChat vào cùng 1 thư mục và thực hiện:
Code:
./bin/run.sh cpd --minimum-tokens 50 --files ./src/ --language java
( cpd là công cụ “copy-paste-detector”, minimum-token xác định độ dài tối thiểu của đoạn mã cần so sánh. )
Output của chương trình ra giống như sau:
Code:
Found a 257 line (1735 tokens) duplication in the following files:
Starting at line 278 of ./src/ZaloRE/src/unk/com/zing/zalo/utils/a.java
Starting at line 545 of ./src/ZaloRE/src/unk/com/zing/zalo/e/a.java
qC = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145 };
int[] arrayOfInt1 = new int[256];
arrayOfInt1[0] = -1520213050;
arrayOfInt1[1] = -2072216328;
….
=====================================================================
Found a 177 line (1211 tokens) duplication in the following files:
Starting at line 663 of ./src/WeChat/com/tencent/qqpim/dao/SYSSmsDaoV2.java
Starting at line 585 of ./src/WeChat/com/tencent/qqpim/dao/SYSSmsDaoV1.java
...
Kông tốt lắm vì cpd không so sánh 2 bộ mã nguồn mà chỉ có so sánh trong cùng một bộ tuy vậy ta có thể làm được điều mình muốn bằng một thủ thuật nhỏ đó là tìm những file giống nhau trong 2 folder khác nhau từ output của chương trình.
Tiếp tục luyện kungfu ruby script:
Code:
zalo = wechat = found = nil
File.open(ARGV[0]).each_line do |line|
if line =~ /^=+$/
puts "#{found}#{zalo}#{wechat}\n" if (zalo and wechat)
found = zalo = wechat = nil
end
found = line if line =~ /Found/
zalo = line if line =~ /Zalo/
wechat = line if line =~ /WeChat/
end
puts "#{found}#{zalo}#{wechat}\n" if (zalo and wechat)
Sau khi chạy script trên với output phần trước thì ta thấy cpd đã tìm ra được tổng cộng 7 tập tin sau đây có sự trùng lặp giữa mã nguồn của Zalo và WeChat =]]]]
(Các file dưới đây các bạn có thể xem tại github mình đã up lên ở phía trên, ví dụ file đầu tiên có thể xem ở https://github.com/danghvu/ZaloRE/blob/master/src/com/facebook/android/Util.java)
Code:
Found a 10 line (86 tokens) duplication in the following files:
Starting at line 131 of ./src/ZaloRE/src/com/facebook/android/Util.java
Starting at line 62 of ./src/WeChat/src/unk/com/tencent/mm/ui/facebook/a/m.java
Found a 5 line (70 tokens) duplication in the following files:
Starting at line 87 of ./src/ZaloRE/src/unk/com/a/b/e.java
Starting at line 155 of ./src/WeChat/src/unk/com/tencent/mm/sdk/platformtools/bg.java
Found a 5 line (69 tokens) duplication in the following files:
Starting at line 87 of ./src/ZaloRE/src/unk/com/a/b/e.java
Starting at line 562 of ./src/WeChat/src/unk/com/tencent/mm/platformtools/bf.java
Found a 16 line (65 tokens) duplication in the following files:
Starting at line 81 of ./src/ZaloRE/src/unk/com/zing/zalo/uicontrol/w.java
Starting at line 55 of ./src/WeChat/src/unk/com/tencent/mm/modelemoji/l.java
Found a 11 line (59 tokens) duplication in the following files:
Starting at line 21 of ./src/ZaloRE/src/me/zing/vn/gl/FilterGLSurfaceView$ConfigChooser.java
Starting at line 21 of ./src/WeChat/src/unk/com/badlogic/gdx/backends/android/w.java
Found a 13 line (59 tokens) duplication in the following files:
Starting at line 161 of ./src/ZaloRE/src/com/zing/zalo/uicontrol/HorizontalPager.java
Starting at line 148 of ./src/WeChat/src/com/tencent/mm/ui/base/MMFlipper.java
Found a 16 line (55 tokens) duplication in the following files:
Starting at line 12 of ./src/ZaloRE/src/unk/com/zing/zalo/plugin/a.java
Starting at line 36 of ./src/WeChat/src/com/android/internal/telephony/ISms$Stub.java
Hm.. liệu Zalo có ăn cắp mã của WeChat / ngược lại ? Tôi cẩn thận xem xét từng file và nhận thấy những đoạn code giống nhau là từ những mã nguồn của các thư viện mở mà 2 ứng dụng này cùng sử dụng.
Lấy ví dụ, ta thử so sánh:
Code:
Starting at line 131 of ./src/ZaloRE/src/com/facebook/android/Util.java
Starting at line 62 of ./src/WeChat/src/unk/com/tencent/mm/ui/facebook/a/m.java
if (!paramBundle.containsKey("method")) "
paramBundle.putString("method", paramString2);
if (paramBundle.containsKey("access_token"))
paramBundle.putString("access_token", URLDecoder.decode(paramBundle.getString("access_token")));
localHttpURLConnection.setRequestMethod("POST");
localHttpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f");
localHttpURLConnection.setDoOutput(true);
localHttpURLConnection.setDoInput(true);
localHttpURLConnection.setRequestProperty("Connection", "Keep-Alive");
localHttpURLConnection.connect();
Đây là một đoạn xử lý khi ứng dụng muốn gửi 1 request lên ứng dụng facebook ( vì Zalo và WeChat đều có facebook integration ) nằm trong bộ Facebook-Sdk (File version nằm ở src/com/facebook/FacebookSdkVersion.java )
Một điều thú vị nữa khi đọc đoạn code này là dường như cả Zalo và WeChat đều không sử dụng giao thức HTTPS , bởi vì cả 2 cùng sử dụng “HttpURLConnection” thay vì "HttpsURLConnection” , attacker có thể dễ dàng “sniff” các gói tin … Để khẳng định điều này chúng ta sẽ sniff packet của Zalo và WeChat để so sánh, nhưng xin hẹn lại dịp sau.
Kết luận của tôi tạm thời hiện nay qua việc kiểm tra mã nguồn thì tuy có 1 số trùng lặp trong code nhưng điều đó chưa chứng tỏ được Zalo có sử dụng mã nguổn sao chép từ WeChat.
Để khẳng định rõ hơn nữa thì cần phải tiếp tục rà soát các yếu tố trong các tính năng chính của cả 2 bên, phần bộ nhớ lúc thực thi (phần sau sẽ hướng dẫn sử dụng debugger cho android) và các phần mã bị làm rối mà jd-gui không dịch ngược lại được. ( Chẳng hạn : WeChat/src/unk/com/tencent/mm/sdk/platformtools/bg.java :1272 )
To be continue ..
|
|
-- w~ -- |
|
|
|
[Analyzing] Dịch ngược APK để so sánh WeChat và Zalo |
29/05/2013 02:37:32 (+0700) | #2 | 276069 |
|
xnohat
Moderator
|
Joined: 30/01/2005 13:59:19
Messages: 1210
Location: /dev/null
Offline
|
|
Về vụ sniff dữ liệu của Zalo và Wechat thì đã test rồi nghen. Hai thằng hành động khá khác nhau
Wechat thì submit contact list của user lên server ngay sau khi mở App
Code:
POST /cgi-bin/micromsg-bin/uploadmcontact HTTP/1.1
Accept: */*
User-Agent: Mozilla/4.0
Content-Type: application/x-www-form-urlencoded
Host: hkshort.weixin.qq.com
Content-Length: 1032
....
Zalo thì down contact list đã submit trước đó theo JSON format về ngay sau khi mở App ( mền chưa chưa chụp được packet đoạn submit contact list lên server, sẽ gửi lên sau )
Code:
{"error_code":0,"error_message":"Successful.","data":[{"userId":102282593,"username":"t_m7e07m90f0","displayName":"Lan XXX","avatar":"http://avatar.talk.zdn.vn/d/b/1/2/0/75/ea334590xxxx094f346084a16.jpg","gender":1,"dob":50xxx00,"phoneNumber":"+849xxxxxx" ...
Hề hề nhờ Zalo, Wechat không dùng HTTPS connection nên có vẻ mền có thể lấy khá nhiều contact của user một cách dễ dàng :v |
|
iJust clear, "What I need to do and how to do it"/i
br
brBox tán gẫu dời về: http://www.facebook.com/hvaonline |
|
|
|
[Analyzing] Dịch ngược APK để so sánh WeChat và Zalo |
29/05/2013 13:25:52 (+0700) | #3 | 276093 |
|
sieeuquay
Member
|
0 |
|
|
Joined: 02/05/2010 01:35:51
Messages: 4
Offline
|
|
Có thể do HTTPS tốn thời gian handshake nên bị bỏ qua, nhất là trên môi người 3G.
Các file trùng lặp mà a WinDak đưa ra em thấy phần lớn là render img, chỗ facebook thì gần như các app đều viết vậy.
Rất hi vọng a WinDak làm rõ để cộng đồng có câu trả lời rõ ràng về việc zalo có phải do người việt chúng ta viết ? (1 điều rất đáng quý) hay chỉ là 1 sp được việt hoá lại.
|
|
|
|
|
[Analyzing] Dịch ngược APK để so sánh WeChat và Zalo |
29/05/2013 14:30:56 (+0700) | #4 | 276096 |
namnx
Member
|
0 |
|
|
Joined: 09/07/2006 01:22:18
Messages: 5
Offline
|
|
Theo mình nghĩ thì việc xác định 2 sản phẩm này có dùng mã nguồn của nhau không bằng cách reverse 2 file APK thì khó mà chính xác được. 2 sản phẩm này đều có 2 phần là front-end (app trên smartphone) và back-end. Mình nghĩ rằng đối với những sản phẩm như Zalo và WeChat, bằng back-end sẽ nặng và phức tạp hơn nhiều so với phần front-end. Còn phần back-end được phát triển như thế nào chỉ có những người phát triển nó mới biết, người ngoài thì khó mà biết được.
Do đó chỉ có reverse 2 app này để kết luận thì hơi... thiếu chính xác.
|
|
-namnx |
|
|
|
[Analyzing] Dịch ngược APK để so sánh WeChat và Zalo |
29/05/2013 16:09:57 (+0700) | #5 | 276101 |
TQN
Elite Member
|
0 |
|
|
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
|
|
Em thì từ lúc đầu, dùng SourceInsight để xây dựng lưu đồ, block, workflow... gì đó tá lã của 2 thằng, rồi các block nào tương đương thì nhảy vào đọc code
|
|
|
[Analyzing] Dịch ngược APK để so sánh WeChat và Zalo |
29/05/2013 16:58:40 (+0700) | #6 | 276104 |
logichvaonline
Member
|
0 |
|
|
Joined: 20/04/2013 21:41:45
Messages: 2
Offline
|
|
Em root máy android của em rồi thì có thể dùng ứng dụng explorer nào đó để lấy file đó ra phải không ạ? Còn chưa root thì chắc là dùng android adb nhưng em không rõ như thế nào |
|
|
|