Your Ad Here

The best way to Crack Practically Any Mac App (and The right way to Prevent It) [Hacking]

The best way to Crack Practically Any Mac App (and The right way to Prevent It) [Hacking] While the Mac isn’t targeted for security exploits and viruses, it’s no stranger to software piracy-likely because Mac apps are pretty easy to crack. Here’s how it’s done and the way to prevent it.

How I’d Crack Your Mac App

Disclaimer: I am fervently against software piracy, and I do not participate in piracy. Some will view this newsletter as an endorsement of piracy, but rest assured that it’s not. However, I don’t believe that obscurity and ignoring the difficulty is an appropriate solution.

Well, not you specifically, but by you I mean the typical Mac developer. It’s too easy to crack Mac apps. Way too easy. By walking through how I will be able to hack your app with only 1 Terminal shell, I am hoping to shed some light on how it really is ordinarily done, and hopefully convince you to give protection to yourself against me. I’ll be ending this text with some tips that could prevent such a hack.

In order to follow along you’re going to want a couple of command line utilities. You’re going to want the Xcode tools installed. And, lastly, you’re going to wish an app to operate on. I chose Exces , a shareware App I wrote decades ago.

Let’s start by making certain we’ve the two utilities we’d like: otx and class-dump. I am keen on to take advantage of Homebrew as my package manager of choice. Note that i’ll use command line utilities only, including vim. In case you prefer GUIs, be at liberty to take advantage of your code editor of choice, HexFiend and otx’s GUI app.

$ sudo brew install otx
$ sudo brew install class-dump

The first step is to poke into the target app’s headers, gentlemanly left intact by the unwitting developer.

$ cd Exces.app/Contents/MacOS
$ class-dump Exces | vim

Browse around, and find here gem:

@interface SSExcesAppController : NSObject
{
[...]
BOOL registred;
[...]
- (void)verifyLicenseFile:(id)arg1;
- (id)verifyPath:(id)arg1;
- (BOOL)registred;

What can we have here?! A (badly spelt) variable and what appears like three methods on the topic of registration. We are able to now focus our efforts around these symbols. Let’s continue poking by disassembling the source code for these methods.

$ otx Exces -arch i386

Note that Exces is a universal binary, and that we’d like to confirm we only care for the active architecture. For this reason, Intel’s i386. Let us find out what verifyLicenseFile: does.

-(void)[SSExcesAppController verifyLicenseFile:]
[...]
+34 0000521e e8c21e0100 calll 0x000170e5 -[(%esp,1) verifyPath:]
+39 00005223 85c0 testl %eax,%eax
+41 00005225 0f84e2000000 je 0x0000530d
[...]
+226 000052de c6472c01 movb $0×01,0x2c(%edi) (BOOL)registred
[...]

This is simply not straight Objective-C code, but rather assembly-what C compiles into. The first element of each line, the offset, +34, shows what percentage bytes into the tactic the instruction is. 0000521e is the address of the instruction inside the program. e8c21e0100 is the instruction in byte code. calll 0x000170e5 is the instruction in assembly language. -[(%esp,1) verifyPath:] is what otx could gather the instruction to represent in Obj-C from the symbols left inside the binary.

With this in mind, we will realize that verifyLicenseFile: calls the tactic verifyPath: and later sets the boolean instance variable registred. We will be able to guess that verifyPath: is one of the method that checks the validity of a license file. We are able to see from the header that verifyPath: returns an object and thus can be way too complex to patch. We’d like something that deals in booleans.

Let’s launch Exces within the gdb debugger and check when verifyLicenseFile: is named.

$ gdb Exces
(gdb) break [SSExcesAppController verifyLicenseFile:]
Breakpoint 1 at 0×5205
(gdb) run

No bite. The breakpoint will never be hit on startup. We will be able to assume that there’s an efficient the reason for this is that verifyLicenseFile: and verifyPath: are two separate methods. While we could patch verifyLicenseFile: to always set registred to true, verifyLicenseFile: is maybe called only to ascertain license files entered by the user. Quit gdb and let’s instead lookup another piece of code that calls verifyPath:. Within the otx dump, find right here in awakeFromNib:

-(void)[SSExcesAppController awakeFromNib]
[...]
+885 00004c8c a1a0410100 movl 0x000141a0,%eax verifyPath:
+890 00004c91 89442404 movl %eax,0×04(%esp)
+894 00004c95 e84b240100 calll 0x000170e5 -[(%esp,1) verifyPath:]
+899 00004c9a 85c0 testl %eax,%eax
+901 00004c9c 7409 je 0x00004ca7
+903 00004c9e 8b4508 movl 0×08(%ebp),%eax
+906 00004ca1 c6402c01 movb $0×01,0x2c(%eax) (BOOL)registred
+910 00004ca5 eb7d jmp 0x00004d24 return;
[...]

The code is nearly clone of verifyLicenseFile:. Here’s what happens:

verifyPath: is known as. (+894 calll)
A test happens based on the outcome of the call. (+899 testl)
Based on the outcome of the text, jump if equal. (+901 je) A test followed by a je or jne (jump if not equal) is assembly-speak for an if statement.
The registred ivar is ready, if we haven’t jumped away.

Since awakeFromNib is executed at launch, we will be able to safely assume that if we override this check, we will fool the app into thinking it’s registered. The best way to do this is to modify the je into a jne, essentially reversing its meaning.

Search the dump for any jne statement, and compare it to the je:

+901 00004c9c 7409 je 0x00004ca7
+14 00004d9f 7534 jne 0x00004dd5 return;

7409 is the binary code for je 0x00004ca7. 7534 is the same binary code. If we simply switch the binary code for the je to 7534, at address 00004c9c, we must always have our crack. Let’s check it out in gdb.

$ gdb Exces
(gdb) break [SSExcesAppController awakeFromNib]
Breakpoint 1 at 0×4920
(gdb) r
(gdb) x/x 0x00004c9c
0x4c9c : 0x458b0974

We break on awakeFromNib so we’re ready to fiddle around while the app is frozen. x/x reads the code in memory at the given address.Now here’s the confusing thing to pay attention to: endianness. While on disk, the binary code is normal, intel is a little bit-endian system which puts probably the most significant byte last, and thus reverses every four-byte block in memory. so while the code at address 0x4c9c is printed as 0x458b0974, it’s actually 0x74098b45. We recognize the first two bytes 7409 from earlier.

We must switch the first two bytes to 7534. Let’s start by disassembling the tactic on the way to better see our way around. Find the relevant statement:

0x00004c9c : je 0x4ca7

Now let’s edit code in memory.

(gdb) set {char}0x00004c9c=0×75
(gdb) x/x 0x00004c9c
0x4c9c : 0x458b0975
(gdb) set {char}0x00004c9d=0×34
(gdb) x/x 0x00004c9c
0x4c9c : 0x458b3475

Here we set the first byte at 0x00004c9c. By simply counting in hexadecimal, we know that the subsequent byte goes at address 0x00004c9d, and set it as such. Let’s disassemble again to examine if the change was done right.

(gdb) disas
0x00004c9c : jne 0x4cd2

Whoops, we made a mistake and altered the destination of the jump from +912 to +955. We realize that the first byte (74) of the byte code stands for the je/jne and the second byte is the offset, or what number bytes to jump by. We must always only have changed 74 to 75, and not 09 to 34. Let’s fix our mistake.

(gdb) set {char}0x00004c9c=0×75
(gdb) set {char}0x00004c9d=0×09

And check again…

0x00004c9c : jne 0x4ca7

Hooray! This looks good! Let’s execute the app to admire our crack.

(gdb) continue

Woot! Victory! We’re in, and the app thinks we’re a valid customer. Time to get wasted and party! (I recommend Vessel nightclub in downtown San Francisco.) Well, not quite. We still want to make our change permanent. As it currently stands, everything shall be erased as soon as we quit gdb. We want to edit the code on disk, within the actual binary file. Let’s find a bit of our edited binary large enough that it likely won’t be repeated within the whole binary.

(gdb) x/8x 0x00004c9c
0x4c9c : 0x458b0975 0x2c40c608 0x8b7deb01 0xa4a10855
0x4cac : 0×89000141 0×89082454 0×89042444 0x26e82414

That’s the memory representation of the code, an entire 8 blocks of four bytes starting at 0x00004c9c. Taking endianness under consideration, we must reverse them and we get the next:

0x75098b45 0x08c6402c 0x01eb7d8b 0x5508a1a4
0×41010089 0×54240889 0×44240489 0x1424e826

The very first byte of the series is the 74 that we switched into 75. By changing it back, we will deduce the original binary code to be:

0x74098b45 0x08c6402c 0x01eb7d8b 0x5508a1a4
0×41010089 0×54240889 0×44240489 0x1424e826

Let’s open the binary in a hex editor. I used vim, but be at liberty to exploit any hex editor at this point. HexFiend has an excellent GUI.

(gdb) quit
$ vim Exces

This loads up the binary as ascii text, that is of little help. Convert it to hex thusly:

:%!xxd

vim formats hex like this:

0000000: cafe babe 0000 0002 0000 0012 0000 0000 …………….

The first part, before the colon, is the address of block. Following it are 16 bytes, broken off in two-byte segments. Incidentally, every Mach-O binary starts with the hex bytes cafebabe. Drunk Kernel programmers probably thought it’d be funny. Now that we’ve got our beautiful hex code loaded up, let’s look for the first two bytes of our code to interchange:

/7409

Shit. Too many results to make sense of. Let’s add another two bytes. Look for ” 7409 8b45″ instead and boom, only 1 result:

001fc90: 0089 4424 04e8 4b24 0100 85c0 7409 8b45 ..D$..K$….t..E

Edit it to the subsequent:

001fc90: 0089 4424 04e8 4b24 0100 85c0 7509 8b45 ..D$..K$….t..E

Convert it back to binary form, then save and quit:

:%!xxd -r
:wq

And… We’re done! To examine our work, launch the app in gdb, break to [SSExcesAppController awakeFromNib] and disassemble.

$ gdb Exces
(gdb) break [SSExcesAppController awakeFromNib]
Breakpoint 1 at 0x4c90
(gdb) r
(gdb) disas

Admire our work:

0x00004c9c : jne 0x4ca7

Quit gdb and relaunch the app from the Finder, and take pleasure in your leet glory.

How to stop This

Objective-C makes it really easy to clutter with an app’s internals. Try and program the licensing mechanism to your app in pure C, for you to already make it harder for me to search out my way around your binary. Also read this older article of mine on three easy tips-stripping debug symbols, using PT_DENY_ATTACH, and doing a checksum of your binary-you may implement to make it a whole bunch harder to your app to be cracked.

A truly skilled hacker will always find his way around your protection, but implementing a bare minimum of security will weed out 99% of amateurs. it’s not that i am a skilled hacker-yet with some very basic knowledge I tore this apart right away. Implementing the numerous easy tips above takes very little time, yet would have made it enough of a pain for me that I’d have given up.

Kenneth Ballenegger develops cool Mac and iPhone software. Visit his personal blog for more writing on the realm of design, software, and life. You are able to contact him at kenneth@ballenegger.com .


Source

