In a rootme exercise, i'm trying to bypass the control impleted to protect a "read" function. You'll find enclosed the code i'm refering to. As you may understand, i can inject data (with limitations) in rax (with the limitation that ax be under 100h due to the previous instruction:

cmp ax, 100h

I know I can change eax value before entering that part of the programe (part of the programe before the asm instructions enclosed). However, I have the feeling that the following instruction prevent from reading the ah part of the eax register.

movzx eax, word ptr [rax]

Would you have any idea if it would be possible to write into the upper bits of rax so that it be taken into account by the read function?

Thanks a lot! Sorry if all is not very clear, I can try to re-explain if needed.

disassembled piece of code

1 Answer 1


Did you mean the upper bits of rax rather than ah? There seems to be a vulnerability (presumably created by compiling and not handling the 32-bit to 64-bit conversion correctly).

If the address stored at [rbp+username_buffer_input] is beyond the 4 GiB space, then the upper 32-bits will contain a non-zero value in register rax. The following code can then lead to a very large nbytes value and potential for a buffer overflow.

mov rax, [rbp+username_buffer_input]    ; upper 32-bits of rax may not be zero
movzx eax, word ptr [rax]               ; doesn't clear out upper 32-bits when reading from an address > 4 GiB
movzx eax, ax                           ; doesn't clear out upper 32-bits
mov rdx, rax                            ; uh-oh - nbytes can have a non-zero value in the upper 32-bits of rax carried over from above
  • Thanks for your precious answer! You're right, I meant the upper bits of rax so that the upper bits of rdx don't get zero-ed. I do not really understand your statement on line 2: "doesn't clear out upper 32-bits when reading from an address > 4 GiB". When debugging with gdb, I can see that upper bits of rax are cleared when performing the first movzx while rax valued previously 0x7fffffffe410 so that it is a bit confusing... Dec 5, 2017 at 20:17
  • Let's say rax was 0x7fffffffe410 and the 16-bit value at that address was 0x1234. After the movzx eax, word ptr [rax] instruction, eax would be set to 0x00001234 but rax would be 0x00007fff00001234
    – cimarron
    Dec 6, 2017 at 1:25
  • I understand your idea I tried earlier to monitor this behaviour through gdb, but it ended with a different result: I set a breakpoint on the mov rax, [rbp+username_buffer_input] line and performed: i r rax: rax 0x7fffffffe410 140737488348176 x/s $rax: 0x7fffffffe410: "\003" Ok, this is fine until here, however, after a step in si i performed a i r eax rax resulting in eax 0x3 3 rax 0x3 3. So the question would be: would you know a compilation option or system option which could forced the behaviour you were describing earlier? Dec 18, 2017 at 13:31
  • any more ideas? Dec 26, 2017 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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