Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- I find, genuinely, what you predicate quite interesting, as a matter of fact I have an ingenious example to satisfy yours rigorously and to prove all axiomatic natures of what I'd said in benefit to what you clarified!
- [quote]
- 0x00000000080005c0 <+0>: push rbp
- 0x00000000080005c1 <+1>: push rbx
- 0x00000000080005c2 <+2>: sub rsp,0x8
- 0x00000000080005c6 <+6>: mov rbx,QWORD PTR [rsi+0x8]
- 0x00000000080005ca <+10>: mov rdi,rbx
- 0x00000000080005cd <+13>: call 0x80005a0 <strlen@plt>
- 0x00000000080005d2 <+18>: mov rdi,rbx
- 0x00000000080005d5 <+21>: add rax,rbx
- 0x00000000080005d8 <+24>: jmp 0x80005e9 <main+41>
- 0x00000000080005da <+26>: nop WORD PTR [rax+rax*1+0x0]
- 0x00000000080005e0 <+32>: movsx edx,BYTE PTR [rdi]
- 0x00000000080005e3 <+35>: add rdi,0x1
- 0x00000000080005e7 <+39>: add ebp,edx
- 0x00000000080005e9 <+41>: cmp rax,rdi
- 0x00000000080005ec <+44>: jne 0x80005e0 <main+32>
- 0x00000000080005ee <+46>: and ebp,0x1
- 0x00000000080005f1 <+49>: je 0x80005ff <main+63>
- 0x00000000080005f3 <+51>: lea rdi,[rip+0x1ca] # 0x80007c4
- 0x00000000080005fa <+58>: call 0x8000590 <puts@plt>
- 0x00000000080005ff <+63>: add rsp,0x8
- 0x0000000008000603 <+67>: xor eax,eax
- 0x0000000008000605 <+69>: pop rbx
- 0x0000000008000606 <+70>: pop rbp
- 0x0000000008000607 <+71>: ret
- [/quote]
- Thanks to @unrealskill for the original C source-code.
- I will simplify the response, as I assume that the reader and yourself (obviously) have fluent knowledge in x86-64 assembly, however I will use the Intel-flavoured syntax for the readability nonetheless, however I do support the beauty of AT&T.
- {main+0}->{main+2} Function prologue, 8 bytes allocated on the stackframe.
- {main+6}->{main+10} `rbx` = `argv[1]`
- {main+13} `rax` = `strlen (argv[1])`
- {main+18}->{main+24} `rdi` = `argv[1]`, `rax = strlen (argv[1]) + argv[1]`, afterwards unconditional jump to {main+41} which is a condition implying this is a `while` loop.
- Let `end = strlen (argv[1]) + argv[1]`
- {main+41}->{main+44} `while (end != argv[1])`
- [code]
- size_t end = strlen (argv[1]) + argv[1];
- while (end != argv[1])
- {
- ...
- }
- ...
- [/code]
- {main+32}->{main+39} moves into `edx` the character at `rdi` which is `argv[1]`, afterwards we increment `rdi` by `1` to go to the next character, and have `ebp` be the accumulator which accumulates the value of each character via `add ebp, edx`, you might wonder why `ebp` isn't zeroed in the `main` function, although it's used? That is due to the fact of the System V ABI which dictates that the EBP register must be zeroed upon calling into the UEP (user entry-point), which is neat as an optimization. Now we can see that we have a variable to accumulate the values, and that our final loop will look like such:
- [code]
- size_t acc = 0;
- size_t end = strlen (argv[1]) + argv[1];
- while (end != argv[1])
- {
- acc += argv[1][0];
- ++argv[1];
- }
- [/code]
- {main+46}->{main+71} We logically AND the `acc`umulator by `1`, and if it's not zero then we `puts ("Success.");`, otherwise we don't, and finally we `return 0;`
- [code]
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- int
- main (int argc, char **argv)
- {
- size_t acc = 0;
- size_t end = strlen (argv[1]) + argv[1];
- while (end != argv[1])
- {
- acc += argv[1][0];
- ++argv[1];
- }
- if (acc & 1)
- puts ("Success.");
- return 0;
- }
- [/code]
- Beautiful, dare I say.
- #humblegang
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement