04 Mar 2014 @ 12:56 AM 

Rarverseme is a rar file, and rar has an inbuilt VM which can be programmed(http://blog.cmpxchg8b.com/2012/09/fun-with-constrained-programming.html). Given challenge contains a custom bytecode which will print πŸ™ every time upon unraring. Our target is to understand the bytecode, reverse it to find the flag.

Idea is to disassemble/debug the rarVM to figure out what exactly is getting executed. After getting unrar source compiled, rest was pretty straight forward.

Running a trace resulted in this.

MOVD [010DC294], 0x00002000
MOVD [010FFC30], 0x796f7572 ;your
MOVD [010FFC34], 0x666c6167 ;flag
MOVD [010FFC38], 0x676f6573 ;goes
MOVD [010FFC3C], 0x68657275 ;heru
MOVD [010DC298], 0x00005000
MOVD [01102C30], 0x31337357 ;13sW
MOVD [01102C34], 0x63561227 ;cV.'
MOVD [01102C38], 0x6666654a ;ffeJ
MOVD [01102C3C], 0x78584148 ;xXAH
JMP 0x000000ae
MOVD [010DC290], 0x796f7572 ; flag[i]
AND 0x796f7572, 0x000000ff
MOVD [010DC29C], 0x31337357 ; arr[i]
AND 0x31337357, 0x000000ff
MUL 0x00000072, 0x00000057 ; flag[i] * arr[i]

MOVD [010DC28C], 0x000026be
MOVD [010DC290], 0x796f7572
SHR 0x796f7572, 0x00000008 
AND 0x00796f75, 0x000000ff
MOVD [010DC29C], 0x63561227
AND 0x63561227, 0x000000ff
MUL 0x00000075, 0x00000027
ADDD 0x00003891, 0x000011d3 ; sum the results

MOVD [010DC290], 0x796f7572
SHR 0x796f7572, 0x00000010
AND 0x0000796f, 0x000000ff
MOVD [010DC29C], 0x6666654a
AND 0x6666654a, 0x000000ff
MUL 0x0000006f, 0x0000004a
ADDD 0x000058a7, 0x00002016

MOVD [010DC290], 0x796f7572
SHR 0x796f7572, 0x00000018
AND 0x00000079, 0x000000ff
MOVD [010DC29C], 0x78584148
AND 0x78584148, 0x000000ff
MUL 0x00000079, 0x00000048
ADDD 0x00007aaf, 0x00002208

CMPD 0x00007aaf, 0x0000706f

its doing a multiplication of flag values and a fixed array and comparing to a hardcoded value. If the comparison is wrong, it is jumping to bad_boy. The whole checking code can be dumped by setting CMPD as success. As we have the code figured, rest was simple bruteforcing. Before I started bruteforcing, my friend wrote a z3 code which runs much faster and yielded the flag as: evenmoarvms?rly?

V = [0x706f, 0x7972, 0x89d1, 0x9cc5]
#add rest of hardcoded values

w0, w1, w2, w3 = BitVecs("w0 w1 w2 w3", 16)

solve( w0 * 0x57 + w1 * 0x27 + w2 * 0x4a + w3 * 0x48 == V[0],  
	   w0 * 0x73 + w1 * 0x12 + w2 * 0x65 + w3 * 0x41 == V[1],  
	   w0 * 0x33 + w1 * 0x56 + w2 * 0x66 + w3 * 0x58 == V[2], 
	   w0 * 0x31 + w1 * 0x63 + w2 * 0x66 + w3 * 0x78 == V[3],
	   ULT(w0, 128), ULT(w1, 128))

Posted By: Dan
Last Edit: 04 Mar 2014 @ 12:56 AM

EmailPermalinkComments (2)
Categories: CTF, Reverse Engineering
 03 Mar 2014 @ 11:09 PM 

Hypercube is a DOL file which points us to gamecube and Dolphin emulator. Once we have the emulator, we can see the output. It clearly states that we are in a gamecube and only hypercube is fast enough to get the flag. This pretty much sounds like Hypercomputer challenge from PlaidCTF. Now its time to do some RE then.

To get disassembly we will need specific loader for DOL files. Hopefully some of those are available and we can directly start our disassembly. We can easily reach interesting function by looking up for strings. Reading Power PC assembly is not in my usual work description, but I can do that too while doing a CTF πŸ˜‰
Next thing I did was to try to debug it in the emulator and see what exactly happens. Once the call at 0x80005c78 was invoked, it just went into full on computation which eventually crashed the emulator. Now the Hyper part was pretty much making sense πŸ™‚
Upon analyzing there are only 3 functions we have to worry about – 80005B18, 80005A4C and 800059E4.

After converting the PPC to higher language, it was evident that these operations are simple and written in a way that will consume lot of CPU cycles.

We can rename those functions as 80005B18 -Multiply, 80005A4C – Add and 800059E4 – Increment

That reduces our code to minimal and running it yields our flag. (Don’t mind the variable names – happens when you haven’t slept for more than 24 hours πŸ˜€ )

UInt32 s_8 = 0xadd;
UInt32 s_c = 0x5dd11;
UInt32 s_10 = 0x352463;
UInt32 s_14 = 0x8008135;
UInt32 r0, r11, r3, r9, r4;
for (int i = 0; i <= 31390; i++)
	for (int j = 0; j <= 21; j++)
		r9 = s_c * s_10;

		r0 = (UInt32)((((UInt64)r9 * (UInt64)3) & 0xFFFFFFFF00000000) >> 32);
		r11 = r9 - r0;
		r11 = r11 >> 1;
		r0 += r11;
		r11 = r0 >> 30;
		r0 = r11 << 31;
		r0 = r0 - r11;
		r0 = r9 - r0;
		s_8 = r0;

		r3 = s_c;
		r4 = 0x6ddb;
		r9 = r3 * r4;
		r0 = (UInt32)((((UInt64)r9 * (UInt64)3)&0xFFFFFFFF00000000)>>32);
		r11 = r9 - r0;
		r11 = r11 >> 1;
		r0 += r11;
		r11 = r0 >> 30;
		r0 = r11 << 31;
		r0 = r0 - r11;
		r0 = r9 - r0;
		s_c = r0;

		s_10 = s_c ^ 0x1BA40000 ^ 0x1c3c;
richText.Text = "key{1337" + s_8.ToString() + s_c.ToString() + s_10.ToString() + "h4x" + s_14.ToString() + "}";

Posted By: Dan
Last Edit: 03 Mar 2014 @ 11:22 PM

EmailPermalinkComments (0)
Categories: CTF, Reverse Engineering
 08 Aug 2013 @ 8:52 PM 

Cross posted from my team site: http://seg.fault.in

I started looking at cone when I got frustrated with cnot. Initial analysis confirmed that it is a x64 binary, asks for a password when run, and prints whether the password was right or not.

Running through ltrace went fine and there was no trace for anti-dbg (like ptrace call from cnot).


Next logical step is to load into IDA and take a look at the disassembly.

No, not this madness again :/ (Both CNOT and CON are obfuscated x64 binaries).

Looking at the disassembly it looked similar to cnot, but expectedly lesser protection/obfuscation. From previous experience from cnot, I started to rename fgetc/fputc/calloc wrapper functions to get a better understanding. In the mean time, lets look at the ltrace logs.


There is one calloc just after the password prompt is printed and lot of callocs after the password is read. We can easily assume that lot of allocated memory will be used for password verification.

Now looking back at the disassembly and looking only at function calls we can get the flow ofΒ  fputc->calloc->fgetc function wrappers. Its time to start debugging as we have figured out where exactly our input is being read. I started debugging by putting breakpoint at the place where it checks for ‘\n’.

.text:0000000000404B0C         mov     qword ptr [rbp-58h], 0
.text:0000000000404B14         mov     dword ptr [rbp-58h], 0Ah
.text:0000000000404B1B         mov     r15d, [rbp-50h]
.text:0000000000404B1F         cmp     r15d, [rbp-58h]
.text:0000000000404B23         jz      short loc_404B36

Then traced down ignoring everything other than function calls (experience from cnot). I stepped into first function call and spent sometime trying to understand what it does, got frustrated and went back into disassembly to see whether the function calls return values is being used/checked at some place. As the check was there, I put BP on the next statement to see the return value. It turned to be 1, and the execution continues. The next function call is interesting one.

3Yes, we have our input in stack and its being referenced in couple of registers(I entered password as “abcd”). Now we can safely assume that call_404f89 does some operation on our password. Stepping into the function and tracing manually was a frustrating experience and decided to do what I previously did –Β  lets check the return value of the function. Return value was 0xa46c74bb and it is saved to stack. Tracing down the function, it ended up in doing a comparison with a hardcoded value.


Doing couple of more testing with different passwords verified that the password is split into 4bytes and passed to the function call_404f89, and the return values are compared with different hardcoded values. A total of 9 values are being compared – making our password 36 characters (including ‘\0’ – we will see how we got that later).

So essentially the algo should look like this:

char* szPassword = ReadPassword();
unsigned int hardcoded[] = {0x247BFB03, 0x8C33E4BB, 0xD49D047B,
                            0x7303FC73, 0x8C950303, 0x2304743B,
                            0x64647303, 0xA454949B, 0xD48CB5DB};
for(int i=0; i < 9; i++)
 retVals[i] = call_404f89(szPassword + (i * 4));
for(int i=0; i < 9; i++)
 if(retVals[i] != hardcoded[i])
  //return -1;

As we have partially figured out the algo, the next big thing is to understand call_404f89. I tried to single step through the code but resulted in spending more time staring at the disassembly that doesn’t make much sense. Meantime I was also trying out the other challenges and partially solved compression (CRIME attack) and three_eyed_fish (didn’t complete both due to lack of time/resource :/). Revisiting the challenge again, I took a look at the ltrace log – well we havn’t looked at the calloc function calls yet. I put a BP on calloc wrapper function (0x400bc4). We should be worried about breaks only after call_404f89 starts. Once the call_404f89 started, I looked into the allocated memory to see if something interesting gets stored in those places. As the memory got allocated, I looked into the previous allocated space (when 3rd allocation happened, I looked into second allocated heap memory and so on). By the time the processing of call_404f89 got over, I had the full memory dump of all allocated memories. I ran couple of sample inputs and compared the output to make sure that I am not looking at heap headers rather than actual values. Clearly a pattern emerged as shown in the below pic.
While debugging at calloc return statement (jmp rdi), we can see that our password (4bytes) are used in somekind of operation and temporary results are stored in heap memory and eventually our calculated value (0xa46c74bb see above) is generated. While debugging after calloc and copy of 4bytes, I stumbled upon a piece of code which actually does an operation on our password values.
6It is a shift-arithmetic-right (sar val,0x15) which produced 0x323, which is present in the memory dump. Yiyeks! we have one operation figured. Looking at the disassembly near by, I figured some kind of pattern and found another operation by address 0x004019bf -> shl val, 0x0b. Now I restarted the debugging session with BP set on to 0x004019bf and 0x00401aea. BP on 0x004019bf hit first, and I can see the value (0x64636261 – “abcd”) is being left shifted with 0x0b resulting 0x1b130800 – which is again present in the memory dump. 2nd BP hit and we got 0x323. Now I looked at the memory dump to see if some info can be retrieved out of it. From the values in memory, I deduced the rest of the operation. Pure intuition and luck works sometime ;). Till now our algo is
value = 0x64636261;

t1 = value << 0x0b; //0x1b130800
t2 = value >> 0x15; //0x323

//next values in memory
//[0x1b130b23] - which is t1 ^ t2
//[0xc5beb5cc] = 0x1b130b23 ^ 0xdeadbeef
//[0xa46c74bb] = 0xc5beb5cc + 0xdeadbeef

We can rewrite the function as:
unsigned int call_404f89(char* password)
 unsigned int value = (unsigned int *)password;
 return ((((value << 0x0b)^(value >> 0x15))^ 0xdeadbeef)+ 0xdeadbeef);

Now we have the checking algo inΒ  hand. Next is to write small script/program to do brute-forcing.
for (int i = rangeStart; i < rangeEnd; i++)
 for (int j = rangeStart; j < rangeEnd; j++)
  for (int k = rangeStart; k < rangeEnd; k++)
   for (int l = rangeStart; l < rangeEnd; l++)
    val = (uint)(i << 0 | j << 8 | k << 16 | l << 24);
    t1 = val << 0x0b;
    t2 = val >> 0x15;
    t2 ^= t1;
    t2 ^= 0xdeadbeef;
    t2 += 0xdeadbeef;
    if (t2 == 0x247BFB03)  //change the hardcoded values to get next 4 chars.
     MessageBox.Show("Got it: " + Convert.ToChar(i) +
                                  Convert.ToChar(j) + 
                                  Convert.ToChar(k) + 
     goto done;

The last hadcoded value won’t be found through bruteforcing until you start with rangeStart=0; – the C string delimiter ‘\0’. Anyway last part can be easily guessed πŸ™‚

Finally the password/flag is: pls_send_help_im_in_a_stack_machine

Posted By: Dan
Last Edit: 08 Aug 2013 @ 08:52 PM

EmailPermalinkComments (0)
Categories: CTF, Reverse Engineering
 25 Jan 2012 @ 12:54 AM 

HackIM scoreboard


Malcon 2011 CTM write up – Malcon-CTM-Writeup

NULLCON 2012 HackIM write up – HackIM – danny

Thanks to many people for constant help and support. I won both the CTFs and hope to participate and learn from the newer ones πŸ™‚

Posted By: Dan
Last Edit: 25 Jan 2012 @ 12:56 AM

EmailPermalinkComments (0)
Categories: CTF, Reverse Engineering
 22 Jul 2011 @ 6:34 PM 

One of my friend and colleague was working on automating Microsoft Attack Surface Analyzer (not going to explain what it is or what it does) for some of the projects. There is nothing much to automate other than generating baseline/product cabs and generating reports. For generating cabs, one has to just run the command asa.exe and you have the cabs in position. But for making reports, one has to run “Attack Surface Analyzer.exe”, select the cabs and press “Generate” button. Not quite scriptable is it? Searched for documentation or any online help, but there was none. Well, it is time for a (very) little bit of reverse engineering πŸ˜€

Microsoft Attack Surface Analyzer

“Attack Surface Analyzer.exe” is a .NET exe. So let us fire up Reflector. Oops, we don’t have free version of Reflector these days (too bad Red Gate). Fortunately we have ILSpy :). Fire up ILSpy and load the exe.

ILSpy have already identified the entry point for us, just click there and we will end up in Main.

Well, game over!

For the sake of completeness, I am posting the command line parameters here.

“Attack Surface Analyzer.exe” /BASELINE “your_baseline.cab” /PRODUCT “your_product.cab” /REPORT “your_report_dir” /USEHTML

Not sure why it was not documented πŸ˜›

Posted By: Dan
Last Edit: 22 Jul 2011 @ 06:45 PM

EmailPermalinkComments (0)
 16 Nov 2010 @ 4:05 PM 

[This post has been screwed due to Anti viruses claiming plain text as live exploits. I omitted most of the stuffs I planned to post 😐 ]

Many people don’t consider PDF files as a possible threat and oh, well I agree to them(!). It is not the PDF files but the rendering softwares we have to be afraid of. If you think I am referring to those Adobe Reader 0-days popping up periodically, hell yeah, you are RIGHT!. We are going to talk about PDF files, few Adobe Reader vulnerabilities, exploits and malwares that comes along with it πŸ˜‰

You can read about PDF in wiki page. PDF files are binary files with proper formatting and looks like a collection of objects. You can open a PDF file in a text editor or hex editor to view it’s object structure.

pdf file

As you can see PDF files start with a magic header %PDF or %%PDF followed by the spec version number.Β  From next line onwards you can see a pattern emerging, like [obj][data][endobj]. Well, this is the collection of object thing I said earlier. Each object is identified by an ID and a version number. 41 0 obj represents object 41 version 0. You can look into PDF specs for better understanding of the file architecture. You don’t have to understand every details of the spec, but you can specifically look into streams, encodings, java script implementations, acro forms etc… Before going further, I would like to explain a little more about streams. Streams are used to store data(images, text, java scripts etc…) and to make it efficient PDF allows us to use compression and encoding techniques like Flate/LZW/RLE etc. This creates sort of problem for us, we can’t just use text/hex editor for understanding the true content of PDF!. As a programmer I can’t ignore this challenge and I made a tool(PDF Analyzer) to solve this issue. I will use PDF Analyzer throughout this post but you won’t be able to get it as it is still in private build(I will release it…eventually ;)). For now you guys have other options, both commercial and freeware tools are available. I will post some links here.

