บทความเป็นการอธิบายขั้นตอนในกระบวนการติดตั้งและใช้งานโปรแกรม Frida บนอุปกรณ์ Android ที่มีขั้นตอนเช่นการตรวจสอบสถาปัตยกรรม CPU, จับคู่สถาปัตยกรรม CPU กับการดาวน์โหลด, ดาวน์โหลดและแตกไฟล์ .xz, คัดลอกไฟล์เข้าสู่อุปกรณ์ Android, และเริ่มต้นเซิร์ฟเวอร์ Frida บนอุปกรณ์ Android ผ่าน Script python ที่ชื่อว่า LazyFrida เพื่อช่วยในการทำเจาะระบบ Application บน Android (Android Mobile Application Penetration Test) เร็วขึ้นและสะดวกมากยิ่งขึ้น
Warunyou Sunpachit และ Boonperm Mark
Cybersecurity consultant
คำสั่งรวดเดียวในการติดตั้ง
คำสั่งนี้ใช้สำหรับการเตรียมการ Download Frida และ Frida Server จาก https://github.com/frida/frida/releases เรียบร้อยแล้ว
adb push frida-server /data/local/tmp && adb shell "su -c 'chmod 755 /data/local/tmp/frida-server && ./data/local/tmp/frida-server &'"
คำสั่งดังกล่าวเป็นคำสั่งที่ใช้ในการส่งและเริ่มต้นการทำงานของเซิร์ฟเวอร์ของเครื่องมือ Frida ในอุปกรณ์ Android ผ่าน adb (Android Debug Bridge) และใช้สิทธิ์ root เพื่อเปิดใช้งานเซิร์ฟเวอร์นั้นในพื้นที่ /data/local/tmp
อธิบายได้ดังนี้:
adb push frida-server /data/local/tmp
– คำสั่งนี้จะส่งไฟล์frida-server
ไปยังพาธ/data/local/tmp
ในอุปกรณ์ Android โดยใช้ adbadb shell "su -c 'chmod 755 /data/local/tmp/frida-server && ./data/local/tmp/frida-server &'"
– คำสั่งนี้จะทำการเรียกใช้ adb shell เพื่อใช้สิทธิ์ root (su -c
) และดำเนินการทำงานในอุปกรณ์ Android คำสั่งที่ดำเนินการภายในคำสั่งsu -c
คือchmod 755 /data/local/tmp/frida-server
ที่ใช้เปลี่ยนสิทธิ์การเข้าถึงของไฟล์frida-server
เป็น 755 (อ่าน, เขียน, และเรียกใช้ได้ สำหรับเจ้าของไฟล์) และ./data/local/tmp/frida-server &
ที่ใช้เริ่มต้นการทำงานของfrida-server
ในพื้นที่/data/local/tmp
โดยใช้&
เพื่อให้โปรแกรมทำงานในพื้นหลัง (Background process)
สำหรับท่านที่มีปัญหาการติดตั้ง หรือความสะดวกในการติดตั้ง Frida และ Frida-server สำหรับ Android สามารถใช้งาน Script ดังนี้
LazyFrida
อุปกรณ์จัดเตรียม
- เครื่อง Android Device ที่ Root เรียบร้อยแล้ว
- เปิด USB debugging แล้ว (แต่ละเครื่องอาจการเข้าเมนู Developer options ไม่เหมือนกัน)
- สาย USB
- ลง Python3
- ลง PIP
ตัวอย่างการใช้งาน
สำหรับคำสั่งรวดเดียวตั้งแต่ดาวน์โหลดติดตั้งเชื่อมต่อสามารถใช้งาน LazyFrida ดังนี้
ตัวอย่างการใช้งาน Command เพื่อติดตั้ง Frida
python3 lazyfrida.py install-frida
ตัวอย่างทดสอบการเชื่อมต่อ
python lazyfrida.py -q runn
ดูตัวอย่างการใช้งานอื่น ๆ
positional arguments:
{install-frida,install-cert,patch-apk}
installation commands
install-frida installs frida and frida-server on Android
install-cert installs CA Burp suite certificate
defines [ip] of Burp Suite: default: 127.0.0.1
patch-apk installs frida gadget to apk
options:
-h, --help show this help message and exit
-q [QUERY ...], --query [QUERY ...]
connects to frida server and accepts multiple parameters.
potential parameters: apps, proc, runn
-u USB_PROXY [USB_PROXY ...], --usb-proxy USB_PROXY [USB_PROXY ...]
start and stop the usb proxy
potential parameters: start, stop
-f FRIDA [FRIDA ...], --frida FRIDA [FRIDA ...]
start, stop, check version of frida server
potential parameters: start, stop, version

