كيف اكتشفت بيضة عيد الفصح في أمان Android ولم أحصل على وظيفة في Google

جوجل يحب بيض عيد الفصح. إنه يحبهم كثيرًا ، في الواقع ، بحيث يمكنك العثور عليهم في كل منتج تقريبًا من منتجاتهم. بدأ تقليد بيض عيد الفصح الذي يعمل بنظام Android في الإصدارات الأقدم من نظام التشغيل (أعتقد أن كل شخص يعرف ما يحدث عند الانتقال إلى الإعدادات العامة والاستفادة من رقم الإصدار عدة مرات).

لكن في بعض الأحيان يمكنك العثور على بيضة عيد الفصح في الأماكن الأكثر ترجيحًا. حتى أن هناك أسطورة حضرية في يوم من الأيام ، قام مبرمج غوغل بـ "قفل mutex" ، ولكن بدلاً من نتائج البحث هبطت على foo.bar ، وحل جميع المهام وهبط وظيفة في Google.

إعادة الإعمار
صورة

حدث الشيء نفسه (باستثناء بدون نهاية سعيدة) لي. الرسائل المخفية التي لا يمكن أن توجد بها بالتأكيد ، تعكس تعليمات برمجية Java ومكتباتها الأصلية ، و VM سرية ، ومقابلة Google - وكل ذلك أدناه.

DroidGuard


في إحدى الليالي المملة ، قمت بإعادة ضبط هاتفي في المصنع وحصلت على إعداده مرة أخرى. أول الأشياء أولاً ، طلب من تثبيت Android جديد تسجيل الدخول إلى حساب Google. وتساءلت: كيف تعمل عملية تسجيل الدخول إلى Android؟ وأصبحت الليل فجأة أقل مملة.

يمكنني استخدام Burp Suite في PortSwigger لاعتراض حركة مرور الشبكة وتحليلها. نسخة المجتمع المجانية كافية لأغراضنا. للاطلاع على طلبات https ، نحتاج أولاً إلى تثبيت شهادة PortSwigger على الجهاز. كجهاز اختبار ، اخترت هاتف Samsung Galaxy S يبلغ من العمر 8 أعوام مع نظام Android 4.4. أي شيء أحدث من ذلك ، وربما لديك مشاكل مع تثبيت شهادة والأشياء.

بكل صدق ، لا يوجد شيء خاص بشكل خاص مع طلبات Google API. يرسل الجهاز معلومات عن نفسه ويحصل على رموز استجابة ... والخطوة الفضولية الوحيدة هي طلب POST لخدمة مكافحة إساءة الاستخدام.



بعد تقديم الطلب ، من بين العديد من المعلمات العادية جدًا ، تظهر علامة مثيرة للإعجاب باسم droidguard_result . إنها سلسلة Base64 طويلة جدًا:



DroidGuard هي آلية Google للكشف عن برامج الروبوت والمحاكاة بين الأجهزة الحقيقية. يستخدم SafetyNet ، على سبيل المثال ، بيانات DroidGuard. لدى Google شيء مشابه للمتصفحات أيضًا - Botguard.

ولكن ما هذه البيانات؟ لنكتشف ذلك.

مخازن بروتوكول


ما الذي يولد هذا الرابط ( www.googleapis.com/androidantiabuse/v1/x/create؟alt=PROTO&key=AIzaSyBofcZsgLSS7BOnBjZPEkk4rYwzOIz-lTI ) وما الذي يجعل Android داخل هذا الطلب؟ بعد إجراء تحقيق قصير ، تبين أن الرابط ، في هذا النموذج الدقيق ، يقع داخل إحدى الفصول المظلمة في خدمات Google Play:

public bdd(Context var1, bdh var2) { this(var1, "https://www.googleapis.com/androidantiabuse/v1/x/create?alt=PROTO&key=AIzaSyBofcZsgLSS7BOnBjZPEkk4rYwzOIz-lTI", var2); } 

