tag:blogger.com,1999:blog-72711726418195232832024-03-18T04:19:43.780-07:00android crackingtools and techniques for android reversing. educational purposes only!lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.comBlogger68125tag:blogger.com,1999:blog-7271172641819523283.post-73999863727250310932015-07-03T08:23:00.001-07:002015-07-03T08:32:31.840-07:00increase soundcloud cache<div dir="ltr" style="text-align: left;" trbidi="on">
tl;dr: i can't link to the apk because i'm not getting banned for you. you can repeat these steps yourself if you're interested. i can't stop anyone from posting a link in the comments. sorry!<br />
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
<br /></h3>
<h3 style="text-align: left;">
background</h3>
soundcloud used to let you cache a lot of songs for offline listening. then they took it away. i'm half sure they have some reason for doing it that has vaguely to do with money dollars. but, hey, when you have a nice feature and you take it away, peeps get mad. the mad peeps are here:<br />
<a href="https://www.soundcloudcommunity.com/soundcloud/topics/how-do-i-change-the-size-of-the-mobile-audio-cache-on-android">https://www.soundcloudcommunity.com/soundcloud/topics/how-do-i-change-the-size-of-the-mobile-audio-cache-on-android</a> <i>(warning, internet drama)</i><br />
<br />
many users recommend downloading 2.8.3, which you can find in the crybaby fest linked above. personally, i'm not content rolling with an ancient version like some bucolic hillbilly. nah. i must break the latest version and get all those sweet sweet features.<br />
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
<br /></h3>
<h3 style="text-align: left;">
compare old and new</h3>
i reckoned the best way to find where the cache was controlled would be to compare 2.8.3 and 2.8.4, where it changed. maybe there was just a setting somewhere they changed, or a number was reduced from "big" to "tiny". here's how i did it:<br />
<br />
<ol style="text-align: left;">
<li>acquire 2.8.3 and 2.8.4. former was in link above, latter was from play store. i used <a href="https://chrome.google.com/webstore/detail/apk-downloader/cgihflhdpokeobcfimliamffejfnmfii">this extension</a> to download from play</li>
<li>convert apks to jars with <a href="https://github.com/google/enjarify">enjarify</a></li>
<li>use latest jd-gui to get java for whole app (file -> save all sources)</li>
<li>use diff -rq <dir1> <dir2> to get a sense of what changed</li>
<li>give up on diff inspection because delta was huge</li>
<li>randomly search for "cache" in 2.8.3</li>
</ol>
<div>
thank you soundcloud, for not obfuscating your app at all. it was much easier to find what i was looking for with class and variable names. it takes about an hour to setup proguard such that you still get debugging symbols, but hey, whatever, right?</div>
<div>
<br /></div>
<div>
found some likely places for cache control in 2.8.3, but it looked like there was an api rewrite between 2.8.3 and 2.8.4, so even if i found it, it wouldn't help me, because none of that code was used in later versions.</div>
<div>
<br />
enjarify is supposed to be this snazzy new dex -> java class conversion tool. the results were "meh". i'm sure it's going to be very good eventually, and i have more faith in the professionalism of the devs of enjarify than, say, <a href="https://github.com/pxb1988/dex2jar/commit/7e62a5f28692f7abc99f6367eb69da1b99eb4291">other</a> <a href="https://github.com/pxb1988/dex2jar/commit/21eadfaab96338c62f80c78ba075a79cd9972660">devs</a>.<br />
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
<br /></h3>
<h3 style="text-align: left;">
educated guess searching</h3>
</div>
started searching around for the word "cache". there's quite a lot of caching going on. i poked around a few files that looked like they were just setting up LRU caches for something, and those looked promising, but then i found: <b>Lcom/soundcloud/android/playback/CacheConfig;</b>.<br />
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
<br /></h3>
<h3 style="text-align: left;">
results</h3>
<pre class="brush:java;">public class CacheConfig
{
// ~524 megs
static final long MAX_SIZE_BYTES = 524288000L;
// ~63 megs, aka "fuck you lol"
static final long MIN_SIZE_BYTES = 62914560L;
public static long getCacheSize(@Nullable String country) {
if ((ScTextUtils.isBlank(country)) || (Locale.US.getCountry().equalsIgnoreCase(country))
|| (Locale.GERMANY.getCountry().equalsIgnoreCase(country))
|| (Locale.FRANCE.getCountry().equalsIgnoreCase(country))
|| (Locale.UK.getCountry().equalsIgnoreCase(country))) {
return MIN_SIZE_BYTES;
}
return MAX_SIZE_BYTES;
}
}</pre>
<br />
<b>boom sha ka la ka.</b> this must be it. if you're in the US, Germany, France, or UK, you get burned with a tiny, micro cache. here's what the fix looks like:<br />
<pre class="brush:smali;">.method public static getCacheSize(Ljava/lang/String;)J
.registers 3
.param p0 # Ljava/lang/String;
.annotation build Landroid/support/annotation/Nullable;
.end annotation
.end param
.prologue
.line 15
# return "totally random" number, 555555
const-wide/32 v0, 0x4fb10040
return-wide v0
invoke-static {p0}, Lcom/soundcloud/android/utils/ScTextUtils;->isBlank(Ljava/lang/String;)Z
# ...</pre>
<br />
unfortunately, this creates new problems. as soon as you modify the code, you have to update the dex. if you update the dex, you break the signature and have to resign. if you resign, it breaks facebook logins, and probably some other stuff, because they uses signatures to generate a token that identifies which app is trying to do the login. luckily, antilvl knows how to handle spoofing signatures.<br />
<br />
<br />
<br /></div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com510tag:blogger.com,1999:blog-7271172641819523283.post-37680397324863192942014-12-08T22:22:00.002-08:002014-12-08T22:26:03.528-08:00Simplify - Android Deobfuscator / Decryptor<div dir="ltr" style="text-align: left;" trbidi="on">
Here it is: <a href="https://github.com/CalebFenton/simplify">https://github.com/CalebFenton/simplify</a><br />
I'd build you a jar, but there have been a lot of commits recently, and you'll probably want to build it yourself.<br />
<br />
It decrypts most types of string encryption and can remove some types of obfuscation, especially code that doesn't actually do anything.<br />
<br />
This may be all you want to know. But this has got me thinking about optimization and deobfuscation, so continue on if you're into that sort of thing.<br />
<br />
App obfuscation and string encryption are getting more popular, and they can be annoying as fuck. But, fundamentally, obfuscators just apply a set of rules to code, and the rules aren't that complex, because complex is really hard. It's just a thin layer of changes added on top. Intuitively, this means a general solution for undoing the changes probably takes a little more effort to undo than it did to conceive the original rules. So no matter how bad things get for crackers, it should always be possible to make a tool to fix things up.<br />
<br />
In the PC scene, obfuscators are more evolved, but so are the deobfuscators. Just look at the feature list on this: <a href="https://github.com/0xd4d/de4dot">https://github.com/0xd4d/de4dot</a>. It's a deobfuscator and an unpacker, plus it supports a huge list of stuff.<br />
<br />
There are a few tools like this for Android, but they are not nearly as complex (yet). Time for bullet points!<br />
<ul style="text-align: left;">
<li><a href="http://siis.cse.psu.edu/dare/downloads.html">Dare</a> - Made by people who certainly <a href="http://siis.cse.psu.edu/dare/papers/octeau-fse12.pdf">seem to know what they're doing</a>, but it often fails or gets put into infinite loops, and it focuses on optimization more than deobfuscation.</li>
<li><a href="http://webcache.googleusercontent.com/search?q=cache:UdYXYS36U6QJ:jbremer.org/wp-posts/athcon.pdf+&cd=1&hl=en&ct=clnk&gl=us">Automated Analysis and Deobfuscation of Android Apps & Malware by Jurriaan Bremer</a> (original PDF link doesn't work, closed source tool)</li>
<li>If you retarget DEX to JAR via JEB, dex2jar, or similar, you can use Java deobfuscators</li>
</ul>
<div>
Simplify deobfuscates by virtually executing an app and analyzing the execution afterwards. So if there is an encrypted string that gets decrypted at run time, Simplify will see the encrypted, see it passed to the decryption method, and see it get get decrypted. And after it knows the value, it can remove the encrypted value and the decryption method call as redundant and replace it with a 'const-string' instruction with the decrypted literal.</div>
<div>
<br /></div>
<div>
It's not all the way cooked yet, but the idea is solid, and there are some interesting issues github page I'd quite like to see implemented. One of them is <a href="https://github.com/CalebFenton/simplify/issues/14">deobfuscating reflection</a>.</div>
<div>
<br /></div>
<div>
Also, anyone who takes the time to create issues on github and follow through with c<a href="https://github.com/CalebFenton/simplify/issues?q=is%3Aissue+is%3Aclosed+author%3ACalebFenton">losing them when they're resolved</a>, is probably more than a little obsessive. Should be fun to watch.</div>
</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com66tag:blogger.com,1999:blog-7271172641819523283.post-39725206506337964652014-09-20T01:07:00.003-07:002014-09-20T01:07:32.051-07:00Things Look Different<div dir="ltr" style="text-align: left;" trbidi="on">
After a bunch of people told me how much the black background + white text was murderizing their eyes, I decided a bunch of people didn't appreciate my enlightened aesthetic sensibilities. Today's blog layout change to a white background + black text is in<b> no way </b>me admitting <a href="http://www.ironicsans.com/owmyeyes/">I was wrong</a>.<br />
<br />
Enjoy.</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com40tag:blogger.com,1999:blog-7271172641819523283.post-53178374612070439752014-09-20T00:49:00.001-07:002014-09-20T00:49:11.315-07:00Unpacking APKProtect, Bangcle, LIAPP, Qihoo<div dir="ltr" style="text-align: left;" trbidi="on">
Android packers getting more common, and if you're doing any significant amount of reversing, you're bound to come across one. While any serious reverser should 1.) <span id="goog_2053059169"></span><a href="https://www.defcon.org/images/defcon-22/dc-22-presentations/Strazzere-Sawyer/DEFCON-22-Strazzere-and-Sawyer-Android-Hacker-Protection-Level-UPDATED.pdf">fam<span id="goog_2053059172"></span><span id="goog_2053059173"></span>iliarize themselves with how they work<span id="goog_2053059170"></span></a>, 2.) unpack a few by hand, and 3.) write their own tool, it's always nice to kick back and pull something off the shelf. Or, at least, learn how someone else is doing it.<br />
<br />
For this reason, I'd like to share with you the provocatively named <span id="goog_2053059150"></span><span id="goog_2053059160"></span><b>android-<span id="goog_2053059154"></span><span id="goog_2053059155"></span>un<span id="goog_2053059163"></span><span id="goog_2053059164"></span>packer</b><span id="goog_2053059161"></span><span id="goog_2053059151"></span><span id="goog_2053059157"></span><span id="goog_2053059158"></span> from strazzere. Nothing says "i write c code" like a blunt and unambiguous project title!<br />
<a href="https://github.com/strazzere/android-unpacker/tree/master/native-unpacker">https://github.com/strazzere/android-unpacker/tree/master/native-unpacker</a><br />
<br />
From the readme, it already supports a few popular unpackers:<br />
<ul style="text-align: left;">
<li>Bangcle (SecNeo)</li>
<li>APKProtect</li>
<li>LIAPP (preprelease demo)</li>
<li>Qihoo</li>
</ul>
<br />
<ul style="text-align: left;">
</ul>
</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com51tag:blogger.com,1999:blog-7271172641819523283.post-15289087691170632402014-03-20T10:06:00.002-07:002014-09-20T01:12:26.861-07:00jadx - Dex to Java decompiler<div dir="ltr" style="text-align: left;" trbidi="on">
there's a new decompiler on the block. it targets dex directly,
rather than java class bytecode, so it doesn't rely on dex2jar. i'm
pleased by it's performance so far, and it's worth checking out:
<a href="https://github.com/skylot/jadx">https://github.com/skylot/jadx</a><br />
<ul style="text-align: left;">
<li>it's mostly a cli, with a simple, "experimental" <a href="https://www.youtube.com/watch?v=hkDD03yeLnU" target="_blank">gui</a>.</li>
<li>it takes dex or jar files as input</li>
<li>it can make a control flow graph.</li>
<li>output
is configurable -- you can chose to have "simple" branching, where it
wont try to be smart about how it decompiles conditionals and loops.
this can actually be much easier to read than jd-gui's pervasive
"while(true) //a bunch of stuff" constructs.</li>
</ul>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-Nn-xuvJNSI0/Uysf6iIqDxI/AAAAAAAAADU/Eg95eyUOkZ0/s1600/Screen+Shot+2014-03-19+at+5.12.39+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="screenshot" border="0" src="http://3.bp.blogspot.com/-Nn-xuvJNSI0/Uysf6iIqDxI/AAAAAAAAADU/Eg95eyUOkZ0/s1600/Screen+Shot+2014-03-19+at+5.12.39+PM.png" height="242" title="" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">GitHub page curiously lacking in GUI money-shot</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com153tag:blogger.com,1999:blog-7271172641819523283.post-34439700498303346372014-02-13T02:00:00.000-08:002015-05-21T14:59:38.990-07:00Native Protection & Mono by Nihilus<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div class="page" title="Page 1">
<div class="layoutArea">
<div class="column">
<span style="font-family: 'Consolas'; font-size: 11.000000pt;">another interesting tutorial from Nihilus. here's the description from the guide:</span><br />
<blockquote class="tr_bq">
<span style="font-family: 'Consolas'; font-size: 11.000000pt;">this tutorial covers a basic understanding of the Mono/Xamarin for Android,
specifically how C#/.NET is used lately to protect games and, who knows, even
malwares.</span></blockquote>
<span style="font-family: 'Consolas'; font-size: 11.000000pt;">here's the link: </span><a href="https://mega.co.nz/#!jpwkTY4J">https://mega.co.nz/#!jpwkTY4J</a><span class="export-link-gray-txt file-key"><a href="https://mega.co.nz/#!jpwkTY4J!eXzXCngQAPlUjVvJtiSzEbSxqEv8EbYmMqaLTFxF01Q">!eXzXCngQAPlUjVvJtiSzEbSxqEv8EbYmMqaLTFxF01Q</a> (updated 5/21/2015)</span><br />
<br />
<span class="export-link-gray-txt file-key"> </span>
<span style="font-family: 'Consolas'; font-size: 11.000000pt;">i was not aware of this ability to run mono code on android and found it interesting.</span><br />
<br />
<span style="font-family: 'Consolas'; font-size: 11.000000pt;">related to this, wine is on the way for android. this could get interesting.</span><br />
<a href="http://wiki.winehq.org/FOSDEM2014?action=AttachFile&do=get&target=wine-on-android-fosdem-2014.pdf"><span style="font-family: 'Consolas'; font-size: 11.000000pt;">http://wiki.winehq.org/FOSDEM2014?action=AttachFile&do=get&target=wine-on-android-fosdem-2014.pdf</span></a><br />
<span style="font-family: 'Consolas'; font-size: 11.000000pt;"><br /></span>
<span style="font-family: 'Consolas'; font-size: 11.000000pt;"><br /></span>
</div>
</div>
</div>
</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com26tag:blogger.com,1999:blog-7271172641819523283.post-35900864000395742452014-02-12T05:11:00.000-08:002014-02-12T20:11:26.774-08:00zerdei's luyten, a worthwhile jd-gui alternative<div dir="ltr" style="text-align: left;" trbidi="on">
if you use dex2jar + jd-gui and you find the results less than satisfying, that's normal. jd-gui hasn't been updated in <i>at least 100 years</i>. methods often fail to compile and blocks of code are sometimes omitted.<br />
<br />
luyten, by deathmarine, which you can get here: <a href="https://github.com/deathmarine/Luyten/releases">https://github.com/deathmarine/Luyten/releases</a> is a front end for <a href="https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler" target="_blank">procyon</a>, a java decompiler. procyon+luyten has a higher success rate for decompiling methods in my experience, and has higher fidelity output, though it's more verbose. the UI isn't that great, but this pull request by zerdei includes several noteworthy improvements: <a href="https://github.com/deathmarine/Luyten/pull/13">https://github.com/deathmarine/Luyten/pull/13</a><br />
<br />
feel free to clone and build the jar yourself, but if you're lazy, and somewhat trusting, i built this for you!<br />
<a href="https://mega.co.nz/#!K95RlRiB!ak2DWRxC2DgPYDic0eDpQibAuGtIoFZGtU67GzyjEjM">https://mega.co.nz/#!K95RlRiB!ak2DWRxC2DgPYDic0eDpQibAuGtIoFZGtU67GzyjEjM</a></div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com42tag:blogger.com,1999:blog-7271172641819523283.post-6148855991147566552013-12-24T11:56:00.000-08:002013-12-24T11:57:03.570-08:00hexicle utility<div dir="ltr" style="text-align: left;" trbidi="on">
Hex has released a tool called hexicle which wraps a lot of common tools such as smali, baksmali, zipalign, etc. with a friendly ui. it's written in python and is made for linux. here's a bit from the readme, which you should totally read:<br />
<blockquote class="tr_bq">
<br />
The tool is written in python using curses library. The tool comes inclusive of all tools that are necessary for it's fuctionality. Hexicle will always overwrite files. The sources are decompiled in a folder with a same name.</blockquote>
<br />
<br />
download <b>v1.1</b>: http://www.mediafire.com/download/8o9m2dr7pky2mnf/Hexicle+v1.1.zip<br />
<b>password: <span style="color: red;">hexicle</span></b><br />
<br />
<br />
if you have any bugs or comments, Hex requested that you just post them here.</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com15tag:blogger.com,1999:blog-7271172641819523283.post-71484824607753635282013-10-29T02:12:00.000-07:002014-09-20T10:11:39.233-07:00Nihilus' Reversing DexGuard 5.x<div dir="ltr" style="text-align: left;" trbidi="on">
Here's another tutorial kindly written by <b>Nihilus</b>.<br />
<br />
It's a teardown of reversing DexGuard's protections, which are legion, along with some of the thought process behind it. I like it because it's pure reversing -- no cracking of the commercial app.<br />
<br />
<a href="https://tuts4you.com/download.php?view.3517">https://tuts4you.com/download.php?view.3517</a><br />
<br />
alternate link: <a href="https://mega.co.nz/#!s8MgkDyY!Qd36YVri66wLN1mXFRCQrlebNnxqRKT-ftrlpybCs80">https://mega.co.nz/#!s8MgkDyY!Qd36YVri66wLN1mXFRCQrlebNnxqRKT-ftrlpybCs80</a><br />
<br />
Kindly post feedback if you're so inclined, and contact me if you'd like to share your reversing knowledge :D</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com12tag:blogger.com,1999:blog-7271172641819523283.post-64872116760866320982013-10-25T11:56:00.001-07:002013-10-25T11:56:13.766-07:00hex's keygen tutorial<div dir="ltr" style="text-align: left;" trbidi="on">
Got a new tutorial for you good people. The author is <b>hex</b> and he was kind enough to write it and send it to me. It's a no-nonsense keygen'ing guide.<br />
<br />
Here's the download: <a href="https://mega.co.nz/#!cg4FFB5b!Sw1a0hB2MHNk72sr8VEU8Wi8LMhxt7mqLtBvCfWikHU">https://mega.co.nz/#!cg4FFB5b!Sw1a0hB2MHNk72sr8VEU8Wi8LMhxt7mqLtBvCfWikHU</a><br />
<br />
Feel free to leave some comments and let him know what you think.<br />
<br />
If you'd like to share a cracking tutorial, I'd be glad to link to it, unless it's shit, so let me know. :D</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com9tag:blogger.com,1999:blog-7271172641819523283.post-59411776327220273062013-06-01T17:49:00.000-07:002013-06-01T17:49:28.737-07:00smali syntax highlighting for sublime<div dir="ltr" style="text-align: left;" trbidi="on">
i have been using <a href="https://code.google.com/p/androguard/#Sublime_Text_2_Plugin">sublime text 2 + androguard plugin</a> for decompiling and am liking it very much. it doesn't do as well producing correct java as, say, dex2jar + jdgui, but it's sometimes easier to read. it doesn't handle try/catch blocks at all -- just ignores them. this means it's a great alternative for jdgui, which will error out on methods with overlapping try/catch stuff.<br />
<br />
since i've been using sublime, i've also needed a smali syntax highlighter, which i found here: <a href="https://github.com/ShaneWilton/sublime-smali">https://github.com/ShaneWilton/sublime-smali</a><br />
<br />
it's the best syntax highlighter i've seen because of the line level syntax validation it does. when you write smali, you can be more confident it is correct with this. you should check out the regex if you're a fan of such tedium. </div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com11tag:blogger.com,1999:blog-7271172641819523283.post-21425055133887896872013-05-25T15:29:00.000-07:002014-07-16T14:37:13.420-07:00three MessyBinary tutorials<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="left-box">MessyBinary has been hard at it, writing up some pretty slick tutorials. i'd like to share them with you. bonus points for posting mirrors.</span><br />
<ul style="text-align: left;">
<li><span class="left-box">FaceNiff v2.4 </span>- <a href="https://hotfile.com/dl/192441522/1464c87/fn24tut.zip.html">https://hotfile.com/dl/192441522/1464c87/fn24tut.zip.html</a></li>
<li>WifiKill v2.2 - <a href="https://hotfile.com/dl/194586198/224b441/wfk22tut.zip.html">https://hotfile.com/dl/194586198/224b441/wfk22tut.zip.html</a></li>
<li>GMD Smart Rotate v2.2.0 - <a href="https://hotfile.com/dl/202164304/8ac3409/gsr220tut.zip.html">https://hotfile.com/dl/202164304/8ac3409/gsr220tut.zip.html</a></li>
</ul>
the android reversing community is continually getting larger, but i'm not aware of any good forum where crackme's and specific app tutorials can be posted. when i find one, i'll let you all know. <br />
<br />
<h2 style="text-align: left;">
<span style="color: red;">update~~</span></h2>
new link for all three tutorials, https://www.mediafire.com/?l9e5k1a43kvccvd<br />
thanks Nihilus!</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com11tag:blogger.com,1999:blog-7271172641819523283.post-91849532486996088132013-01-26T09:58:00.000-08:002014-12-08T22:22:59.756-08:00string decryption with dex2jar<div dir="ltr" style="text-align: left;" trbidi="on">
i have been getting a lot of questions about string decryption lately, so let's talk.<br />
<br />
let's say you have an app and notice encrypted strings. strings are an easy way to get a basic idea of what code is doing so naturally you want to decrypt them. but how? there are many different ways to encrypt strings and then decrypt at runtime but in practices there are some assumptions we can make in decreasing order of likelihood.<br />
<br />
1. the encryption must be reversible. the strings must be decrypted at run time somehow. this is good but we can assume even more.<br />
<br />
2. the process is automated. when Alice wants to release her app she puts the source code through an automated modification process which iterates over every string literal, encrypts it and replaces it with a call to a decryption method with the encrypted string as a parameter.<br />
<br />
3. decryption is the same or nearly the same for each string. there is only one decryption method.<br />
<br />
4. the type signature of the method is:
<br />
<pre class="brush:java;">static String decryptMethod(String)</pre>
<br />
while these assumptions hold, it is not very difficult to create a general technique by which we can decrypt all of the strings of an app in place. the real question is do you want to do it at the java or smali level? if you primarily look at decompiled code you can work at the java level. and you're in luck, such a tool already exists in dex2jar: <a href="http://code.google.com/p/dex2jar/">http://code.google.com/p/dex2jar/</a><br />
<br />
there is a wiki article about it here: <a href="http://code.google.com/p/dex2jar/wiki/DecryptStrings">http://code.google.com/p/dex2jar/wiki/DecryptStrings</a> but it is unfinished. you can at least get a visual for what the decompiled code will look like before and after. if you're a good person, you will update the wiki. i leave that as a task for some good reader.<br />
<br />
the tool is currently incorrectly spelled as <b>d2j-decrpyt-string</b>.(sh|bat). it takes at least two parameters and sometimes needs three. they are:<br />
<ol style="text-align: left;">
<li>method name, <b>-mn</b> : in our case, decryptMethod</li>
<li>method owner, <b>-mo </b>: let's say com.alice.utils</li>
<li>class path, <b>-cp</b> : if decryptMethod makes use of any framework api, you will need to give the path to a framework.jar from the android.sdk</li>
</ol>
<pre class="brush:shell;">d2j-decrpyt-string -mn decryptMethod -mo com.alice.utils -cp ~/android/sdk/platforms/android-4/framework.jar</pre>
<br />
doing this at the smali level requires access to a dalvik vm, so in that regard it is trickier, but there are many emulators and you can even use your phone. here's how the process can work:<br />
<ul style="text-align: left;">
<li>pull out all of the strings and put into a file</li>
<li>write some java code, unless you're comfortable with smali, to open the file and iterate over each line and call the decryption method on each string.</li>
<li>compile java bytecode and convert to dalvik executable with <b>dx </b>from the android sdk</li>
<li><a href="http://androidcracking.blogspot.com/2011/02/more-smali-syntax-examples.html">run the code on a dalvik vm</a></li>
</ul>
</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com20tag:blogger.com,1999:blog-7271172641819523283.post-7740519512906649182012-04-10T11:58:00.000-07:002013-01-26T10:02:45.348-08:00android reverse tools - ART<div dir="ltr" style="text-align: left;" trbidi="on">
here's a cool tool i was shown the other day. it's an easy-mode gui for all your decompiling and recompiling needs. ordinarily this would be rather unimpressive. it's not too hard to write a little wrapper for some java commands, but he/she really put some polish on this.<br />
<br />
not only does it come with everything you need, including java and bits of the android sdk, but it even has a slick manual and a complete walk-through for my <a href="http://www.mediafire.com/download.php?5ybhkqbzwguubf3">lesson0.crackme0</a>.<br />
<br />
here's a screen shot of the app:<br />
<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="http://1.bp.blogspot.com/-pURG6zLdzuU/T4R-PzvnHOI/AAAAAAAAACM/nqr1zfcB5WA/s1600/Untitled.png" /> </div>
</div>
<br />
here's the link to download (24mb): <a href="http://ul.to/or3kme6t">http://ul.to/or3kme6t</a><br />
virus scan: <a href="https://www.virustotal.com/file/f6ac4279161b666811d80736a7a23790709c5b3ccb36a8f83dd138d9601eb480/analysis/1334082130/">https://www.virustotal.com/file/f6ac4279161b666811d80736a7a23790709c5b3ccb36a8f83dd138d9601eb480/analysis/1334082130/</a> <br />
<br />
as a first exercise, i recommend that you update the apktool included with the pack. it may have gone out of date. you can update the other components if you're so inclined but it might not help much.<br />
<br />
if you have any trouble decompiling or compiling, remember it's using apktool under the hood so trouble shoot apktool first.<br />
<br />
and if you want some more crackmes to try, here's deurus' profile on crackmes.de<a href="http://crackmes.de/"></a>: <a href="http://crackmes.de/users/deurus">http://crackmes.de/users/deurus</a></div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com391tag:blogger.com,1999:blog-7271172641819523283.post-32541979124306741042012-01-18T12:56:00.000-08:002012-01-18T13:32:42.834-08:00self-keygen tutorial by synack<div dir="ltr" style="text-align: left;" trbidi="on">
previously, i posted a <a href="http://androidcracking.blogspot.com/2012/01/keygen-tutorial-and-challenge.html">keygen tutorial and challenge</a>, and <b>synack</b> has put his solution forward along with an interesting tutorial on creating a self-keygen, or a keygen that makes use of the original code to do the heavy lifting. it's very clearly written and organized, with plenty of good insight into the <i>thought process</i> as opposed to low-level "click here change this with no idea why" style tutorials.<br />
<br />
download the solution and tutorial here: <a href="http://www.mediafire.com/?wzc45p269bcpbr5">http://www.mediafire.com/?wzc45p269bcpbr5</a></div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com29tag:blogger.com,1999:blog-7271172641819523283.post-78291852122158474272012-01-14T07:16:00.001-08:002012-01-18T12:56:21.056-08:00keygen tutorial and challenge by zAWS!<div dir="ltr" style="text-align: left;" trbidi="on">
keygen'ing as a style of cracking requires you to really know and understand how the protection works. it also requires no modification of the original application, so is a very pure way of cracking.<br />
<br />
zAWS!, who posted a keygen for lesson 0's crackme0b, sent me this challenge to share:<br />
<a href="http://www.mediafire.com/?5ik1659n1k514f9">http://www.mediafire.com/?5ik1659n1k514f9</a><br />
<br />
<br />
but before you start, you may want to see his/her keygen tutorial. it comes with the original apk and has videos showing the process:<br />
<a href="http://www.mediafire.com/?ckvuiadh5cegl9l">http://www.mediafire.com/?ckvuiadh5cegl9l</a></div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com10tag:blogger.com,1999:blog-7271172641819523283.post-81298558966709330712012-01-06T15:16:00.003-08:002012-01-16T19:29:32.096-08:00way of the android cracker 0 rewrite<div dir="ltr" style="text-align: left;" trbidi="on">
i have learned a lot since first writing way of the android cracker so i rewrote it. actually i rewrote it about 17 times. this one was the least annoyingly pedantic.<br />
<br />
here's a direct link: <a href="http://www.mediafire.com/download.php?5ybhkqbzwguubf3">http://www.mediafire.com/download.php?5ybhkqbzwguubf3</a><a href="http://www.mediafire.com/download.php?5ybhkqbzwguubf3"></a><br />
<br />
lesson 1 rewrite is next.<br />
<br />
<span style="color: red;">update</span>: crackme0b has been updated. thanks to zAWS! for writing a keygen for crackme0b so quickly (even copied the icon) and helping me see it. unfortunately the update breaks the keygen.</div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com41tag:blogger.com,1999:blog-7271172641819523283.post-86791956300051490022011-10-27T07:49:00.001-07:002012-05-01T12:27:42.598-07:00antilvl 1.4.0<div dir="ltr" style="text-align: left;" trbidi="on">
it's been a while, but antilvl 1.4.0 is finally released. i did not plan to make another release, but there were some show-stopping bugs in the linux version and some other things that were just embarrassing. :D<br />
<br />
major changes include:<br />
<ul style="text-align: left;">
<li>option to use your own signatures</li>
<li>more control over which fingerprints are used</li>
<li>support for verizon drm</li>
<li>a few new anti-tampering checks are known</li>
<li>some fixes in how fingerprints were applied</li>
</ul>
<br />
you can read more / download here: <a href="http://androidcracking.blogspot.com/p/antilvl_01.html">http://androidcracking.blogspot.com/p/antilvl_01.html</a> </div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com36tag:blogger.com,1999:blog-7271172641819523283.post-12448809894374022452011-10-17T12:34:00.002-07:002011-10-17T12:38:22.411-07:00protection using checksums and key / unlocker apps<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
if an app requires an unlocker key app, it's likely there will be protection hidden in the key. perhaps the key performs a checksum on the main app, or the key stores pre-computed checksum values for the main app. this is easy to add if you're a developer and is somewhat tricky to handle as a cracker. the reason is the cracker must know how to calculate the checksums himself and inject those values into the app.<br />
<br />
calculating checksums is a way to determine if your apk has been modified. there are at least four easy methods to do this. they are: md5, sha1, crc32 and adler32. once you run these guys on your apk you will have either a long number or a byte array. of course, you can't store the checksum in your main app since you wont know the checksum until the app is finished. for this reason, either the calculations or just the checksum values must be stored in another app signed by the same certificate, such as a key / unlocker app.<br />
<br />
here's some example code of what the protection may look like in java:<br />
<pre class="brush:java;">// Copied directly and made private from R.java of Key App
// After creating strings..
private static final int tt_crc32=0x7f040002;
private static final int tt_md5=0x7f040004;
public static TestResult checkCRC32ChkSum() {
// Get path to our apk on the system.
String apkPath = Main.MyContext.getPackageCodePath();
Long chksum = null;
try {
// Open the file and build a CRC32 checksum.
// You could also use Adler32 in place of CRC32.
FileInputStream fis = new FileInputStream(new File(apkPath));
CRC32 chk = new CRC32();
CheckedInputStream cis = new CheckedInputStream(fis, chk);
byte[] buff = new byte[80];
while ( cis.read(buff) >= 0 ) ;
chksum = chk.getValue();
} catch (Exception e) {
e.printStackTrace();
}
// After creating your apk, calculate the crc32 checksum
// and store it as a string value in the KEY / unlock App.
String keyStrVal = getKeyString(tt_crc32);
// Key is not installed.
if ( keyStrVal.equals("") ) {
// Key not installed. Validation failure.
}
Long chksumCmp = Long.parseLong(keyStrVal);
if ( chksum.equals(chksumCmp) ) {
// Success. Checksum stored in key matches the
// checksum we just created. We can assume APK
// is not modified. Kinda.
}
else {
// Validation failure! Apk has been modified.
}
}
public static TestResult checkMD5ChkSum() {
// Do pretty much the exact same thing here,
// except instead of a CRC32 checksum, we'll be
// using an MD5 digest. You could also use SHA1.
// Any cracker worth his salt will immediately recognize
// CRC32 and MD5 keywords and know them to be checksum
// attempts. Using Adler32 or SHA1 may put them off.
String apkPath = Main.MyContext.getPackageCodePath();
MessageDigest msgDigest = null;
byte[] digest = null;
try {
msgDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
byte[] bytes = new byte[8192];
int byteCount;
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(apkPath));
while ((byteCount = fis.read(bytes)) > 0)
msgDigest.update(bytes, 0, byteCount);
digest = msgDigest.digest();
} catch (Exception e) {
e.printStackTrace();
}
String keyStrVal = getKeyString(tt_md5);
// Key is not installed.
if ( keyStrVal.equals("") ) {
// Key not installed. Validation failure.
}
// Using Base64 encoding is just a lazy way to store byte arrays.
// You -could- also embed the values in the code of the Apk
// Read more here:
// http://stackoverflow.com/questions/2721386/android-how-to-share-code-between-projects-signed-with-the-same-certificate
if ( Arrays.equals(Base64.decode(keyStrVal, Base64.DEFAULT), digest) )
// Validated
else
// Apk has been modified
}
private static String getKeyString(int resId) {
// You will need this to retrieve the stored checksums from the KEY App.
String result = "";
try {
Context c = Main.MyContext.createPackageContext("your.package.name.key", Context.CONTEXT_IGNORE_SECURITY);
result = c.getString(resId);
} catch (Exception e) {
Console.log("Error while getting key string:\n" + e);
e.printStackTrace();
result = "";
}
return result;
}</pre>
<br />
<br />
and here's what the above java looks like in smali, so you have some idea what to look for. cracking this will require you to write an app that simulates how the app calculates the checksum. then you'll have to come up with a clever way to get the value into the smali. if it's a long number, this is fairly easy, but if it's a byte array, you may need to use base64 encoding or some other method to make a byte array safe for literal strings. the keywords to look for, of course, are md5, sha1, crc32 and adler32. they may not appear at all if the developer is using reflection to make the method calls.<br />
<pre class="brush:smali;">.method public static checkCRC32ChkSum()V
.locals 11
.prologue
.line 934
sget-object v9, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
invoke-virtual {v9}, Landroid/content/Context;->getPackageCodePath()Ljava/lang/String;
move-result-object v0
.line 935
.local v0, apkPath:Ljava/lang/String;
const/4 v3, 0x0
.line 939
.local v3, chksum:Ljava/lang/Long;
:try_start_0
new-instance v7, Ljava/io/FileInputStream;
new-instance v9, Ljava/io/File;
invoke-direct {v9, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
invoke-direct {v7, v9}, Ljava/io/FileInputStream;-><init>(Ljava/io/File;)V
.line 940
.local v7, fis:Ljava/io/FileInputStream;
new-instance v2, Ljava/util/zip/CRC32;
invoke-direct {v2}, Ljava/util/zip/CRC32;-><init>()V
.line 942
.local v2, chk:Ljava/util/zip/CRC32;
new-instance v5, Ljava/util/zip/CheckedInputStream;
invoke-direct {v5, v7, v2}, Ljava/util/zip/CheckedInputStream;-><init>(Ljava/io/InputStream;Ljava/util/zip/Checksum;)V
.line 943
.local v5, cis:Ljava/util/zip/CheckedInputStream;
const/16 v9, 0x50
new-array v1, v9, [B
.line 944
.local v1, buff:[B
:cond_0
invoke-virtual {v5, v1}, Ljava/util/zip/CheckedInputStream;->read([B)I
move-result v9
if-gez v9, :cond_0
.line 946
invoke-virtual {v2}, Ljava/util/zip/CRC32;->getValue()J
move-result-wide v9
invoke-static {v9, v10}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
move-result-object v3
.line 953
.end local v1 #buff:[B
.end local v2 #chk:Ljava/util/zip/CRC32;
.end local v5 #cis:Ljava/util/zip/CheckedInputStream;
.end local v7 #fis:Ljava/io/FileInputStream;
:goto_0
const v9, 0x7f040002
invoke-static {v9}, Lcom/lohan/testtarget/PerformTestsTask;->getKeyString(I)Ljava/lang/String;
move-result-object v8
.line 956
.local v8, keyStrVal:Ljava/lang/String;
const-string v9, ""
invoke-virtual {v8, v9}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
.line 960
invoke-static {v8}, Ljava/lang/Long;->parseLong(Ljava/lang/String;)J
move-result-wide v9
invoke-static {v9, v10}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
move-result-object v4
.line 962
.local v4, chksumCmp:Ljava/lang/Long;
invoke-virtual {v3, v4}, Ljava/lang/Long;->equals(Ljava/lang/Object;)Z
.line 970
return-void
.line 947
.end local v4 #chksumCmp:Ljava/lang/Long;
.end local v8 #keyStrVal:Ljava/lang/String;
:catch_0
move-exception v9
move-object v6, v9
.line 948
.local v6, e:Ljava/lang/Exception;
invoke-virtual {v6}, Ljava/lang/Exception;->printStackTrace()V
goto :goto_0
.end method
.method public static checkMD5ChkSum()V
.locals 12
.prologue
const/4 v11, 0x0
.line 981
sget-object v10, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
invoke-virtual {v10}, Landroid/content/Context;->getPackageCodePath()Ljava/lang/String;
move-result-object v0
.line 982
.local v0, apkPath:Ljava/lang/String;
const/4 v9, 0x0
.line 983
.local v9, msgDigest:Ljava/security/MessageDigest;
const/4 v3, 0x0
check-cast v3, [B
.line 985
.local v3, digest:[B
:try_start_0
const-string v10, "MD5"
invoke-static {v10}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;
:try_end_0
.catch Ljava/security/NoSuchAlgorithmException; {:try_start_0 .. :try_end_0} :catch_0
move-result-object v9
.line 990
:goto_0
const/16 v10, 0x2000
new-array v2, v10, [B
.line 992
.local v2, bytes:[B
const/4 v6, 0x0
.line 995
.local v6, fis:Ljava/io/FileInputStream;
:try_start_1
new-instance v7, Ljava/io/FileInputStream;
new-instance v10, Ljava/io/File;
invoke-direct {v10, v0}, Ljava/io/File;-><init>(Ljava/lang/String;)V
invoke-direct {v7, v10}, Ljava/io/FileInputStream;-><init>(Ljava/io/File;)V
:try_end_1
.catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_2
.line 997
.end local v6 #fis:Ljava/io/FileInputStream;
.local v7, fis:Ljava/io/FileInputStream;
:goto_1
:try_start_2
invoke-virtual {v7, v2}, Ljava/io/FileInputStream;->read([B)I
move-result v1
.local v1, byteCount:I
if-gtz v1, :cond_0
.line 1000
invoke-virtual {v9}, Ljava/security/MessageDigest;->digest()[B
:try_end_2
.catch Ljava/lang/Exception; {:try_start_2 .. :try_end_2} :catch_1
move-result-object v3
move-object v6, v7
.line 1005
.end local v1 #byteCount:I
.end local v7 #fis:Ljava/io/FileInputStream;
.restart local v6 #fis:Ljava/io/FileInputStream;
:goto_2
const v10, 0x7f040004
invoke-static {v10}, Lcom/lohan/testtarget/PerformTestsTask;->getKeyString(I)Ljava/lang/String;
move-result-object v8
.line 1007
.local v8, keyStrVal:Ljava/lang/String;
const-string v10, ""
invoke-virtual {v8, v10}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
.line 1015
invoke-static {v8, v11}, Landroid/util/Base64;->decode(Ljava/lang/String;I)[B
move-result-object v10
invoke-static {v10, v3}, Ljava/util/Arrays;->equals([B[B)Z
.line 1020
return-void
.line 986
.end local v2 #bytes:[B
.end local v6 #fis:Ljava/io/FileInputStream;
.end local v8 #keyStrVal:Ljava/lang/String;
:catch_0
move-exception v10
move-object v5, v10
.line 987
.local v5, e1:Ljava/security/NoSuchAlgorithmException;
invoke-virtual {v5}, Ljava/security/NoSuchAlgorithmException;->printStackTrace()V
goto :goto_0
.line 998
.end local v5 #e1:Ljava/security/NoSuchAlgorithmException;
.restart local v1 #byteCount:I
.restart local v2 #bytes:[B
.restart local v7 #fis:Ljava/io/FileInputStream;
:cond_0
const/4 v10, 0x0
:try_start_3
invoke-virtual {v9, v2, v10, v1}, Ljava/security/MessageDigest;->update([BII)V
:try_end_3
.catch Ljava/lang/Exception; {:try_start_3 .. :try_end_3} :catch_1
goto :goto_1
.line 1001
.end local v1 #byteCount:I
:catch_1
move-exception v10
move-object v4, v10
move-object v6, v7
.line 1002
.end local v7 #fis:Ljava/io/FileInputStream;
.local v4, e:Ljava/lang/Exception;
.restart local v6 #fis:Ljava/io/FileInputStream;
:goto_3
invoke-virtual {v4}, Ljava/lang/Exception;->printStackTrace()V
goto :goto_2
.line 1001
.end local v4 #e:Ljava/lang/Exception;
:catch_2
move-exception v10
move-object v4, v10
goto :goto_3
.end method
.method private static asdfgetKeyString(I)Ljava/lang/String;
.locals 6
.parameter "resId"
.prologue
.line 1025
const-string v2, ""
.line 1028
.local v2, result:Ljava/lang/String;
:try_start_0
sget-object v3, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
const-string v4, "your.package.name.key"
const/4 v5, 0x2
invoke-virtual {v3, v4, v5}, Landroid/content/Context;->createPackageContext(Ljava/lang/String;I)Landroid/content/Context;
move-result-object v0
.line 1029
.local v0, c:Landroid/content/Context;
invoke-virtual {v0, p0}, Landroid/content/Context;->getString(I)Ljava/lang/String;
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
move-result-object v2
.line 1036
.end local v0 #c:Landroid/content/Context;
:goto_0
return-object v2
.line 1030
:catch_0
move-exception v3
move-object v1, v3
.line 1031
.local v1, e:Ljava/lang/Exception;
new-instance v3, Ljava/lang/StringBuilder;
const-string v4, "Error while getting key string:\n"
invoke-direct {v3, v4}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v3, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
move-result-object v3
invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v3
invoke-static {v3}, Lcom/lohan/testtarget/Console;->log(Ljava/lang/String;)V
.line 1032
invoke-virtual {v1}, Ljava/lang/Exception;->printStackTrace()V
.line 1033
const-string v2, ""
goto :goto_0
.end method</init></init></init></init></init></init></init></pre>
</div>
<br /></div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com11tag:blogger.com,1999:blog-7271172641819523283.post-42587634674585354312011-06-10T09:55:00.001-07:002014-09-20T01:10:32.562-07:00cracking verizon's v cast apps drm<div dir="ltr" style="text-align: left;" trbidi="on">
verizon has a new app store. it has an amazon-store like drm that's fairly simple to crack.<br />
<br />
here's how it works. in the launching activity a thread is started that calls checkLicense(). this was in com/cp/app/MainActivity$2.smali:<br />
<pre class="brush:smali;">.method public run()V
.locals 2
.prologue
.line 100
invoke-static {}, Landroid/os/Looper;->prepare()V
.line 102
:try_start_0
iget-object v0, p0, Lcom/cp/app/MainActivity$2;->this$0:Lcom/cp/app/MainActivity;
iget-object v0, v0, Lcom/cp/app/MainActivity;->licenseAuthenticator:Lcom/verizon/vcast/apps/LicenseAuthenticator;
sget-object v1, Lcom/cp/app/MainActivity;->verizonAppKeyword:Ljava/lang/String;
# call checkLicense and store result in v0
invoke-virtual {v0, v1}, Lcom/verizon/vcast/apps/LicenseAuthenticator;->checkLicense(Ljava/lang/String;)I
move-result v0
.line 103
iget-object v1, p0, Lcom/cp/app/MainActivity$2;->this$0:Lcom/cp/app/MainActivity;
# send result of checkLicense (v0) to isDRMDone()
invoke-virtual {v1, v0}, Lcom/cp/app/MainActivity;->isDRMDone(I)Z
move-result v0
# isDRMDone() handles error messages and returns true when all is good
if-eqz v0, :cond_0
# ... rest of code</pre>
<br />
if you look at isDRMDone() you'll see that it's basically a big switch. input of 0 or 1 counts as valid. everything else is some kind of error. so we just need to make sure checkLicense returns 1 and doesn't call anything else that may have side effects (timeouts, checking to see if verizon app store is installed, etc..).<br />
<br />
checkLicense() is defined in com/verizon/vcast/apps/LicenseAuthenticator.smali. after modification it looks like:<br />
<pre class="brush:smali;">.method public declared-synchronized checkLicense(Ljava/lang/String;)I
.locals 10
.parameter "keyword"
.prologue
# just set v0 to true and return
# the rest of the code never runs
const/4 v0, 0x1
return v0
const/16 v9, 0x64
const-string v7, "checkLicense() finished. Trying to shutDownLicenseService()"
const-string v7, "LicenseAuthenticator"
.line 256
monitor-enter p0
:try_start_0
const-string v7, "LicenseAuthenticator"
const-string v8, "begin checkLicense()"
# ... rest of code</pre>
<br />
if you're a developer, depending on how they implement the insertion of their drm, it may still be possible to use classical protection / anti-tampering techniques. i'd like to know. but really though, don't waste your time on protection. i'm not blasting verizon or amazon or google for weak security. real effort should be spent improving the program, not slowing down (because you can't stop) crackers. if you want money, use ads.</div>
lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com24tag:blogger.com,1999:blog-7271172641819523283.post-45859857798082480062011-06-08T14:46:00.002-07:002012-04-13T04:20:07.973-07:00anti-tampering with crc check<div dir="ltr" style="text-align: left;" trbidi="on">
one way an app will try to detect if it has been tampered with is to look at classes.dex inside the apk. just so you know, java code is compiled to java .class files, which is then transformed by dx into classes.dex. this one file contains all the compiled code of an app. once the code is finished and the app is ready to be published, properties of the file such as the size or crc (<a href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">cyclic redundancy check</a>) can be determined and then stored inside the resources of the app.<br />
<br />
when the app runs, it can compare the stored values with the actual values of the classes.dex file. if they do not match, then the code was likely tampered with.<br />
<br />
note that we're using <a href="http://developer.android.com/reference/java/util/zip/ZipEntry.html">zipentry</a> here, but we could also use <a href="http://developer.android.com/reference/java/util/jar/JarEntry.html">jarentry</a> and jarfile. you can't simply look for <a href="http://developer.android.com/reference/java/util/zip/ZipEntry.html#getCrc%28%29">getCrc()</a> and feel safe either, because the method could be called with reflection.<br />
<br />
here's what a crc check may look like in java:<br />
<pre class="brush: java;">private void crcTest() throws IOException {
boolean modified = false;
// required dex crc value stored as a text string.
// it could be any invisible layout element
long dexCrc = Long.parseLong(Main.MyContext.getString(R.string.dex_crc));
ZipFile zf = new ZipFile(Main.MyContext.getPackageCodePath());
ZipEntry ze = zf.getEntry("classes.dex");
if ( ze.getCrc() != dexCrc ) {
// dex has been modified
modified = true;
}
else {
// dex not tampered with
modified = false;
}
}</pre>
<br />
and here's the above code translated into smali:<br />
<pre class="brush: smali;">.method private crcTest()V
.locals 7
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/io/IOException;
}
.end annotation
.prologue
.line 599
const/4 v2, 0x0
.line 602
# modified will be set to true if classes.dex crc is not what it should be
.local v2, modified:Z
sget-object v5, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
# get the crc value from string resources
const v6, 0x7f040002
invoke-virtual {v5, v6}, Landroid/content/Context;->getString(I)Ljava/lang/String;
move-result-object v5
# convert it to a long since ZipEntry.getCrc gives us long
invoke-static {v5}, Ljava/lang/Long;->parseLong(Ljava/lang/String;)J
move-result-wide v0
.line 604
.local v0, dexCrc:J
new-instance v4, Ljava/util/zip/ZipFile;
sget-object v5, Lcom/lohan/testtarget/Main;->MyContext:Landroid/content/Context;
# get the path to the apk on the system
invoke-virtual {v5}, Landroid/content/Context;->getPackageCodePath()Ljava/lang/String;
move-result-object v5
invoke-direct {v4, v5}, Ljava/util/zip/ZipFile;-><init>(Ljava/lang/String;)V
.line 605
.local v4, zf:Ljava/util/zip/ZipFile;
# get classes.dex entry from our apk
const-string v5, "classes.dex"
invoke-virtual {v4, v5}, Ljava/util/zip/ZipFile;->getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;
move-result-object v3
.line 607
.local v3, ze:Ljava/util/zip/ZipEntry;
# you could crack here by providing v5 with the correct
# long value. this may be easier if later logic is convoluted
# or if the result is stored in a class variable and acted
# on later. you can write your own java program to get the</init></pre>
<pre class="brush: smali;"><init> # correct value. </init></pre>
<pre class="brush: smali;"><init> invoke-virtual {v3}, Ljava/util/zip/ZipEntry;->getCrc()J
move-result-wide v5
# compare v5 (actual crc) with v0 (stored crc)
cmp-long v5, v5, v0
# if v5 is 0, meaning cmp-long reports values are NOT the same
# goto :cond_0. this is where this could be cracked.
# could simply remove this line, in this case.
if-eqz v5, :cond_0
.line 609
# otherwise store true in v2.
# normally there will be code to act on the value of v2.
const/4 v2, 0x1
.line 615
:goto_0
return-void
.line 613
:cond_0
# store false in v2.
const/4 v2, 0x0
goto :goto_0
.end method</init></pre>
</div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com16tag:blogger.com,1999:blog-7271172641819523283.post-29905891065809965442011-06-06T08:40:00.000-07:002011-06-06T08:40:10.971-07:00protection by checking for debuggers<div dir="ltr" style="text-align: left;" trbidi="on">one way to figure out what an app is doing is to use a debugger so you can step through line by line. apktool makes it possible to debug apps to which you do not have the source, and you also have to setup a few other things covered in lesson 1 of the way of the android crack tutorials.<br />
<br />
some apps try to protect against this and there are two techniques of doing so. the first is to check the android manifest to see if the app is set to debuggable. the java code would look something like this:<br />
<br />
<pre class="brush: java;">boolean isDebuggable = (0 != (getApplcationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE));
if ( isDebuggable )
invalidLicense(); // you get the idea </pre><br />
in smali, specifically from the testtarget app distributed with antilvl, it looks like:<br />
<pre class="brush: smali;"># get app info object
invoke-virtual {p0}, Lcom/lohan/testtarget/Main;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
move-result-object v1
# get flags mask
iget v2, v1, Landroid/content/pm/ApplicationInfo;->flags:I
# 0x2 is ApplicationInfo.FLAG_DEBUGGABLE
and-int/lit8 v2, v2, 0x2
iput v2, v1, Landroid/content/pm/ApplicationInfo;->flags:I
# if v2 is 0x0 (the debuggable flag is not set), goto :cond_0
if-eqz v2, :cond_0</pre><br />
<br />
the second method is to check if a debugger is currently connected. the java looks like:<br />
<pre class="brush: java;">boolean debugConn = Debug.isDebuggerConnected();</pre></div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com3tag:blogger.com,1999:blog-7271172641819523283.post-23073771087641891572011-04-27T06:36:00.000-07:002011-04-27T06:36:34.284-07:00smali syntax resource<div dir="ltr" style="text-align: left;" trbidi="on">jesusfreke, the guy who wrote smali/baksmali, has some nice documentation on the smali syntax on the wiki for his project: <a href="http://code.google.com/p/smali/w/list">http://code.google.com/p/smali/w/list</a> i learned some stuff! thanks jesusfreke.</div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com8tag:blogger.com,1999:blog-7271172641819523283.post-85619314231072721872011-04-18T11:25:00.000-07:002012-05-01T12:28:02.884-07:00antilvl 1.1.5<div dir="ltr" style="text-align: left;" trbidi="on">
thanks to Notion and SuRViVe pointing out some instances of the lvl not being properly identified. i removed some requirements to match some key files that weren't likely necessary and were not being found recently. two new anti-cracking methods have been added and testtarget was updated appropriately.<br />
<br />
grab it here:<br />
<a href="http://androidcracking.blogspot.com/p/antilvl_01.html">http://androidcracking.blogspot.com/p/antilvl_01.html</a></div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com5tag:blogger.com,1999:blog-7271172641819523283.post-28429787457317355942011-04-08T13:47:00.001-07:002012-05-01T12:28:23.908-07:00antilvl 1.1.4<div dir="ltr" style="text-align: left;" trbidi="on">
antilvl 1.1.4 has been released. main new feature is support for cracking amazon appstore drm. it also includes the apk i use to test new releases called testtarget.apk.<br />
<br />
let me know if the new release breaks something :D<br />
<br />
grab it here: <a href="http://androidcracking.blogspot.com/p/antilvl_01.html">http://androidcracking.blogspot.com/p/antilvl_01.html</a></div>lohan+http://www.blogger.com/profile/11908388368574470787noreply@blogger.com2