อธิบายการทำงานที่สำคัญ
ติดตั้ง Frida-Tools ลงเครื่อง Computer
ฟังก์ชัน install_or_upgrade_frida_tools()
ใช้ในการติดตั้งหรืออัปเกรดเครื่องมือ Frida-tools ผ่านการใช้งานคำสั่ง pip
ใน Python.
def install_or_upgrade_frida_tools(): print_green("\nStart installing or upgrading frida-tools...") try: subprocess.check_call(['pip', 'install', '--index-url=https://pypi.python.org/simple/', '--upgrade', 'frida-tools']) print_green("Frida-tools installed or upgraded successfully.") return True except subprocess.CalledProcessError as e: print_red("Failed to install or upgrade Frida-tools. Error:", e) return False
ฟังก์ชันนี้จะดำเนินการดังนี้:
- ใช้
subprocess.check_call()
เพื่อเรียกใช้คำสั่งpip install --index-url=https://pypi.python.org/simple/ --upgrade frida-tools
เพื่อติดตั้งหรืออัปเกรด Frida-tools - ถ้าการดำเนินการเสร็จสมบูรณ์และไม่เกิดข้อผิดพลาด (ไม่เกิด
subprocess.CalledProcessError
) ฟังก์ชันจะพิมพ์ข้อความสีเขียวเพื่อแสดงว่า Frida-tools ได้ถูกติดตั้งหรืออัปเกรดสำเร็จแล้ว และจะคืนค่าTrue
- ถ้าการดำเนินการล้มเหลวหรือเกิดข้อผิดพลาด (เกิด
subprocess.CalledProcessError
) ฟังก์ชันจะพิมพ์ข้อความสีแดงเพื่อแสดงว่าไม่สามารถติดตั้งหรืออัปเกรด Frida-tools ได้ พร้อมกับแสดงข้อความข้อผิดพลาด และจะคืนค่าFalse
ฟังก์ชันนี้จำเป็นต้องมี import subprocess
และฟังก์ชัน print_green()
และ print_red()
เพื่อแสดงข้อความสีเขียวและสีแดงตามลำดับในส่วนของโค้ด
ตรวจสอบ CPU ของเครื่อง Android
ฟังก์ชัน check_android_cpu()
ใช้ในการตรวจสอบสถาปัตยกรรม CPU ของอุปกรณ์ Android ผ่าน adb (Android Debug Bridge).
def check_android_cpu(): print_green("\nStart checking Android CPU...") try: result = subprocess.run(['adb', 'shell', 'getprop', 'ro.product.cpu.abi'], capture_output=True, text=True) output = result.stdout.strip() if output: print("CPU Architecture:", output) return output else: print_red("Unable to retrieve CPU architecture.") return "" except FileNotFoundError: print_red("ADB is not installed or not found.") return ""
ฟังก์ชันนี้จะดำเนินการดังนี้:
- ใช้
subprocess.run()
เพื่อเรียกใช้คำสั่งadb shell getprop ro.product.cpu.abi
เพื่อรับค่าสถาปัตยกรรม CPU ของอุปกรณ์ Android - ตรวจสอบผลลัพธ์ที่ได้จากคำสั่ง ถ้ามีผลลัพธ์ (ไม่เป็นค่าว่าง) ฟังก์ชันจะพิมพ์ข้อความว่า “CPU Architecture:” ตามด้วยค่าสถาปัตยกรรม CPU และจะคืนค่าสถาปัตยกรรม CPU นั้น
- ถ้าไม่สามารถรับค่าสถาปัตยกรรม CPU ได้ ฟังก์ชันจะพิมพ์ข้อความสีแดงเพื่อแสดงว่าไม่สามารถดึงข้อมูลสถาปัตยกรรม CPU ได้ และจะคืนค่าว่างเปล่า (“”)
- หากพบข้อผิดพลาดในการรันคำสั่ง
adb
(ไม่พบไฟล์หรือโปรแกรม adb) ฟังก์ชันจะพิมพ์ข้อความสีแดงเพื่อแสดงว่า ADB ไม่ได้ติดตั้งหรือไม่พบ และจะคืนค่าว่างเปล่า (“”)
การตรวจสอบสถาปัตยกรรม CPU ที่จะดาวน์โหลด
ฟังก์ชัน match_cpu_architecture_with_download(cpu_architecture, cpu_download, selected_cpu)
ใช้ในการตรวจสอบสถาปัตยกรรม CPU ที่จะดาวน์โหลดสอดคล้องกันหรือไม่
def match_cpu_architecture_with_download(cpu_architecture, cpu_download, selected_cpu): print_green("\nStart checking architecture...") architecture_mapping = dict(zip(cpu_architecture, cpu_download)) if selected_cpu in architecture_mapping: matching_download = architecture_mapping[selected_cpu] print("The matching CPU download for '{}' is: {}".format(selected_cpu, matching_download)) return matching_download else: print_red("No matching CPU download found for '{}'.".format(selected_cpu)) return None
ฟังก์ชันนี้จะดำเนินการดังนี้:
- สร้างตัวแปล Dictionary
architecture_mapping
โดยใช้ฟังก์ชันdict(zip(cpu_architecture, cpu_download))
เพื่อผูกคู่ค่าสถาปัตยกรรม CPU กับการดาวน์โหลดที่สอดคล้องกัน - ตรวจสอบว่า
selected_cpu
อยู่ในarchitecture_mapping
หรือไม่ ถ้าใช่ ฟังก์ชันจะคืนค่าการดาวน์โหลดที่สอดคล้องกัน (matching_download
) และพิมพ์ข้อความว่า “The matching CPU download for ‘{selected_cpu}’ is: {matching_download}” - ถ้า
selected_cpu
ไม่อยู่ในarchitecture_mapping
ฟังก์ชันจะพิมพ์ข้อความสีแดงเพื่อแสดงว่าไม่พบการดาวน์โหลดที่สอดคล้องกับ CPU (selected_cpu
) ที่ระบุ และจะคืนค่าNone
ระบุสถาปัตยกรรม CPU ที่จะใช้เพื่อดาวน์โหลด
cpu_architecture = [ "armeabi-v7a", "arm64-v8a", "x86", "x86_64" ] cpu_download = [ "android-arm", "android-arm64", "android-x86", "android-x86_64" ]
ในรายการ cpu_architecture
สถาปัตยกรรม CPU แต่ละรายการจะมีการดาวน์โหลดที่สอดคล้องกันในรายการ cpu_download
โดยอ้างอิงจากลำดับที่เหมือนกันของสถาปัตยกรรม CPU ในทั้งสองรายการ ซึ่งจะช่วยในกรณีที่ต้องการเลือกรูปแบบการดาวน์โหลดที่ถูกต้องสำหรับสถาปัตยกรรม CPU ที่ระบุ.
ตรวจสอบ URL สำหรับดาวน์โหลด Frida Server
ฟังก์ชัน download_frida_server_url(architecture)
ใช้ในการตรวจสอบ URL สำหรับดาวน์โหลด Frida Server ที่สอดคล้องกับสถาปัตยกรรม CPU ที่ระบุ
def download_frida_server_url(architecture): print_green("\n---> Start checking Frida Download URL...") try: curl_command = 'curl -s https://api.github.com/repos/frida/frida/releases/latest | grep "browser_download_url.*frida-server.*{}.xz"'.format(architecture) result = subprocess.run(curl_command, capture_output=True, text=True, shell=True) output = result.stdout.strip() print(curl_command) if output: download_url = output.split('"')[3] print("Download URL:", download_url) return download_url else: return None except FileNotFoundError: print_red("curl command not found.") print_red("Unable to find the download URL for frida-server.") return None
ฟังก์ชันนี้จะดำเนินการดังนี้:
- ใช้คำสั่ง
curl
เพื่อเรียกดูข้อมูลจาก URL ของ Frida Server โดยใช้คำสั่งcurl -s https://api.github.com/repos/frida/frida/releases/latest | grep "browser_download_url.*frida-server.*{}.xz"
โดยใส่สถาปัตยกรรม CPU (architecture
) ลงในเครื่องหมาย{}
เพื่อค้นหา URL สำหรับดาวน์โหลด Frida Server ที่สอดคล้องกับสถาปัตยกรรม CPU ที่ระบุ - ดำเนินการรับผลลัพธ์จากคำสั่ง
curl
และนำมาเก็บในตัวแปรoutput
- พิมพ์คำสั่ง
curl
เพื่อแสดงให้เห็นว่าคำสั่งที่ใช้เป็นอย่างไร - ถ้ามีผลลัพธ์ (
output
) ฟังก์ชันจะดำเนินการแยก URL ดาวน์โหลด (download_url
) จากผลลัพธ์ที่ได้ โดยใช้การแบ่งสตริง" "
และเลือกตำแหน่งที่ 3 ในลิสต์ที่ได้ เพื่อรับ URL ที่แท้จริงที่ต้องการ - พิมพ์ข้อความว่า “Download URL: {download_url}” และคืนค่า
download_url
- ถ้าไม่มีผลลัพธ์ (
output
) หรือพบข้อผิดพลาดในการรันคำสั่งcurl
หรือไม่พบคำสั่งcurl
ฟังก์ชันจะพิมพ์ข้อความสีแดงเพื่อแสดงว่าไม่สามารถค้นหา URL สำหรับดาวน์โหลด Frida Server ได้ และจะคืนค่าNone
ดาวน์โหลด Frida-server
ฟังก์ชัน download_frida(url, output_path)
ใช้ในการดาวน์โหลด Frida Server จาก URL และบันทึกไฟล์ลงในพาธที่ระบุ
def download_frida(url, output_path): print_green("\nStart downloading Frida-server...") try: urllib.request.urlretrieve(url, output_path) print("File downloaded successfully.") return True except Exception as e: print_red("An error occurred while downloading the file: {}".format(str(e))) return False except KeyboardInterrupt: # Handle Ctrl+C keyboard interrupt print("\nKeyboard interrupt detected. Exiting...")
ฟังก์ชันนี้จะดำเนินการดังนี้:
- ใช้
urllib.request.urlretrieve()
เพื่อดาวน์โหลดไฟล์จาก URL และบันทึกลงในพาธที่ระบุในoutput_path
- พิมพ์ข้อความว่า “File downloaded successfully.”
- คืนค่า
True
เพื่อบ่งชี้ว่าดาวน์โหลดเสร็จสมบูรณ์
ในกรณีที่เกิดข้อผิดพลาดขึ้นระหว่างดาวน์โหลด ฟังก์ชันจะแสดงข้อความสีแดงเพื่อแสดงข้อผิดพลาดที่เกิดขึ้นและจะคืนค่า False
เพื่อบ่งชี้ว่าเกิดข้อผิดพลาดในการดาวน์โหลด
แตกไฟล์ Frida-server ที่ดาวน์โหลดมา
ฟังก์ชัน extract_xz(xz_path, extract_path)
ใช้ในการแตกไฟล์ .xz
def extract_xz(xz_path, extract_path): print_green("\nStart extracting .xz file...") try: with lzma.open(xz_path, 'rb') as xz_file: with open(extract_path, 'wb') as extract_file: extract_file.write(xz_file.read()) print("XZ file extracted successfully.") return True except Exception as e: print_red("An error occurred while extracting the XZ file: {}".format(str(e))) return False
ฟังก์ชันนี้จะดำเนินการดังนี้:
- ใช้
lzma.open()
เพื่อเปิดไฟล์ .xz (xz_path
) ในโหมดอ่านเป็นไบนารี (rb
) - ใช้
open()
เพื่อเปิดไฟล์สำหรับการแตกไฟล์ (extract_path
) ในโหมดเขียนเป็นไบนารี (wb
) - อ่านเนื้อหาจากไฟล์ .xz และเขียนเนื้อหาลงในไฟล์ที่แตกไฟล์ได้
- พิมพ์ข้อความว่า “XZ file extracted successfully.”
- คืนค่า
True
เพื่อบ่งชี้ว่าการแตกไฟล์เสร็จสมบูรณ์
ในกรณีที่เกิดข้อผิดพลาดขึ้นระหว่างการแตกไฟล์ .xz ฟังก์ชันจะแสดงข้อความสีแดงเพื่อแสดงข้อผิดพลาดที่เกิดขึ้นและจะคืนค่า False
เพื่อบ่งชี้ว่าเกิดข้อผิดพลาดในการแตกไฟล์
คัดลอกไฟล์ frida-server เข้าสู่อุปกรณ์ Android
ฟังก์ชัน copy_to_device()
ใช้ในการคัดลอกไฟล์ frida-server เข้าสู่อุปกรณ์ Android
def copy_to_device(): print_green("\nStart coppting frida-server to an android device...") try: # Push frida-server to /data/local/tmp subprocess.run(['adb', 'push', 'frida-server', '/data/local/tmp'], check=True) subprocess.run(['adb', 'shell', 'su', '-c', 'chmod +x /data/local/tmp/frida-server'], check=True) print("Frida server coppied successfully.") return True except subprocess.CalledProcessError as e: print_red("An error occurred while coppied Frida server: {}".format(str(e))) return False
ฟังก์ชันนี้จะดำเนินการดังนี้:
- ใช้
subprocess.run()
เพื่อเรียกใช้คำสั่งadb push frida-server /data/local/tmp
เพื่อคัดลอกไฟล์ frida-server เข้าสู่พาธ/data/local/tmp
ในอุปกรณ์ Android - ใช้
subprocess.run()
เพื่อเรียกใช้คำสั่งadb shell su -c chmod +x /data/local/tmp/frida-server
เพื่อกำหนดสิทธิ์การเข้าถึงและให้สามารถเรียกใช้ไฟล์ frida-server ในพาธ/data/local/tmp
ในอุปกรณ์ Android - พิมพ์ข้อความว่า “Frida server copied successfully.”
- คืนค่า
True
เพื่อบ่งชี้ว่าการคัดลอก frida-server เข้าสู่อุปกรณ์ Android เสร็จสมบูรณ์
ในกรณีที่เกิดข้อผิดพลาดขึ้นระหว่างการคัดลอก frida-server ฟังก์ชันจะแสดงข้อความสีแดงเพื่อแสดงข้อผิดพลาดที่เกิดขึ้นและจะคืนค่า False
เพื่อบ่งชี้ว่าเกิดข้อผิดพลาดในการคัดลอก frida-server
เริ่มต้นเซิร์ฟเวอร์ของ Frida
ฟังก์ชัน start_frida_server()
ใช้ในการเริ่มต้นเซิร์ฟเวอร์ของ Frida
def start_frida_server():
print_green("\nStart Frida Server...")
try:
subprocess.run(['adb', 'shell', 'su', '-c', '/data/local/tmp/frida-server &'], check=True)
print("Frida server started successfully.")
except FileNotFoundError:
print("ADB is not installed.")
except subprocess.CalledProcessError as e:
print_red("An error occurred while starting Frida server:: {}".format(str(e)))
except KeyboardInterrupt:
# Handle Ctrl+C keyboard interrupt
print("\nKeyboard interrupt detected. Exiting...")
ฟังก์ชันนี้จะดำเนินการดังนี้:
- พิมพ์ข้อความสีเขียวเพื่อแสดงข้อความว่าเริ่มต้นเซิร์ฟเวอร์ของ Frida
- ใช้
subprocess.run()
เพื่อเรียกใช้คำสั่งadb shell su -c /data/local/tmp/frida-server &
เพื่อเริ่มต้นเซิร์ฟเวอร์ของ Frida ในอุปกรณ์ Android - พิมพ์ข้อความว่า “Frida server started successfully.”
ในกรณีที่เกิดข้อผิดพลาดระหว่างเริ่มต้นเซิร์ฟเวอร์ของ Frida ฟังก์ชันจะแสดงข้อความสีแดงเพื่อแสดงข้อผิดพลาดที่เกิดขึ้น