说实话我感觉64的比32的难不少..应该是我笨的关系。
其中比较逆天的是bextr我着实找不到太多资料
最后debug了半天发现了规律
举个栗子比如这里bextr rbx,rcx,rdx
rcx = 0b100010100
rdx = 302
rbx的值就是rcx>>2,或者说是忽略掉低位的两位
1 | 100010100 >>2 |
然后取低位开始数3位
1 | 1000101 |
于是rbx = 0b101 = 5
再举个例子比如:2300就可以拆为 23 00
代表从第0位开始取23位
xlat获取在[rbx]的地址+al的偏移的内容,然后再赋值给到al
1 | xlat BYTE PTR ds:[rbx] |
这里stosb是根据df的值来决定,给al值赋给rdi后,目的地址,或是说这里的rdi的地址会+1或者-1,可以看作是前进或者后退,这样的话仅通过操作df就可以控制指针方向了,不过这里用不到df来做指向呢 XD
1 | 0x00400639 aa stosb byte [rdi], al |
思路
思路蛮简单 最终要做的就是给rdi部分写入flag.txt,而给rdi指向的地址具体传东西是由al传递。
所以需要控制xlat BYTE PTR ds:[rbx]这里给rax低位(al)传参的是rbx(这里需要注意因为并没有能pop rax清理rax的指令,所以每次计算rbx给al传参都需要减去上一次al的偏移,去掉去第一次al默认的0xb,后面每一次al都是上一个字符,所以除第一次减0xb之外每次都需要rbx - flag[上一个的位] - 0x3ef2)
再去找rbx就找到了bextr rbx,rcx,rdx 。
要给rbx传参就要控制rcx和rdx这俩,由于会rcx给加0x3ef2所以直接写字符给rcx过去会被破坏掉,指定是不行了。
于是直接从这个程序中找能用的字符所在的地址,直接拿现成的来用就ok。
exp
1 | from pwn import * |