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
lea
ing 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.