關於彙編的一些指令

看雪論壇看了《逆向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

 

 

 

發佈了27 篇原創文章 · 獲贊 7 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章