看雪論壇看了《逆向RING0程序從這裏開始》一文,彙編看得不是太流暢,對一些指令還要查資料。
今特寫下來已加強印象。
rep:重複前綴,ecx爲計數器進行重複,
repz,repe:0標誌被設置且ecx〉0重複
repnz,repne: 0標誌被清除且ecx〉0重複
movsb,movsw ,movsd:從ESI指向的內存位置拷貝數據到EDI指向的內存位置。同時ESI和EDI寄存器自動增加或減少(依據方向標誌的值而定),
方向標誌可由
CLD(清除方向標誌, 尋址低--〉高)、STD(設置方向標誌 高--〉低)顯式改變
例如:(以下片斷摘自提到的該文,感謝)
push 7
.text:000105A2 pop ecx
.text:000105A3 mov esi, offset s_DeviceHdhook ; "//Device//HDHOOK"
.text:000105A8 lea edi, [ebp+regnameNt]
.text:000105AE push 9
.text:000105B0 rep movsd
.text:000105B2 movsw
stosb/stosw/stosd:將al/ax/eax的內容存儲在edi指向的內存單元中,同時edi的值將依據方向標誌的值增加或減少。
lodsb/lodsw/lodsd:將從esi指向的內存位置向al/ax/eax中裝入一個值。同時esi的值將依據方向標誌的值增加或減少。
movzx ,將源操作數(第二操作數)的內容拷貝到目的操作數(第一操作數)中,並將該值0擴展到16位或32位。只能用於無符號整數。目的操作數必須爲寄存器。
movsx,將源操作數(第二操作數)的內容拷貝到目的操作數(第一操作數)中,並將該值符號擴展到16位或32位。只能用於有符號整數
例:
.text:000105FA mov ax, [esi]
.text:000105FD add ax, 2
.text:00010601 movzx ecx, ax
.text:00010604 mov edx, ecx
.text:00010606 xor eax, eax
.text:00010608 shr ecx, 2
.text:0001060B rep stosd
.text:0001060D mov ecx, edx
.text:0001060F and ecx, 3
.text:00010612 rep stosb
相當於RtlZeroMemory,先是4字節對齊的填0,然後使用AND取得除以4後的餘數,繼續填0。
系統的RtlZeroMemory的代碼
00402520: 57 PUSH EDI
00402521: 8B7C2408 MOV EDI, [ESP+08]
00402525: 8B4C240C MOV ECX, [ESP+0C]
00402529: 33C0 XOR EAX, EAX
0040252B: FC CLD ;這一句用來保證DF=0
0040252C: 8BD1 MOV EDX, ECX
0040252E: 83E203 AND EDX, 00000003;除以4的餘數
00402531: C1E902 SHR ECX, 02;除以4的商
00402534: F3AB REP STOSD
00402536: 0BCA OR ECX, EDX
00402538: 7504 JNZ 40253E;非4字節對齊,繼續填0
0040253A: 5F POP EDI
0040253B: C20800 RETN 0008
0040253E: F3AA REP STOSB
00402540: 5F POP EDI
00402541: C20800 RETN 0008
scas /scasb /scasw 串掃描指令SCAS將edi指向的字節或字內容與AL/AX寄存器內容進行比較,根據比較的結果設置標誌,每次比較後修改EDI寄存器的值,使之指向下一個元素。
以下代碼片斷,源於upx加密殼,恢復被加殼exe的IAT功能。edi指向以01分割的調用函數名稱串。
如下示:
0040EA79 53 00 00 01 5F 6C 77 72 69 74 65 00 01 44 65 6C S.._lwrite.Del
0040D015 65 74 65 46 69 6C 65 41 00 01 5F 6C 63 6C 6F 73 eteFileA._lclos
0040D025 65 00 01 5F 6C 6F 70 65 6E 00 01 4C 6F 63 61 6C e._lopen.Local
0040D035 55 6E 6C 6F 63 6B 00 01 5F 6C 63 72 65 61 74 00 Unlock._lcreat.
0040D045 01 5F 6C 6C 73 65 65 6B 00 01 4C 6F 63 61 6C 52 _llseek.LocalR
0040D055 65 41 6C 6C 6F 63 00 eAlloc.
0040EA79 > /8A07 mov al, byte ptr [edi];al=01
0040EA7B . |47 inc edi
0040EA7C . |08C0 or al, al
0040EA7E .^|74 DC je short 0040EA5C ;跳到下一個模塊
0040EA80 . |89F9 mov ecx, edi
0040EA82 . |57 push edi;API函數名稱
0040EA83 . |48 dec eax;執行後 al=0
0040EA84 . |F2:AE repne scas byte ptr es:[edi];掃描,直到遇到0
0040EA86 . |55 push ebp
0040EA87 . |FF96 A4EC0000 call dword ptr [esi+ECA4] ; kernel32.GetProcAddress
0040EA8D . |09C0 or eax, eax
0040EA8F . |74 07 je short 0040EA98
0040EA91 . |8903 mov dword ptr [ebx], eax;填充IAT
0040EA93 . |83C3 04 add ebx, 4
0040EA96 .^/EB E1 jmp short 0040EA79
jmp指令
jmp是相對跳轉,跳轉到相對當前地址的偏移處。相對當前地址是指當前指令地址加上指令長度。例如:
0040123F E9 CC 05 00 00 E9 67 樘...間
00401246 1F 00 00
000005cc + (0040123f + 5) = 00401810