1

I am having a difficult time reversing the following loop:

│       ┌─< 0x100001fea      723b           jb 0x100002027
│       │   0x100001fec      31db           xor ebx, ebx               ; ebx = 0
│       │   0x100001fee      41bc04000000   mov r12d, 4
│       │   0x100001ff4      6666662e0f1f.  nop word cs:[rax + rax]
│      ┌──> 0x100002000      418b441d00     mov eax, dword [r13 + rbx]
│      |│   0x100002005      b959b699f7     mov ecx, 0xf799b659
│      |│   0x10000200a      31c8           xor eax, ecx
│      |│   0x10000200c      418907         mov dword [r15], eax
│      |│   0x10000200f      4189041e       mov dword [r14 + rbx], eax
│      |│   0x100002013      4963dc         movsxd rbx, r12d
│      |│   0x100002016      4c8d6304       lea r12, [rbx + 4]
│      |│   0x10000201a      4c89ef         mov rdi, r13               ; const char * s
│      |│   0x10000201d      e8d0080000     call sym.imp.strlen        ; size_t strlen(const char *s)
│      |│   0x100002022      4939c4         cmp r12, rax
│      └──< 0x100002025      76d9           jbe 0x100002000
│       └─> 0x100002027      488b05d20f00.  mov rax, qword [reloc.__stack_chk_guard_0] ; [0x100003000:8]=0

r13 and r14 contain strings on the heap, and r15 contains a pointer to a buffer of size 4. I tried to write equivalent code in C, where second_string is r13, return_string is r14, value_holder is r15, and atoi_res is r12(d).

int ebx = 0;

atoi_res = 4;

while(1){
    ((int *)second_string)[ebx] ^= 0xf799b659;
    *value_holder = ((int *)second_string)[ebx];
    ((int *)return_string)[ebx] = ((int *)second_string)[ebx];

    ebx = atoi_res;
    if(strlen(second_string) > 8) break;
}   

This does not seem right to me:

  • There is no way to break out of the loop
  • In the disas(I fixed this in the pseudocode) we are dereferencing a constant value of 8, then leaing it again. Wouldn't this segfault?
  • second_string is being XORed by this constant 4 bytes at a time, but the value that is supposedly contained (loaded in another part of the program) returns gibberish when XORed by this.

I can post more of the disassembly if needed. Thanks for any help.

1

This is just taking a cstring pointed to by r13, xoring a dword at a time with the value 0xf799b659 and storing in the memory pointed to by r14.

I think your confusion is in what the lea instruction does. It simply loads the address of the memory instead of the memory value itself. In this case, it is just being used as a fast add operation. Compilers will often use it for simple addition or multiplication which is faster than an add/mul/etc instruction. In the case of lea r12, [rbx + 4], this is doing just r12 = rbx + 4; there is no memory access at all. rbx is being used as a current byte index into the strings and r12 is being used as the next byte index.

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.