I have the following assembly. I don't know how to follow assembly. I was wondering if there is a way to convert assembly to a human readable pseudo code or better yet C code:

init:
 mov    eax, [ebp+8]    # pointer to key
 push   eax
 mov    eax, [ebp+c]    # pointer to ciphertext
 push   eax
 mov    eax, [ebp+10]   # ciphertext length
 push   eax
 mov    eax, [ebp+1c]   # pointer to plaintext
 push   eax
 xor    ecx, ecx    # loop counter

loop:
 xor    edx, edx
 mov    eax, ecx
 mov    ebx, 0x6
 div    ebx

 mov    eax, [esp+c]
 add    eax, edx
 mov    al, byte ptr [eax]
 sub    al, 0x41

 mov    ebx, [esp+8]
 add    ebx, ecx
 mov    bl, byte ptr [ebx]
 sub    bl, 0x41

 sub    bl, al
 jns    tail
 add    bl, 0x1a

tail:
 add    bl, 0x41
 mov    eax, [esp]
 mov    [eax+ecx], bl

 inc    ecx
 cmp    ecx, [esp+4]
 jl loop

closed as off-topic by usr2564301, 0xC0000022L Dec 6 at 14:02

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking for help reverse-engineering a specific system are off-topic unless they demonstrate an understanding of the concepts involved and clearly identify a specific problem." – usr2564301, 0xC0000022L
If this question can be reworded to fit the rules in the help center, please edit the question.

up vote 4 down vote accepted

Although rewriting assembly to pseudo C is not technically reverse engineering, I'll try to help

init:
 mov    eax, [ebp+8]
 push   eax
 mov    eax, [ebp+0xc]
 push   eax
 mov    eax, [ebp+0x10]
 push   eax
 mov    eax, [ebp+0x1c]
 puse   eax
 xor    ecx, ecx

This block just basically sets up parameters, as already mentioned ecx is a counter.

loop:
 xor    edx, edx
 mov    eax, ecx
 mov    ebx, 0x6
 div    ebx

Here edx is zeroed out, counter is moved to eax and unsigned division by 6 is performed. div stores the quotient in eax and remainder in edx.

mov    eax, [esp+0xc]
add    eax, edx
mov    al, [eax]
sub    al, 0x41

Here pointer from the key is accessed at offset edx and 0x41 is subtracted.

char a = key[counter % 6] - 0x41;

On to the next block

mov    ebx, [esp+8]
add    ebx, ecx
mov    bl, [ebx]
sub    bl, 0x41

Here pointer from the ciphertext is accessed at offset counter and 0x41 is subtracted.

char b = ciphertext[counter] - 0x41;

Next

sub    bl, al
jns    tail
add    bl, 0x1a

Here a and b are subtracted and if difference is less than zero 0x1a is added to b;

b = b - a;
if(b < 0) b += 0x1a;

Next:

tail:
 add    bl, 0x41
 mov    eax, [esp]
 mov    byte ptr [eax+ecx], bl
 inc    ecx
 cmp    ecx, [esp+4]
 jl loop

Here 0x41 is added back to b and its written to plaintext at offset counter.

plaintext[counter] = b+0x41;
counter++;

This was done in a loop with length as the limit.

while(counter < length)

Equivalent complete code.

void decode(char *key, char *ciphertext, size_t length, char *plaintext){
    size_t counter = 0; 
    do{
        char diff = ciphertext[counter] - key[counter % 6];
        plaintext[counter++] = 0x41 + diff + (diff < 0 ? 0x1a : 0);
    }
    while(counter < length);
}
  • Probably not much sense commenting on a closed question, but the subtraction is the wrong way around—key is supposed to be subtracted from cipher text. Also it's the Vigenere cipher. – user2347953 yesterday

Not the answer you're looking for? Browse other questions tagged or ask your own question.