[Nasıl Yapılır] C# ve Xamarin ile Android üzerinde Keylogger çalışması (Gelen & Giden Çağrılar, Gelen Mesajlar)

Herkese tekrardan merhaba.

Bu aralar Android’e merak salmış vaziyetteyim.

Üniversite yıllarında yazdığım masaüstü uygulaması olan Muhbir – Informant için, gelen fazlaca talepler doğrultusunda mobil platforma entegre etmeye karar verdim. Prototip halini yazdım ve hatta geçen hafta Makros Bilgisayar adlı bilişim firması ile kurumsal anlamda satışı için anlaşma sağladım. Projeme destek oldular ve daha geniş kapsamlı ele aldık yazılımı. Önümüzdeki aylarda yeni ismiyle beraber ve daha kurumsal bir yapıda; yazılımın yeni özellikleriyle karşınıza çıkacak. Açıkçası bir yazılımcı için şu aralar ego yapıyorum, mazur görünüz 🙂

Aldığımız kararlar doğrultusunda hukuki anlamda ne kullanıcılarımızın ne de firmamızın sıkıntı yaşanmaması adına bireysel müşterilere değil, kurumsal firmalara satışını gerçekleştirmeye karar verdik. Çünkü bireysel kullanıcılar; kişisel bilgisayarlarına kuracaklarını iddia etseler de üçüncü bir kişinin bilgisayarına gizli kurduğu takdirde yasal sorumluluk tamamen kendisine aittir. Kaldı ki hiçbir şekilde yazılımı yazan sorumlu tutulamadığı gibi sadece şahitlik bakımından davaya müdahil olmaktadır. Çünkü yazdığım yazılımda sözleşmede tüm sorumluluk belirtilerek kullanıcı onaylayarak kurulum işlemini tamamlayabilmekteydi.

* * *

Bildiğiniz üzere Microsoft’un yaklaşık bir hafta kadar önce Xamarin’i satın alarak, daha iyi geliştirmeler yapacağını umduğum bu teknoloji sayesinde; Java öğrenmeden .Net ortamında kodlarınızı mobil platforma entegre edebilme imkanına sahipsiniz.

Xamarin’den bahsetmek gerekirse aslında bir bileşendir. Mono ile gelen bir teknoloji olmasına rağmen, adı günümüzde çok sık duyulmaya başlandı. Microsoft 2011 yılından beri bu teknolojiyi yakından izliyor ve şu ana kadar yapılan resmi açıklamalara göre 82 milyon dolar kadar bir yatırım yaptı. VS 2015 (Visual Studio) kullananlar bilirler ki Xamarin’i yeni projeler geliştirdiğimizde sol framede görebiliyorduk. Team Service veya Azure entegrasyonuyla da inceleme fırsatımız vardı. Gün geldi çattı ve Microsoft mobil platformda başarılı olmak için kendi renklerine katmak istedi, geçen hafta resmi olarak satın aldı.

.Net ortamında hep uygulama geliştirenler için oldukça ideal ve mobil platformlar için başlangıç seviyesi olabilir; ancak bir Java kadar rahat değil, bunu baştan söylemem gerekir. Çünkü optimize ve performans bakımından oldukça başarı geliyor bana Java. Yani Java, Android’te başarılı uygulama geliştirmek isteyenler için birebir.

“Ben .Net kullanırım, başka bir şey kullanmam” diyenleri de anlamam. Yenilik istiyorsak, algıyı açmak istiyorsak ve yeni diğer teknolojileri değerlendirme ihtiyacı doğurur, ki hangisi daha iyi hangisi kötü ayırt edebilelim. “.NET’ten şaşmam!” diyorsan, şuraya alalım sizi [1].

Microsoft’un Xamarin başarısını ise ileri zamanlarda göreceğiz. Yapılan resmi açıklamalara göre Nisan aylarında gelecek yeniliklerle performans bakımından oldukça daha ileri seviyeye çekileceğini belirtti. Merakla bekliyoruz efendim.

Şimdi gelelim bizim konuya..

* * *

Sizlere bu makaleyi video şeklinde çekip, en baştan nasıl yaptığımı göstermek isterdim ancak bu işlem için çok geç. Xamarin nasıl kurulur, nasıl debug modda telefon çalıştırılır, driverların kurulumu falan filan hiç Amerika’yı yeniden keşfetmeye gerek yok. Yeniden Windows kurulum ihtiyacım olduğunda elbet çeker, bu makalenin ilgili yerinde paylaşırım; sizlerde görmüş olursunuz.

Ben doğrudan kaynak kodlara, Xamarin’in genel yapısını ve bu işin püf noktasını göstermeye çalışacağım. Çünkü Xamarin ile alakalı araştırmalar yaptığımda, evet benden önce birileri “Gelen & Giden çağrıları” gösteren uygulamalar yazmışlar, hatta “Anında gelen & giden mesajları göstermeyi” bile yapmışlar 🙂

Ama bir kişi de, “Mevcut olan mesajları bulmayı” yazmamış, işte burada ben devreye giriyorum.

Hadi başlayalım.

* * *

Sisteminizde kurulu olması gerekenler:

  1. Visual Studio 2015 (Ultimate, Professional farketmez)
  2. Xamarin Studio
  3. Kendi Android telefonunuzda denemeyi düşünüyorsanız, ilgili telefonun driverlarının yüklü olması.

İlk yapmanız gereken VS 2015’te yeni bir proje oluşturmak, ilgili adımlar New Project ->Visual C# -> Android -> Blank App (Android)

Resim 1

Yeni proje ekledikten sonra, Resim 1’de görüldüğü gibi Solution Explorer’da ilgili alanlar gözükecektir.

Şimdi Xamarin’de uygulama geliştirmenin esas noktasına gelelim.
Layout ve Class’lardan bahsedelim.

Layout, aslında uygulamamızdaki tasarımıdır, katmanıdır. Yani uygulamaya eklemek istediğimiz nesneleri, araçları, resimleri veya yazıları burada yaparız. Default olarak “Main.axml” gelecektir. İçerisini açtığınızda varsayılan olarak eklendiğini göreceksiniz. Layout -> Main.axml yönergelerini takip ederek, ilgili axml dosyasına çift tıklamanız yeterlidir Solution Explorer üzerinden.

Resim 2

Resim 2’de gördüğünüz ve bir bakışta anlayacağınız üzere, bu bir basit “Kaç defa tıklandığını” gösteren bir uygulama. Klasik Hello World işte 😉

Peki bu tasarımı oluşturan asıl kodlara nerede?
İşte burada devreye XAML devreye giriyor. XML yapısına benzer, WPF ile tanıdığımız özellik var. Resim 2’in sol alt köşesinde bulunan Desing | Source kısmı dikkatinizi çekmiştir. Source’a tıklayalım ve görelim bu tasarımı oluşturan ilgili kodlara.

Resim 3

Resim 3’te görüldüğü üzere bir XML yapısından esinlenmiş ve ilgili butona ait nitelikler tanımlanmış. Yükseklik boyutu, içerisindeki metin, name (id) gibi alanlar tanımlı.

Burada dikkatinizi çekmesini istediğim şey, id alanı. Birazdan göreceğimiz Resim 4’te, bu buton nesnesine id üzerinden erişeceğiz. Burada Id yani Name kısmı MyButton diye geçmekte. Bir nesneye ID tanımlamak için @+id/Nesneİsmi mantığı kullanılmış.

Şimdi Solution Explorer’da yer alan MainActivity.cs dosyasına çift tıklayalım. Bu formun kullanıcıya gösterilmesi ve butona tıklandığında ne yapması gerektiğini ifade eden alanları inceleyelim.

Resim 4

Resim 4’te görüldüğü üzere kodlar gene hazır default olarak gelmiş ve Main.axml içerisinde yer alan butona tıklandığında yapılacak işlemler tanımlanmış.

Uygulamadaki MainActivity aslında bizim kod alanımızdır. Yani classlar üzerinden formdaki nesneye erişeceğiz, ilgili eventları, tanımlamaları burada yaparak çalışmasını istediğimiz şeyleri burada yapacağız.

Dikkatinizi çekerse Override edilmiş bir void içerisinde base’in altına yazılmış asıl kodlar.

SetContentView(Resource.Layout.Main): Uygulamamızın ilk çalıştırıldığında hangi formun ekrana geleceğini ifade eder. Masaüstünde formlarla uygulama yazan arkadaşlar Application.Run() özelliğini hatırlayacaktır. Mantık aynıdır.

Formdaki nesneye ise FindViewById ile ulaşmaktayız ve değişken olarak tanımladığımız bir buton nesnesine atanmış Resim 4’te.

Button button = FindViewById<Button>(Resource.Id.MyButton);

Yukarıdaki kod ile button adlı oluşturduğumuz Button değişkenine, Layout içerisinde yer alan buton nesnesine ulaştık. Buradaki en önemli etken ID’ye ulaşmaktır ve axml içerisinde tanımlı ilgili butonun ID’sinin MyButton olmasıdır.

button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };

Buradaki kodlarda ise layout içerisinde yer alan butona tıklandığında, hangi işlemi gerçekleştireceğini delegate ile tanımlamıştır. Yani bu kodlar derlenecek ve butonun Click event’ı çalıştığında ilgili delegate arasında yazdığımız kodlar aktif olarak, ilgili işlemi gerçekleştirecektir.

* * *

Mesajları okumak için örnek teşkil etmesi adına prototip yapabileceğimiz uygulama yazacağım. Yeni bir proje oluşturdum ve adını EKY.Mobile koydum.

Resim 5’teki gibi EKY.axml Layout’u oluşturdum olacaktır (Layout klasörüne sağ tıklayıp -> Add -> New Item dedikten sonra adını EKY.axml diye değiştirmeniz yeterli). XAML kodlarını Source alanına geçerek, kopyala/yapıştır şeklinde de otomatik gerçekleştirebilirsiniz:

Resim 5
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <EditText
        android:id="@+id/editText"
        android:layout_width="fill_parent"
        android:layout_height="198.0dp"
        android:textAlignment="viewStart" />
    <Button
        android:text="Button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/buttonEKY" />
</LinearLayout>

Buraya kadar işlemimiz form ekranımızın tasarımıydı.

Xamarin’de eğer Android’in bazı özelliklerinden yararlanmak adına API’lerini kullanarak çalışmak istiyorsanız, yetkilendirme tanımlamanız gerekmektedir. Örneğin şimdi biz bu uygulamamızda mesajları okumak, telefona gelen kayıtları görüntülemek istiyorsak; bunun için özel izinleri uygulamamızda tanımlamamız gerekmektedir.

Bu işlemi Solution Explorer üzerinden, ilgili projemizin Properties kısmından yapıyoruz.
Android Manifest sekmesinde, Required permissions alanlarından Resim 6’te yer alan alanlar seçilmelidir.

Resim 6

Şimdi gelelim kodlara.

Direk doğrudan kodları, MainActivity.cs içerisinde yer alan alana yapıştırmanız veya kendinize göre düzenlemeniz yeterlidir.

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Webkit;
using Android.Provider;
using System.Collections.Generic;
using Java.Text;
 
namespace EKY.Mobile
{
    [Activity(Label = "EKY.Mobile", MainLauncher = true, Icon = "@drawable/icon")]
    [IntentFilter(new string[] { "android.provider.Telephony.READ_SMS" }, Priority = (int)IntentFilterPriority.HighPriority)]
    public class MainActivity : Activity
    {
 
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
 
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.EKY);
 
            // Get our button from the layout resource,
            // and attach an event to it
 
            Button button = FindViewById<Button>(Resource.Id.buttonEKY);
 
            button.Text = "GİT!";
            button.Click += delegate
            {
                //Gelen son 10 çağrıyı bulur. 
                //Değiştirmek için querySorter değişkeninde yer alan limit 10 kısmını değiştirmek yeterli
                var editText = FindViewById<EditText>(Resource.Id.editText);
                editText.Text = "http://eniskurtayyilmaz.com";
                editText.Text = "Gelen çağrılar:" + "\n";
                string queryFilter = String.Format("{0}={1}", CallLog.Calls.Type, (int)CallType.Incoming);
                string querySorter = String.Format("{0} desc limit 10", CallLog.Calls.Date);
                Android.Database.ICursor queryData = ContentResolver.Query(CallLog.Calls.ContentUri, null, queryFilter, null, querySorter);
                while (queryData.MoveToNext())
                {
                    editText.Text += queryData.GetString(queryData.GetColumnIndex(CallLog.Calls.Number)) + "\n";
                }
 
                //Giden son 10 çağrıyı bulur
                editText.Text += "Giden Çağrılar:" + "\n";
                queryFilter = String.Format("{0}={1}", CallLog.Calls.Type, (int)CallType.Outgoing);
                querySorter = String.Format("{0} desc limit 10", CallLog.Calls.Date);
                queryData = ContentResolver.Query(CallLog.Calls.ContentUri, null, queryFilter, null, querySorter);
                while (queryData.MoveToNext())
                {
                    editText.Text += queryData.GetString(queryData.GetColumnIndex(CallLog.Calls.Number)) + "\n";
 
                }
 
                /* 
                    Gelen SMS'leri bulmak için gerekli alan.
                    Giden smsler için Query içerisine "Telephony.Sms.Outbox.ContentUri" yazmak yeterlidir.
                */
                editText.Text += "-------------" + "\n";
                Android.Database.ICursor c = ContentResolver.Query(Telephony.Sms.Inbox.ContentUri, new String[] { "address", "body", "date" }, null, null, null);
                while (c.MoveToNext())
                {
                    long unixDate = long.Parse(c.GetString(c.GetColumnIndex("date")));
                    DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                    DateTime date = start.AddMilliseconds(unixDate).ToLocalTime();
                    editText.Text += "Gönderen:" + c.GetString(c.GetColumnIndex("address")) + "\n";
                    editText.Text += "Mesaj:" + c.GetString(c.GetColumnIndex("body")) + "\n";
                    editText.Text += "Tarih:" + date.ToString() + "\n";
                    editText.Text += "-------------" + "\n";
                }
            };
        }
    }
}
 

Unutmamanız gereken bir diğer önemli konu ise ilgili yazılıma bulunduğu kod bloğunun, class başlangıcında yetki tanımlanmasıdır. Bu olmadan mesajları okumayı aklınızdan bile geçirmeyin 🙂 (Tecrübeyle sabittir)

[IntentFilter(new string[] { "android.provider.Telephony.READ_SMS" }, Priority = (int)IntentFilterPriority.HighPriority)]

Uygulamayı cep telefonunda çalıştırdıktan sonra, bendeki Screenshot’larını da sizlerle paylaşayım Resim 7-8-9):

Resim 7
Resim 8
Resim 9

Bu makalede geçen bütün kodları github adresimde bulabilirsiniz:
https://github.com/eniskurtayyilmaz/EKY.Mobile-Android-Keylogger–Prototype-

Bu makale yazılırken kullanılan yardımcı şarkılar [2]

Bir sonraki makalede görüşmek üzere.

Enis Kurtay YILMAZ

Microsoft mu yoksa Linux mu; PHP mi ya da ASP.Net mi; yoksa Elma veya Armut mu?

windows-mac-or-linux

Herkese tekrardan merhaba.

Çok tartışmalı ve her seferinde aldığım geri bildirimler doğrultusunda yazılımcı arkadaşların bana gerek forumlarda, sosyal medyada veya attıkları e-postalarda bahsettikleri bir konuyu biraz karışık ve biraz da basit manada ele almak istiyorum.

Başlık, evet biraz tuhaf.

* * *

Kendimden ve sektörden örnekler vererek bu konuyu açıklığa kavuşturma hedefindeyim.

Aldığım freelancer işlerde, çalıştığım şimdiki veya önceki şirketlerde yaptığım projelerde; yapısı gereği yazdığım uygulamalar veya bileşenler çoğunlukla son kullanıcıya hitap eder.

Biz yazılımcılar uygulama geliştirirken yaptığımız ilk şey analizdir. Bu yadsınamaz bir gerçektir. Yani bir müşteri bizden bir X yazılımı / Y websitesi / Z bileşeni yaratmamızı istediğinde; önce onu anlamak isteriz. Bu müşteri ne istediğini biliyor mu?

(Bu soru, yüzlerce proje geliştirdikten sonra ortaya çıkan bir sorudur tabi. Çünkü müşteri çoğu zaman ne istediğini bilmez veya yapmak istediği şey hakkında bilgi eksikliğinden tarif edemez. O yüzden bu soruyu gerekirse defalarca kendimize ve onlara sorarak teyit almaya çalışırız, “Kullanıcı buraya tıkladığında yapılmasını istediğiniz şey nedir?, bu alan neyi ifade eder?, neyi tetiklemeli?, istediğiniz sonuç nedir?” vb. gibi sorular sorarız. Önce müşteriyi ve müşterinin istek/ihtiyaçlarını anlamak gerekir. Emin olun, müşterinin her zaman danışacağı veya fikir alacağı; bilgili veya çok az bilgili insanlar etrafında vardır. Fakat size değer katacağı yeni bilgiler veya yeni teknolojileri bile keşfetmenize olanak sağlayabilir. Tek yapmanız gereken Google amcaya sormaktır.) 

Eğer müşteri ne istediğini biliyorsa veya siz bu sorunu çözüme kavuşturmayı başarmışsanız; geriye hangi yöntemler, hangi teknolojiler, hangi bileşenler kullanılmalı şeklinde; kısacası “Hangi X kullanılacak” denklemleri kafanızda belirmeye başlar.

Bu süreçte vereceğiniz cevaplar çoğunluk kişisel olmakla beraber geleceğe bakış açınızla alakalıdır. Örneğin,

  • Desteği bitmiş bir teknolojiyi/bir bileşeni kullanıp, bir an önce işi çözüp zamanı nakit durumuna çevirmek ama gelecekte aynı müşteri size “Yeni özellikler eklenmeli isteğiyle” geldiğinde sıfırdan yazmak zorunda kalmak mı?
  • Performans bakımından şahane hızlı ama hiç bilmediğiniz bir teknolojiyi öğrenmek mi?
  • “Ya ben yazayım, nasıl çalışıyorsa çalışsın, zaten bir daha böyle iş ne zaman gelir?” mantığıyla işe tamamlamak mı?

Acemisinden profesyoneline; çakalından işin ehlisine kadar pek çok kişinin takıldığı yerlerdendir bu.

Profesyonel yazılım şirketleri veya geliştiriciler ise “Gelecek vaat eder mi?”, “İlerde bize ihtiyaç duyarlar mı? Duymazlarsa ne yap(ıl)malı?” sorusunun cevabını öngörür.

* * *

Bu yazıyı yazarken aklıma üniversite yıllarından Microsoft sevdalısı; hayranı ve bağımlısı bir arkadaşım geldi. Varsa yoksa “.Net” derdi. Biraz da egoistti. Microsoft tarafından aldığı MCPD sertifikalı bir arkadaşımızdı. Mesleki bakımından gerçekten başarılı bulduğum bir arkadaş olsa da bakış açılarımız tamamen çok farklıydı bu sektör ile alakalı. Çünkü gerektiğinde takım oyununu oynaman gerektirir bu sektör. Bu yüzden yenilikçi bakış açısına sahip olman gerekir.

Bir keresinde üniversite içerisindeki Teknopark gezimizde gerçekten profesyonel bakış açısına sahip, senelerini yazılıma vermiş; lise mezunu ve 4 milyon dolar üzerinde ciroya sahip olduğu yazılım şirketinin sahibine saçma sapan bir soru sorup, beş-on dakika sorular havada uçuşturarak “.Net” i kendince savunmuştu (Bana sorarsanız daha temkinli yaklaşabilir veya daha somut konuşarak işi çözümleyebilirdi. Bu şirket sahibi ağabeyimiz, %100 Pure Java takılırmış zamanında ama sırası geldiğinde başka teknolojileri de kullanmaktan çekinmezmiş). Bu deneyimli ve başarılı yazılımcı ağabeyimizin de cevabı yerindeydi, “Gözlerini biraz aç, yazılım sadece Microsoft’tan ibaret değil.”