PDF Dissector by zynamics – commercial

Origami by Sogeti ESEC Labs – freeware

PDF Stream Dumper by Dave – freeware

Various python PDF parsers from Didier Stevens and inREVERSE guys – freeware (search!)

PDF Analyzer is made in C# with only 3 external libraries, zlib(I should have used GZipStream with 2 byte header hack),Β  BeaEngine(Thanks BeatriX) and JSBeautifier(I ported 95% of code from js to C#). I spent around 2 weeks of free time on it. It may not be the fastest PDF parser, but it can handle every ill formatted PDF I have in my repository ;).

pdf analyzerAdobe reader’s top vulnerabilities come from Adobe specific javascript APIs. This gives us a chance to disable javascript and protect us from any of those javascript based exploits. Disabling javascript is crucial but it doesn’t fix vulnerabilities from other parts of Adobe Reader such as embedded image files and flash files.

Now we will look into some of the malware samples which exploits these vulnerabilities. You can find malware sample from many security blogs and I must thank two of my friends who sent a big archive of malware PDFs for analysis and testing :).

pdf analyzer jsThis particular sample splits javascript into three streams and concatenates them using <</Names[(1)6 0 R (2)7 0 R (3)8 0 R]>> which will eventually refer to three objects marked in red. After beautification, it seems it is exploiting one vulnerability existed inΒ  Adobe Reader namely this.media.newPlayer(null).