كما رأينا بالفعل في Burp ، تحتوي طلبات POST على هذا الرابط على نوع المحتوى - application / x-protobuf (مخازن بروتوكول Google ، بروتوكول Google للتسلسل الثنائي). إنه ليس json ، لكن من الصعب الكشف عما يتم إرساله بالضبط.

تعمل المخازن المؤقتة البروتوكول مثل هذا:

  • أولاً نصف بنية الرسالة بتنسيق خاص ونحفظها في ملف .proto ؛
  • ثم نقوم بتجميع ملفات .proto ، ويقوم برنامج التحويل البرمجي protoc بإنشاء شفرة المصدر بلغة مختارة (في حالة Android ، إنها Java) ؛
  • أخيرًا ، نستخدم الفئات المولدة في مشروعنا.

لدينا طريقتان لفك تشفير رسائل protobuf. الأول هو استخدام محلل protobuf ومحاولة إعادة إنشاء الوصف الأصلي لملفات .proto. والثاني هو إخراج الفئات التي تم إنشاؤها بواسطة protoc من خدمات Google Play ، وهذا ما قررت القيام به.

نحن نأخذ ملف .apk لخدمات Google Play من نفس الإصدار المثبت على الجهاز (أو ، إذا كان الجهاز متجذرًا ، فاخذ الملف مباشرة من هناك). باستخدام dex2jar ، نقوم بتحويل ملف .dex مرة أخرى إلى .jar وفتحه في برنامج فك تشفير مختار. أنا شخصيا أحب JetBrains 'Fernflower. إنه يعمل كبرنامج إضافي لبرنامج IntelliJ IDEA (أو Android Studio) ، لذلك نحن ببساطة نطلق Android Studio ونفتح الملف بالرابط الذي نحاول تحليله. إذا كان proguard لا يحاول بشدة ، فقد يتم لصق رمز Java الذي تم فك تشفيره لإنشاء رسائل protobuf في مشروعك.

بالنظر إلى الكود الذي تم فك تشفيره ، نرى أن Build. * يتم إرسال الثوابت داخل رسالة protobuf. (حسنا ، هذا لم يكن من الصعب جدا تخمين).

 ... var3.a("4.0.33 (910055-30)"); a(var3, "BOARD", Build.BOARD); a(var3, "BOOTLOADER", Build.BOOTLOADER); a(var3, "BRAND", Build.BRAND); a(var3, "CPU_ABI", Build.CPU_ABI); a(var3, "CPU_ABI2", Build.CPU_ABI2); a(var3, "DEVICE", Build.DEVICE); ... 

لكن لسوء الحظ ، في رد الخادم ، تحولت جميع حقول protobuf إلى حساء الأبجدية بعد التعتيم. ولكن يمكننا اكتشاف ما يوجد هناك باستخدام معالج الأخطاء. إليك كيفية فحص البيانات الواردة من الخادم:

 if (!var7.d()) { throw new bdf("byteCode"); } if (!var7.f()) { throw new bdf("vmUrl"); } if (!var7.h()) { throw new bdf("vmChecksum"); } if (!var7.j()) { throw new bdf("expiryTimeSecs"); } 

على ما يبدو ، هكذا تم استدعاء الحقول قبل التعتيم: byteCode و vmUrl و vmChecksum و expiryTimeSecs . مخطط التسمية هذا يعطينا بالفعل بعض الأفكار.

نحن نجمع بين جميع الفئات المحولة من خدمات Google Play في مشروع اختبار ، وإعادة تسميتها ، وإنشاء اختبار بناء. * الأوامر وإطلاق (تقليد أي جهاز نريد). إذا أراد شخص ما القيام بذلك بنفسه ، فإليك الرابط الخاص بـ GitHub .