  • Twitter
  • Facebook
  • email
  • PDF
  • Digg
  • del.icio.us
  • Google Bookmarks
  • RSS

This post is tagged: , , , ,

One Response

  1. aRealHacker says:

    You stole LifeHackers article you motherfucker.
    If your not good enough to write your own ones
    then you better just go fuck yourself you bitch.

    This is copyright violation. You should pay for
    this.

Leave a Reply





  • Everything Everywhere promises ‘small-scale LTE launch’ in UK by the top of 2012Everything Everywhere promises ‘small-scale LTE launch’ in UK by the top of 2012

    Everything Everywhere's spilled more details on its 4G hopes and dreams. That £1.5 billion investment is aiming to get a small scale LTE launch by the tip of the year -- subject to Ofcom's say-so . The lucky epicenter of for the way forward for mobile communications within the UK? That'll be Bristol, which is able to begin its trial on 1800MHz spectrum from April. It's already… »
  • ASUS MWC teaser video hints at possible hi-res tablet display?ASUS MWC teaser video hints at possible hi-res tablet display?

    What's to not love a couple of short video insinuating something marvelous could be coming soon -- especially if it means a hi-res screen on a tablet, à la that purported Retina Display we saw a couple of days back . We need to give ASUS credit for this one, as it's teasing us with a clip titled "Twice the Detail, Twice the thrill." The vid's lead actors are a plethora of… »

Categories

Subscribe

Enter your email address: