<![CDATA[Latest posts for the topic "Dịch ngược APK để so sánh WeChat và Zalo"]]> /hvaonline/posts/list/36.html JForum - http://www.jforum.net Dịch ngược APK để so sánh WeChat và Zalo
  • 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ụ:
    1. 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:
    ./jd-gui
    Kết quả:
    Mã nguồn rất tuyệt và dễ đọc hơn java bytecode gấp 10000 lần :D 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 :D, 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 .. ]]>
    /hvaonline/posts/list/44782.html#276065 /hvaonline/posts/list/44782.html#276065 GMT
    Dịch ngược APK để so sánh WeChat và Zalo 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]]>
    /hvaonline/posts/list/44782.html#276069 /hvaonline/posts/list/44782.html#276069 GMT
    Dịch ngược APK để so sánh WeChat và Zalo /hvaonline/posts/list/44782.html#276093 /hvaonline/posts/list/44782.html#276093 GMT Dịch ngược APK để so sánh WeChat và Zalo /hvaonline/posts/list/44782.html#276096 /hvaonline/posts/list/44782.html#276096 GMT Dịch ngược APK để so sánh WeChat và Zalo /hvaonline/posts/list/44782.html#276101 /hvaonline/posts/list/44782.html#276101 GMT Dịch ngược APK để so sánh WeChat và Zalo /hvaonline/posts/list/44782.html#276104 /hvaonline/posts/list/44782.html#276104 GMT Dịch ngược APK để so sánh WeChat và Zalo

    namnx wrote:
    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.  
    Cảm ơn đóng góp của anh namnx, mục đích của mình là so sánh ứng dụng Android xem có xài source của nhau không, còn phần back-end thì chưa có ý kiến và cũng chỉ có thể phán đoán qua các gói tin chứ không thể kết luận được. @TQN: source sau khi extract em có upload đó :D cảm ơn nhiều nếu anh giúp đỡ, cũng sẽ thử SourceInsight xem sao. @logichvaonline: thường thì bạn phải root máy mới chui vào dc /data/app, có thể xài các "root explorer" app hoặc adb ( xài lệnh adb pull ) Mình rất hoan nghênh và cảm ơn các bạn có đóng góp tiếp tục phân tích 2 ứng dụng này. ]]>
    /hvaonline/posts/list/44782.html#276106 /hvaonline/posts/list/44782.html#276106 GMT
    Dịch ngược APK để so sánh WeChat và Zalo /hvaonline/posts/list/44782.html#276108 /hvaonline/posts/list/44782.html#276108 GMT Dịch ngược APK để so sánh WeChat và Zalo

    namnx wrote:
    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.  
    Cái này vụ backend và frontend thì công nhận là đúng. Tuy nhiên phần lớn các đồng chí trên mạng đều nói từ Zing me tới Zalo đều là lấy mã nguồn của Tàu vì nhìn bề ngoài nó ... giống giống sản phẩm tương tự của Tencent. Mấy hôm trước có cái slide nhắc tới hạ tầng đằng sau zalo, nếu loại trừ bớt các yếu tố PR thì chắc cũng dựa trên một phần sự thật www.slideshare.net/Zalo_app/inside-zalo-developing-a-mobile-messenger-for-the-audience-of-millions-vn-mobile-day-2013]]>
    /hvaonline/posts/list/44782.html#276112 /hvaonline/posts/list/44782.html#276112 GMT
    Dịch ngược APK để so sánh WeChat và Zalo 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.   File APK không cần phải chuyển qua JAR đâu bạn ơi Định dạng của APK vốn là của PKZIP Nên chỉ cần đổi extension từ APK sang ZIP là được]]> /hvaonline/posts/list/44782.html#276165 /hvaonline/posts/list/44782.html#276165 GMT