50
Downloading market applications without the vending app
Mmmmm... Market Data...

Mmmmm... Market Data...

It turns out downloading a free application is actually pretty easy to reproduce. The things required by the google android servers are just four variables. The server needs to know your userId, authToken, deviceId and the applications assetId.
The userId is a unique number that is associated only with your gmail account, the one that is currently linked to the phone. I’m working on getting a generic way to grab this number, though I believe the request is buried in an ssl request to the google servers. So for now, you can obtain your own userId by doing a tcpdump of your market traffic, just do a download of an application and look for a “GET” request in wireshark. There does not appear to be a “hard” maximum character on this, I’ve seen userIds as low as 8 in length and as high as 13. A bad userId will return a 403 forbidden response.
The authToken is sent in cookie form to the server, to authenticate that the user is using a valid and non-expired token and well, is who they say they are! This is linked to the userId and must match the account that the userId is taken from. Expired tokens will return a 403 forbidden response.
The deviceId is simply your Android_ID, and is linked in anyway to the authtoken or user-id, so feel free to spoof this.
The assetId is a number (negative or positive) that identifies the current stream of the application you wish to download. More on this later when I cover how to get live market data. Note that this number is not always the same – it (appears) to change when something from the application is changed. Originally I referred to this in my research as a “cacheAppID” for just that purpose.

Hopefully someone will find this stuff useful 😉 Better than me just sitting on it forever!