media newPlayer

It is essentially spraying heap with NOP sled and shellcode and calling the vulnerable function. The shellcode present here is a dropper/downloader, you can dump it to a file and use IDA to disassemble it.

Another PDF file which exploits util.printf is given below.

util printf
Again you can dump shellcode and disassemble with IDA. Another option is to use PDF Analyzers unescape functionality to directly disassemble the shell code.

disassemblyDisassembly starts with pretty straight forward steps to find base address via delta calculation(call – pop – sub). Then it fetches kernel32 base from PEB(fs[0x30])->Ldr.InInitOrder[0].base_address. This will be used to eventually load other modules and APIs.

Malware writers use multiple techniques to protect their payload. Techniques involves obfuscation, multiple and multi-level usage of encoding/compression schemes.

multiple encodingsIf any of you guys have samples that uses multi-level encoding, please send them to me πŸ˜‰ , I would like to test those with PDF Analyzer.

I will conclude the exploit samples by posting the latest exploit for the vulnerability printSeps. This code is retrieved from the PDF posted in full disclosure list.

Evil actions of PDF malwares varies from regular password stealer to rootkits. Once you have attained arbitrary code execution, rest will be just imagination of malware writer. As malware writers are mainly targeting Adobe Reader, try to shift to other PDF rendering software or at least update to latest version. There are free PDF readers like Sumatra or GhostScript, try those out and always be cautious when opening a PDF file.

Posted By: Dan
Last Edit: 24 Nov 2010 @ 03:23 PM

EmailPermalinkComments (10)
 06 Nov 2010 @ 6:09 PM 

Well, it seems people are getting crazy about android platform(everyone is trying to buy an android phone!). I don’t have an android cell phone but, lets see if I can get my hands dirty with this Linux+java clean room engineered platform πŸ˜‰

To begin our journey we need Android SDK, a target to test with and the necessary tools.

You can download the necessary file from these locations:

Android SDK: http://developer.android.com/sdk/index.html

Deurus android crackme 03: http://crackmes.de/users/deurus/android_crackme03/

Smali and baksmali: http://code.google.com/p/smali/

Dex2jar: http://code.google.com/p/dex2jar/

Java decompiler: http://java.decompiler.free.fr/

Download and install android SDK, SDK platform(latest is 2.2 at the time of writing), necessary java packages and rest of the tools. Create a virtual device from SDK menu and start emulation. Within few minutes you can see the emulator booting up and showing the phone screen. Well, thats it! we have our emulator up and running.

Now we need to install the software(crackme, its legal!) to the emulator. For that you may have to get acquainted with android debug bridge(adb).Β  Installing a apk file is pretty simple, all you have to do is to run two commands from android SDK directory/tools.

adb install

After the installation you can see the crackme icon from application menu.

android emulator

Now run the crackme by clicking on it. If everything went as expected you will see the crackme application on the screen.

android crackme

Now we will play with it, pressing check button with no inputs pops a message “Min 4 chars”, and with a proper name it pops up “Bad boy”. We have to remember these strings because we will be using them as our search keys when we dis assemble the apk(actually dex) files. Also note that we have two hardware ids and we need to find out what those exactly means.

As our crackme is up and running in emulator, we now move onto reversing it. If you have read apk file format, you can visualize it as a extended jar file which essentially is a zip file. Now you can change the crackme file name from Crackme03.apk to Crackme03.zip and decompress it to any folder.

apk file

Now the interesting file for us is classes.dex, which contains the compiled vm codes. We are going to disassemble the dex file with baksmali. Commands are pretty simple as you can see from screen shots.

baksmali disassembly

If everything worked fine, we will have a folder structure similar to java packages. Interesting .smali files are located at “\com\example\helloandroid”. Open all the .smali files into your favorite text editor(I use NPP). If you have never done anything related to reverse engineering/esoteric programming/assembly(IL) programming, you will probably think: WTF!. Relax. We have just opened a disassembled dex file. Now, if you are thinking how on earth someone can find the correct location of checking function, I hope you remember those pop up strings I told earlier. Yeah, “Min 4 chars” and “Bad boy”. Now we will use those strings as our search keys. Searching “Min 4 chars” in all the opened .smali files, we will find a hit in HelloAndroid$2.smali line 130.

dex disassembly(I just applied java syntax highlighter as I don’t have dalvik syntax files)

Our aim is to understand the serial checking function and write a keygen for it. For that we have to know all the dalvik opcodes that are used here. You can visit this page to understand the opcodes and after that you can convert disassembled code to much higher language constructs. I will provide a briefΒ  code snippet which actually implements the algorithm. Two hardware ids used are IMEI and sim serial number.

//Read name from text box
const v23, 0x7f050004
invoke-virtual/range {v22 .. v23}, Lcom/example/helloandroid/HelloAndroid;->findViewById(I)Landroid/view/View;
move-result-object v9

//Read serial from text box
const v23, 0x7f050006
invoke-virtual/range {v22 .. v23}, Lcom/example/helloandroid/HelloAndroid;->findViewById(I)Landroid/view/View;
move-result-object v21

//Checking whether the name is of length greate than 4
const/16 v22, 0x4
move v0, v11
move/from16 v1, v22
if-ge v0, v1, :cond_51

//Popup showing Min 4 chars
const-string v23, "Min 4 chars"
const/16 v24, 0x1
.line 86
invoke-static/range {v22 .. v24}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v13
.line 88
.local v13, notificacionToast:Landroid/widget/Toast;
invoke-virtual {v13}, Landroid/widget/Toast;->show()V

//There is a little exception trick to make integer string from username
//It converts aaaa to 97979797 which is ascii equivalent
invoke-virtual {v10, v5}, Ljava/lang/String;->charAt(I)C
move-result v3

//Getting first 5 chars from ascii converted name
const/16 v22, 0x0
const/16 v23, 0x5
move-object v0, v12
move/from16 v1, v22
move/from16 v2, v23
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;

//Converting it into integer and xoring with 0x6B016   - Serial part 1
invoke-static {v12}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v22
const v23, 0x6b016
xor-int v22, v22, v23

//Getting IMEI from TelephonyManager
invoke-virtual {v8}, Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;
move-result-object v6
.line 102
.local v6, imei2:Ljava/lang/String;

//Getting sim serial
invoke-virtual {v8}, Landroid/telephony/TelephonyManager;->getSimSerialNumber()Ljava/lang/String;
move-result-object v16
.line 103
.local v16, simsn:Ljava/lang/String;

//Getting first 6 chars from IMEI, and similarly from sim serial (IMEI.Substring(0,6) will be used as Serial part 3)
const/16 v22, 0x0
const/16 v23, 0x6
move-object v0, v6
move/from16 v1, v22
move/from16 v2, v23
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;

//Converting them to integer and xoring    - Serial part2
invoke-static/range {v19 .. v19}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v22
invoke-static/range {v20 .. v20}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v23
xor-int v22, v22, v23

//Making a new StringBuilder object and formatting the string to part1-part2-part3
new-instance v22, Ljava/lang/StringBuilder;
invoke-static {v12}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
move-result-object v23
invoke-direct/range {v22 .. v23}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
const-string v23, "-"
invoke-virtual/range {v22 .. v23}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22
invoke-static/range {v17 .. v18}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
move-result-object v23
invoke-virtual/range {v22 .. v23}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22
const-string v23, "-"
invoke-virtual/range {v22 .. v23}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22
move-object/from16 v0, v22
move-object/from16 v1, v19
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22

//Checking whether user entered serial and program made serials are equal.
invoke-virtual {v14, v15}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

As you can see, the algorithm is pretty straight forward. It is using name and two hardware ids as input and doing some operations on them to make a serial.Β  We can easily recode it in any programming language we prefer to make it as a keygen. Anyway, I am not posting any keygen sources as it will spoil the whole phun!

A demonstrative serial calculation routine is given below:

Name: aaaaa

HW ID1: 0000000000000000

HW ID2: 89014103211118510720

“aaaaa” will be converted to “9797979797”, from which we will take first 5 letters and convert it into integer 97979. This will be xored with 0x6B016(438294 in base to 10) resulting 511661 and this will be first part of serial. For second part, we will take first 6 letters from HW ID1 and HW ID2, convert them to integer and xor, resulting 000000^890141 = 890141. For third part we will use first 6 characters from HW ID1. Formatting with the specified delimiter the serial will become “511661-890141-000000”.

generated serial

Bingo! everything worked as expected. Now, for all those who thinks it is pretty hard to read all those disassembled instructions and manually converting them to higher language constructs, there are other options. As dalvik is based on design of java, it is also susceptible to decompilation. There is no decompiler available at this moment, but there is hope. For now we can use another utility which converts dex files to jar files so that we can use java decompilers to see much more abstracted code. From starting of this blog post you may have noticed the tool dex2jar. Use dex2jar to convert classes.dex to classes.dex.dex2jar.jar. Open it in a java decompiler and you can see much better output than dalvik disassembly. Please note that dex2jar is still in development phase and the output is meaningless at many places. This should be used only to get a quick understanding of all the functions called.

java decompiler

Well, thats it! We have analyzed an android program and defeated its protection. Cheerio!

Posted By: Dan
Last Edit: 14 May 2012 @ 05:54 PM

EmailPermalinkComments (20)

 Last 50 Posts
Change Theme...
  • Users » 1
  • Posts/Pages » 19
  • Comments » 41
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight


    No Child Pages.