1 adc(carry)指令:带进位的加法
77A5134C 10C8 adc al,cl :al==1,cl==2,c位==1, al==4
77A5134E 8015 40F31B00>adc byte ptr ds:[0x1BF340],0x2
77A5134E 【0x0x1BF340】==000008 ,c位==1,
77A5134E 【0x0x1BF340】==00000B。
2 sbb(borrow):带借位的减法
77A51355 1AC1 sbb al,cl : al==4,cl==1,c位==1------->al ==1.
3 xchg(borrow):交换数据 :注意:数据宽度一样。
格式:xchg r/m ,r/m
77A51357 86C8 xchg al,cl
77A51359 8705 40F31B00 xchg dword ptr ds:[0x1BF340],eax
77A5135F 860D 40F31B00 xchg byte ptr ds:[0x1BF340],cl
4 movs:移动数据 内存—内存
byte / word / dword
movs byte ptr es:[edi], byte ptr ds:[esi] .————-> movsb
movs word ptr es:[edi], word ptr ds:[esi] . .————-> movsw
movs dword ptr es:[edi], dword ptr ds:[esi] . .————-> movsd
实例:
77A51365 BE 40F31B00 mov esi,0x1BF340
77A5136A BF 44F31B00 mov edi,0x1BF344
77A5136F/ A5 movs dword ptr es:[edi],dword ptr ds:[esi]
77A5136F| esi==0x1BF340 ; [0x1BF340] ==1 ; edi ==0x1BF344 ; [0x1BF344] ==7.
77A5136F| -------------->注意:地址变了。
77A5136F\ esi==0x1BF344 ; [0x1BF340] ==1 ; edi ==0x1BF348 ; [0x1BF344] ==1
Cpaz stido(0246 7891011)
77A51370 BE 60F31B00 mov esi,0x1BF360
77A51375 BF 5CF31B00 mov edi,0x1BF35C
77A5137A 66:A5 movs word ptr es:[edi],word ptr ds:[esi]
执行前:esi ==0x1BF360;edi==0x1BF35C;[0x1BF360] ==0000000 ;[0x1BF360] ==77b777b7 ;df=1
执行后:esi == 001BF35E;edi== 001BF35A;[0x1BF360] ==00077B7 ;[0x1BF360] ==77b777b7.
注:减2,d标志为1.
Movs:逆向要注意,很有可能就是复制字符串呢。
5. movsx 先符号扩展,再传送。
mov al,0FF; // 如果只看这一行,你说了算
movsx cx,al;
---
0xFF == 1111 1111
符号位是1,所以 1111 1111 1111 1111
cx == 0xFFFF
mov al,0x0F;
movsx cx,al
---
0x0F == 0000 1111
符号位是0,所以 0000 0000 0000 1111
cx == 0x000F
mov al,0x80;
movsx cx,al
---
0x80 == 1000 0000
符号位是1,所以 1111 1111 1000 0000
ecx:11111111--->ecx:1111 FF80.
mov al,0x70;
movsx cx,al
---
0x70 == 0111 0000
符号位是0,所以 0000 0000 0111 0000
ecx:11111111--->ecx:1111 0070.
003E1090 66:B8 690A mov ax,0xA69
003E1094 0FBFC8 movsx ecx,ax
ecx:11111111--->ecx:1111 0A69.
6.movzx 先零扩展,再传送
不管最高位是什么,都是补0,扩展。
003E107E B0 FF mov al,0xFF
003E1080 66:0FB6C8 movzx cx,al
ecx:11111111--->ecx:1111 00FF.
mov al,80;
movzx cx,al
ecx:11111111--->ecx:1111 0080.
003E1084 B0 70 mov al,0x70
003E1086 66:0FB6C8 movzx cx,al
ecx:11111111--->ecx:1111 0070.
// 这边注意数据宽度-和上面的不同
003E1090 66:B8 690A mov ax,0xA69
003E1094 0FB7C8 movzx ecx,ax
ecx:11111111--->ecx:0000 0A69.
1.要拓展容器的大小,如果是有符号的,汇编用movsx,无符号的用movzx.
7 stos:将al/ax/eax存储到[edi]指定的内存单元
stos byte es:[edi] ---------------> stosb.
Edi :前面要写 es。
77A5137C B8 78563412 mov eax,0x12345678
77A51381 BF 40F31B00 mov edi,0x1BF340
77A51386 AB stos dword ptr es:[edi]
执行前:eax==0x12345678;edi==0x1BF340;[0x1BF340]==00000000; df==1;
后:eax==0x12345678;edi==0x1BF33C;[0x1BF340]==0X12345678; df==1;
Df标志位:正常情况是0,edi,esi 的地址是加的;;;为1时,地址是减小的。
8 rep:
根据[ecx]中指定的次数(16进制)重复执行字符串指令。
77A51387 B9 04000000 mov ecx,0x4
77A5138C F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[e>
77A5138E F3:AB rep stos dword ptr es:[edi]
9 JCC:
eip:存储了一个地址,决定了cpu下一行要执行的代码是什么。
想修改eip的值。
77A51310 /EB 02 jmp short Xntdll.77A51314
注意:如果跳的地方小于128字节,自动加short。
Jmp:jmp 寄存器/立即数
jmp 和跳转没关系,仅仅是修改eip的值,cpu执行要去哪。
执行jmp时,唯一映像eip时。
过某些检测的时候,堆栈不影响,寄存器不影响。
Jmp 没有任何附加条件的把eip的值改掉。
EIP: Goto 、call 、ret 、jmp
od 里面变灰:因为你看过了,因为有udd缓存。
11 Call:
Call 和jmp 的相同:都修改eip ,call 要回来,jmp 可能不回来。
不同:call时esp变小,push入栈。
Eip 检查。游戏保护中用。检查返回地址是不是人家游戏自己的。
77A51310 /EB 02 jmp Xntdll.77A51314
77A51312 |90 nop
77A51313 |90 nop
77A51314 \E8 00000000 call ntdll.77A51319
77A51319 C3 retn
77A5131A 8BFF mov edi,edi
12 ret
(pop eip):把栈顶esp 的值pop到eip。Eip改变,esp改变。
77A51300 E8 FBFFFFFF call ntdll.77A51300
执行后:esp、入栈77a51305.
77A5131F C3 retn
如果此时栈中是已经push 好的好几个 77A5131F,则esp不断的变化,程序还在原地踏步。
13 Cmp:比较两个值的。
指令格式:
77A51305 B8 00010000 mov eax,0x100
77A5130A B9 00010000 mov ecx,0x100
77A5130F 2BC1 sub eax,ecx
执行后:eax == 00000000;ZF标志位为1.
77A51311 B8 00010000 mov eax,0x100
77A51316 B9 00010000 mov ecx,0x100
77A5131B 3BC1 cmp eax,ecx
执行后:eax == 00000100;ZF标志位为1.
77A5131D B8 00010000 mov eax,0x100
77A51322 B9 00020000 mov ecx,0x200
77A51327 3BC1 cmp eax,ecx
执行后:eax ==00000100;zf =1 ,SF =1. 可以判断eax<ecx.
77A51329 90 nop
77A5132A B8 00020000 mov eax,0x200
77A5132F B9 00010000 mov ecx,0x100
77A51334 3BC1 cmp eax,ecx
14 Test:
一定程度和cmp类似。常见用法:判断某寄存器是否等于0.
指令格式:test r/m ,r/m/imm
该指令一定程度上和cmp指令类似,两个数值进行与操作,结果不保存,但是会改变相应标志位。
JCC: 它不认识cmp,test ,只认标志寄存器。
Je(jump equal),jz(jmp zf); ZF ==1.—-结果相等则跳
Jne,jnz( ),jz(jmp zf); ZF ==0;—-不相等则跳
Js(),js(jmp zf); SF ==1;—结果为负 cmp eax(100),ecx(200)
Jns,jnz()SF ==1;
Jp,jpe (l) PF ==0;
设计有符号的,无符号的。
77A51338 B0 FF mov al,0xFF
77A5133A B1 01 mov cl,0x1
Cmp al,cl;
77A5133C 7F 00 jg Xntdll.77A5133E
77A5133E 77 01 ja Xntdll.77A51341