Thursday, March 24, 2011

original smalihook java source

i've noticed some interest about a file that antilvl sometimes uses when cracking a program. it's called smalihook and it's purpose is to provide "hook" (actually replacement) methods for things like getting device id or signature. it's not really anything special, unless you actually modify the places in the app that make use of certain function calls. there is also a floating around that is actually a badly decompiled, broken version. i'd rather people have the real thing.

the variable strings that start with "%!" (ex: %!AppPackage%) are for antilvl to replace with the actual information when it copies it over.

if you want to use any of the functions here you can simply use antilvl.

if you just want to spoof your android_id or getdeviceid, try this:

package lohan;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Random;

import android.content.Context;
import android.content.SharedPreferences;
import android.telephony.TelephonyManager;
import android.util.Log;

 * TODO:
 * I wonder if it's possible to check getClasses or getMethods to detect this
 * hook
 * Hooks:
 * PackageManager
 * getInstallerPackageName
 * getPackageInfo
 * getApplicationEnabledSetting
 * checkSignatures
 * getDeviceID - requires context
 * File
 * length
 * lastModified

public class SmaliHook {

 // replace with random var per antilvl run
 private static String PrefsFile = "HookSettings";
 private static Context myAppContext = null;
 // random - always random, permute - unreversible permutation
 // session means until app is reinstalled
 private static enum DEVICE_ID_SPOOF {
 private static String LOG_TAG = "lohan";
 private static boolean DEBUG = true;
 private static boolean DUMP_STACK = false;

 public static Object invokeHook(Method method, Object receiver,
   Object[] args) throws IllegalArgumentException,
   IllegalAccessException, InvocationTargetException,
   NameNotFoundException {

  boolean HookEnabled = true;

  String methodClassName = "unknown-static";
  String methodName = method.getName();
  if ( receiver != null )
   methodClassName = receiver.getClass().getName();
  else methodClassName = method.getDeclaringClass().getName();

  if ( DEBUG ) {
   String logStr = "Invoke Hook: " + methodClassName + "."
     + methodName + "(";
   if ( args != null ) {
    String argStr = "";
    for ( Object arg : args )
     argStr += arg.getClass().getName() + ":" + arg + ", ";
    if ( argStr.length() > 2 )
     argStr = argStr.substring(0, argStr.length() - 2);
    logStr += argStr;

   Log(logStr + ")");


  if ( !HookEnabled ) return method.invoke(receiver, args);

  if ( methodClassName
    || methodClassName
    || methodClassName.equals("")
    || methodClassName.contains("ApplicationPackageManager") ) {
   if ( methodName.equals("getInstallerPackageName") ) {
    // Hook get installer package name
    return getInstallerPackageName((String) args[0]);
   else if ( methodName.equals("getPackageInfo") ) {
    // Hook get package info for signatures
    int flags = (Integer) args[1];

    if ( methodClassName
      .equals("") )
     return SmaliHook.getPackageInfo(
       ((PackageManager) receiver), (String) args[0],

    // Cannot simply recast receiver to
    // ContextImpl.ApplicationPackageManager or we get error
    Object result = null;
    try {
     result = method.invoke(receiver, args);
    catch (Exception e) {
     result = method.invoke(receiver, "%!AppPackage%");

    if ( (flags & PackageManager.GET_SIGNATURES) == PackageManager.GET_SIGNATURES ) {
     Signature[] spoofSigs = SmaliHook.spoofSignatures();
     // should only need to spoof the first one
     ((PackageInfo) result).signatures[0] = spoofSigs[0];

    return result;
   else if ( methodName.equals("getApplicationEnabledSetting") ) {
    int result = getApplicationEnabledSetting(
      (PackageManager) receiver, (String) args[0]);
    return (Object) Integer.valueOf(result);
   else if ( methodName.equals("checkSignatures") ) {
    // This could be detected by comparing a known installed package
    // that will not match signatures. Will deal with that if it
    // ever happens. :D
    return checkSignatures((String) args[0], (String) args[1]);

  else if ( methodClassName.equals("") ) {
   if ( shouldSpoofFileInfo((File) receiver) ) {
    if ( methodName.equals("length") ) { return length((File) receiver); }

    if ( methodName.equals("lastModified") ) { return lastModified((File) receiver); }

  // No hooks, work as normal
  return method.invoke(receiver, args);

 public static int checkSignatures(String p1, String p2) {
  Log("checkSignatures returning SIGNATURE_MATCH");

  return PackageManager.SIGNATURE_MATCH;

 public static int checkSignatures() {
  Log("checkSignatures returning SIGNATURE_MATCH");

  return PackageManager.SIGNATURE_MATCH;

 public static String getInstallerPackageName(String packageName) {
  // LIE and say installed from market :D
  String result = "";
  Log("getInstallerPackageName returning " + result);
  return result;

 public static int getApplicationEnabledSetting(PackageManager pm,
   String packageName) {

  int result;
  try {
   result = pm.getApplicationEnabledSetting(packageName);
  catch (IllegalArgumentException ex) {

  // Fake value if it's disabled
  if ( result == PackageManager.COMPONENT_ENABLED_STATE_DISABLED )

  Log("enabledSetting returning " + result);
  return result;

 public static PackageInfo getPackageInfo(PackageManager pm,
   String packageName, int flags) throws NameNotFoundException {

  // Get regular package info
  PackageInfo pi = null;
  try {
   pi = pm.getPackageInfo(packageName, flags);
  catch (NameNotFoundException e) {
   // Sometimes the app wants to know of other, helper apps are
   // installed or if trial / nonfull versions are installed
   // Fail normally if it's NOT checking for pro/full version stuff
   if ( !(packageName.toLowerCase().contains("pro")
     || packageName.toLowerCase().contains("full")
     || packageName.toLowerCase().contains("donate") || packageName
     .toLowerCase().endsWith("key")) )
    throw new NameNotFoundException();

   // Spoof with this package's info
   pi = pm.getPackageInfo("%!AppPackage%", flags);

  // Populate with fake signatures if flags ask for it
  if ( (flags & PackageManager.GET_SIGNATURES) == PackageManager.GET_SIGNATURES ) {
   Signature[] spoofSigs = SmaliHook.spoofSignatures();
   for ( int i = 0; i < pi.signatures.length; i++ )
    pi.signatures[i] = spoofSigs[i];
   Log("spoofing signatures for " + packageName);

  return pi;

 public static Signature[] spoofSignatures() {
  final int certCount = Integer.parseInt("%!CertCount%");
  Signature[] result = new Signature[certCount];

  // Usually check signature of package and not individual files
  // This will only fool checks of entire package
  // Individual files would require a lot of smali generation
  String replace = "%!SignatureChars%";

  for ( int i = 0; i < certCount; i++ )
   result[i] = new Signature(replace);

  return result;

 public static long length(File f) {
  long retVal = Long.parseLong("%!OrigFileSize%");

  if ( !shouldSpoofFileInfo(f) ) {
   retVal = f.length();
   Log("spoofing file length of " + f.getName() + " with " + retVal);

  return retVal;

 public static long lastModified(File f) {
  // long retVal = 1287850800968L;
  long retVal = Long.parseLong("%!OrigLastModified%");

  if ( DUMP_STACK ) Thread.dumpStack();

  if ( !shouldSpoofFileInfo(f) ) {
   retVal = f.lastModified();
   Log("spoofing file modified of " + f.getName() + " with " + retVal);

  return retVal;

 public static String getDeviceID() {
  if ( myAppContext == null ) {
   Log("getDeviceID has no context, can't spoof device id");
   return "";

  // final TelephonyManager tm = (TelephonyManager)
  // myAppContext.getSystemService(Context.TELEPHONY_SERVICE);
  // Log("this is my device id: " + tm.getDeviceId());

  // fallback id
  String spoofID = "359881030314356";
  if ( myIDSpoof == DEVICE_ID_SPOOF.RANDOM )
   spoofID = generateRandomDeviceID();
  else {
   SharedPreferences settings = myAppContext.getSharedPreferences(
     PrefsFile, Context.MODE_PRIVATE);
   spoofID = settings.getString("android_id", "");

   if ( spoofID.length() == 0 ) {
     spoofID = generateRandomDeviceID();
    else if ( myIDSpoof == DEVICE_ID_SPOOF.SESSION_PERMUTE )
     spoofID = getPermutedDeviceID();
    SharedPreferences.Editor editor = settings.edit();
    editor.putString("android_id", spoofID);
  Log("spoofing device id: " + spoofID);

  return spoofID;

 private static boolean shouldSpoofFileInfo(File f) {
  boolean result = false;

  if ( f.exists() ) result = false;

  if ( f.getName().contains("%!AppPackage%")
    && f.getName().endsWith(".apk") ) result = true;

  return result;

 public static void SetAppContext(Context c) {
  if ( myAppContext == null ) myAppContext = c;

 private static String getPermutedDeviceID() {
  // permute device id
  final TelephonyManager tm = (TelephonyManager) myAppContext
  // lazy lazy lazy
  // this is a permutation with a loss of information
  // prevent anyone from knowing the id even if they knew the mapping
  final int[] p = { 12, 2, 10, 2, 13, 8, 0, 3, 14, 3, 6, 9, 5, 1, 12 };

  String deviceId = tm.getDeviceId();
  String result = "";
  if ( deviceId != null ) {
   for ( int i : p )
    result += deviceId.charAt(i);

  return result;

 private static String generateRandomDeviceID() {
  // device id is 15 digit number with seemingly no pattern
  // only changed by factory reset or with root
  // ex: 359881030314356 (emulators is all 0s)
  return generateString("0123456789", 15);

 private static String generateString(String charSet, int length) {
  Random rng = new Random();
  char[] text = new char[length];
  for ( int i = 0; i < length; i++ )
   text[i] = charSet.charAt(rng.nextInt(charSet.length()));

  return new String(text);

 public static void Log(Object o) {
  if ( !DEBUG ) return;

  Log.d(LOG_TAG, String.valueOf(o));

 public static void DumpStackIfWeShould() {
  if ( !DUMP_STACK ) return;


 public static void DumpStack() {
  StackTraceElement[] ste = Thread.currentThread().getStackTrace();

  // skip the first 4, it's just local stuff
  String trace = "Stack trace:\n";
  for ( int i = 4; i < ste.length; i++ )
   trace += "  " + ste[i].toString() + "\n";

  Log.d(LOG_TAG, trace);

 public static void Toast(Object o) {
  // todo: implement


  1. Great Article..Thanks for the sharing..

    Bigo live is a GooD APK.Connect friends.
    Install the application here.....

    Bigo Live App

  2. Great Article..Thanks for the sharing..

    Bigo live is a GooD APK.Connect friends.
    Install the application here.....

    Windows Phone

    Youtube tenders and Facebook

    Bigo Live for Windows

    Bigo Live for Windows Phone

    brand new outlook

  3. Faisalabad is one of the biggest cities in Pakistan and the hub of the textile industry. It is widely acknowledged as the Manchester of Pakistan due to its large industrial role. The quality of the fabrics produced in this city has no parallel. In fact, the fabric is something of a specialty of Faisalabad. Many people from all over the country flock to this city for a spot of cloth shopping. We aim to provide you all of the best of Faisalabad at our store.

  4. Great Article..Thanks for the sharing..

    Bigo live is a GooD APK.Connect friends.
    Install the application here.....
    Uncovered lightbulbs may expose food to which type of hazard?


    Telegram > @leadsupplier
    ICQ > 752822040
    Email >

    >>1$ each without DL/ID number
    >>2$ each with DL
    >>5$ each for premium (also included relative info)

    *Will reduce price if buying in bulk
    *Hope for a long term business



    >Fresh Leads for tax returns & w-2 form filling
    >Payment mode BTC, ETH, LTC, PayPal, USDT & PERFECT MONEY


    >SSN+DOB Fullz
    >CC with CVV
    >Photo ID's
    >Dead Fullz
    >Spamming Tutorials
    >Carding Tutorials
    >Hacking Tutorials
    >SMTP Linux Root
    >DUMPS with pins track 1 and 2
    >Sock Tools
    >Server I.P's
    >HQ Emails with passwords

    Email >
    Telegram > @leadsupplier
    ICQ > 752822040


  6. toptan iç giyim tercih etmenizin sebebi kaliteyi ucuza satın alabilmektir. Ürünler yine orjinaldir ve size sorun yaşatmaz. Yine de bilinen tekstil markalarını tercih etmelisiniz.

    Digitürk başvuru güncel adresine hoşgeldiniz. Hemen başvuru yaparsanız anında kurulum yapmaktayız.

    tutku iç giyim Türkiye'nin önde gelen iç giyim markalarından birisi olmasının yanı sıra en çok satan markalardan birisidir. Ürünleri hem çok kalitelidir hem de pamuk kullanımı daha fazladır.

    nbb sütyen hem kaliteli hem de uygun fiyatlı sütyenler üretmektedir. Sütyene ek olarak sütyen takımı ve jartiyer gibi ürünleri de mevcuttur. Özellikle Avrupa ve Orta Doğu'da çokça tercih edilmektedir.

    yeni inci sütyen kaliteyi ucuz olarak sizlere ulaştırmaktadır. Çok çeşitli sütyen varyantları mevcuttur. iç giyime damga vuran markalardan biridir ve genellikle Avrupa'da ismi sıklıkla duyulur.

    iç giyim ürünlerine her zaman dikkat etmemiz gerekmektedir. Üretimde kullanılan malzemelerin kullanım oranları, kumaşın esnekliği, çekmezlik testi gibi birçok unsuru aynı anda değerlendirerek seçim yapmalıyız.

    iç giyim bayanların erkeklere göre daha dikkatli oldukları bir alandır. Erkeklere göre daha özenli ve daha seçici davranırlar. Biliyorlar ki iç giyimde kullandıkları şeyler kafalarındaki ve ruhlarındaki özellikleri dışa vururlar.

  7. A bar chart or bar graph is a chart or graph that presents categorical data with rectangular bars with heights or lengths proportional to the values that they represent. Here are few Bar Graph Examples for consideration.

  8. Very good written information. It will be valuable to anybody who employees it, as well as yours truly :). Keep up the good work ? for sure i will check out more posts. 메이저사이트

  9. You should take part in a contest for one of the highest quality sites on the web.
    I’m going to recommend this website!

  10. İnstagram yorum satın al ve profilinin büyük görünmesini sağla. İnstagram otomatik beğeni satın al ve hiç uğraşmadan profilini organik göster. İnstagram canlı yayın seyirci satın al ve fenomen gibi görün.

  11. It's nice to know that there are tv media online that helps in spreading news worldwide. A social community open for everyone online, and I must say, you have done a great job. Feel free to visit my website; 안전놀이터

  12. Its an amazing website, really enjoy your articles. Helpful and interesting too. Keep doing this in future. I will support you.Such a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. Feel free to visit my website; 온라인카지노

  13. I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work. Feel free to visit my website; 카지노

  14. Your style is really unique compared to other people I have read stuff from. I appreciate you for posting when you have the opportunity, Guess I’ll just book mark this site. Feel free to visit my website; 토토

  15. I really like looking at and I believe this website got some really useful stuff on it! 카지노사이트존

  16. I know this site presents quality based content and other information, is there any other website which gives these things in quality? 바카라사이트


  17. blank apparel perfect for the worksite in our wide selection of wholesale work jackets.

  18. As the Internet develops further in the future, I think we need to collect materials that people might be interested in. Among the data to be collected, your 메가슬롯 will also be included.

  19. I really enjoy your web’s topic. Very creative and friendly for users. Definitely bookmark this and follow it everyday.

  20. All your hard work is much appreciated. This content data gives truly quality and unique information. I’m definitely going to look into it. Really very beneficial tips are provided here and, Thank you so much. Keep up the good works.

  21. Do you like the kind of articles related to 메이저놀이터 If someone asks, they'll say they like related articles like yours. I think the same thing. Related articles are you the best.

  22. We still cannot quite believe that I was able to often be any type of those staring at the important points located on your blog post. 토토

  23. As expected, I can only see articles that can grow. I ll let you know around me. 토토

  24. is still among the leading topics of our time. I appreciate your post and look forward to more. 토토

  25. I like your blog. i ma happy to read your blog its very informative and your blog is really good and impressive you made it mice article. 스포츠토토

  26. will be praised anywhere. I am a columnist and I am writing articles related to 안전사이트

  27. After reading your article 메이저검증 was amazed. I know that you explain it very well. And I hope that other readers will also experience how I feel after reading your article


Do NOT post about or link to specific apps!