ابزار Frida برای رمزگشایی اپهای Qt6
خلاصهٔ کاملتر
اگه تا حالا سعی کردی یه اپ Qt6 رو با ابزارهای معمول آنالیز کنی، احتمالاً به دیوار خوردی. سه چیز Qt6 رو از بقیهی اپهای دسکتاپ متمایز میکنه: QString یه رشتهی C معمولی نیست، dispatch رویدادها پشت QMetaObject::activate پنهانه، و سیمبلهای Qt مانگلشدهان در حالی که بایناری اصلی اپ معمولاً stripped هست. این مقاله با یه اپ تمرینی بهاسم HackPass این چالشها رو قدمبهقدم حل میکنه.
چالش اول: خوندن رشتههای Qt. QString متن رو بهصورت UTF-16 در حافظه نگه میداره با یه سایز جداگانه و مکانیزم copy-on-write. هیچ ابزار مبتنی بر strcmp یا strncpy اینجا کار نمیکنه. راهحل اینه که سه متد دسترسی به بافر رو هوک کنیم: constData()، data() و utf16(). این متدها هر بار که اپ محتوای یه QString رو میخونه فایر میشن.
برای پیدا کردن نام دقیق سیمبلها (که بین بیلدهای مختلف Qt فرق دارن)، اسکریپت qt-discover.js ماژول Qt6Core.dll رو اسکن میکنه:
// qt-discover.js
const qt = Process.getModuleByName('Qt6Core.dll');
function scan(pattern) {
const hits = qt.enumerateExports().filter(e => e.name.includes(pattern));
console.log('=== ' + pattern + ' (' + hits.length + ' hits) ===');
hits.forEach(e => console.log(' ' + e.name));
return hits;
}
['?constData@QString@', '?data@QString@', '?utf16@QString@'].forEach(scan);بعد از شناسایی سیمبلها، اسکریپت qt-qstring-trace.js این سه نقطه رو هوک میکنه. فیلترهایی هم داره: طول رشته بین ۶ تا ۶۴ کاراکتر باشه، فقط ASCII قابل چاپ باشه، و پیشوندهای داخلی Qt مثل qrc: یا file: رو نادیده میگیره. نتیجه؟ وقتی پسورد رو در HackPass تایپ میکنی، کنسول Frida بهصورت زنده رشد رشته رو نشون میده: hackpa، hackpas، hackpass. علاوه بر پسورد، آدرس رجیستری، هاست لوکال (127.0.0.1) و تمام متنهای UI هم ردیابی میشن — چیزهایی که با strings روی بایناری اثری ازشون پیدا نمیشد.
چالش دوم: شنود سیگنالهای UI. در Qt، کلیک دکمه یا هر رویداد UI از طریق مکانیزم سیگنال-اسلات به متدها وصل میشه — اما dispatch این رویدادها از طریق QMetaObject::activate انجام میشه و هیچ سیمبل جداگانهای برای هر سیگنال وجود نداره. راهحل اینه که خود activate رو هوک کنیم. با این کار میشه فهمید کدوم آبجکت، کدوم سیگنال رو emit کرده — مثلاً کلیک دکمهی Unlock یه clicked() از QQuickButton فایر میکنه. آدرس هر آبجکت QObject هم در لاگ میآد که میشه بعداً برای enumerate کردن متدهایش استفاده کرد.
این دو تکنیک با هم یه پایهی قوی برای تحلیل رفتار اپ Qt6 میسازن: یکی نشون میده اپ چه دادههایی رو پردازش میکنه، دیگری نشون میده چه رویدادهایی اتفاق میافته. مقاله قراره در قسمتهای بعدی به موضوعاتی مثل walk کردن متادیتای QObject و دستکاری منطق برنامه بپرداز.
نکات کلیدی:
- QString در Qt6 از UTF-16 استفاده میکنه و با ابزارهای C string قابل ردیابی نیست
- هوک کردن constData، data و utf16 تمام خواندنهای رشتهای رو زنده نشون میده
- سیگنالهای Qt از طریق QMetaObject::activate dispatch میشن — نه با سیمبل مستقل
- اسکریپت qt-discover.js سیمبلهای دقیق هر بیلد Qt رو پیدا میکنه
- این تکنیکها روی Qt6/Windows تست شدن؛ روی macOS نام سیمبلها متفاوته