إذا كان الطلب صحيحًا ، يعرض الخادم هذا:
00: 06: 26.761 [رئيسي] INFO daresponse.AntiabuseResponse - حجم البايت: 34446
00: 06: 26.761 [main] INFO daresponse.AntiabuseResponse - vmChecksum: C15E93CCFD9EF178293A2334A1C9F9B08F115993
00: 06: 26.761 [رئيسي] INFO daresponse.AntiabuseResponse - vmUrl: www.gstatic.com/droidguard/C15E93CCFD9EF178293A2334A1C9F9B08F115993
00: 06: 26.761 [رئيسي] INFO daresponse.AntiabuseResponse - expiryTimeSecs: 10

الخطوة 1 كاملة. الآن دعونا نرى ما هو مخفي وراء رابط vmUrl .

سر APK


يقودنا الرابط مباشرة إلى ملف .apk ، سمي باسم تجزئة SHA-1 الخاصة به. انها صغيرة نوعا ما - 150KB فقط. وهذا مبرر تمامًا: إذا تم تنزيله من قِبل كل واحد من أجهزة Android التي يبلغ عددها ملياري جهاز ، فهذا يمثل 270 تيرابايت من حركة المرور على خدمات Google.



فئة DroidGuardService ، كونها جزءًا من خدمات Google Play ، تقوم بتنزيل الملف على الجهاز وتفريغه واستخراج .dex ويستخدم فئة com.google.ccc.abuse.droidguard.DroidGuard خلال الانعكاس. إذا كان هناك خطأ ، DroidGuardService من DroidGuard إلى Droidguasso. ولكن هذه قصة أخرى تماما.

بشكل أساسي ، فئة DroidGuard عبارة عن غلاف JNI بسيط حول مكتبة .so الأصلية. يطابق ABI بالمكتبة الأصلية ما CPU_ABI في حقل CPU_ABI في طلب protobuf: يمكننا طلب armeabi أو x86 أو حتى MIPS.

لا تحتوي خدمة DroidGuardService نفسها على أي منطق مثير للاهتمام للعمل مع فئة DroidGuard . ببساطة يخلق مثيل جديد من DroidGuard ، يرسله بايت من رسالة protobuf ، يستدعي طريقة عامة ، والتي ترجع صفيف بايت. ثم يتم إرسال هذه الصفيف إلى الخادم داخل المعلمة droidguard_result .

للحصول على فكرة تقريبية حول ما يجري داخل DroidGuard يمكننا تكرار منطق DroidGuardService (ولكن دون تنزيل ملف .apk ، نظرًا لأن لدينا بالفعل مكتبة أصلية). يمكننا أخذ ملف .dex من ملف APK السري ، وتحويله إلى ملف .jar ثم استخدامه في مشروعنا. المشكلة الوحيدة هي كيفية تحميل فئة DroidGuard المكتبة الأصلية. يستدعي كتلة التهيئة الثابتة الأسلوب loadDroidGuardLibrary() :

 static { try { loadDroidGuardLibrary(); } catch (Exception ex) { throw new RuntimeException(ex); } } 

ثم يقرأ الأسلوب loadDroidGuardLibrary() library.txt (الموجود في جذر ملف .apk) ويقوم بتحميل المكتبة بهذا الاسم من خلال استدعاء System.load(String filename) . غير ملائم للغاية بالنسبة لنا ، حيث نحتاج إلى إنشاء ملف .apk بطريقة محددة جدًا لوضع library.txt وملف .so في جذره. سيكون أكثر ملاءمة للاحتفاظ بملف .so في مجلد lib System.loadLibrary(String libname) خلال System.loadLibrary(String libname) .

ليس من الصعب القيام به. سنستخدم smali / baksmali - أداة التجميع / أداة فك الارتباط لملفات .dex. بعد استخدامه ، يتحول classes.dex إلى مجموعة من ملفات .smali. يجب تعديل فئة com.google.ccc.abuse.droidguard.DroidGuard ، بحيث تستدعي كتلة التهيئة الثابتة طريقة System.loadLibrary("droidguard") بدلاً من loadDroidGuardLibrary() . بناء جملة Smali بسيط جدًا ، تبدو كتلة التهيئة الجديدة كما يلي:

 .method static constructor <clinit>()V .locals 1 const-string v0, "droidguard" invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V return-void .end method 

ثم نستخدم backsmali لإعادة بنائه إلى .dex ، ثم نقوم بتحويله إلى .jar. في النهاية ، نحصل على ملف .jar يمكننا استخدامه في مشروعنا - وهنا ، بالمناسبة.

قسم DroidGuard بأكمله مرتبط بسلاسل من السلاسل الطويلة. الجزء الأكثر أهمية هو تنزيل صفيف البايت الذي حصلنا عليه في الخطوة السابقة بعد معالجة خدمة مكافحة إساءة الاستخدام وتسليمها إلى مُنشئ DroidGuard :

 private fun runDroidguard() { var byteCode: ByteArray? = loadBytecode("bytecode.base64"); byteCode?.let { val droidguard = DroidGuard(applicationContext, "addAccount", it) val params = mapOf("dg_email" to "test@gmail.com", "dg_gmsCoreVersion" to "910055-30", "dg_package" to "com.google.android.gms", "dg_androidId" to UUID.randomUUID().toString()) droidguard.init() val result = droidguard.ss(params) droidguard.close() } } 

الآن يمكننا استخدام ملف التعريف الخاص بـ Android Studio ومعرفة ما يحدث أثناء عمل DroidGuard:



تقوم الطريقة الأصلية () الخاصة بجمع البيانات حول الجهاز hasSystemFeature(), getMemoryInfo(), getPackageInfo() أساليب Java hasSystemFeature(), getMemoryInfo(), getPackageInfo() ... هذا شيء ، لكن ما زلت لا أرى أي منطق صلب. حسنًا ، كل ما تبقى هو تفكيك ملف .so.

libdroidguard.so


لحسن الحظ ، فإن تحليل المكتبة الأصلية ليس أكثر صعوبة في القيام بذلك باستخدام ملفات .dex و. jar. نحتاج إلى تطبيق مشابه لـ Hex-Rays IDA وبعض المعرفة برمز المجمّع x86 أو ARM. لقد اخترت ARM ، لأنني امتلكت جذرًا راسخًا للتصحيح عليه. إذا لم يكن لديك واحدة ، يمكنك أن تأخذ مكتبة x86 وتصحيح الأخطاء باستخدام محاكي.

يقوم تطبيق مشابه لـ Hex-Rays IDA بفك تشفير الملف الثنائي إلى شيء يشبه رمز C. إذا Java_com_google_ccc_abuse_droidguard_DroidGuard_ssNative الطريقة Java_com_google_ccc_abuse_droidguard_DroidGuard_ssNative ، Java_com_google_ccc_abuse_droidguard_DroidGuard_ssNative شيئًا مثل هذا:

 __int64 __fastcall Java_com_google_ccc_abuse_droidguard_DroidGuard_initNative(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) ... v14 = (*(_DWORD *)v9 + 684))(v9, a5); v15 = (*(_DWORD *)v9 + 736))(v9, a5, 0); ... 

لا يبدو واعدا جدا. أولاً ، نحتاج إلى اتخاذ بعض الخطوات الأولية لتحويل ذلك إلى شيء أكثر فائدة. لا يعرف جهاز فك التشفير أي شيء عن JNI ، لذلك نقوم بتثبيت Android NDK واستيراد ملف jni.h. كما نعلم ، JNIEnv* لطريقة JNI هما JNIEnv* و jobject (this) . يمكننا معرفة أنواع المعلمات الأخرى من كود Java الخاص بـ DroidGuard. بعد تعيين الأنواع الصحيحة ، تتحول الإزاحات بلا معنى إلى استدعاءات طريقة JNI:

 __int64 __fastcall Java_com_google_ccc_abuse_droidguard_DroidGuard_initNative(_JNIEnv *env, jobject thiz, jobject context, jstring flow, jbyteArray byteCode, jobject runtimeApi, jobject extras, jint loggingFd, int runningInAppSide) { ... programLength = _env->functions->GetArrayLength)(_env, byteCode); programBytes = (jbyte *)_env->functions->GetByteArrayElements)(_env, byteCode, 0); ... 

