PDA

View Full Version : Help for simple encryption


LaptoniC
December 28th, 2007, 09:55
Hi,
I think I am rusted,my brain stopped for simple encryption.

I am reversing a dictionary application.Dictionary use below code to decrypt its database.So, I made a program to decrypt database and changed it.I have also disabled this process so I can use plain text database for dictionary. My problem is what is the code that makes reverse of this ? The division part struggles me maybe it is to obvious to write in simple code.Thanks

arg_0=length of text
arg_4=pointer to encrypted text
Code:
decryptit proc

arg_0 = dword ptr 4
arg_4 = dword ptr 8

push ebx
mov ebx, [esp+4+arg_0]
push ebp
push esi
push edi
mov edi, [esp+10h+arg_4]
test ebx, ebx
jl short loc_401089

loc_401050:
xor ecx, ecx
mov esi, ebx

loc_401054:
cmp ecx, ebx
jge short loc_4010CF
mov al, [ecx+edi]
cmp al, 1Fh ;skip some chars
jbe short loc_401085
lea edx, [esi-1] ;len-1 variable
and eax, 0FFh
xor edx, 0FFFFFFAAh
mov ebp, 0E0h
and edx, 0FFh
sub eax, edx
add eax, 0C0h
cdq
idiv ebp
add dl, 20h
mov [ecx+edi], dl

loc_401085:
inc ecx
dec esi
jmp short loc_401054


loc_401089:
lea eax, [ebx-1]
test eax, eax
jl short loc_401050
mov esi, ebx
lea ecx, [eax+edi]
sub esi, edi
lea ebp, [eax+1]

loc_40109A:
mov al, [ecx]
cmp al, 7Ah
jnb short loc_4010C9
lea edx, [esi+ecx-1]
and eax, 0FFh
and edx, 80h
xor edx, 55h
sub eax, edx
sub eax, 20h
cdq
xor eax, edx
sub eax, edx
and eax, 0FFh
xor eax, edx
sub eax, edx
add al, 20h
mov [ecx], al

loc_4010C9:
dec ecx
dec ebp
jnz short loc_40109A
jmp short loc_401050

loc_4010CF:
pop edi
pop esi
pop ebp
pop ebx
retn
decryptit endp

naides
December 28th, 2007, 11:23
Sorry for the dumb question LaptoniC, but what you want is the code for ENCRYPRTING instead of DECRYPTING right??

LaptoniC
December 28th, 2007, 17:33
Yes you are right.I want a code to encrypt the contents.

dELTA
December 28th, 2007, 18:13
If your main interest is to understand this decryption algorithm (and its reverse) and not just the assembler code itself, I would really recommend describing it with some kind of pseudo code, or at least with good comments for the assembly. As it looks now, 99% of the people who could probably answer your question (including me) won't bother to take the time to first decode the disassembly to discover the actual decryption algorithm, before even being able to try to reverse it in the first place. Just a friendly tip.

A good advice if you want good help with anything is to always make it as simple (and enjoyable/lucrative, if possible) as possible to help you.

disavowed
December 28th, 2007, 18:17
Looks like it does this:

Code:
for (i = 0; i < len; i++)
{
if (szText[I] <= 0x1F)
{
continue;
}
szText[I] = (c - ((char)(len - i - 1) ^ 0xAA) + 0xC0) % 0xE0 + 0x20;
}


So backwards would be:

Code:
for (int i = 0; i < len; i++)
{
if (szText[i[ <= 0x1F)
{
continue;
}
szText[I] = szText[I] - 0xE0 + ((char)(len - i - 1) ^ 0xAA);
}

LaptoniC
December 29th, 2007, 00:28
sorry disavowed your code is not working where is the C0 ?

Let me give you some examples
len-1=0x44
szText[I]=0x6F

0x44 ^ 0xAA=0xEE
0x6F-0xEE=0xFFFFFF81
0xFFFFFF81+0xC0=0x41
0x41/0xE0=0x41
0x41+0x20=0x61 decrypted.
---------------------------
len-1=0x3E
szText[I]=0xC4

0x3E ^ 0xAA=0x94
0xC4-0x94=0x30 *Interesting!!
0x30+0xC0=0xF0
0xF0/0xE0=10
0x10+0x20=0x30 decrypted
--------------------------

This division is struggling me.Because it takes remainder.How you can go back from 0x10 ? you should add 0xE0.How you can go back from 0x41? you add nothing.Also it is interesting to note that 0xF0-0xC0=0x20. For some numbers, decryption could be done by using just 2 steps like in second example.

I guess I have found a way but don't know it is correct or coincidence.
I think maybe if subtraction gives negative value remove other bits by anding 0xFF and subtract 0x20

if subtraction gives positive value,then you have the value. I will try my idea later.
Regards.

upb
December 29th, 2007, 02:10
assuming disavowed first code is correct:

the point of the check, mod and add is simple -
input 0x00 - 0x1F maps to output 0x00 - 0x1F
input 0x20 - 0xFF maps to output 0x20 - 0xFF.

why? because in mod 0xE0 output is in range 0x00 - 0xDF,
0x20 + (in mod 0xE0) output is in range 0x20 - 0xFF

so the reverse is smth like this

Code:

for (i = 0; i < len; i++)
{
if (szText[I] <= 0x1F)
{
continue;
}
szText[I] = (c - ((char)(len - i - 1) ^ 0xAA) + 0xC0) % 0xE0 + 0x20;
}


Code:

if output is <= 0x1F, input is output, else

out = (in - ((char)(len - i - 1) ^ 0xAA) + 0xC0) % 0xE0 + 0x20 =>
out - 0x20 = (in - ((char)(len - i - 1) ^ 0xAA) + 0xC0) % 0xE0 =>
out - 0x20 - 0xC0 = in - ((len - i - 1) ^ 0xAA) =>
out - 0x20 - 0xC0 + ((len - i - 1) ^ 0xAA) = in
)


run a simple testcase with all inputs from input range to test if this is right

disavowed
December 29th, 2007, 14:30
Quote:
[Originally Posted by LaptoniC]sorry disavowed your code is not working where is the C0 ?

I combined the 0xC0 and the 0x20 into 0xE0. My code worked correctly for my simple test-cases (like "hello".

Quote:
[Originally Posted by upb]out - 0x20 - 0xC0 + ((len - i - 1) ^ 0xAA) = in

That's exactly what I ended up with above

upb
December 29th, 2007, 18:12
umm, duh
/me facepalms

LaptoniC
December 30th, 2007, 01:51
I use windows calculator and it doesnt work.Where is my mistake ?
let me give you example.

len-1=0x3E
szText[I]=0xC4

0x3E ^ 0xAA=0x94
0xC4-0x94=0x30
0x30+0xC0=0xF0
0xF0/0xE0=10
0x10+0x20=0x30

So original value is 0x30 right ?

lets use your codes to go back from 0x30 to 0xC4
disavowed
szText[I] = szText[I] - 0xE0 + ((char)(len - i - 1) ^ 0xAA);
30-E0+94=FFFFFFE4 (it is interesting that 30+94 =C4)

or
out - 0x20 - 0xC0 + ((len - i - 1) ^ 0xAA)
30-20-C0+94=FFFFFFE4
I still think that there is an error in the code.

janus68
December 30th, 2007, 08:47
Try this :
Code:

x = len;
for (i = 0;i < len;i++ )
{
if (szText[I] > 0x1F )
{
szText[I] = ((szText[I] - ((x - 1) ^ 0xAA) + 0xC0) % 0xE0) + 0x20;
--x;
}
}


ps.this is "encrypt" - perhaps "decrypt" should be just reverse of this,i.e:

x=0;
for (i=len;i>0;i--)
{
......
x++;
}

disavowed
December 31st, 2007, 13:58
LaptoniC, it looks like we're both a little wrong...

For the decryption, you're not using the right order-of-operations. I used parentheses in my code for a reason

Using your example values above (I'm assuming for your example that i = 0 (first character)):
0x3E ^ 0xAA = 0x94
0x94 + 0xC0 = 0x154
0x154 % 0xE0 = 0x74
0xC4 - 0x74 = 0x50
0x50 + 0x20 = 0x70

So original value is 0x70.

Now going in reverse, one does need to keep the 0xC0 and the 0x20 separate (and factor in the %). This is the correct encryption algorithm:
Code:

for (int i = 0; i < len; i++)
{
if (szText[I] <= 0x1F)
{
continue;
}
szText[I] = szText[I] + ((char)(len - i - 1) ^ 0xAA + 0xC0) % 0xE0 - 0x20;
}


This results in:

0x3E ^ 0xAA = 0x94
0x94 + 0xC0 = 0x154
0x154 % 0xE0 = 0x74
0x70 + 0x74 = 0xE4
0xE4 - 0x20 = 0xC4

This returns our original encrypted value, 0xC4.

LaptoniC
January 1st, 2008, 02:34
I think I am very stupid to see something very obvious.Could you help to me to find my error ?
Using my above example
-----------------------
i=0
len-1=0x3E
szText[I]=0xC4
-------------------
0x3E ^ 0xAA=0x94
0xC4-0x94=0x30
0x30+0xC0=0xF0
0xF0/0xE0=10
0x10+0x20=0x30

So original value is 0x30 right ?

using your algorithm

0x3E ^ 0xAA = 0x94
0x94 + 0xC0 = 0x154
0x154 % 0xE0 = 0x74
0x30 + 0x74 = 0xA4
0xA4 - 0x20 = 0x84 but the original value is C4 ?
By the way, 0xA4 + 0x20 =0xC4

So sometimes you have to subtract 0x20 and sometimes you have to add.I am really puzzled.

I attached small sample of encrypted and original data.You may test your algorithm.I am sorry if my mistake is very obvious.

disavowed
January 1st, 2008, 15:07
LaptoniC, you're not following the right order of operations. Please refer to http://msdn2.microsoft.com/en-us/library/126fe14k.aspx for C++ operator precedence reference. Please see where your step-by-step calculations differ from mine above and understand that you have to follow the order dictated by the parentheses. Or just step through my code in a debugger and you'll see that it works correctly for both encrypting and decrypting.

LaptoniC
January 1st, 2008, 22:04
I am using your representation let me quote your writing again

Quote:
This results in:

0x3E ^ 0xAA = 0x94
0x94 + 0xC0 = 0x154
0x154 % 0xE0 = 0x74
0x70 + 0x74 = 0xE4
0xE4 - 0x20 = 0xC4

This returns our original encrypted value, 0xC4.


I am just changing szText[I] from there.which makes

0x3E ^ 0xAA = 0x94
0x94 + 0xC0 = 0x154
0x154 % 0xE0 = 0x74
0x30 + 0x74 = 0xA4
0xA4 - 0x20 = 0x84

but the original is 0xC4.This is where I am puzzled.I am using 1-1 representation of yours.

Please use my sample to test your algorithm.I compiled your code with GCC and it didn't worked for me.
Code:

int encrypt (int len,char* szText){

for (int i = 0; i < len; i++)
{
if (szText[I] <= 0x1F)
{
continue;
}
szText[I] = szText[I] + ((char)(len - i - 1) ^ 0xAA + 0xC0) % 0xE0 - 0x20;
}
}

LaptoniC
January 2nd, 2008, 19:29
Finally I have managed to write function to encrypt the contents.However, I think that this encryption algoritm is flawed.Here is the scenario:

original value F0h
len-1=058h


By using those values it is impossible to get a byte value that when used in decryption gives F0 value.
By using below brute force code, we find that only value that will pass decryption to give F0 is, "102" which is not a byte!So it is impossible for some values to encrypt.

Code:
push ebp
xor edi,edi ;start from 0 and try all values
dec edi ; until decrypted value is F0h
@@:
inc edi
mov eax,edi
mov edx,058h
and eax, 0FFh
xor edx, 0FFFFFFAAh ;F2
mov ebp, 0E0h
and edx, 0FFh
sub eax, edx
add eax, 0C0h
cdq
idiv ebp
add dl, 20h
cmp edx,0F0h ;decrypted value found ?
jnz @B
pop ebp ;when we are here edi=102h!!!!



Besides this, here is my encryption algorithm that works.

Code:
encryptit proc
len = dword ptr 4
szText = dword ptr 8

push ebx
mov ebx, [esp+4+len]
push ebp
push esi
push edi
mov edi, [esp+10h+szText]
xor ecx, ecx
mov esi, ebx

@loop:
cmp ecx, ebx
jge @finished
mov al, [ecx+edi]
cmp al,1BH ;deliminator
je @skipit ;skip it!!!
lea edx, [esi-1]
and eax, 0FFh ;F0
xor edx, 0AAh
mov ebp, 0E0h
add eax, edx
cdq
idiv ebp
cmp edx,01Fh
jg @F
add dl,0E0h
@@:
mov [ecx+edi], dl

@skipit:
inc ecx
dec esi
jmp @loop

@finished:
pop edi
pop esi
pop ebp
pop ebx
retn
encryptit endp

Sorry for taking your time.Regards.