Wall of Text #2: Copy protection

คำถามที่สองถามว่า จะเขียนแอพ Android ป้องกันไม่ให้คน Crack ได้ไหม?

คำตอบคือ It depends

อืม ตอบแบบนี้เปลี่ยนอาชีพเป็น consult เลย…

Depends ยังไง คำตอบคือเราสามารถใช้ Google Play Licensing API เพื่อเช็คได้ว่าผู้ใช้งานซื้อแอพเราหรือยัง

แต่ถ้าเราเช็คในแอพ ปัญหาที่ตามมาคือมันถูกเจาะได้ 2 ท่า

  1. ปลอม response จาก Google Play ให้บอกว่ามีแอพแล้ว (คล้ายๆ iAP Cracker ใน iOS)
  2. ถ้าเราเช็ค 1 อย่างดีแล้ว cracker ก็จะ recompile app เราใหม่โดยลบ check ออก

วิธีเดียวที่จะปลอดภัยคือย้าย check นี้ไปรันบน server ของเราเวลาเราขอให้ server ทำอะไรบางอย่าง

ถ้าไม่มี license ก็ปฏิเสธ ไม่ทำให้

แต่ไม่ใช่ทุกแอพจะสามารถทำแบบนี้ได้ เพราะต้องมี server และ server ต้องทำอะไรบางอย่างด้วย ไม่ใช่แค่ยิงไป check license บน server อย่างเดียว แบบนี้โดนถอดโค้ดแบบข้อ 2 แน่นอน

ตัวอย่างการใช้ server เช่น

  1. Music Game ขายเพลงเป็น In app purchase เวลาจะกดโหลดเพลงฝั่ง server จะต้องเช็ค Licensing ก่อนถึงจะเอาไฟล์เพลงไปให้โหลดได้
  2. แอพที่มี Cloud backup อาจจะล็อคไม่ให้ Cloud backup ได้ (แต่ก็ยัง crack ใช้ feature อื่นๆ ได้อยู่ดี)
  3. ระบบ Social เช่น WhatApps ตอน Login ก็ส่ง Licensing status ไปด้วยเลย ถ้าไม่ซื้อ Login ไม่ได้

แอพที่ทำงานเป็น offline อย่างเดียว ก็ทำอะไรไม่ได้เท่าไรนัก เช่นแอพ Keyboard หรือแอพกล้องถ่ายรูป

วิธีหนึ่งที่พอจะช่วยได้คือใช้โปรแกรมประเภท Obfuscator เพื่อทำให้โค้ดโปรแกรมที่ถอดออกมาแล้วอ่านไม่ออก จะได้ลบ check ได้ยากขึ้น แต่ก็เป็นแค่วิธีถ่วงเวลาเท่านั้นไม่ได้สามารถป้องกันการ crack ได้ 100%

myHTC