إذا كان لدينا ما يكفي من الصبر لتتبع مجموعة البايت المستلمة من خادم مكافحة إساءة الاستخدام ، فسوف نشعر بخيبة أمل. لسوء الحظ ، لا توجد إجابة بسيطة على "ما يحدث هنا؟". إنه رمز بايت مقطر نقي ، والمكتبة الأصلية عبارة عن جهاز افتراضي. يتم رش بعض تشفير AES في الأعلى ثم يقوم VM بقراءة شفرة البايت والبايتة البايتة وتنفيذ الأوامر. كل بايت هو أمر يتبعه المعاملون. لا يوجد العديد من الأوامر ، إلا حوالي 70: قراءة int ، قراءة البايت ، قراءة السلسلة ، استدعاء طريقة Java ، ضرب رقمين ، if-goto إلخ.

استيقظ الجدد


قررت أن أذهب أبعد من ذلك واكتشف بنية رمز البايت لهذا الجهاز الظاهري. هناك مشكلة أخرى في المكالمات: في بعض الأحيان (مرة كل أسبوعين) هناك إصدار جديد من المكتبة الأصلية حيث يتم خلط أزواج أوامر البايت. لم توقفني وقررت إعادة إنشاء VM باستخدام Java.

ما يفعله رمز البايت هو القيام بكل الأعمال الروتينية على جمع المعلومات حول الجهاز. على سبيل المثال ، يتم تحميل سلسلة باسم الطريقة ، وتحصل على عنوانها عبر dlsym وتنفيذه. في إصدار Java الخاص بي من VM ، قمت بإعادة إنشاء 5 طرق فقط أو نحو ذلك وتعلمت تفسير أول 25 أمرًا من شفرة بايت لخدمة مكافحة إساءة الاستخدام. في الأمر 26 ، يقرأ VM سلسلة أخرى مشفرة من شفرة البايت. اتضح فجأة أنه ليس اسمًا لطريقة أخرى. بعيدا عن ذلك.
قيادة الجهاز الظاهري # 26
استدعاء الأسلوب vm-> vm_method_table [2 * 0x77]
طريقة vmMethod_readString
الفهرس هو 0x9d
طول السلسلة هو 0x0066
(يتم إنشاء مفتاح جديد)
بايت السلسلة المشفرة هي EB 4E E6 DC 34 13 35 4A DD 55 B3 91 33 05 61 04 C0 54 FD 95 2F 18 72 04 C1 55 E1 92 28 11 66 04 DD 4F B3 94 33 04 35 0A C1 4E B2 DB 12 17 79 4F 92 55 FC DB 33 05 35 45 C6 01 F7 89 29 1F 71 43 C7 40 E1 9F 6B 1E 70 48 DE 4E B8 CD 75 44 23 14 85 14 A7 C2 7F 40 26 42 84 17 A2 BB 21 19 7A 43 DE 44 BD 98 29 1B
بايت سلسلة فك الشفرة هي 59 6F 75 27 72 65 20 6E 6F 74 20 6A 75 73 74 20 72 75 6E 6E 69 6E 67 20 73 74 72 69 6E 67 73 20 6F 6E 20 6F 75 72 20 2E 73 6F 21 20 54 61 6C 6B 20 74 6F 20 75 73 20 61 74 20 64 72 6F 69 64 67 75 61 72 64 2D 68 65 6C 6C 6B 2B 36 33 32 36 30 37 35 34 39 39 36 33 39 36 36 31 40 67 6F 6F 67 6C 65 2E 63 6F 6D
قيمة السلسلة غير المشفرة هي ( أنت لا تقوم فقط بتشغيل سلاسل على موقعنا. لذا! تحدث إلينا على droidguard@google.com )
هذا غريب. آلة افتراضية لم تتحدث معي من قبل. اعتقدت أنه إذا بدأت برؤية رسائل سرية موجهة إليك ، فأنت مجنون. فقط للتأكد من أنني كنت لا أزال عاقلًا ، جريت بضع مئات من الإجابات المختلفة من خدمة مكافحة إساءة المعاملة من خلال جهاز VM الخاص بي. حرفيا كل أوامر 25-30 كان هناك رسالة مخبأة داخل رمز البايت. وغالبا ما تتكرر ، ولكن أدناه هي بعض فريدة من نوعها. لقد قمت بتحرير عناوين البريد الإلكتروني ، على الرغم من أن كل رسالة لها عنوان مختلف ، مثل "droidguard+tag@google.com" ، حيث تكون العلامة فريدة لكل واحدة.
droidguard@google.com: لا تكن غريباً!
حصلت في! تحدث إلينا على droidguard@google.com
تحيات من droidguard@google.com مسافر مقدام! قل مرحبا!
هل كان من السهل العثور على هذا؟ يود droidguard@google.com أن يعرف
الناس في droidguard@google.com نقدر سماع منك!
ما كل هذا gobbledygook؟ اسأل droidguard@google.com ... سيعلمون!
مهلا! يتوهم رؤيتك هنا. هل تحدثت إلى droidguard@google.com حتى الآن؟
أنت لا تقوم فقط بتشغيل سلاسل على .so! تحدث إلينا على droidguard@google.com
هل أنا المختار؟ اعتقدت أن الوقت قد حان للتوقف عن المراسلة مع DroidGuard والتحدث إلى Google ، حيث طلبوا مني ذلك.

مكالمتك مهمة جدا بالنسبة لنا


قلت نتائجي على البريد الإلكتروني الذي وجدته. لجعل النتائج أكثر إثارة للإعجاب ، قمت بأتمتة عملية التحليل قليلاً. الشيء ، يتم تخزين السلاسل والصفائف البايت في رمز البايت المشفرة. يقوم VM بفك تشفيرها باستخدام الثوابت المضمنة بواسطة المترجم. باستخدام تطبيق مشابه لـ Hex-Rays IDA ، يمكنك استخراجها بسهولة. ولكن مع كل نسخة جديدة تتغير الثوابت ومن غير المناسب إلى حد ما استخراجها يدويًا.

لكن تحليل جافا للمكتبة الوطنية أثبت أنه بسيط بشكل مدهش. باستخدام jelf (مكتبة لتحليل ملفات ELF) نجد إزاحة Java_com_google_ccc_abuse_droidguard_DroidGuard_initNative طريقة ثنائية ، ثم نستخدم Capstone (إطار تفكيك مع ارتباطات بلغات مختلفة ، بما في ذلك Java) نحصل عليها السجلات.

في النهاية ، حصلت على تطبيق يحاكي عملية DroidGuard بأكملها: يقدم طلبًا إلى خدمة مكافحة إساءة الاستخدام ، ويقوم بتنزيل ملف .apk وتفريغه ، ويوزع المكتبة المحلية ، ويستخرج الثوابت المطلوبة ، ويختار تعيين أوامر VM و يفسر رمز البايت. جمعت كل شيء وأرسلته إلى Google. بينما كنت في ذلك ، بدأت التحضير لهذه الخطوة وفتشت Glassdoor للحصول على راتب متوسط ​​في Google. قررت عدم الموافقة على أي شيء أقل من ستة أرقام.

الجواب لم يستغرق وقتا طويلا. رسالة بريد إلكتروني من أحد أعضاء فريق DroidGuard تقرأ ببساطة: "لماذا أنت تفعل هذا حتى؟"



