بالنسبة لهذا المشروع، قمت بإجراء هندسة عكسية لتطبيق "C by GE" للتحكم في مصابيح الإضاءة الذكية المتصلة بشبكة WiFi من GE. وللقيام بذلك، بدأت بفك ترجمة تطبيق Android، ثم أجريت هندسة عكسية للبروتوكول الثنائي الذي يستخدمه التطبيق للتواصل مع الخادم. لمزيد من التفاصيل، راجع الهندسة العكسية C بواسطة GE.
المنتجات النهائية لهذا المشروع هي:
إخلاء المسؤولية: هذا الرمز هو نتيجة الهندسة العكسية ولم يتم إبلاغه بمواصفات البروتوكول. ونتيجة لذلك، ليس هناك ما يضمن استمراره في العمل أو أنه سيعمل مع كل شبكة أو جهاز ذكي. في حين أن الآخرين استخدموا واجهة برمجة التطبيقات هذه بنجاح في بعض الحالات، فمن الممكن أن تضع التعليمات البرمجية افتراضات غير صحيحة لا تصمد في كل حالة استخدام.
دليل الخادم عبارة عن تطبيق ويب قائم بذاته ونقطة نهاية JSON API لـ C من مصابيح GE. يبدو الموقع كما يلي:
إذا قمت بتشغيل موقع الويب باستخدام وسيطة -email
و- -password
، فسيقوم موقع الويب بعرض صفحة مصادقة ثنائية في المرة الأولى التي تقوم فيها بتحميله. سوف تضغط على زر وتقوم بإدخال رمز التحقق المرسل إلى بريدك الإلكتروني. وبدلاً من ذلك، يمكنك تسجيل الدخول مسبقًا عن طريق تشغيل الأمر login_2fa مع تعيين علامتي -email
و- -password
على معلومات حسابك. سيطالبك الأمر برمز التحقق 2FA. بمجرد إدخال هذا الرمز، سيقوم الأمر بإخراج معلومات الجلسة على هيئة JSON blob. يمكنك بعد ذلك تمرير JSON هذا إلى وسيطة -sessinfo
للخادم، على سبيل المثال -sessinfo 'JSON HERE'
. لاحظ أن جزءًا من الجلسة تنتهي صلاحيته بعد أسبوع، لكن مثيل الخادم قيد التشغيل سيستمر في العمل بعد هذا الوقت نظرًا لأن الجزء القابل لانتهاء الصلاحية من الجلسة يُستخدم مرة واحدة فقط لتعداد الأجهزة.
تتطلب الحسابات الأحدث استخدام المصادقة الثنائية. يمكنك إجراء مصافحة 2FA لإنشاء جلسة كما يلي:
callback , err := cbyge . Login2FA ( "my_email" , "my_password" , "" )
// Handle error...
sessionInfo , err := callback ( "2FA code from email" )
// Handle error...
session , err := cbyge . NewController ( sessionInfo , 0 )
// Handle error...
بالنسبة للحسابات القديمة التي لم تستخدم المصادقة الثنائية من قبل، فقد تتمكن من تسجيل الدخول مباشرة:
session , err := cbyge . NewControllerLogin ( "my_email" , "my_password" )
// Handle error...
بمجرد الانتهاء من الجلسة، يمكنك تعداد الأجهزة مثل:
devs , err := session . Devices ()
// Handle error...
for _ , x := range devs {
fmt . Println ( x . Name ())
}
يمكنك التحكم في المصابيح مثل هذا:
x := devs [ 0 ]
session . SetDeviceStatus ( x , true ) // turn on
session . SetDeviceLum ( x , 50 ) // set brightness
session . SetDeviceCT ( x , 100 ) // set color tone (100=blue, 0=orange)
يمكنك أيضًا الاستعلام عن الإعدادات الحالية للمبة:
status , err := session . DeviceStatus ( x )
// Handle error...
fmt . Println ( status . IsOn )
fmt . Println ( status . ColorTone )
في هذا القسم، سأطلعك على كيفية إجراء هندسة عكسية لأجزاء من بروتوكول C بواسطة GE.
كانت الخطوة الأولى هي تفكيك تطبيق Android باستخدام Apktool. يؤدي هذا إلى تفكيك Smali للتطبيق. أثناء التجوال، بحثت عن عناوين URL وأسماء النطاقات. في البداية وجدت هذا:
.field public static final API_VERSION : L java/lang/String ; = " v2/ "
.field public static final BASE_URL : L java/lang/String ; = " https://api-ge.xlink.cn:443/ "
إن رؤية مكان استخدام نقطة نهاية واجهة برمجة التطبيقات هذه قادتني بسرعة إلى مجموعة من استدعاءات HTTP المستندة إلى JSON لتسجيل الدخول، وإدراج الأجهزة، وما إلى ذلك. ومع ذلك، لا يبدو أن نقطة النهاية هذه توفر طريقة لـ 1) الحصول على حالة الأجهزة، أو 2) تحديث لون أو سطوع الأجهزة.
لا بد أن تكون هناك طريقة أخرى يتواصل بها التطبيق مع المصابيح الذكية. ومع ذلك، كان التفكيك مليئًا برمز اتصال Bluetooth والشبكة المحلية (LAN)، وكنت قلقًا بعض الشيء من عدم وجود نقطة نهاية عالمية لواجهة برمجة التطبيقات (API) للتحكم في المصابيح. والأسوأ من ذلك هو أن تطبيق C by GE كان يشتكي كلما قمت بإيقاف تشغيل Bluetooth ثم حاولت استخدامه. ومع ذلك، وجدت في النهاية أنه يمكنني فتح التطبيق، والسماح له بالقيام بعمله، ثم إيقاف تشغيل Bluetooth وWiFi مع الاستمرار في التحكم في المصابيح. كل ما كان علي فعله هو الضغط على زر "الرجوع" في Android عندما يفتح التطبيق نافذة منبثقة تطلب مني "تشغيل تتبع الموقع" (اسم غريب للبلوتوث والواي فاي، انتبه).
في هذه المرحلة، كنت متأكدًا تمامًا من أن التطبيق لا يقوم بإجراء بعض اتصالات HTTP(S) الغامضة الأخرى. ومن المثير للاهتمام أنني وجدت المجال "xlink.cn" في مكان آخر في كود Smali:
.field public static final CM_SERVER_ADDRESS : L java/lang/String ; = " cm-ge.xlink.cn "
.field public static final CM_SERVER_PORT : I = 0x5ce2
البقرة المقدسة، هل يمكن أن يكون هذا بروتوكولًا خامًا يعتمد على المقبس؟ لقد حاولت، وبالتأكيد تمكنت من فتح اتصال TCP بـ cm-ge.xlink.cn:23778
. ومع ذلك، كان Smali أيضًا مليئًا بمنطق حزم UDP ، لذلك لم أكن متأكدًا من البروتوكول الذي سيستخدمه التطبيق. مع وضع ذلك في الاعتبار، قمت بإنشاء packet-proxy وقمت بتعيينه على المنفذ 23778. ثم استبدلت المجال cm-ge.xlink.cn
بعنوان IP الخاص بي في كود Smali، وأعدت ترجمة التطبيق إلى ملف APK، وقمت بتثبيته على هاتفي.
من المؤكد أن تطبيق C by GE المصحح الخاص بي اتصل على الفور بمثيل وكيل الحزمة الخاص بي وبدأ الدردشة. والجدير بالذكر أنه لم يفعل ذلك إلا عند إيقاف تشغيل Bluetooth و WiFi. وبخلاف ذلك، يبدو أنها تفضل واحدة منها للتواصل محليًا مع المصابيح الذكية.
كان البروتوكول الذي اختار التطبيق استخدامه هو النتيجة الأسهل للتعامل معه على الإطلاق: 1) كان TCP بدلاً من UDP، 2) كان غير مشفر تمامًا. إن الافتقار إلى التشفير أمر مثير للقلق إلى حد ما بعد فوات الأوان، حيث أن الرسالة الأولى تتضمن رمز تفويض مميز لا يبدو أنه يتغير أبدًا بالنسبة لحسابي.
لقد وجدت أن الرسائل من التطبيق إلى الخادم يمكن "إعادة تشغيلها" بشكل فعال. بمجرد أن اكتشفت البايتات (أو "الحزم"، بفضل وكيل الحزمة) المخصصة لتشغيل وإطفاء الأضواء، يمكنني ببساطة فتح مقبس جديد وإرسال نفس هذه الحزم والحصول على نفس النتائج. وكانت هذه علامة عظيمة. في أسوأ السيناريوهات، كان لدي بالفعل طريقة لتنفيذ ما أردته بنفسي، حتى لو لم يكن عامًا جدًا.
في هذه المرحلة، حان الوقت للتعمق أكثر في البروتوكول. بعد مجموعة من التجارب باستخدام وكيل الحزم والتعمق في تفكيك Smali، أصبح لدي فهم عام إلى حد ما لما كان يحدث من اتصالات. أول شيء لاحظته هو أن الاتصال تم في "الرسائل" التي تبدأ بنوع وحقل طول (باللغة الإنجليزية الكبيرة). والشيء التالي هو معرفة أنواع الحزم ومكانها، وفي النهاية كيف تم تشفير الحزم المحددة نفسها. فيما يلي مثال لحزمة من الخادم تحتوي على حالات أجهزتي الثلاثة:
73 00 00 00 60 47 e2 be ab 00 37 00 7e 00 01 00 00 f9 52 4e
00 03 00 00 00 03 00 03 00 81 01 00 00 81 01 00 00 00 00 35
00 00 00 27 00 00 00 00 00 00 00 02 00 00 01 00 00 00 01 00
00 00 00 35 00 00 00 27 00 00 00 00 00 00 00 01 00 00 01 00
00 00 01 00 00 00 00 35 00 00 00 27 00 00 00 00 00 00 00 c8
7e
بمجرد أن انتهيت من إعداد البروتوكول، قمت بإنشاء واجهة برمجة التطبيقات (API) له. يمكن لواجهة برمجة التطبيقات هذه سرد الأجهزة والحصول على حالاتها وتحديث الخصائص المختلفة للأجهزة (مثل السطوع ودرجة اللون). والمثير للدهشة أنني وجدت أن واجهة برمجة التطبيقات (API) الخاصة بي أسرع بكثير وأكثر موثوقية من التطبيق نفسه. يبدو أن محاولة استخدام Bluetooth أو WiFi قبل الرجوع إلى خادم بعيد يؤدي إلى أن يكون التطبيق أكثر هشاشة وأقل موثوقية مما يمكن أن يكون عليه.
كملاحظة أخيرة، لا أملك جميع الأجهزة التي يدعمها هذا التطبيق، لذلك لم يكن لدي الحافز (أو القدرة بسهولة) على إجراء هندسة عكسية لكيفية عمل هذه الأجهزة. على سبيل المثال، تنتج نفس الشركة المنافذ الذكية وأجهزة الاستشعار ومفاتيح الإضاءة.