第四課 記憶體地址_堆疊
記憶體地址
db與dd命令
db:d表示查詢,b表示byte
dd:d表示查詢,d表示dword
db命令在資料區找出目的記憶體地址,發現資料區內和堆疊區顯示的是相反的
反彙編視窗和暫存器視窗的都是從高位到低位,資料區反之(比如資料0x12345678,12是高位,8是低位)
所以0012FFDC這塊記憶體(1位元組)是E4,由此得出資料區地址表示的記憶體是第一個位元組,堆疊區表示的則是第四個位元組
下面兩張圖幫助理解(我xdbg工具的命令列出了點毛病,先用上課的圖代替)
dd命令在查詢時自動幫我們倒過來了
五種定址方式
堆疊
push與pop
push:在棧頂壓入一個值且把棧頂提高也就是-4個位元組push 0x12345678
pop:把棧頂的值彈出來,也可以理解成複製到一個暫存器裡面,再把棧頂壓低也就是+4個位元組,且原來棧頂的值還在pop eax
注:
push只能push立即數以及16位32位暫存器,不允許push8位暫存器,push16位暫存器時esp棧頂-2
pushad與popad命令
pushad相當於把所有通用暫存器壓入堆疊,popad則是為了恢復現場,在反除錯的時候很好用,在pushad後可以隨便動暫存器,除錯後用popad恢復現場
作業
1、
mov ebx,ebp
mov edx,esp
mov dword ptr ds:[edx-0x4],0xAAAA
mov dword ptr ds:[edx-0x8],0xAAAA
mov dword ptr ds:[edx-0xC],0xAAAA
mov dword ptr ds:[edx-0x10],0xAAAA
mov dword ptr ds:[edx-0x14],0xAAAA
2、
mov eax,dword ptr ds:[edx-0x4]
mov eax,dword ptr ds:[edx-0x8]
mov eax,dword ptr ds:[edx-0xc]
...
6、push esp
第一種方法:mov dword ptr ds:[esp-0x4], esp
lea esp, dword ptr ds:[esp-0x4]
第二種方法:mov dword ptr ds:[esp-0x4], esp
sub esp,0x4
7、pop esp
第一種方法:mov esp,dword ptr ds:[esp-4]
add esp,0x4
第二種方法:mov esp,dword ptr ds:[esp-4]
lea esp,dword ptr ds:[esp+0x4]
第五課 標誌暫存器
EFL拆開就是上面的各個標誌位
例:202(001000000010)對照下圖
1.運算結構標誌位
- CF位(進位標誌):表示最高位有沒有進位,借位不算
- PF位(輔助標誌):表示運算結果中最低有效位元組“1”的個數是否是偶數,偶數則為1,奇數反之
(最低有效位元組也就是0000 0010 0000 0011 最後兩個位元組,8、16、32位都看最後兩個位元組)
- AF位(輔助進位標誌):表示低4位的相加是否有進位,有進位則為1,比如32位0555FFFF就是看第四位(加粗)有沒有進位,16位時05FF就看第二位有沒有進位,8位時5F就看第一位有沒有進位
- ZF位(零標誌):表示運算結果是否為0,是則為1(判斷運算結果是否為1)
**注: **mov eax,0
不影響標誌暫存器,因為mov是賦值操作不是運算
- SF位(符號標誌):反映運算結果的符號位,與運算結果的最高位相同,因為如果是運算結果的最高位即表示正負(7F:01111111)+2=(81:10000001)
如al 7F+2
或者ax 7fff+2
SF才能進1
- OF位(溢位標誌):表示有符號數加減運算所得結果是否溢位(先大概可以理解成有符號計算看OF,無符號計算看CF)
2.狀態控制標誌位
3.命令
ADC與SBB
ADC:目前理解是不僅計算了1+2,還加上了進位標誌的1
標誌位都清空,留下CF為1,等一下可以演示出CF的1被加上的效果
1+2本應為3,但是此時計算結果是4,說明CF進位的1被加上了
SBB:與加法相同,4-2-1
XCHG命令
movs命令
簡寫:
注意:
1、只能使用EDI和ESI兩個暫存器(暫存器裡面需要是地址)
2、只是mov複製操作
3、ESI和EDI都進行了加4的操作,方便下一個值的賦值,這裡加4還是加2取決於movd還是movw,加還是減取決於DF標誌位
4、堆疊地址不變
STOS命令
注:
1、和MOVS命令一樣執行後EDI地址會加或減
2、加或減一樣受DF標誌控制
3、注意資料寬度
4、得用簡寫,不知道為什麼具體寫會語法錯誤
REP命令
注意:
1、用完後ecx會清空
2、不能用cx去定義,最後迴圈幾次是看整個ecx暫存器
作業:
第六課 JCC命令
JMP:修改EIP
CALL:push 下一條語句地址(棧頂+4)+修改eip
CMP:相減後不保留相減結果保留零標誌位結果(用於判斷兩數是否相等,相等時相減即是0,零標誌位為1)
TEST:兩個數值進行與操作,結果不儲存,改變標誌位(用於確定某個暫存器是否等於0)
JCC指令:
JCC指令 | 中文含義 | 英文原意 | 檢查符號位 | 典型C應用 |
---|---|---|---|---|
JZ/JE | 若為0則跳轉;若相等則跳轉 | jump if zero;jump if equal | ZF=1 | if (i == j);if (i == 0); |
JNZ/JNE | 若不為0則跳轉;若不相等則跳轉 | jump if not zero;jump if not equal | ZF=0 | if (i != j);if (i != 0); |
JS | 若為負則跳轉 | jump if sign | SF=1 | if (i < 0); |
JNS | 若為正則跳轉 | jump if not sign | SF=0 | if (i > 0); |
JP/JPE | 若1出現次數為偶數則跳轉 | jump if Parity (Even) | PF=1 | (null) |
JNP/JPO | 若1出現次數為奇數則跳轉 | jump if not parity (odd) | PF=0 | (null) |
JO | 若溢位則跳轉 | jump if overflow | OF=1 | (null) |
JNO | 若無溢位則跳轉 | jump if not overflow | OF=0 | (null) |
JC/JB/JNAE | 若進位則跳轉;若低於則跳轉;若不高於等於則跳轉 | jump if carry;jump if below;jump if not above equal | CF=1 | if (i < j); |
JNC/JNB/JAE | 若無進位則跳轉;若不低於則跳轉;若高於等於則跳轉; | jump if not carry;jump if not below;jump if above equal | CF=0 | if (i >= j); |
JBE/JNA | 若低於等於則跳轉;若不高於則跳轉 | jump if below equal;jump if not above | ZF=1或CF=1 | if (i <= j); |
JNBE/JA | 若不低於等於則跳轉;若高於則跳轉 | jump if not below equal;jump if above | ZF=0或CF=0 | if (i > j); |
JL/JNGE | 若小於則跳轉;若不大於等於則跳轉 | jump if less;jump if not greater equal | SF != OF | if (si < sj); |
JNL/JGE | 若不小於則跳轉;若大於等於則跳轉; | jump if not less;jump if greater equal | SF = OF | if (si >= sj); |
JLE/JNG | 若小於等於則跳轉;若不大於則跳轉 | jump if less equal;jump if not greater | SF != OF 或 ZF=1 | if (si <= sj); |
JNLE/JG | 若不小於等於則跳轉;若大於則跳轉 | jump if not less equal;jump if greater | SF=0F 且 ZF=0 | if(si>sj) |
作業
1、call把返回地址壓入棧,再把eip指向函式地址(eip變成立我們要跳轉執行的地址)
2、把原先call壓進去的返回地址彈出來了,棧頂+4,eip指向返回地址