Tabi bu bahsi geçen arkadaşım, üniversite sonrasında edindiği sektörel tecrübelerden artık şimdi Linux ortamında da uygulama geliştirmeye başlamış. Üstelik script bile yazıyormuş, laf aramızda kalsın ama arada bloğuna bakıp inceleme fırsatı buluyorum. Başarılı buluyorum. .Net’ten de biraz uzaklaşmış sanki. Ağabeyin verdiği tavsiyeye de uymuş.

* * *

Microsoft ile Linux’un bile yıldızları barıştı, siz neyden bahsediyorsunuz?

* * *

Uygulama geliştirirken, körü körüne bakmayı sevmem; kaldı ki şirketler de böyle yapmaz. Elindeki yeteneği ve bilgiyi dikkate alır çoğunlukla, alsalar da asıl olay; yazının başında belirttiğim gibi gelecek, zaman maliyeti ve bakış açısı ile ilgilidir.

Örneğin, ben web servislerle iletişim halinde olacak paket gönderen/alan bir web uygulaması yazacağım ve frameworklere ihtiyacım var. Hadi hep bildiğimiz teknolojiyi kullanalım, ASP.Net’te ilgili web servisini referans olarak gösterip, projeme dahil etmem sadece dört-beş tıklama. Hadi diyelim paket alıp gönderen kodu da yazdım.. Peki, ilgili paketi gönderip, cevabı response ederken bu arada geçen süre ne kadar verimli? Daha aza indirgeyen başka bir şey var mıdır?

Araştırmaya başlarım.
Benim gözümde bir şeyi araştırırken üç temel kavram vardır;

  1. Sizden önce Amerikayı keşfeden mutlaka biri vardır.
  2. Yanlış şekilde araştırıyor olabilir misin?
  3. İlk keşfeden sen olabilir misin?

Dileyim ki, bulduğum sonuçlar arasında yaptığıma benzer ama farklı içerikler kullanan biri “PHP ile birlikte Laravel kullanarak daha hızlı verim elde ettiğini” iddia etmiş.

Denerim, acımam..

Denemek için aldığım kodu komple indirdim, kendime göre düzenledim ve çalıştırdım (diyelim)..

İncelemeler sonucu, verimlilik ve performans bakımından, ASP.Net’ten daha etkin ve başarılı bir şey olduğuna kanaat kıldım. “Evet bu sefer oldu, şahane çalışıyor!”. 

Hiç vakit kaybetmeden bu projeyi kendime göre yeniden yapmaya karar veriyorum. Laravel’in son versiyonunu indiriyorum, önceden bulduğum kodları kendime göre entegre etmeye çalışıyorum.. Bir de ne göreyim, önceki indirdiğim kodlar Laravel’in eski versiyonu içinmiş.. Hayde..

Dur bakayım eski versiyonuna ait dökümantasyon var mı?

beş-on dakika sonra..
E, o da yok; ne yapacağız şimdi?

İşte burada bir çıkmaza girdik. Eski versiyona artık destek kalkmış.
Biraz daha araştırıyorum ve araştırmalarımın sonucunda CodeIgniter ile bu işi başaranları keşfediyorum. Ama ben hiç CodeIgniter kullanmamış biriyim.. Birkaç deneme yapıp, makale okuduktan sonra bakıyorum ki Laravel’den bile daha iyiymiş ve CodeIngiter framework’un dökümantasyonu şahane olmakla beraber, desteği hep verilecekmiş..

Hadi CodeIgniter öğrenelim,

bir-iki gün sonra..
aaa şahane bir şey lan bu!

* * *

Yukarıdakine benzer bir senaryoyu bir ay kadar önce bir projede yaşadık.
Neyse ki şirketteki deneyimli ağabeylerim sayesinde sorunu kısa sürede çözümledik.
Şimdilerde ise çatır çutur yazıyorum kodları acımadan.

* * *

Bu ana kadar anlattıklarımı gelişi güzel yazdım.
Yani akademik dilden çok, daha samimi şekilde ifade etmek istedim ama bazı detayları atlayarak 🙂

Daha fazla bilgi ve bakış açısı için; yazılım geliştirme süreci ile alakalı bu tezi incelemenizi isterim.

Bir sonraki makalede görüşmek üzere.

Enis Kurtay YILMAZ