Wie ich in der Sicherheit von Android ein Osterei entdeckte und keinen Job bei Google bekam

Google liebt Ostereier. Es liebt sie so sehr, dass man sie in praktisch jedem ihrer Produkte finden kann. Die Tradition der Android-Ostereier begann in den frühesten Versionen des Betriebssystems (ich denke, jeder dort weiß, was passiert, wenn Sie in die allgemeinen Einstellungen gehen und einige Male auf die Versionsnummer tippen).

Aber manchmal findet man an den unwahrscheinlichsten Orten ein Osterei. Es gibt sogar eine urbane Legende, dass eines Tages ein Programmierer „Mutex Lock“ gegoogelt hat, aber statt Suchergebnisse auf foo.bar gelandet ist, alle Aufgaben gelöst und einen Job bei Google bekommen hat.

Wiederaufbau
Bild

Das gleiche (außer ohne Happy End) ist mir passiert. Versteckte Nachrichten, in denen es definitiv keine geben konnte, Java-Code und seine nativen Bibliotheken, eine geheime VM, ein Google-Interview - all das finden Sie weiter unten.

Droidenschutz


In einer langweiligen Nacht habe ich mein Telefon auf die Werkseinstellungen zurückgesetzt und es erneut eingerichtet. Das Wichtigste zuerst: Bei einer neuen Android-Installation wurde ich aufgefordert, mich bei Google anzumelden. Und ich fragte mich: Wie funktioniert die Anmeldung bei Android überhaupt? Und die Nacht wurde plötzlich weniger langweilig.

Ich verwende die Burp Suite von PortSwigger, um den Netzwerkverkehr abzufangen und zu analysieren. Die kostenlose Community-Version reicht für unsere Zwecke aus. Um die https-Anforderungen anzuzeigen, müssen Sie zuerst das PortSwigger-Zertifikat auf dem Gerät installieren. Als Testgerät habe ich mir ein 8 Jahre altes Samsung Galaxy S mit Android 4.4 ausgesucht. Alles neuere als das und Sie könnten Probleme mit dem Anheften von Zertifikaten und so weiter haben.

Ehrlich gesagt gibt es bei Google API-Anfragen nichts Besonderes. Das Gerät sendet Informationen über sich selbst und erhält als Antwort Token ... Der einzige merkwürdige Schritt ist eine POST-Anfrage an den Anti-Missbrauchs-Dienst.



Nachdem die Anfrage gestellt wurde, erscheint unter zahlreichen sehr normalen Parametern ein interessanter Parameter namens droidguard_result . Es ist eine sehr lange Base64-Zeichenfolge:



DroidGuard ist Googles Mechanismus zum Erkennen von Bots und Emulatoren auf realen Geräten. SafetyNet verwendet beispielsweise auch die Daten von DroidGuard. Google hat eine ähnliche Sache auch für Browser - Botguard.

Aber was sind das für Daten? Lass es uns herausfinden.

Protokollpuffer


Was erzeugt diesen Link ( www.googleapis.com/androidantiabuse/v1/x/create?alt=PROTO&key=AIzaSyBofcZsgLSS7BOnBjZPEkk4rYwzOIz-lTI ) und was in Android macht diese Anfrage? Nach einer kurzen Untersuchung stellte sich heraus, dass sich der Link in genau dieser Form in einer der verschleierten Klassen von Google Play Services befindet:

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

Wie wir bereits in Burp gesehen haben, haben POST-Anforderungen auf diesem Link den Inhaltstyp - application / x-protobuf (Google Protocol Buffers, Googles Protokoll für die binäre Serialisierung). Es ist jedoch kein Json - es ist schwierig herauszufinden, was genau gesendet wird.

Protokollpuffer funktionieren folgendermaßen:

  • Zuerst beschreiben wir die Struktur der Nachricht in einem speziellen Format und speichern sie in einer .proto-Datei.
  • Dann kompilieren wir .proto-Dateien und der Protoc-Compiler generiert Quellcode in einer ausgewählten Sprache (im Fall von Android ist es Java).
  • Schließlich verwenden wir die generierten Klassen in unserem Projekt.

Wir haben zwei Möglichkeiten, Protobuf-Nachrichten zu dekodieren. Der erste besteht darin, einen Protobuf-Analysator zu verwenden und zu versuchen, die ursprüngliche Beschreibung der .proto-Dateien wiederherzustellen. Die zweite besteht darin, die von Protokollen generierten Klassen aus Google Play Services herauszureißen, was ich beschlossen habe.

Wir verwenden die APK-Datei von Google Play Services mit derselben Version, die auf dem Gerät installiert ist (oder, wenn das Gerät gerootet ist, nehmen Sie die Datei direkt von dort). Mit dex2jar konvertieren wir die .dex-Datei zurück in .jar und öffnen sie in einem Dekompiler Ihrer Wahl. Ich persönlich mag JetBrains 'Fernflower. Es funktioniert als Plugin für IntelliJ IDEA (oder Android Studio), daher starten wir einfach Android Studio und öffnen die Datei mit dem Link, den wir analysieren möchten. Wenn sich Proguard nicht zu sehr bemüht hat, kann der dekompilierte Java-Code zum Erstellen von Protobuf-Nachrichten einfach in Ihr Projekt kopiert werden.

Wenn wir uns den dekompilierten Code ansehen, sehen wir, dass Build. * Konstanten innerhalb der Protobuf-Nachricht gesendet werden. (Okay, das war nicht zu schwer zu erraten).

 ... 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); ... 

Leider wurden in der Antwort des Servers alle Protobuf-Felder nach der Verschleierung zu Buchstabensuppe. Mit einem Fehlerhandler können wir jedoch herausfinden, was sich dort befindet. So werden die vom Server kommenden Daten überprüft:

 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"); } 

Anscheinend wurden Felder vor der Verschleierung so aufgerufen: byteCode , vmUrl , vmChecksum und expiryTimeSecs . Dieses Namensschema gibt uns bereits einige Ideen.

Wir kombinieren alle dekompilierten Klassen von Google Play Services zu einem Testprojekt, benennen sie um, generieren Testbuild. * Befehle und starten (imitieren jedes gewünschten Geräts). Wenn jemand es selbst machen will, ist hier der Link zu meinem GitHub .

Wenn die Anforderung korrekt ist, gibt der Server Folgendes zurück:
00: 06: 26.761 [main] INFO daresponse.AntiabuseResponse - byteCode size: 34446
00: 06: 26.761 [main] INFO daresponse.AntiabuseResponse - vmChecksum: C15E93CCFD9EF178293A2334A1C9F9B08F115993
00: 06: 26.761 [main] INFO daresponse.AntiabuseResponse - vmUrl: www.gstatic.com/droidguard/C15E93CCFD9EF178293A2334A1C9F9B08F115993
00: 06: 26.761 [main] INFO daresponse.AntiabuseResponse - expiryTimeSecs: 10

Schritt 1 abgeschlossen. Nun wollen wir sehen, was sich hinter dem vmUrl- Link verbirgt .

Geheime APK


Der Link führt uns direkt zu einer APK-Datei, die nach ihrem eigenen SHA-1-Hash benannt ist. Es ist ziemlich klein - nur 150 KB. Und es ist durchaus gerechtfertigt: Wenn es von jedem der 2 Milliarden Android-Geräte heruntergeladen wird, sind das 270 TB Verkehr auf den Google-Diensten.



DroidGuardService Klasse, die Teil von Google Play Services ist, lädt die Datei auf das Gerät herunter, entpackt sie, extrahiert .dex und verwendet die com.google.ccc.abuse.droidguard.DroidGuard Klasse durch Reflektion. Wenn ein Fehler DroidGuardService wechselt DroidGuardService von DroidGuard zurück zu Droidguasso. Aber das ist eine ganz andere Geschichte.

Im Wesentlichen ist die DroidGuard Klasse ein einfacher JNI-Wrapper um die native .so-Bibliothek. Der ABI der nativen Bibliothek stimmt mit dem überein, was wir im Feld CPU_ABI in der Protobuf-Anfrage gesendet haben: Wir können nach Armeabi, x86 oder sogar MIPS fragen.

Der DroidGuardService Dienst selbst enthält keine interessante Logik für die Arbeit mit der DroidGuard Klasse. Es wird einfach eine neue Instanz von DroidGuard , der ByteCode aus der Protobuf-Nachricht gesendet und eine öffentliche Methode aufgerufen, die ein Byte-Array zurückgibt. Dieses Array wird dann innerhalb des Parameters droidguard_result an den Server gesendet .

Um eine ungefähre Vorstellung davon zu bekommen, was in DroidGuard , können wir die Logik von DroidGuardService wiederholen (jedoch ohne die APK herunterzuladen, da wir bereits über die native Bibliothek verfügen). Wir können eine .dex-Datei aus der geheimen APK nehmen, sie in .jar konvertieren und dann in unserem Projekt verwenden. Das einzige Problem ist, wie die DroidGuard Klasse die native Bibliothek lädt. Der statische Initialisierungsblock ruft die Methode loadDroidGuardLibrary() :

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

Anschließend liest die Methode loadDroidGuardLibrary() die Datei library.txt (im Stammverzeichnis der APK-Datei) und lädt die Bibliothek mit diesem Namen über den System.load(String filename) . Für uns nicht sehr praktisch, da wir die APK auf eine ganz bestimmte Art und Weise erstellen müssten, um die Datei library.txt und die Datei .so in das Stammverzeichnis zu stellen. Es wäre viel bequemer, die .so-Datei im lib-Ordner zu System.loadLibrary(String libname) und über System.loadLibrary(String libname) .

Es ist nicht schwer zu tun. Wir werden smali / baksmali - Assembler / Disassembler für .dex-Dateien verwenden. Nach der Verwendung verwandelt sich classes.dex in eine Reihe von .smali-Dateien. Die Klasse com.google.ccc.abuse.droidguard.DroidGuard sollte so geändert werden, dass der statische Initialisierungsblock die Methode System.loadLibrary("droidguard") anstelle von loadDroidGuardLibrary() . Die Syntax von Smali ist ziemlich einfach. Der neue Initialisierungsblock sieht folgendermaßen aus:

 .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 

Dann verwenden wir backsmali, um alles wieder in .dex zu erstellen, und konvertieren es dann in .jar. Am Ende erhalten wir eine .jar-Datei, die wir in unserem Projekt verwenden können - hier ist es übrigens.

Der gesamte DroidGuard-bezogene Abschnitt ist ein paar Zeichenfolgen lang. Der wichtigste Teil besteht darin, das Byte-Array, das wir im vorherigen Schritt nach dem Adressieren des Anti-Missbrauchs-Dienstes erhalten haben, herunterzuladen und an den DroidGuard Konstruktor 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() } } 

Jetzt können wir den Profiler von Android Studio verwenden und sehen, was während der Arbeit von DroidGuard passiert:



Die native Methode initNative () sammelt Daten über das Gerät und ruft die Java-Methoden hasSystemFeature(), getMemoryInfo(), getPackageInfo() ... das ist etwas, aber ich sehe immer noch keine solide Logik. Nun, alles was bleibt ist, die .so-Datei zu zerlegen.

libdroidguard.so


Glücklicherweise ist die Analyse der nativen Bibliothek nicht schwieriger als die mit .dex- und .jar-Dateien. Wir benötigen eine App ähnlich Hex-Rays IDA und einige Kenntnisse in x86- oder ARM-Assembler-Code. Ich habe mich für ARM entschieden, da ich ein gerootetes Gerät zum Debuggen hatte. Wenn Sie keine haben, können Sie eine x86-Bibliothek nehmen und mit einem Emulator debuggen.

Eine App ähnlich Hex-Rays IDA dekompiliert die Binärdatei in etwas, das C-Code ähnelt. Wenn wir die Methode Java_com_google_ccc_abuse_droidguard_DroidGuard_ssNative öffnen, sehen wir 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); ... 

Sieht nicht zu vielversprechend aus. Zuerst müssen wir ein paar vorbereitende Schritte machen, um dies in etwas Nützlicheres umzuwandeln. Der Dekompiler weiß nichts über JNI, daher installieren wir Android NDK und importieren die Datei jni.h. Wie wir wissen, sind die ersten beiden Parameter einer JNI-Methode JNIEnv* und jobject (this) . Wir können die Arten anderer Parameter aus dem Java-Code von DroidGuard herausfinden. Nach dem Zuweisen der richtigen Typen werden bedeutungslose Offsets zu JNI-Methodenaufrufen:

 __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); ... 

Wenn wir genug Geduld haben, um das vom Anti-Missbrauchsserver empfangene Byte-Array zu verfolgen, werden wir ... enttäuscht sein. Leider gibt es keine einfache Antwort auf "Was passiert hier?". Es ist reiner, destillierter Bytecode, und die native Bibliothek ist eine virtuelle Maschine. Einige AES-Verschlüsselungen wurden darüber gestreut, und dann liest die VM den Bytecode Byte für Byte und führt Befehle aus. Jedes Byte ist ein Befehl, gefolgt von Operanden. Es gibt nicht viele Befehle, nur ungefähr 70: read int, read byte, read string, Java-Methode aufrufen, zwei Zahlen multiplizieren, if-goto usw.

Wach auf, neo


