1

I have an assignment for reverse engineering a binary. The function I'm up to takes a string input and reads one character at a time. It is as follows (push/pop registers removed):


 8048b6e: mov    $0x8049ee9,%esi 
 8048b73: movzbl (%esi),%edx ; (%esi) = 0x654A6167
 8048b76: test   %dl,%dl
 8048b78: je     8048bb2 
 8048b7a: mov    0x8(%ebp),%ebx
 8048b7d: mov    $0x16,%edi
 8048b82: movzbl (%ebx),%eax
 8048b85: sub    $0x61,%eax
 8048b88: cmp    $0x19,%al
 8048b8a: ja     8048b97 
 8048b8c: mov    %edi,%ecx
 8048b8e: sub    %al,%cl
 8048b90: mov    %ecx,%eax
 8048b92: jns    8048b97 
 8048b94: add    $0x1a,%eax
 8048b97: add    $0x61,%eax
 8048b9a: cmp    %al,%dl
 8048b9c: je     8048ba3 
 8048b9e: call   8048e18 
 8048ba3: add    $0x1,%esi
 8048ba6: movzbl (%esi),%edx
 8048ba9: test   %dl,%dl
 8048bab: je     8048bb2 
 8048bad: add    $0x1,%ebx
 8048bb0: jmp    8048b82 

I'm having a little trouble understanding the logic of one part (8048b85 onwards) so I converted it to C


eax = *ebx;                                 // movzbl (%ebx),%eax
eax -= 97;                                  // sub    $0x61,%eax

// cmp    $0x19,%al
// ja     8048b97 <phase_3+0x32>
if((unsigned)(eax & 0xFF) < 25)
{
  ecx = edi;                                // mov    %edi,%ecx
  int cl = (eax & 0xFF) - (ecx & 0xFF);     // sub    %al,%cl
  ecx &= cl;
  eax = ecx;                                // mov    %ecx,%eax

  if(cl >= -127 && cl < 128)                // jns    8048b97
  {
    eax += 0x1A;                              // add    $0x1a,%eax
  }
}
eax += 97;                                  // add    $0x61,%eax
if((eax & 0xFF) != (edx & 0xFF))            // cmp    %al,%dl
{
  trigger_bomb();                           //  call   8048e18 <trigger_bomb>
}

I'm not sure if what I converted to is correct. The first value being compared is 0x67 which is g in ascii which wont set the flag for ja as 0x19 > 0x67 - 0x61. If I try 0x67 - 0x1A as the input, since it's unsigned comparison it will never be < 25 as it will overflow back to 236. I thought then I would need to use a negative number so that if it overflows, it would go 0x67 but since the input is ascii I'm not sure that it is possible to input a negative value.

So my question is where am I going wrong in my logic? I'm not looking to be given the answer since I will need to figure out the other 3 values, but what I'm trying just doesn't seem to be correct. Any pointers/advice would be greatly appreciated.

Thankyou

2

The problem was sadly my own stupidity.. First issue,

int cl = (eax & 0xFF) - (ecx & 0xFF);

Has the arguments around the wrong way (dest = dest - source not dest = source - dest)

And second was my confusion about the JNS instruction. I misinterpreted it as signed byte not the sign flag thus,

if(cl >= -127 && cl < 128)

should have been written as

if(cl < 0)

After a week of trying to work this out the answer was rather annoying :)

1

The 0x61 is a well-known value in the ASCII table it corresponds to the a character. And, in fact, when you encounter:

8048b85: sub    $0x61,%eax

It usually means that you are shifting a character from the usual printable characters intervals down to the unprintable characters values.

I didn't take a deep look at your code, but I really suspect that what is done here is about encoding an ASCII text into a set of unprintable characters.

But, it is just a wild guess (taken in less than 5 minutes). So, beat me if I am wrong ! :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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