"لأنني أستطيع" - أجبت. أوضح لي أحد موظفي Google أن DroidGuard من المفترض أن يحمي Android من المتسللين (لا تقل!) وسيكون من الحكمة الحفاظ على الكود المصدري لـ DroidGuard VM لنفسي. انتهى حديثنا هناك.

مقابلة


وبعد شهر تلقيت بريدًا إلكترونيًا آخر. احتاج فريق DroidGuard في زيوريخ إلى موظف جديد. هل كنت مهتمًا بالانضمام؟ بالطبع!

لا توجد اختصارات للدخول إلى Google. كل ما يمكنني القيام به هو توجيه سيرتي الذاتية إلى قسم الموارد البشرية. بعد ذلك ، كان عليّ أن أذهب إلى قاعدة البيروقراطية المعتادة وسلسلة من المقابلات.

هناك الكثير من القصص حول مقابلات جوجل. الخوارزميات ومهام Olympiad وبرمجة محرّر مستندات Google ليست هي شيئًا ، لذلك بدأت الاستعدادات الخاصة بي. قرأت خلال دورة "الخوارزميات" في كورسيرا عشرات المرات ، وحلّت مئات المهام على Hackerrank وتعلمت التجول حول رسم بياني في كلا البعدين وأغلقت عيني.

مرت شهرين. أن أقول إنني شعرت بالاستعداد سيكون بخس. أصبح مُحرر مستندات Google IDE المفضل لدي. شعرت كأنني عرفت كل ما يمكن معرفته عن الخوارزميات. بالطبع ، كنت أعرف نقاط ضعفي وأدركت أنني ربما لن أجتاز سلسلة المقابلات الخمسة في زيورخ ، لكن الذهاب إلى ديزني لاند للمبرمج مجانًا كان مكافأة بحد ذاتها. كانت الخطوة الأولى مقابلة عبر الهاتف للتخلص من أضعف المرشحين وعدم إضاعة الوقت لمطوري زيوريخ في الاجتماعات الشخصية. تم ضبط اليوم ، رن جرس الهاتف ...



... وفشلت على الفور أول اختبار لي. لقد حالفني الحظ - لقد طرحوا سؤالًا رأيته على الإنترنت من قبل وتم حلهم بالفعل. كان حول تسلسل مجموعة سلسلة. عرضت سلاسل الأكواد في Base64 وحفظها من خلال مقسم. طلب مني القائم بإجراء المقابلة تطوير خوارزمية Base64. بعد ذلك تحولت المقابلة إلى نوع من المونولوج ، حيث أوضح لي من تمت مقابلته كيف يعمل Base64 وحاولت أن أتذكر عمليات البت في Java.

إذا كان أي شخص في جوجل يقرأ هذا
يا رفاق ، أنت عباقرة دامية إذا وصلت إلى هناك! على محمل الجد. لا أستطيع أن أتخيل كيف يمكن للمرء أن يزيل كل العقبات التي يضعونها أمامك.

بعد 3 أيام من المكالمة تلقيت رسالة بريد إلكتروني تفيد أنهم لا يريدون إجراء المزيد من المقابلات معي. وهذه هي الطريقة التي انتهى بها اتصالي بـ Google.

لماذا توجد رسائل في DroidGuard تطالب بالدردشة ، لا يزال لدي أي فكرة. ربما فقط للإحصائيات. أخبرني الرجل الذي كتبت إليه في المقام الأول أن الأشخاص يكتبون فعليًا هناك ، لكن التردد يختلف: في بعض الأحيان يحصلون على 3 ردود في الأسبوع ، وأحيانًا 1 في السنة.

أعتقد أن هناك طرقًا أسهل للحصول على مقابلة في Google. بعد كل شيء ، يمكنك فقط أن تسأل أيًا من 100000 موظف (على الرغم من أن جميعهم ليسوا مطورين ، من المسلم به). لكنها كانت تجربة ممتعة رغم ذلك.

Source: https://habr.com/ru/post/ar446790/


All Articles