xorpd има някои подобни на гатанки части от асемблерния код тук. В тази публикация ще анализирам гатанки 0x12, 0x0d и 0x0e, които имат някои общи неща. Нека се заемем!
xorpd гатанка 0x12
Ето кода:
mov rcx,rdx and rdx,rax or rax,rcx add rax,rdx
Да вървим стъпка по стъпка:
mov rcx,rdx ; rcx = x and rdx,rax ; rdx = x && y or rax,rcx ; rax = y || x add rax,rdx ; rax = (y || x) + (x && y)
Интересният факт за този израз е, че е еквивалентен на или. За да ви покажа това, ще проведа някои тестове. Представяйки всяка неизвестна стойност като един бит, правдоподобните случаи са:
| X | Y | --------- | 0 | 0 | | 0 | 1 | | 1 | 0 | | 1 | 1 |
Разглобяването на израза е лесно да се забележи, че:
- Последната част (x && y) ще бъде trueсамо ако и двете променливи са true
- Първата част (x || y) ще бъде false само ако и двете променливи са false
Можем ясно да видим, че тези наблюдения се припокриват с някои от операторите +(add mnemonic), всъщност, ако изчислим таблицата на истинатаза целия израз (с име exp) и addможем да наблюдаваме, че са еквивалентни:
| X | Y | => | exp | add | --------- ------------- | 0 | 0 | => | 0 | 0| | 0 | 1 | => | 1 | 1| | 1 | 0 | => | 1 | 1| | 1 | 1 | => | 10 | 10|
xorpd гатанка 0x0d
Този път кодът изглежда така:
mov rdx,rbx xor rbx,rcx and rbx,rax and rdx,rax and rax,rcx xor rax,rdx cmp rax,rbx
Какво става тук? Имаме 3 неизвестни стойности, идващи от регистрите rbx,rcxиrax. Нека ги наречем X, Y, Z. Ако заменим регистъра за променливи в кодовия фрагмент, получаваме следното:
mov rdx,rbx ; rdx = X xor rbx,rcx ; rbx = X ^ Y and rbx,rax ; rbx = Z & (X ^ Y) and rdx,rax ; rdx = Z & X and rax,rcx ; rax = Z & Y xor rax,rdx ; rax = (Z & Y) ^ (Z & X) cmp rax,rbx ; ((Z & Y) ^ (Z & X)) - (Z & (X ^ Y))
След като проследихме този поток от xor и и операции, достигаме до следното опростено сравнение в края:
cmp (Z & (X ^ Y)), ((Z & Y) ^ (X & Z))
В крайна сметка и двата израза ще имат една и съща стойност, независимо от началните стойности на регистрите. Това се случва поради разпределителното свойство на и върху xor, което произтича от законите на Де Морган.
xorpd гатанка 0x0e
Нека анализираме третия:
mov rcx,rax and rcx,rbx not rcx not rax not rbx or rax,rbx cmp rax,rcx
Замяната на неизвестните стойности с променливи X и Y ни дава известна представа:
mov rcx,rax ; rcx = X and rcx,rbx ; rcx = X & Y not rcx ; rcx = !(X && Y) not rax ; rax = !X not rbx ; rbx = !Y or rax,rbx ; rax = !X || !Y cmp rax,rcx ; cmp !X || !Y, !(X && Y)
Виждаме, че подобно на предишната гатанка, последното твърдение винаги ще бъде вярно, тъй като съответства на следния закон на Де Морган:
!X || !Y is equivalent to !(X && Y)
Така че, независимо от първоначалните стойности за rax и rbx, raxиrcxще имат една и съща стойност в края.