Android Hook teknolojisini ve basit gerçek savaşı anlayın

1. Kanca nedir

Kanca, İngilizce'de "kanca" anlamına gelir. Bu "kancayı" ne zaman kullanacağız? Sistem, Android işletim sisteminde kendi olay dağıtım mekanizmasını korur. Uygulama tetikleme olayları ve arka planda mantık işleme dahil olmak üzere uygulama programları da olay akışına göre adım adım yürütülür. Ve "kanca", olayın hedefe iletilmesinden önce, bir kanca olayı gibi, olayın iletimini durdurmak ve izlemek anlamına gelir ve olay bağlandığında kendi özel olaylarından bazılarını idare edebilir.

Kanca şematik

Hook'un bu yeteneği, kendi kodunu bağlanmış program sürecine "dahil etmesini" ve hedef sürecin bir parçası olmasını sağlar. API Hook teknolojisi, API yürütmesinin sonuçlarını değiştirmek için kullanılan ve sistem API işlevlerinin yürütülmesini yeniden yönlendirebilen bir teknolojidir. Sandbox mekanizması Android sisteminde kullanılır ve sıradan kullanıcı programlarının işlem alanı bağımsızdır ve programların çalışması birbirine karışmaz. Bu, diğer programların bazı davranışlarını bir program aracılığıyla değiştirme fikrini doğrudan gerçekleştirmemizi imkansız kılar, ancak Hook'un ortaya çıkışı, bu tür sorunları çözmemiz için bir yol açar. Elbette Hook'lar, Hook nesneleri ve Hook'lardan sonra farklı olay işleme yöntemlerine göre mesaj kancaları, API kancaları vb. Gibi farklı türlere ayrılmıştır.

2. Yaygın olarak kullanılan Hook çerçevesi

Android'deki Hook mekanizmasıyla ilgili olarak kabaca iki yol vardır:

  • Yetkiyi köklendirmek için, sistemi doğrudan bağlayın, tüm uygulamaları öldürebilirsiniz.
  • Kök ayrıcalıkları yoktur, ancak yalnızca Hook'un kendisi vardır ve sistemdeki diğer uygulamalarla hiçbir şey yapamaz.

Birkaç Kanca şeması:

Xposed

Zygote sürecini kontrol etmek için / system / bin / app_process programını değiştirerek, app_process başlatma işlemi sırasında XposedBridge.jar Jar paketini yükler ve böylece Zygote işleminin ve onun tarafından oluşturulan Dalvik sanal makinesinin ele geçirilmesini tamamlar.

Xposed, tüm Kanca İşlevlerinin ele geçirilmesini önyükleme sırasında tamamlar ve orijinal İşlev yürütmeden önce ve sonra özel kod ekler.

Cydia Substrat

Cydia Substrate çerçevesi, Apple kullanıcıları için jailbreak ile ilgili bir hizmet çerçevesi sağlar ve elbette Android sürümü de başlatılır. Cydia Substrate, herhangi bir işlemin kodunu değiştirebilen bir kod değiştirme platformudur. Java veya C / C ++ (yerel kod) ile yazılmış olursa olsun, Xposed yalnızca Hook app_process'te Java işlevlerini destekler.

Efsane

Legend, Android Root'suz ortamda bir Apk Hook çerçevesidir.Çerçeve basit bir kod tasarımına ve yüksek çok yönlülüğe sahiptir.Tersine mühendislikteki bazı Hook senaryoları için uygundur. İşlevlerin çoğu Java katmanına yerleştirilir, bu nedenle uyumluluk çok iyidir.

Prensip bu, yeni ve eski yöntemlere karşılık gelen sanal makine veri yapısını doğrudan oluşturmak ve ardından değiştirme bilgilerini belleğe yazmaktır.

3. API Kancasını uygulamak için Java yansımasını kullanın

Android platformunun sanal makinesini ve Java yansımasını enjekte ederek, Android sanal makinesinin işlevi (ClassLoader) çağırma biçimi, Java işlev yeniden yönlendirmesinin amacına ulaşmak için değiştirilir.Burada bu tür bir işleme Java API Kancası diyoruz.

Aşağıda, Hook View'ın OnClickListener aracılığıyla Hook'u nasıl kullanacağınız açıklanmaktadır.

Öncelikle View'ın setOnClickListener yöntemini girin, OnClickListener nesnesinin ListenerInfo adlı dahili bir sınıfta depolandığını görürüz, burada mListenerInfo, View'un bir üye değişkendir. ListeneInfo, OnClickListener, OnLongClickListener, OnKeyListener ve benzerleri gibi çeşitli View izleme olaylarını depolar.

public void setOnClickListener (@Nullable OnClickListener l) { if (! isClickable ()) { setClickable (doğru); } getListenerInfo (). mOnClickListener = l; } ListenerInfo getListenerInfo () { if (mListenerInfo! = null) { mListenerInfo dönüşü; } mListenerInfo = new ListenerInfo (); mListenerInfo dönüşü; }

Amacımız, OnClickListener'ı Hook'lamaktır, bu nedenle View için dinleyici olayını ayarladıktan sonra, OnClickListener nesnesini değiştirin ve özel işlemleri enjekte edin.

private void hookOnClickListener (Görünümü görüntüleyin) { Deneyin { // View'un ListenerInfo nesnesini alın Yöntem getListenerInfo = View.class.getDeclaredMethod ("getListenerInfo"); getListenerInfo.setAccessible (true); Nesne dinleyiciInfo = getListenerInfo.invoke (görünüm); // Orijinal OnClickListener nesnesini alın Sınıf < ? > listenerInfoClz = Class.forName ("android.view.View $ ListenerInfo"); Alan mOnClickListener = listenerInfoClz.getDeclaredField ("mOnClickListener"); mOnClickListener.setAccessible (true); View.OnClickListener originOnClickListener = (View.OnClickListener) mOnClickListener.get (listenerInfo); // Orijinal OnClickListener'ı özel bir OnClickListener ile değiştirin View.OnClickListener hookedOnClickListener = new HookedOnClickListener (originOnClickListener); mOnClickListener.set (listenerInfo, hookedOnClickListener); } catch (İstisna e) { log.warn ("hook clickListener başarısız oldu!", e); } } HookedOnClickListener sınıfı, View.OnClickListener { özel View.OnClickListener kaynağı; HookedOnClickListener (View.OnClickListener kaynağı) { this.origin = kaynak; } @Override public void onClick (View v) { Toast.makeText (MainActivity.this, "çengel tıklama", Toast.LENGTH_SHORT) .show (); log.info ("Tıklamadan önce, yapmak istediğinizi yapın."); eğer (kaynak! = null) { origin.onClick (v); } log.info ("Tıkladıktan sonra, yapmak istediğinizi yapın."); } }

Bu noktada, tıklama öncesi ve sonrasında belirli işlemleri gerçekleştirebilen OnClickListener'ı başarıyla kancalayarak hedefimize ulaştık. Aşağıdakiler çağıran kısımdır: OnClickListener'ı Button'a ayarladıktan sonra Hook işlemini gerçekleştirin. Düğmeye tıkladıktan sonra, günlük yazdırma sonucu şu şekildedir: onClick Tıkladıktan sonra tıklamadan önce.

Düğme btnSend = (Düğme) findViewById (R.id.btn_send); btnSend.setOnClickListener (new View.OnClickListener () { @Override public void onClick (View v) { log.info ("onClick"); } }); hookOnClickListener (btnSend);

4. Uygulama içi bildirimleri engellemek için Kanca'yı kullanın

Uygulamaya birçok SDK bağlandığında, SDK, bildirim göndermek için sistem hizmeti NotificationManager'ı kullanır, bu da bildirimlerin yönetilmesini ve kontrol edilmesini zorlaştırır. Şimdi bazı bildirimleri engellemek ve uygulama içinde bildirim gönderme işlemlerini kısıtlamak için Hook teknolojisini kullanacağız.

Bildirim göndermek, NotificationManager'ın notify yöntemini kullanır. Bir göz atmak için API'yi takip edelim. INotificationManager türünde bir nesne kullanacak ve bildirimi tamamlamak için enqueueNotificationWithTag yöntemini çağıracaktır.

public void notify (Dize etiketi, int id, Bildirim bildirimi) { INotificationManager hizmeti = getService (); // Kodun bir kısmını atlayın Deneyin { service.enqueueNotificationWithTag (pkg, mContext.getOpPackageName (), etiket, id, stripped, idOut, UserHandle.myUserId ()); eğer (id! = idOut) { Log.w (TAG, "notify: id bozuk:" + id + "gönderildi, geri döndü" + idOut); } } catch (RemoteException e) { } } özel statik INotificationManager sService; /** @saklamak */ statik genel INotificationManager getService () { eğer (sService! = null) { return sService; } IBinder b = ServiceManager.getService ("bildirim"); sService = INotificationManager.Stub.asInterface (b); return sService; }

INotificationManager, süreçler arası iletişim için Binder sınıfıdır. SService, istemci tarafındaki NMS (NotificationManagerService) aracısıdır. Gönderme bildirimleri sService'e devredilmeli ve NMS'ye aktarılmalıdır. Belirli ilkeler burada ayrıntılı değildir. İlgilenenler sistem hizmetleri hakkında bilgi alabilir Uygulamanın iletişim süreci.

SService'in statik bir üye değişkeni olduğunu ve yalnızca bir kez başlatılacağını gördük. SService'i özel bir servisle değiştirin. Bu doğru. Aşağıda pek çok Java yansıması ve dinamik proxy kullanılmıştır.Kodun yazılmasına özellikle dikkat edin.

private void hookNotificationManager (Bağlam bağlamı) { Deneyin { NotificationManager notificationManager = (NotificationManager) context.getSystemService (Context.NOTIFICATION_SERVICE); // Sistemin hizmetini alın Yöntem getService = NotificationManager.class.getDeclaredMethod ("getService"); getService.setAccessible (true); final Object sService = getService.invoke (notificationManager); Sınıf iNotiMngClz = Class.forName ("android.app.INotificationManager"); // Dinamik proxy INotificationManager Object proxyNotiMng = Proxy.newProxyInstance (getClass (). GetClassLoader (), yeni Sınıf {iNotiMngClz}, yeni InvocationHandler () { @Override public Object invoke (Object proxy, Method method, Object args) Throwable { log.debug ("invoke (). yöntem: {}", yöntem); eğer (args! = null args.length > 0) { for (Object arg: args) { log.debug ("tür: {}, arg: {}", arg! = null? arg.getClass (): null, arg); } } // İşlem sService tarafından ele alınır ve bildirimler engellenmez // return method.invoke (sService, args); // bildirime müdahale edin ve hiçbir şey yapmayın boş döndür; // Veya bildirilen Etikete ve kimliğe göre filtreleyin } }); // sService'i değiştirin Alan sServiceField = NotificationManager.class.getDeclaredField ("sService"); sServiceField.setAccessible (true); sServiceField.set (notificationManager, proxyNotiMng); } catch (İstisna e) { log.warn ("Hook NotificationManager başarısız oldu!", e); } }

Hook'un zamanlaması hala mümkün olduğu kadar erken, attachBaseContext'te çalışıyoruz.

@Override korumalı void attachBaseContext (Context newBase) { super.attachBaseContext (newBase); hookNotificationManager (newBase); }

Böylelikle bildirimlerin ele geçirilmesini tamamlamış olduk, Hook teknolojisinin gerçekten güçlü olduğu ve birçok eklenti prensibinin Hook'a dayandığı görülebilmektedir.

sonuç olarak:

Hook'un seçimi: statik değişkenler ve tekler, çünkü bir nesne oluşturulduktan sonra, değiştirilmeleri ve bulunmaları çok kolay değildir.

Kanca işlemi:

Hook noktalarını ararken, ilke statik değişkenler veya tekli nesnelerdir, genel nesneleri ve yöntemleri Hook'lamaya çalışın.

Uygun bir proxy yöntemi seçin, eğer arayüz ise dinamik bir proxy kullanabilirsiniz.

Esasları çalmak ve gönderileri değiştirmek - orijinal nesneyi bir proxy nesnesiyle değiştirin.

Android'in birçok API sürümü vardır ve yöntemler ve sınıflar farklı olabilir, bu nedenle API uyumluluğu konusunda iyi bir iş çıkarmalıyız.

Son olarak, editör tarafından derlenen Android ile ilgili öğrenme zihin haritasını ekleyin, böylece herkesin bir öğrenme yönü olsun.

Android gelişmiş

En son Android teknolojisi

Flutter

Mobil mimar

Bu Android eğitim materyallerine ve röportaj materyallerine ihtiyaç duyan herkesin ilgiye ihtiyacı var + özel mesaj "Android materyallerini" ücretsiz olarak yanıtlıyor!

Ayrıca grupta, ileri düzey kullanıcı arayüzü, performans optimizasyonu, mimar kursları, NDK, hibrit geliştirme: ReactNative + Weex ve diğer Android teknik bilgi mimarisi video materyalleri ve kariyer planlaması dahil olmak üzere üst düzey Android hakkında birçok ücretsiz öğrenme materyali bulunmaktadır. Ve röportaj rehberliği.

Çin'de resmi olarak piyasaya sürülen Sony PSVR, VR'yi nasıl izliyor? | Haftalık Daldırma
önceki
Modal Oynatma Kontrolü: Üç Hızlı MS-09R Charın Özel Şeytanı
Sonraki
Yapay zekanın geleceği nedir? Obama ve diğer büyük kahvelerin ne dediğini görün | AI Technology Review Weekly
Uncharted: Lost Legacy'de "çılgın" bir ayrıntı
Hoshino Resorts Tomamu, 2017 yazının başında açılıyor ve size bulut denizine yeni bir yolculuk getiriyor
Android Pie, Anahtar Deposu'nun yeni özelliklerini sunar ve güvenlik korumasını yükseltir
Ortalama 7 ay sonra bırakılan ilk iş olan 95'ten sonra, iş değiştirerek CXO olabilir miyim?
Model oyun kontrolü: RG Torukis değişim karanlık ekipmanı
Tesla'nın "beklenmedik" yeni ürünlerini bekliyor musunuz? | Haftalık Yeni Akıllı Sürücü
Android geliştiricilerinin gözünde "Sayfa nedir?" Sayfası
Model oyun kontrolü: GTO RGM-79HC Jim savunma özel tipi
Bu hafta oyun zamanı sıcak: FF15'i bu yıl Köln'ün kahramanı olarak düşünebilir misiniz?
Ödüller açıklanmak üzere2017 Jincheng Ödülleri Şangay Değerlendirme Toplantısı başarıyla sona erdi
Not 7 olayının tozu yerleşti ve devler kendi kendini söndürücü Büyük Şirket Haftalık
To Top