November 29, 2021

How to avoid reverse engineering of an APK file

If someone changes the .apk extension to .zip then they can unzip it and easily access all the app's resources and assets, and using dex2jar and a Java decompiler, they can also access the source code. It's very easy to reverse engineer an Android APK file - for more details see Stack Overflow question Reverse engineering from an APK file to a project.

I have used the Proguard tool provided with the Android SDK. When I reverse engineer an APK file generated using a signed keystore and Proguard, I get obfuscated code.

However, the names of Android components remain unchanged and some code, like key-values used in the app, remains unchanged. As per Proguard documentation the tool can't obfuscate components mentioned in the Manifest file.



* How can I completely prevent reverse engineering of an Android APK? Is this possible?

AFAIK, there is not any trick for complete avoidance of reverse engineering. And also Whatever you do to your code, a potential attacker is able to change it in any way she or he finds it feasible. You basically can't protect your application from being modified. And any protection you put in there can be disabled/removed.



* How can I protect all the app's resources, assets and source code so that hackers can't hack the APK file in any way?

You can do different tricks to make hacking harder though. For example, use obfuscation (if it's Java code). This usually slows down reverse engineering significantly.



* Is there a way to make hacking more tough or even impossible? What more can I do to protect the source code in my APK file?


As everyone says, and as you probably know, there's no 100% security. But the place to start for Android, that Google has built in, is ProGuard. If you have the option of including shared libraries, you can include the needed code in C++ to verify file sizes, integration, etc. If you need to add an external native library to your APK's library folder on every build, then you can use it by the below suggestion.

Put the library in the native library path which defaults to "libs" in your project folder. If you built the native code for the 'armeabi' target then put it under libs/armeabi. If it was built with armeabi-v7a then put it under libs/armeabi-v7a.

<project>/libs/armeabi/libstuff.so

March 31, 2021

How to Commit code to Git / Bitbucket from Android Studio

                             On this blog I am going to explain how to commit the code to a git or bitbucket repository from android studio.  I already created a got repository on bitbucket, Here I will show how to commit and push the code to the repository I created on bitbucket.

I am doing this using the command on Android studio Terminal,


Step 1

First we need to initialize the git on out code, 

git init

         This command creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository.


Step 2

Adding a remote git repository, 

git remote add origin YOUR_GIT_REPOSITORY_HTTPS_LINK

          To add a new remote, use the git remote add command on the terminal, in the directory your repository is stored at. The git remote add command takes two arguments: A remote name, for example, origin.


Step 3

Adding the files or changes to the repository, 

git add --all

         If this code is not working with you you can try the below code also, 

git add -A

         If you are in any subdirectory of the working directory, git add -A will add all files from the entire working directory, and git add . will add files from your current directory.

git add .

         If you are in any subdirectory of the working directory, git add .  will add new files and modifications, without deletions (on the current directory and its subdirectories).

git add -u

         If you are in any subdirectory of the working directory, git add -u will add stages modifications and deletions, without new files.


Step 4

Moves changes from the working directory to the local repository

git commit -m "YOUR_COMMIT_MESSAGE"

      This command takes the staged snapshot and commits it to the project history. My passing the Message you can Identify the changes we made on that commit.


Step 5

Upload local repository content to a remote repository, 

git push origin master --force

      This command  is used to upload local repository content to a remote repository. Pushing is how you transfer commits from your local repository to a remote repository.

--force This option overrides the “fast forward” restriction and matches our local branch to the remote branch.







March 28, 2021

Draw direction and by parsing direction API response

 I want to draw direction with waypoints based on the result of google direction API, From this URL I want to parse the response and draw the route on the google map.


I need to draw direction from 10.1849092, 76.3753045   to 10.3080271 , 76.3336779 

also I have some waypoints(this means need to reach destination through that points), Here is my waypoints 
10.2269749, 76.3750218
10.2632015, 76.3492569
10.2834370, 76.3420206


For this first we need to generate the request URL, Here is the format

https://maps.googleapis.com/maps/api/directions/json?
origin
=Toronto&destination=Montreal
&key=YOUR_API_KEY

This is is the format of URL without passing waypoints.

https://maps.googleapis.com/maps/api/directions/json?
origin
=Boston,MA&destination=Concord,MA
&waypoints=via:Charlestown,MA|via:Lexington,MA &departure_time=now
&key=YOUR_API_KEY

Here is the final URL from my origin , destination and waypoint locations,

https://maps.googleapis.com/maps/api/directions/json?origin=0.1849092,76.3753045&destination=10.3080271 ,76.3336779&waypoints=10.2269749,76.3750218|10.2632015, 76.3492569|10.2834370, 76.3420206&key=YOUR_API_KEY

Here will be the response format from Google Direction Api,

From this Google Direction Api response we use the value "routes" -> "overview_polyline"-> "points" to drew the direction, 

"overview_polyline" : {
            "points" : "yhd}@madqMD]CiA]eF[_HMaCKg@]]SUIUMq@Cw@Cy@M_AUkAsCqAuA{@Y]w@oAeA}BuAaDaAkCa@{@g@y@eCsCi@g@kAs@o@OuBWwCUs@As@@cBJoAVaI`CiC|@iD~@mBf@gFjB{C`AoBl@eEnA_HxBYHiEj@wDd@uEv@aEv@{BNkA@sACwEGy@?oAHiBVs@P}@\\aEpBuHpDuG~CqDbB{FpCeDrAyCv@kIlBwLrCkCl@qF~@cDf@yEx@}BZ[DCSdBWzAWCMvCg@rF_AhAQC_@S}Ak@oAs@qAKg@EiCOuAEi@PqCj@}DBc@?_EMwB?{AJoAAoAgAEoE?aCEkACHv@AZm@XmA`@m@H@FF~@KrAYhAe@xCIhFCxC?jBDf@Bj@ZzDFn@Nt@TlBB~@N`BDd@@Jn@IlCe@t@MBLpKaB`Eu@pEeAxKoCvJ{BvBq@tAm@JT]L}B|@yCv@kIlBwLrCkCl@qF~@cDf@yEx@}BZmCb@gMtB{GbAiHhAeBR_CJaA@mACuG[gBGiABcDHwGRqQl@yANaBZ{Bl@qB~@qAv@aCjByCfCmA|@uBhAwCvAkAd@kBl@sDhA}HbCyH|BeBx@oErB}Br@sFlAoAZu@Zu@\\}A`AwAdAa@^m@n@i@x@i@dAe@tAkBpGoAjDgCtGqFfOyErL{@jBsAbCmAtBo@x@s@t@i@f@mE|C?HEJ_DjC{CbCmD`DMLFFLLv@g@f@WTE^AxBJrCRv@L\\Lf@^d@p@HZH\\Rc@L[@@PD`@J~@HR?@IBET@l@BBG@OH[Fc@dADDAE@eAEGb@IZANCFm@CUACDAHS?_AIs@QAAMZSb@I]I[e@q@g@_@]Mw@MsCSyBK_@@UDg@Vw@f@_@e@oAdAmAp@gChAwAb@qHxBsHfCcAd@sBjAoHrFgAt@}@j@w@b@cBl@eBd@aANuAJ}EBqCEuCFoD`@s@NcAXSHEHQNwG|BXbDYcDwDxAOFEOiAb@cBt@mBrA}@~@cAvAkApB_AfCuAvDy@zBi@tAq@nAk@v@g@h@aAp@wAr@}@ZaATyB\\w@B}@@wACs@EoAOuBk@cM{DaAQwAImA?uIZgDBwDCsA@_AF}@LkAX{@ZcCdA{JhEyAl@cEnBkCvAsEnCiBnAcEdCaDtB{D`CaClA_GlCsErBJPkHzCwSjJCk@`GmCzG}CtHcDzMeGlEwBlMcIvA{@MItCkB"
         }


We are  using drawDirectionToStop() to draw the route, I am passing to the value of "points" decodeOverviewPolyLinePonts() for parse the response, Here is the functions


//This function is to parse the value of "points"
public List<LatLng> decodeOverviewPolyLinePonts(String encoded) {
    List<LatLng> poly = new ArrayList<LatLng>();
    if (encoded != null && !encoded.isEmpty() && encoded.trim().length() > 0) {
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }
    }
    return poly;
}

private void drawDirectionToStop(DirectionData.Overview_polyline overviewPolyline) {
    if (overviewPolyline != null) {
        List<LatLng> polyz = decodeOverviewPolyLinePonts(overviewPolyline.getPoints());
        if (polyz != null) {
            PolylineOptions lineOptions = new PolylineOptions();
            lineOptions.addAll(polyz);
            lineOptions.width(5);
            lineOptions.color(ContextCompat.getColor(getActivity(), R.color.colorAccent));
            mGoogleMap.addPolyline(lineOptions);
        }
    }
}