
يحلّل ملفات Go الثنائية لاستعادة الرموز وبيانات التعريف الخاصة بالدوال والأنواع ومسارات الملفات والسلاسل النصية المضمّنة، بما في ذلك العينات المُجرَّدة أو المحزومة بـ UPX، مع دعم الاستيراد إلى IDA Pro.

GoReSym هو محلل رموز (symbol parser) لـ Go يستخرج البيانات الوصفية للبرنامج (مثل معمارية المعالج، ونظام التشغيل، وترتيب البايتات (endianness)، وإصدار المترجم، وغيرها)، والبيانات الوصفية للدوال (عناوين البداية والنهاية، والأسماء، والمصادر)، والبيانات الوصفية لأسماء الملفات وأرقام الأسطر، والبنى والأنواع المضمّنة. يعتمد هذا البرنامج متعدد المنصات مباشرةً على مترجم Go مفتوح المصدر وشيفرة وقت التشغيل (runtime).
تم توسيع شيفرة وقت التشغيل الأصلية لـ Go للتعامل مع:
moduledataراجع https://www.mandiant.com/resources/blog/golang-internals-symbol-recovery للحصول على تفاصيل الهندسة العكسية وأمثلة الاستخدام.
يمكنك تنزيل ملفات GoReSym الثنائية الجاهزة لأنظمة linux وmacos وwindows من علامة تبويب الإصدارات (Releases).
للبناء من المصدر باستخدام مترجم Go حديث، استدعِ مترجم Go:
go build
عند الانتهاء من البناء، استدعِ GoReSym بهذه الطريقة:
GoReSym.exe -t -d -p /path/to/input.exe
في هذا المثال، نطلب من GoReSym استعادة أسماء الأنواع (-t)، وأسماء حزم المستخدم، وأسماء حزم Go القياسية (-d)، ومسارات ملفات الإدخال (-p) المضمّنة داخل الملف /path/to/input.exe. يبدو الناتج هكذا:
{
"Version": "1.14.15",
"BuildId": "Zb9QmokKTiOUgHKmaIwz/wd2rtE3W9PN-um1Ocdzh/qTdqcTY_jVajHy_-TtYv/Z_kJu9M77OjfijEiHMcF",
"Arch": "amd64",
"TabMeta": {
"VA": 5174784,
"Version": "1.2",
"Endianess": "LittleEndian",
"CpuQuantum": 1,
"CpuQuantumStr": "x86/x64",
"PointerSize": 8
},
"ModuleMeta": {
"VA": 5678816,
"Types": 4845568,
"ETypes": 5171904,
"Typelinks": {
"Data": 5171904,
"Len": 695,
"Capacity": 695
},
"ITablinks": {
"Data": 5174688,
"Len": 11,
"Capacity": 11
},
"LegacyTypes": {
"Data": 0,
"Len": 0,
"Capacity": 0
}
},
"Types": [ ... ],
"Files": [ ... ],
"Strings": [ ... ],
"UserFunctions": [ ... ],
"StdFunctions": [ ... ]
}
فيما يلي جميع الخيارات المتاحة:
-d ("default"، اختياري) سيطبع حزم Go القياسية بالإضافة إلى حزم المستخدم.-p ("paths"، اختياري) سيطبع أي مسارات ملفات مضمّنة في pclntab.-t ("types"، اختياري) سيطبع أسماء أنواع Go.-strings (اختياري) سيستخرج سلاسل Go المضمّنة من الملف الثنائي عبر تحليل جدول تخزين السلاسل الداخلية (string internment table).-m <virtual address> ("manual"، اختياري) سيقوم بتفريغ بنية RTYPE بشكل تكراري عند العنوان الظاهري المحدد-v <version string> ("version"، اختياري) سيتجاوز الكشف الآلي عن الإصدار ويستخدم الإصدار المقدَّم. هذا مطلوب لبعض الملفات الثنائية المنزوعة الرموز (stripped binaries). سيفشل تحليل الأنواع إذا لم يكن الإصدار دقيقًا.-human (اختياري) سيطبع قائمة نصية مسطّحة بدلًا من JSON. مفيد بشكل خاص عند طباعة أنواع البنى والواجهات.-about (اختياري) سيطبع معلومات الترخيصلاستيراد هذه المعلومات إلى IDA Pro يمكنك تشغيل السكربت الموجود في https://github.com/mandiant/GoReSym/blob/master/IDAPython/goresym_rename.py. سيقرأ ملف json أنتجه GoReSym ويضبط الرموز/التسميات في IDA.
بما أن مترجم Go وبيئة التشغيل قد تغيّرا، تغيّرت أيضًا بنى البيانات الوصفية المضمّنة. يدعم GoReSym المجموعات التالية من إصدارات Go والبيانات الوصفية:
pclntab: >= Go 1.2moduledata: >= Go 1.2moduledata: >= Go 1.5جدول moduledata المستخدم لاستخراج الأنواع غير موجود قبل Go 1.5، لذا لن تدعم هذه المكتبة أبدًا استخراج الأنواع من إصدارات Go القديمة جدًا.
تتعامل هذه المكتبة حاليًا مع تخطيطات pclntab لما قبل 1.2 و1.2 و1.16 و1.18 و1.20. لاحظ أن إصدار pclntab دائمًا <= إصدار بيئة تشغيل Go (مثال: بيئة تشغيل Go 1.19 تستخدم تخطيط pclntab الخاص بـ 1.18)، ونهدف إلى دعم أحدث إصدارات بيئة التشغيل دائمًا.
الكثير من الشيفرة المصدرية في GoReSym منسوخة من دليل مصدر مترجم Go الأصلي /internal. لجعل هذا يعمل، اضطررنا إلى تعديل المصدر قليلًا. إذا كنت ترغب في المساهمة في GoReSym، تابع القراءة لنشرح لك عملية الاستيراد هذه.
بسبب طريقة عمل حزم Go، احتجنا إلى إزالة مسار /internal من شجرة ملفات المصدر. أدى ذلك إلى نسخ الكثير من ملفات Go الداخلية، حيث تبقى شجرة الأدلة سليمة في الغالب لكن مع تغييرات صغيرة في استيرادات العديد من الملفات: استُبدلت الإشارات إلى مسارات /internal بـ github.com/mandiant/GoReSym/.
كما عدّلنا العديد من البنى الداخلية لتصدير الحقول والدوال. هذه غير مُصدَّرة في Go الأصلي لأن المستخدمين يجب ألا يعتمدوا عليها. ومع ذلك، فإن الغرض من هذه الأداة هو استخراج المعلومات الداخلية، لذا نتحمل مهمة صيانة هذه البنى. الوضع ليس مثاليًا، لكنه ليس سهل التجنب. إذا حدّثت هذا المستودع، يجب عليك الحرص على إبقاء هذه التعديلات سليمة. من الأفضل على الأرجح دمج الإيداعات (commits) من المصدر الأصلي يدويًا بدلًا من نسخ ملفات المصدر بالكامل.
أنا منفتح على الاقتراحات حول كيفية هيكلة هذا المشروع بشكل أفضل لتجنب هذه المشكلات مع الاستمرار في الترجمة باستخدام go build المعتاد. هناك نقاش سابق يضم مشرفي Go هنا.
بتجاهل بعض التغييرات التافهة، توجد معظم المنطق الجديد في /objfile. على سبيل المثال، يعرّف الملف objfile/internals بنى Go الداخلية المعكوسة التي يحللها GoReSym.
pclntab: golang.org/s/go12symtabpclntab السحرية: pclntab.go#L169objfile:
buildID القديم: golang/go#50809runtime_modulesinit ومحاولة إصلاح قيمة pclntab السحرية (في الحالات التي تم فيها تعديل قيمة pclntab السحرية).pcln() في objfile/<fileformat> لدعم المسح البايتي لقيمة pclntab السحريةDataAfterSection لدعم مسح التوقيع في محللات صيغ الملفات في /debug/<fileformat>walksymtab في debug/gosym/symtab.go للخروج مبكرًا عندما يكون قسم symtab الاختياري فارغًاgoobj في PCLineTable() في objfile/objfile.goloadPeTable (وغيرها من متغيرات الصيغ) لتجنب الذعر (panic) عندما تكون الرموز موجودة ولكن تم تعديلها بشكل خبيث لتصبح غير صالحة (المرجع: golang/go#47981)read_memory لصيغ الملفات المدعومة لقراءة بيانات الملف عبر العنوان الافتراضيmoduledata للمساعدة في تحديد موقع moduledata دعمًا لمسح الأنواع والواجهات (عبر typelinks)readStringTable لجداول الرموز غير الصالحة. يتم تجاهل إخفاقات التحليل أيضًا.MIT