Good day all.
some times ago I asked about modifying an apk on the fly, the thing I would like to achieve is to track an ak from the download to the uninstall, via some track calls during its life.
the first thing first, of course is to find some way to "brand" it before the user downloads it on the phone.
things to take in advice are:
I will not use the normal store to give the apk to people.
I can't make the user wait for 30 seconds during the download to make the build on the fly.
I can't ask users to "register, or login" I'm not able to arrive to that part to the server, too bad.
so far I have only guessd about modify the apk code on the fly, to search for a pattern in its code, and change it accordingly to my needs and save it on the database.
for example, lets say that in the values.xml there is a url like this:
www.server.com?token=xxxxxxxxxxxxxxx
before servince the apk to the user, i search for the pattern xxxxxxxxxxxxxxx and change it with an alphanumeric value that i save on db, later, when the user go to the url via the apk, he will bring the token value and I could continue to track him again and again...
ok, this is the situation.. my question is simple... any ideas? am I mad... does someone already do this without any efforts and I'm try to reinvent the wheel?
You can't modify the apk, it would break the signing.
You would need to resign it. If you're able to resign it, you could easily change a value in an xml file of your choice.
It's rather easy to achieve with a bash script.
#!/bin/sh
sed -i ‘s/replace_key/actual_key/’ app/src/main/res/values/strings.xml
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name
why dont you save the URL prefixes in DB instead of values.xml or in code. and when the user installs the apk, do a server hit in the Application class and get your tokens the first time and persist in DB. Since you say you already know the logic to generate the tokens fo reach user, so it should not be a big deal to generate the same token when users ask your server for it.
Related
I am currently writing an app (App A) that depends on another app's data (App B).
Being an Android noobie, I thought that the only way to enable that is to use a ContentProvider and doing a query.
As it stands, the current way of doing is problematic, because App B has another signature than the one we're using for App A. This means:
The only way we can get our apps to talk to each other is to send our apk on a signing server so that it is also signed with the same key used for App B
This process is not automated, so it is therefore time-inefficient (takes around 2 - 4 mins).
This also mean we can't set debug points, which causes us a lot of pain when trying to see what data exactly is being returned by the ContentProvider
I did some more research and got told by a colleague that instead of signing our apk every time we make a slight change, we could extract the apk of App B and sign it with our key only once.
It led me to then create a keystore and key for my team, which I used to re-sign App B's apk and reinstall it on our test device. I then set my Android Studio to automatically sign the debug versions of App A with that exact same key.
The problem is that didn't change anything unfortunately...
It always ends up with the following exception being thrown:
Failed to find provider info for com.App.B.provider
(basically the same error thrown when we are using the default App B apk withouth sending our App A apk to the signing server)
Just to point out, if you're wondering, sending App A's apk to the signing server and running that does work and we're getting the data from the ContentProvider
So yea, I'm not sure what to do anymore... Any ideas ?
Also, since I'm not sure I have a clue of what I'm doing, any explanation of how these things are supposed to go would be very welcome !
<provider> tag should be placed inside <application> tag.
Also, be careful not to put it inside an <activity> tag.
Also you can get it working specify full path in <authorities> tag in manifest file (see SearchableDictionary sample code in SDK).
<provider android:name=".DictionaryProvider"
android:authorities="com.example.android.searchabledict.DictionaryProvider">
Alternatively you can use external storage,create directories and access the data from there directly.
I'm completely new to Calabash, have spent the day learning (including getting all setup).
One thing i need some help with is how to find IDs with ease. So i have an Android app, which contains the placeholder text Username.
I've tried the following however its simply not working (I keep getting a timeout error that I presume is down to it not being able to find):
When I enter "some#user.com" as "Username"
So my questions:
1- is the above actually correct if i want to enter that email into a field with Username
2- If i didnt have a placeholder like above how can i easily obtain References or IDs and use that in
Then /^I enter "([^\"]*)" into input field number (\d+)$/
Many Thanks.
To find locators you should use the calabash console. If you run
calabash-android console your_app.apk
then once it starts
reinstall_apps
and then
start_test_server_in_background.
Once it's running you can use the calabash query syntax to find the elements you want to interact with - https://github.com/calabash/calabash-ios/wiki/05-Query-syntax.
To get you started query("*") will return everything that is currently on screen.
query("id:'UserNameField'") would only return the element with the id UserNameField.
To check if it's the one you actually want you can use flash("id:'UserNameField'") to make it flash a few times on your emulator/device.
Then to interact with it, I would advise not using the pre written steps. Make your own step definition and remember to require in the files you need to use calabash if you haven't already
require 'calabash-android/operations'
When /^I enter the username (.*)$/ do |username|
enter_text("id:'UserNameField'", username)
end
The prewritten steps can be useful but they end up making your scenarios hard to read, and once you do some more complicated things with it you will probably have to write your own steps anyway.
To help you decide the correct commands for your step definition it can be useful to run the commands, e.g. enter_text("id:'UserNameField'", 'username_you_want') in the calabash console so you don't have to run your tests everytime you add a line.
I inherited an android app that has some security-related code that seems to basically be a no-op and that I'd like to remove. However, I'm concerned that my assessment of it as a no-op may be incorrect. The app sub-classes Application and, in its onCreate() method, gets the serial number of the certificate that the app was signed with:
ByteArrayInputStream bais = new ByteArrayInputStream(context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0].toByteArray()));
X509Certificate cert = CertificateFactory.getInstance("X509").generateCertificate(bais);
BigInteger sn = cert.getSerialNumber();
It then computes a hash of this value and compares it to an expected value that's embedded in a Java class as a byte[]. If the hashes don't match it throws an exception, crashing the app.
What this seems to prevent is someone stealing our source code, building the app and signing it themselves, then trying to install and run it. However, if someone has the source, they can simply remove the check at app launch. (Or change the embedded hash value to match the serial number of their certificate).
Is that accurate? Or is there some reason I'm missing that this code is useful?
I don't think it's to protect people from stealing your source code. It's to prevent people from replacing all the assets, thereby rebranding the app as their own, then re-signing it and putting it in the play store as their own.
However, the program shouldn't be verifying the serial number, which is easily modified. It should be verifying the signature.
If someone goes to the trouble of decompiling the app, as you said, they can remove that security check.
It's just another hoop for a cracker to jump through. Consider keeping it, but be sure to check the signature, not just the serial number.
I was updating my code for next version. After i clicked "export signed Application package", i got this error stating that my keystore does not exists. Actually i didn't delete it for sure. Now i am unable to update the app since the existing keystore vanished. Just to check whether i have deleted the file, i tried all recovery software. But unable to find. Tried all similar questions and there was no suitable result. Now please help me to recover the the old keystore.
(sorry for bad English)
First Check out ,Where is your key Storeexits ? at the default location or you have stored at some where else.
Default Path
Other Location
If you are storing your Key Store at other location then check out that rebuild time so you will get idea.
And if there is a okay with everything the issue is about password.
So,It will be good if you Create New Key Store and use it
You cannot create upgrade application if you loss app's keystore.
You have to rename your package, create new keystore and publish as a new application.
There are some rules about keystore:
When create keystore, you have to choose expired date is greater
than 20 years.
Create with password to sure that you can remember
it.
Keep the keystore file you generate with Keytool in a safe,
secure place (Best place is on Google Drive but please not
same account that you published your app, Dropbox, Box, ... ) and never loss
it. If you loss it, you have to do same above things.
Hope this help to remember.
This might be a complete "no-no," but I was wondering if it is at all possible to make an application debuggable after it has been signed and compiled into apk.
I'd like to be able to generate a random key on my server and then use this key to put an application I've published into a debuggable state.
//Build a hidden back door to request the randomly generated key on my server
//Input this key into an edittext box of some sort.
//Check this key against the server
//If key validates, put application in debuggable state.
I realize the potential security risks in doing this, but I was just wondering if it is at all possible.
It's fairly straightforward to generate a debuggable APK from a non-debuggable one if you are willing to re-sign and re-install, but you cannot do so to the already installed instance.
Anything in your actual code which behaves differently based on debuggable/non-debuggable status could also look at something else as Brent suggests, but that's of limited use as most of the debug functionality is built into Android, rather than part of the application code.
You may be able to provide flag-contingent alternatives to debug functionality though. For example, you can provide something to copy private files out to public storage. If you really wanted to, you could bake in a server that would provide a shell running as the application UID. But getting an actual JDWP debugger going may require extreme, android-build-dependent hackery as you'd likely have to provide your own version of a lot of system code.
At the simple end, having your program change its behavior by logging a lot of usually suppressed internal detail would be quite simple.
Do spend some time thinking about the security implications for your users.
Looking through the dev site I see access to the flags via a call to getApplicationInfo().flags; from a given Context. flags is not final, so it appears the getApplicationInfo.flags |= FLAG_DEBUGGABLE; would allow you to enable debugging at runtime: reference to ApplicationInfo doc:http://developer.android.com/reference/android/content/pm/ApplicationInfo.html.
Note, I have not tested this(not by an android environment at the momemnt).