您的位置:首页 > 其它

关于汇编的一些指令

2008-03-06 18:16 316 查看
看雪论坛看了《逆向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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: