Kilka dni temu na Redditie pojawił się wątek gdzie jeden z użytkowników zauważył, że VS 2015 dodaje do kodu aplikacji napisanej w C wywołania funkcji, które brzmiały dość podejrzanie. No bo kto by się troszkę nie zaniepokoił gdy skompilowany pusty main() obdarowuje nas dodatkowym opakowaniem w postaci wywołań __telemetry_main_invoke_trigger ?

Zaciekawiony tematem wrzuciłem info o tym na naszą polską grupę .NET na Fb z pytaniem czy dla C# jest podobnie. W wątku na redditie nie znalazłem jednoznacznej odpowiedzi poza narzekaniem jednego użytkownika, jaki C# i Java to zuo. Mając więc chwilę czasu postawiłem sprawdzić co i jak w temacie…

Swoją analizę rozpocząłem od sprawdzenia czy faktycznie będę miał dodane te wywołania w czystym int main(). Z trudem przypomniałem sobie z czym to C się jadło i po wielogodzinnych męczarniach ( 🙂 )  udało mi się skompilować projekt.

int main() {
 return 0;
}

Po obejrzeniu kodu wynikowego w IDA rzeczywiście pojawiły się tam wywołania
telemetry_vs2015-update2No ok – ale to na najnowszym VS 2015 update 2. Jak na czystym VS 2015? Też…VS 2013? Nope. Skoro już wiemy, że sytuacja występuje – zobaczmy jak się zachowa C#?
Podobnie jak w przypadku C, ale już z mniejszymi trudnościami, skompilowałem pusty projekt dla C sharpa.

namespace ConsoleApplication1
{
 class Program
 {
   static void Main(string[] args)
   {
   }
 }
}

Na pierwszy ogień oczywiście pójdzie podejrzenie exe’a w disassmie dla .NET – ja lubię i używam IlSpy’a tak więc zacząłem od niego. Zarówno przeglądając kod na poziomie C# jak i ILa nic podejrzanego tam nie znalazłem.

telemetria_ilspy_csharp telemetria_ilspy_il

Przegląd pozostałych elementów binarki także nie wykazał nic nadzwyczajnego. Pusty <Module> (do którego nota bene można wstrzyknąć kod – tylko nie z poziomu źródeł C# – Fody Module Init). Tak więc czyżby “problemu” w świecie .NET nie było? Czyżby tym razem C#/.NET był w czymś lepszy?

we-need-to-go-deeper

No tak – ale może przecież samo wywołanie tej złej telemetrii może być niżej – tj. zanim zostanie wykonany nasz kod managed. Zobaczmy…

Jako, że moja wersja IDA nie pozwala na podgląd binarek managed posłużymy się starym dobrym…windbg. Na początek sprawdźmy skąd są importowane te wywołania telemetryczne. Po załadowaniu natywnej dll’ki i krótkim rekonesansie odnajdujemy “podejrzaną” dll’kę – VCRUNTIME140D.dll – zastawiamy pułapkę na VCRUNTIME140D!__telemetry_main_return_trigger jeszcze tylko jedno g i lądujemy w telemetrycznej metodzie:

inside

No dobra – a .NET? Ładujemy naszą zarządzaną dll’kę do WinDbg; breakpoint na tym samym miejscu i uruchamiamy. Hmm…tym razem bez komunikatu Breakpoint 0 hit. Przeglądając listę załadowanych modułów możemy potwierdzić, że nasz podejrzany moduł tym razem nie został załadowany. W sumie nie dziwne, bo nazwa sugeruje, że jednak jest to jakaś dll’ka dla języka C a nie C#. Pytanie jednak co z tymi dll’kami które są ładowane? Czy tam nie ma nic podejrzanego? Zobaczmy…
x /D *!*telemetry*
i troszkę czekamy bo jest tego sporooo… (pełna lista)
Nic z naszych wcześniej podejrzanych funkcji, ale słowo klucz (telemetry) występuje. Ustawmy pułapkę na pierwsze z brzegu (i w sumie ciekawie brzmiącej) clr!Assembly::TelemetryLogTargetFrameworkAttribute

Odpalamy….i lądujemy w TelemetryLogTargetFrameworkAttribute. Czyli jednak coś jest gromadzone. A jak sprawa ma się z aplikacją skompilowaną w VS 2013?

Metod zawierających słowo telemetry też trochę występuje – ale nie tyle co przy użyciu najnowszej edycji IDE – naszej TelemetryLogTargetFrameworkAttribute nie widać. A jak przeszukamy wujka google to dostaniemy link do Assembly.hpp gdzie widzimy naszą metodę w coreclr. CoreClr. Aha…

Ten wpis temat zamknę na tym. Widzimy, że nawet taka szybka i pobieżna analiza daje nam podstawy przypuszczać, że coraz więcej informacji jest zbieranych i gromadzonych. Czy powinniśmy się tego obawiać? Chyba nie…kto wie jednak co tam jeszcze siedzi w przepastnych czeluściach .NETa?

Temat na pewno nie został wyczerpany – sądzę, że na ten temat przyjdzie napisać jeszcze nie jeden post.