Since I am on a roll with blogging, I will post some of my thoughts and work with reverse engineering. I have been doing RE seriously for the past year, and I really love doing it, however it is time consuming and a bit mind numbing :-). While working on some malware I came across a section of code that used a simple encryption routine where the encrypted string was passed byte for byte through this engine. Each byte was broken into a high order and low order nibble and these nibbles were reversed revealing the decoded binary equivelent of the ASCII character. I came across many specimens of malware that used this, so I wrote an IDA Pro script (IDC) to decode these strings for me.
Decryption Subroutine:
subDecrypt
.text:00403F21 014 mov ecx, [ebp+var_C_Arg1] ; start
.text:00403F24 014 mov dl, [ecx]
.text:00403F26 014 mov byte ptr [ebp+var_4], dl
.text:00403F29 014 mov eax, [ebp+var_4]
.text:00403F2C 014 and eax, 0FFh
.text:00403F31 014 shl eax, 4
.text:00403F34 014 mov byte ptr [ebp+var_8], al ; Lower 4 Bits
.text:00403F37 014 mov ecx, [ebp+var_4]
.text:00403F3A 014 and ecx, 0FFh
.text:00403F40 014 sar ecx, 4
.text:00403F43 014 mov byte ptr [ebp+var_4], cl ; Upper 4 Bits
.text:00403F46 014 mov edx, [ebp+var_4]
.text:00403F49 014 and edx, 0FFh
.text:00403F4F 014 mov eax, [ebp+var_8]
.text:00403F52 014 and eax, 0FFh
.text:00403F57 014 or edx, eax ;Swap bits via OR
.text:00403F59 014 mov byte ptr [ebp+var_4], dl
.text:00403F5C 014 mov ecx, [ebp+var_10_Arg2]
.text:00403F5F 014 mov dl, byte ptr [ebp+var_4]
.text:00403F62 014 mov [ecx], dl ; dl contains the patched byte
.text:00403F64 014 mov eax, [ebp+var_C_Arg1]
Here I have broken down and commented the disassembly showing the decryption routine. This should be pretty trivial to script so I don’t have to go byte for byte with a calculator and ASCII table.
DC script for swapping the low order nibble and the high order nibble of a byte
Uncomment one, or both of the functions at the bottom of the script
--Message() will just print the decoded strings to the messages window but will not patch the DB
--PatchByte() is self explanatory
Script by Chris Sia eon.bass@gmail.com
#include
static revbyte(void)
auto start, end, ptr, X, Y, Z;
start = SelStart();
end = SelEnd();
end = end - 1;
Message("Reversing Byte Order\n");
for (ptr = start; ptr <= end; ptr++)
X = Byte(ptr);
Y = Byte(ptr);
{
X = (X & 0xFF);
X = X << 4;
{
Y = (Y & 0xFF);
Y = Y >> 4;
Z = (X | Y);
/* Uncomment below to enable decoded strings to be printed in Messages Window */
Message(Z);
/* Uncomment below to enable swapped bytes to be patched back to the DB */
PatchByte(ptr, Z);
}
}
Uncomment one, or both of the functions at the bottom of the script
--Message() will just print the decoded strings to the messages window but will not patch the DB
--PatchByte() is self explanatory
Script by Chris Sia eon.bass@gmail.com
#include
static revbyte(void)
auto start, end, ptr, X, Y, Z;
start = SelStart();
end = SelEnd();
end = end - 1;
Message("Reversing Byte Order\n");
for (ptr = start; ptr <= end; ptr++)
X = Byte(ptr);
Y = Byte(ptr);
{
X = (X & 0xFF);
X = X << 4;
{
Y = (Y & 0xFF);
Y = Y >> 4;
Z = (X | Y);
/* Uncomment below to enable decoded strings to be printed in Messages Window */
Message(Z);
/* Uncomment below to enable swapped bytes to be patched back to the DB */
PatchByte(ptr, Z);
}
}
This script can send the decrypted ASCII to the messages window in IDA, or actually patch the byte in the disassembly.
Then open the File/IDC command...and run revbyte().
The highlighted data now shows the decrypted strings. The beginning of a URL "http://20" is clearly visible.