Ich beschloss, noch weiter zu gehen und die Struktur des Bytecodes für diese VM herauszufinden. Es gibt ein weiteres Problem mit den Aufrufen: Manchmal (alle paar Wochen) gibt es eine neue Version der nativen Bibliothek, in der Byte-Befehlspaare verschlüsselt werden. Es hat mich nicht aufgehalten und ich habe beschlossen, die VM mit Java neu zu erstellen.

Der Bytecode erledigt alle Routinearbeiten zum Sammeln von Informationen über das Gerät. Beispielsweise lädt es einen String mit dem Namen einer Methode, erhält seine Adresse über dlsym und wird ausgeführt. In meiner Java-Version der VM habe ich nur etwa fünf Methoden neu erstellt und gelernt, die ersten 25 Befehle des Bytecodes des Anti-Missbrauchs-Dienstes zu interpretieren. Beim 26. Befehl las die VM eine weitere verschlüsselte Zeichenfolge aus dem Bytecode. Es stellte sich plötzlich heraus, dass es kein Name einer anderen Methode ist. Weit davon entfernt.
Befehl # 26 der virtuellen Maschine
Methodenaufruf vm-> vm_method_table [2 * 0x77]
Methode vmMethod_readString
Index ist 0x9d
Die Zeichenfolgenlänge beträgt 0x0066
(neuer Schlüssel wird generiert)
codierte Zeichenfolgenbytes sind 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
decodierte String-Bytes sind 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 6F 2B 36 33 32 36 30 37 35 34 39 39 36 33 66 36 36 31 40 67 6F 6F 67 6C 65 2E 63 6F 6D
Der dekodierte Zeichenfolgenwert ist ( Sie führen nicht nur Zeichenfolgen auf unserer .so aus! Sprechen Sie mit uns unter droidguard@google.com )
Das ist seltsam. Eine virtuelle Maschine hat noch nie mit mir gesprochen. Ich dachte, wenn du geheime Nachrichten siehst, die an dich gerichtet sind, wirst du verrückt. Um sicherzugehen, dass ich immer noch gesund bin, habe ich über meine VM ein paar hundert verschiedene Antworten vom Anti-Missbrauchs-Dienst gesendet. Buchstäblich alle 25-30 Befehle war eine Nachricht im Bytecode versteckt. Sie werden oft wiederholt, aber unten sind einige einzigartige aufgeführt. Ich habe die E-Mail-Adressen jedoch bearbeitet: Jede Nachricht hatte eine andere Adresse, etwa "droidguard+tag@google.com", wobei das Tag für jede eindeutig ist.
droidguard@google.com: Sei kein Fremder!
Du bist reingekommen! Sprechen Sie mit uns unter droidguard@google.com
Grüße von droidguard@google.com unerschrockener Reisender! Sag hallo!
War es leicht, das zu finden? droidguard@google.com würde gerne wissen
Die Leute unter droidguard@google.com würden sich freuen, von Ihnen zu hören!
Was ist das alles für ein Gobbledy-Buch? Fragen Sie droidguard@google.com ... sie würden es wissen!
Hey! Lust dich hier zu sehen. Haben Sie schon mit droidguard@google.com gesprochen?
Sie laufen nicht nur auf unserer .so! Sprechen Sie mit uns unter droidguard@google.com
Bin ich der Auserwählte? Ich dachte, es sei an der Zeit, nicht mehr mit DroidGuard zu spielen und mit Google zu sprechen, da sie mich danach fragten.

Ihr Anruf ist uns sehr wichtig


Ich habe meine Ergebnisse in der E-Mail mitgeteilt, die ich gefunden habe. Um die Ergebnisse ein wenig eindrucksvoller zu machen, habe ich den Analyseprozess ein wenig automatisiert. Die Sache ist, Strings und Byte-Arrays werden verschlüsselt im Byte-Code gespeichert. Die VM decodiert sie mit vom Compiler eingefügten Konstanten. Mit einer App ähnlich Hex-Rays IDA können Sie sie ziemlich einfach extrahieren. Aber mit jeder neuen Version ändern sich die Konstanten und es ist ziemlich unpraktisch, sie immer manuell zu extrahieren.

Das Java-Parsen der nativen Bibliothek erwies sich jedoch als überraschend einfach. Mit jelf (einer Bibliothek zum Parsen von ELF-Dateien) finden wir den Offset der Java_com_google_ccc_abuse_droidguard_DroidGuard_initNative Methode in der Binärdatei. Mit Capstone (einem disassemblierenden Framework mit Bindungen für verschiedene Sprachen, einschließlich Java) erhalten wir Assembler-Code und suchen ihn zum Laden von Konstanten Register.

Am Ende habe ich eine App bekommen, die den gesamten DroidGuard-Prozess emuliert: eine Anfrage an den Anti-Missbrauchs-Dienst stellt, die APK herunterlädt, sie entpackt, die native Bibliothek analysiert, die erforderlichen Konstanten extrahiert, die Zuordnung von VM-Befehlen auswählt und interpretiert den Bytecode. Ich habe alles zusammengestellt und an Google gesendet. Während ich dabei war, bereitete ich mich auf einen Umzug vor und suchte bei Glassdoor nach einem Durchschnittsgehalt bei Google. Ich beschloss, nicht weniger als sechs Ziffern zuzustimmen.

Die Antwort dauerte nicht lange. Eine E-Mail von einem Mitglied des DroidGuard-Teams lautete einfach: "Warum machst du das überhaupt?"



"Weil ich kann" - antwortete ich. Ein Google-Mitarbeiter erklärte mir, dass DroidGuard Android vor Hackern schützen soll (sagen Sie nicht!). Es wäre ratsam, den Quellcode meiner DroidGuard-VM für mich zu behalten. Dort endete unser Gespräch.

Interview


Einen Monat später erhielt ich eine weitere E-Mail. Das DroidGuard-Team in Zürich brauchte einen neuen Mitarbeiter. War ich daran interessiert mitzumachen? Natürlich!

Es gibt keine Verknüpfungen, um in Google zu gelangen. Mein Kontakt konnte lediglich meinen Lebenslauf an die Personalabteilung weiterleiten. Danach musste ich das übliche bürokratische Rigmarol und eine Reihe von Interviews durchlaufen.

Es gibt viele Geschichten über Google-Interviews. Algorithmen, Olympiadenaufgaben und Google Docs-Programmierung sind nicht mein Ding, deshalb habe ich mit meinen Vorbereitungen begonnen. Ich habe den Kurs „Algorithmen“ von Coursera Dutzende Male durchgelesen, Hunderte von Aufgaben auf Hackerrank gelöst und gelernt, mit geschlossenen Augen einen Graphen in beiden Dimensionen zu umgehen.

Zwei Monate vergingen. Zu sagen, dass ich mich vorbereitet fühlte, wäre eine Untertreibung. Google Text & Tabellen wurde meine Lieblings-IDE. Ich hatte das Gefühl, alles über Algorithmen zu wissen. Natürlich kannte ich meine Schwächen und erkannte, dass ich die Serie von 5 Interviews in Zürich wahrscheinlich nicht bestehen würde, aber kostenlos ins Disneyland des Programmierers zu gehen, war eine Belohnung für sich. Der erste Schritt war ein Telefoninterview, um die schwächsten Kandidaten auszusortieren und nicht die Zeit der Zürcher Entwickler mit persönlichen Besprechungen zu verschwenden. Der Tag war eingestellt, das Telefon klingelte ...



... und ich habe meinen ersten Test sofort nicht bestanden. Ich hatte Glück - sie stellten eine Frage, die ich zuvor im Internet gesehen und bereits gelöst habe. Es ging darum, ein String-Array zu serialisieren. Ich habe angeboten, Zeichenfolgen in Base64 zu codieren und durch einen Teiler zu speichern. Der Interviewer bat mich, einen Base64-Algorithmus zu entwickeln. Danach wurde das Interview zu einer Art Monolog, in dem mir das Interview erklärte, wie Base64 funktioniert, und ich versuchte, mich an Bitoperationen in Java zu erinnern.

Wenn jemand bei Google dies liest
Leute, ihr seid verdammte Genies, wenn ihr dort ankommt! Im Ernst. Ich kann mir nicht vorstellen, wie man alle Hindernisse beseitigen kann, die sie vor Ihnen haben.

3 Tage nach dem Anruf erhielt ich eine E-Mail mit dem Hinweis, dass sie mich nicht weiter interviewen möchten. Und so endete meine Kommunikation mit Google.

Warum es in DroidGuard Nachrichten gibt, die zum Chatten auffordern, weiß ich immer noch nicht. Wahrscheinlich nur für Statistiken. Der Typ, an den ich zuerst schrieb, sagte mir, dass die Leute dort tatsächlich schreiben, aber die Häufigkeit variiert: Manchmal erhalten sie 3 Antworten pro Woche, manchmal 1 pro Jahr.

Ich glaube, es gibt einfachere Möglichkeiten, ein Interview bei Google zu bekommen. Schließlich könnte man einfach einen der 100.000 Mitarbeiter fragen (obwohl zugegebenermaßen nicht alle Entwickler sind). Aber es war trotzdem eine lustige Erfahrung.

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


All Articles