Static decryption for Android LeNa.[b/c] using IDA Pro

Recently at Lookout we blogged about a newer flavor of Legacy Native (LeNa). This variant is extremely similar to the other ones we’ve found in the past and blogged about in October of 2011, the full tear down I wrote can be found in pdf form here. The samples for both LeNa.b and LeNa.c have been added to the Contagio Mini Dump

While going through some samples I decided to throw together a quick IDC script for IDA Pro to help decrypt the commands and variables without executing the code. The decryption isn’t hard, in fact it actually ends up just being an XOR with 0xFF. Though if anyone hasn’t ever dealt with IDA Pro or ARM, it might look a bit confusing at first. Below is the decryption function commented from one of specific samples of LeNa;
Simple XOR
The IDC script is really simple, the current version can be found on github with the current version featured below;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/* LeNa-Decryption.idc

Simple decryption script for the LeNa.b/.c variants.

Designed for use on the elf binary that LeNa drops, it works by decrypting the
encrypted string and dropping the decrypted bytes as a comment where ever the
string's pointer is used.

The decryption is really easy (a MVNS), basically a xor to 0xFF

Timothy Strazzere <[email protected]>
March 2012
*/

#include <idc.idc>

static decrypt_string(void)
{
auto original_address, ptr, comment;

// This is normally a pointer to a pointer, follow it
original_address = ptr = Dword(ScreenEA());

// Make sure we retrieved a good address
if (ptr == BADADDR) {
Message("Unable to find a actual encrypted string's address!\n");
return;
}

// XOR until we hit the null byte of the string
comment = "";
while(Byte(ptr) != 0x00) {
comment = comment + sprintf("%s", Byte(ptr) ^ 0xFF);
ptr++;
}

// Drop a comment at the address we originally where pointing too
MakeRptCmt(original_address, "Decrypted value: " + comment);

// Drop a comment on all xrefs to this
auto xref = Dfirst(original_address);
while(xref != BADADDR) {
MakeRptCmt(xref, "Decrypted value: " + comment);
xref = Dnext(original_address, xref);
}

// Drop a message in the output window
Message("Decrypted string: %s\n", comment);
}

static main(void) {
// Set hotkey for decryption routine
if(AddHotkey('/', "decrypt_string") != IDCHK_OK) {
Message("Something went wrong with adding a hotkey for the decryption routine");
}
Message("Hotkey added!\n");
}

The script should be really easy to follow, I tried to comment it well enough. Essentially when you load the script it will bind the function for decrypting to the “/“ key. Find the pointer to the encrypted data like below;
Highlighted pointer to the encrypted data
Next just follow the pointer to it’s selection in the text section. Once the encrypted pointer is highlighted, simply hit the assigned hot-key “/“ and let the script do it’s job. The script will dump the decrypted message to the output window and also add a comment next to the pointer as seen below;

The script also traverses back to all the cross references (xrefs) and will add a comment to all those spots where this variable is used.
The original usage in the decryption function
The main use of the decrypted data in another function
Nothing too fancy or complicated, though it was a nice way to get into IDC scripts for IDA Pro. Also it’s a good way to start segwaying people who may only have used baksmali or dex2jar into using IDA Pro for ARM reversing.