Tim
43 Comments
  1. GENIUS im not a dev but this will definately help the ASOP

  2. Hello, Tim

    I did some sniffing via wireshark on emulator for vending.apk.
    I observe the following request string when searching an apk

    POST /market/api/ApiRequest HTTP/1.1
    Host: android.clients.google.com
    Connection: Keep-Alive
    Content-Length: 476
    user-agent: Android-Market/2 (dream CRC1); gzip
    content-type: application/x-www-form-urlencoded

    version=2&request=CsUCCuABRFF….ETXl5Qi1wUDcy

    Do you have any idea of how it is encoded or composed?
    I tried based 64 but only partial contents are human-readable after decoding 🙁

    Any advice would be highly appreciated~!

    Best regards,
    Aaron

  3. Hello,

    I noticed that this POST request might be encoded by google protocol buffer but still no luck when trying com.google.protobuf.UnknownFieldSet or CodedInputStream. Is there any hint or advice that could guide me through this? Just to make sure i’m going the right direction. Thanks very much 🙂

    Best regards,
    Aaron

  4. Looks great !

    Has anyone compiled this snippet into a nice, n00bz-friendly .apk?

    I’d love to use that as I refused to give Google any info since I started using my android….

  5. Hi,

    I run into same issue as Aaron’s post here, and used the same protocol buffer classes to retieve the data, but no luck. A

  6. Hi,

    I run into same issue as Aaron’s post here, and used the same protocol buffer classes to retieve the data, but no luck. Aaron or anyone else here, got a solution for this? Greatly appreciate it.

  7. maybe needing to use this package instead? – com.google.common.io.protocol

  8. @aaron and raul — it is a protobuf, you just need to figure out what fields are what

  9. does it matter if i use com.google.common.io.protocol package that is used in android or the standard implementation com.google.protobuf? Just to make sure I dont run into issues choosing the unsuitable one.

    another question – is the response from market encoded too as the same way as the request?

  10. Could be possible that the required userID is the one visible at http://www.google.com/profiles/me/editprofile (in the bottom of the page, under “Profile URL” ?

    I can’t test this, since I’m using android with an Openmoko Phone and, using an opensource verison of Android, I can’t use the default Vending.apk application.
    So I’m really waiting for a way to use an alternative market app to download the available freeware software there.

    Thanks for your work anyway.

  11. @Treviño

    Sorry no – that is the username, not a userId which appears in the requests.

  12. Tim, sorry. I’m in the same point with raul and Aaorn. We have this base64 encoded string. When we decode, I think I can understand all the fields, but is not a protocol buffer valid string (for my protobuf decompiler).

    Can you help us?

  13. @Alex

    We’ve discussed this via email before — if you’d like to reopen this subject then please reply again to that email.

  14. Hiya Tim,

    Wondering whether you’ve made any progress on decoding the protocol buffer formats for the market app. I’ve been playing with trying to decode the request string that I sniffed out, but protocol buffers aren’t the funnest to reverse engineer, even with the market app ddx files as clues.

    Have you cracked that little gem?

    -Nic

  15. Any chance someone can explain a way to programmatically get the UserID? I got the rest of it working..

  16. @Nas

    There is currently no (released) way to programmatically get the UserID.

    Most people have gotten the rest working, it helps that someone has published an api on google code for it 🙂

  17. java.io.IOException: Server returned HTTP response code: 411 for URL: http://android.clients.google.com/market/download/Download?assetId=7989310633059082746&userId=104400774266988007312&deviceId=2302DEAD532BEEF5367
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1243)
    at com.souapp.market.DownloadApp.main(DownloadApp.java:53)

  18. Tim,
    Is there a programmatically way to get the userId at this time?

    if not, can you point out some possible methods?

  19. @ABitNo

    Sorry, no – at this time there is no programmatic way to get the userId that has been found

  20. Looks like something has changed in the last day. Im no longer able to download the apps. Instead Im getting a
    Server returned HTTP response code: 500 for URL

    Anyone else experience this?

  21. @Conor:

    Yeap it looks like they’re verifying real device ids 😉

  22. Got it working again 🙂

    What is interesting for me is that some apps I can locate on the phone but when I use the api to check I get an Entries_count==0 which means it cannot find it.

    One example is an apk called beansprout.
    Easily found with phone and marketplace but not with the api.
    Frustrating as Im trying different carrier and operator variables and still get Entries_count==0.

    Arghh!!

  23. Just an observation I thought I’d share as Ive not seen anything posted about it elsewhere.

    While downloading some apks Ive observed through the packet capture that the whole process is done through https. Normally Id see an SSL handshake between the device and the server and then Id see the Get request as described above and this still seems to be the case for most of the apks Ive tested with.

    However while testing an apk called “cat print” and also “beansprout”, I found that I couldnt see the Get request at all and in fact the whole data transfer took place in https thus preventing me from seeing what was going on.

    Conor

  24. Hi,

    do you know if this way of downloading the actual apks can be adjusted to work for free copy protected files, too? The downloads seems to work quite differently, wireshark only sees encrypted communication on those files, no more http only 🙁

  25. @Smee

    Last I checked it works the same way, though you may need android-secure token

  26. Hi tim
    I am try to get the market applications without the vending app, and I follow your method to get the information about user-id. But I am not clear about how it is encoded , I tried base64 and protobuf , but still can’t get the result.

    can you offer me some advices?

  27. @Park

    I’ve responded via email to try and help you troubleshoot this matter 🙂

  28. Hi, I heard that now deviceID can’t be easily used, so can someone confirm that this method still works for downloading apps?

    Thanks

  29. @Tim
    Is the deviceID that you’re talking about the one we can get from TelephonyManager?

  30. @Bojan

    The device ID is still the android ID, this method still works fine.

    @Smith

    Yes, as stated above, the deviceId is the android ID

  31. Hello Tim

    i want to get UserID form Android.
    Please help me

    @Tim

  32. how to get UserID form Android?
    and now the userid should be linked to deviceid? otherwise download app will reture 400 error

  33. @edwardqwmw

    Using spoofed deviceId’s still works fine for me

  34. Hi Tim,
    I would like to get in contact with you, but since you don’t have an about page I can not find your email adress.
    You can contact me here: [email protected]
    and I’ll tell you what it’s all about.
    Kind greetings,
    Jip de Beer

  35. Does this method still work with the new Market?

  36. @JohnAdams Yes it does

  37. Hello, Tim

    I used “adb shell” got my deviceId and userId from history (in /data/data/com.android.providers.downloads/databases/downloads.db)

    It’s easy. And I already download a apk file.

    BUT, How do I get a application’s AssetId ?
    I only know a application’s detail uri that looks like ‘market://detail?id=/details?id=com.xxxxx.yyyy’ .
    How to convert “details id” to AssetId?

  38. Hi Tim,
    Is this still working? I can’t work out my auth Token.
    Can’t see any ANDROID cookie, but a MarketDA cookie.
    Yet does not work (answers 403).
    The rest (userId, deviceId, appId) should be ok.
    Thx

  39. hey i want to actualy how it works.. i m designing crawler which downloads all apk frm android market place.. give me some hints..

  40. Forbidden response received!
    java io exception

  41. Hi dulao5,

    Could you explain more details about getting userId? I’ve tried to read download.db but i only see assetId, token and downloadId.

    Thanks.

  42. I have been using downloading APKs till last week.
    Now, I always get ‘Server returned HTTP response code: 400’ when I try a url that succeeded before.
    Did the download url changed by the market?

  43. Here is the solution to what everyone is asking for;

    http://strazzere.com/blog/?p=293

Your Name Email Website