หลายเดือนก่อน HTC Thailand เปิดตัว HTC Desire ซึ่งมาพร้อมกับโปรแกรม myHTC ซึ่งเอาไว้แข่งกับ BB โดยเฉพาะ ปรากฎว่าเขาเขียนไว้ชัดเจนว่าเฉพาะเครื่องศูนย์ประเทศไทยเท่านั้น ผมเองเลยสงสัยว่า ผมอยากได้ Nexus One เนี่ย ศูนย์ไม่เอามาขายเอง งั้นผมก็ hack ซะ ก็เลยดาวน์โหลดมาติดตั้ง โดยโหลดจาก [myhtcsite.com/apk](http://myhtcsite.com/apk)

หลังจากติดตั้งเสร็จแล้ว มันเป็น widget ก็ add ไปตามปกติครับ

เพิ่ม Widget

ใส่ไปปุ๊บ ก็ขึ้นหน้านี้ทันที

หน้าลงทะเบียน

จริงๆ ผมหา Shop ID จากเว็บนึงที่เค้าไม่ให้แจกได้นะครับ แต่ถึงใส่เข้าไปก็จริงแต่…

Error

ดังนั้น ในเมื่อเข้าประตูหน้าไม่ได้ ก็ต้องประตูหลังครับ

adb shell
sqlite3 /data/data/com.js.htc/databases/myhtc

*อ้าว เฮ้ย Java เค้าให้ใช้แพคเกจตามโดเมนที่ตัวเองเป็นเจ้าของนะครับ นี่มันอะไรใช้โดเมนคนอื่น คุณภาพระดับนี้ Market ไม่รับแน่ๆ ถึงไม่ยอมให้ device อื่นใช้*

sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE tbads (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,add_id NUMERIC ,ad_desc TEXT,ad_count INTEGER DEFAULT 0 ,ad_max INTEGER DEFAULT 0 ,ad_promo TEXT,appg_id INTEGER, ad_click INTEGER DEFAULT 0, ad_promotype INTEGER DEFAULT 0, ad_expire DATETIME);
CREATE TABLE tbapps (app_id INTEGER PRIMARY KEY NOT NULL , app_name VARCHAR(100), app_desc VARCHAR(200), app_thumb VARCHAR(50), appg_id INTEGER, app_package VARCHAR(100), app_rev INTEGER, app_vername VARCHAR(15), app_status INTEGER);
CREATE TABLE tbdevice (shop_id VARCHAR(20), pincode VARCHAR(20), age INTEGER, genger INTEGER, lastsync_app DATETIME);

อ๊ะ tbdevice น่าสนใจ ไหนลอง

sqlite> .dump tbdevice
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE tbdevice (shop_id VARCHAR(20), pincode VARCHAR(20), age INTEGER, genger INTEGER, lastsync_app DATETIME);
COMMIT;

ไม่มีอะไรเลย ไม่เป็นไร ยัดไปเลยดีกว่า

sqlite> INSERT INTO tbdevice VALUES(“omgwtflolroflcopters”, “M79AKAC4”, 0, 0, NULL);
sqlite> .quit

แล้วก็ add widget ไปอีกที…

แจ่มมม !!

Chat ได้ด้วย

ปัญหาคือ ผมขอให้เพื่อนที่ใช้ Tattoo add เข้ามา ปรากฎว่าใช้ไม่ได้ ก็เลยไปนั่งแกะทาง backend อยู่นาน จนได้ pin มาอันนึง แต่มันทำกี่ที่ได้เลขเดิมเพราะมันล็อคกับ IMEI ครับ วิธีการที่หาคือ ผมติดตั้ง proxy server ไว้ใน server โดยเลือก privoxy จากนั้นให้มัน log request เต็มรูปแบบ แล้วผมก็กด register จะได้ URL มา ผมก็นั่งเดาอยู่นาน จนพิมพ์ผิดทำให้ argument ตกหายไปหมด ทีนี้ดันได้พินออกมา -*- (เจ๋งจริงๆ security เทพสุดในสามโลก)

ครั้นแล้ว ยังไม่สะใจ เอางี้ดีกว่า..

อ๋อ ได้…

sqlite> UPDATE tbdevice SET pincode=”S0000001″;
sqlite> .quit

(เวลาทำ อย่าลืม kill ตัว myHTC ทิ้งก่อนนะครับ ผมไม่นิยม task manager ก็ใช้ปุ่ม force stop ใน applications setting ได้)

ดี สม

(เนื่องจากว่าผมไม่ได้ต่อผ่าน proxy อะไรเลยไม่อยากแก้อะไรนะครับ ถ้าหาได้แล้วเดี๋ยวอาจจะเอา @petdo ใส่แทนเห็นคล้ายๆ กัน ;P)

เรื่องนี้สอนให้รู้ว่า Login ต้องมีรหัสเสมอนะครับ และ อย่าเชื่่อ user ^^

ปล. myHTC ใช้ polling อะ ผมว่าเด็กป. 6 ก็วางระบบระดับนี้ได้นะ (ใช้คำว่า วาง ไม่ใช่ เขียน แต่ถ้ารู้จักการใช้ภาษาต่างๆ แล้วง่ายนิดเดียว) สากลโลกเค้าใช้ socket กันแล้วคร๊าบบ

ปล2. จริงๆ แล้วสามารถเปลี่ยนเป็น PIN ใครก็ได้นะครับ จะได้ contact กับ status เค้ามาด้วยเลย เรียกได้ว่าแค่ใส่ pin เข้าไปก็ปลอมตัวได้แล้ว แจ่มไหมหละ