就连这四个分别叫做%eax,%ebx,%ecx,%edx的寄存器,尽管看似是随意按照abcd的字母排序的,其实这a,b,c,d也分别是四个单词的缩写。 %——百分号表示这是一个寄存器。 因为以前的intel寄存器都是16位的,它们的名字就是%ax,%bx等等,所以扩展到32位之后就在开头加上一个e,改名叫%eax,%ebx等 1. EAX - Accumulator Register(累加器) 当你写一个函数,最后返回一个值x(return x),那么这个x就要被存到%eax. 当你要把一个数字扩展成64位,那么%eax存这个数的低32位,%edx存这个数的高32位。 2. (当你要把一个数字扩展成64位,那么%eax存这个数的低32位,%edx存这个数的高32位。) 后面四个,大家可以看文章开头的资料,我就懒得翻译了。 5.
y-x*xmovl %edx, %eax eax=edx eax 处=ysall $3, %eax eax < < 3 相当于y < < 3 3 即是 J 的值addl %edx, %eax eax= //eax=0=isall $2, %eax //eax=0*4=0addl 8(%ebp), %eax //eax加上ebp大8的位置,即eax+=a[]movl (%eax), % %eax //eax=i+1=1,sall $2, %eax //eax=4addl 8(%ebp), %eax //eax加上ebp大8的位置 eax=4+a[]movl (%eax ebp小4的位置 eax=i=0addl $2, %eax //eax+=2 eax=2sall $2, %eax //eax*=4 eax=8addl 8(%ebp), %eax //eax=0=isall $2, %eax //eax*4addl 8(%ebp), %eax //eax+大于ebp8的位置的值 即eax=0+a[]movl (%eax), %eax
于ebx 两数相加: 将相加后的结果放入eaxmov eax,1024mov ebx,2048add eax,ebx; 同样两数相减,将结果放到eax中mov eax,1024sub eax,512; eax,00401024hand eax,0ffffh ; eax = 00001024hmov eax,00401024hand eax,0ffff0000h ; eax = 00400000h eax,0ffh ; eax = 0mov eax,4xor eax,5 ; eax = 1mov eax,0401000hxor eax,0400000h ; eax = 00001000hmov eax,0401000hxor eax,01000h ; eax = 00400000h; 异或可用于检查标志位xor eax,eaxmov eax ; 计算 123 * 24; 等式拆分: EAX * 24 => EAX * (16 + 8) => (EAX * 16) + (EAX * 8)mov eax,123mov ebx,eaxshl eax
//eax=[ebp-16],即eax = bar.val ,NOTICE:NO Default Constructor is Called testl %eax, %eax (%ebp), %eax //eax=[ebp-12], 即eax=bra.pnext testl %eax, %eax je .L4 //如果testl //eax=this addl $4, %eax //eax=eax+4,即foo的首地址 subl $12, %esp pushl -20(%ebp), %eax //eax=ebp-20,即eax=b.this pushl %eax //b首地址压栈 call _ZN4BellC1Ev %eax, -24(%ebp) //Widget &w=b movl -24(%ebp), %eax //eax=&w movl (%eax), %eax
于ebx 两数相加: 将相加后的结果放入eax mov eax,1024 mov ebx,2048 add eax,ebx ; 同样两数相减,将结果放到eax中 mov eax mov eax,4 xor eax,5 ; eax = 1 mov eax,0401000h xor eax,0400000h ; eax = 00001000h mov eax,0401000h xor eax,01000h ; eax = 00400000h ; 异或可用于检查标志位 xor eax,eax mov eax * 36 => EAX * (32 + 4) => (EAX * 32) + (EAX * 4) mov eax,123 mov ebx,eax ; 拷贝出一份 shl eax + 4 + 1) => (EAX * 16) + (EAX * 4) + (EAX * 1) mov eax,123 mov ebx,eax mov ecx,eax ;
xor eax,eax mov eax,offset WordVar1 mov eax,offset DwordVar2 ; 使用 PTR 可指定默认取出参数的大小(DWORD/WORD ,eax mov eax,lengthof ArrayDW ; eax = 10 mov eax,lengthof ArrayBT ; eax = xor eax,eax mov eax,TYPE WordVar1 ; eax = 2 mov eax,TYPE DwordVar2 ; xor eax,eax mov eax,sizeof ArrayBT ; eax = 10 mov eax,sizeof ArrayTP ,0100h test eax,eax ; zf=0 mov eax,0 test eax,eax ; zf=0 or al,80h
%edx,%eax 0x08048556 <+86>: mov (%eax),%eax 0x08048558 <+88>: movzbl (%eax),%eax ,%eax 0x08048556 <+86>: mov (%eax),%eax 0x08048558 <+88>: movzbl (%eax),%eax 0x0804855b (%eax),%eax 0x08048558 <+88>: movzbl (%eax),%eax 0x0804855b <+91>: movsbl %al,%eax : movzbl (%eax),%eax 0x0804855b <+91>: movsbl %al,%eax 0x0804855e <+94>: mov %eax,0x4 %eax),%eax 0x0804855b <+91>: movsbl %al,%eax 0x0804855e <+94>: mov %eax,0x4(%esp) 0x08048562
// 保存i push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来 ,再通过pop ecx和eax还原原来的eax和ecx的值 push ecx }; printf("\n\n第一层循环i=%d\n",i); //第一个循环end // 保存i push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来 // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx
假设 eax=3 计算 15 * eax 的结果,拆分过程如下: 1.计算 lea edx,[eax * 4 + eax] 这就相当于计算 edx = (4 * eax) + eax = 5eax 其中的每个 接着计算 (5 * eax) = 5eax 最后得出 10eax + 5eax 4.经过该过程可得出 eax * 15 = 45 最终计算3*15=45得到最终结果. ,dword ptr ds:[x] ; eax = 3 lea edx,dword ptr ds:[eax * 4 + eax] ; edx = 4eax + eax =3 计算 eax * 8 + 10 的结果,拆分过程如下: 1.计算 shl eax,3 这就相当于计算 eax = eax * 2 ^(次方) 3 其公式相当于计算 eax = eax * 8 ,eax ; 计算 eax = eax * 2 ^ 2 相当于计算 eax * 4 mov eax,dword ptr ds:[x] sal eax,2 invoke
//eax=[ebp+8],即eax=z.this movl %edx, (%eax) //设置z的vptr movl 12(%ebp), %eax // eax=b.this movl 4(%eax), %edx //edx = b.loc movl 8(%ebp), %eax //eax=z.this movl %eax, -12(%ebp) xorl %eax, %eax subl $4, %esp pushl $2 pushl $1 leal -24(%ebp), %eax //eax=ebp-24, b对象首地址 pushl %eax //b //eax = ebps-24, 即eax=b.this pushl %eax //b.this压栈 leal -32(%ebp), %eax //eax=ebp
y-x*xmovl %edx, %eax eax=edx eax 处=ysall $3, %eax eax < < 3 相当于y < < 3 3 即是 J 的值addl %edx, %eax eax= //eax=0=isall $2, %eax //eax=0*4=0addl 8(%ebp), %eax //eax加上ebp大8的位置,即eax+=a[]movl (%eax), % %eax //eax=i+1=1,sall $2, %eax //eax=4addl 8(%ebp), %eax //eax加上ebp大8的位置 eax=4+a[]movl (%eax ebp小4的位置 eax=i=0addl $2, %eax //eax+=2 eax=2sall $2, %eax //eax*=4 eax=8addl 8(%ebp), %eax //eax=0=isall $2, %eax //eax*4addl 8(%ebp), %eax //eax+大于ebp8的位置的值 即eax=0+a[]movl (%eax), %eax
,0100h test eax,eax ; zf=0 mov eax,0 test eax,eax ; zf=0 or 例如,要判断eax是否为0并跳转到标号END,可以使用以下代码: cmp eax, 0 je END 在这个代码中,CMP指令将eax和0相减,不保存结果,而是设置相应的条件码标志位。 = 0) mov eax,2 sub eax,1 jnz jump ; zf=0 pf=0 mov eax,2 cmp eax,1 jne >< right) 无符号 mov eax,10 mov ebx,5 cmp eax,ebx ; eax ! >< right) 有符号 mov eax,10 mov ebx,-5 cmp eax,ebx ; eax !
* 操作数长度在指令名后缀,b表示8位,w表示16位,l表示32位,如movl %ebx,%eax。 * 立即操作数(常量)用标示,如addl 5,%eax * 变量加不加有区别。 如movl foo, %eax表示把foo变量地址放入寄存器%eax。movl foo,%eax表示把foo变量值放入寄存器%eax。 Intel Code AT&T Code mov eax,1 movl $1,%eax mov ebx,0ffh movl $0xff,%ebx int 80h int $0x80 mov ebx, eax movl %eax, %ebx mov eax,[ecx] movl (%ecx),%eax mov eax,[ebx+3] movl 3(%ebx),%eax mov eax,[ebx+20h] movl 0x20(%ebx),%eax add eax,[ebx+ecx*2h] addl (%ebx,%ecx,0x2),%eax lea eax,[ebx+ecx] leal (%ebx,%ecx),%eax
,eax;eax置零 mov ah,blue shl eax,8;左移8位 mov ah,green mov al,red endm ;;;;;;已定义数据的数据段 . mov hInstance,eax invoke GetCommandLine;获取命令行的字符串指针 mov CommandLine,eax invoke WinMain,hInstance,NULL mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW;获取一个系统光标 mov wc.hCursor,eax invoke RegisterClassEx ;把指向字体的句柄放入设备环境 mov hfont,eax RGB 200,200,50 invoke SetTextColor,hdc,eax;设置文本颜色 RGB 0,0,255 ,eax;eax置零 ret WndProc endp end start
pop ebx add ebx, 160 mov eax, 0Fh push eax mov eax, ebx push eax push mov eax, PageDirBase mov cr3, eax ; 开启分页机制 mov eax, cr0 or eax, 80000000h ; 初始化非一致代码段描述符 xor eax, eax mov ax, cs shl eax, 4 add eax, LABEL_SEG_CODE32 pop ebx add ebx, 160 mov eax, 0Fh push eax mov eax, ebx push eax push mov eax, PageDirBase mov cr3, eax ; 开启分页机制 mov eax, cr0 or eax, 80000000h
,dword ptr ds:[n] add eax,1 ; n++ mov dword ptr ds:[n],eax L1: mov eax,dword *y*y imul eax,dword ptr ds:[y] add edx,eax mov eax,dword ptr ds:[z] imul eax,dword ptr ,dword ptr ds:[y] add eax,1 ; y++ mov dword ptr ds:[y],eax L3: mov eax, ,dword ptr ds:[y] add eax,1 ; y++ mov dword ptr ds:[y],eax L3: mov eax, ] sub eax,1 mov dword ptr ds:[y],eax jmp L3 L4: mov eax,dword ptr ds:[y] sub eax,1
, 0xBE // NtOpenProcess=转成十六进制等于BEimul eax, eax, 4 // eax , 0x10 // eax+0x10mov eax, [eax] // 取[EAX] eax里面的数据给EAXmov ECXmov eax, 0x211 // 0x211给EAX,NtUserSendInput的序号imul eax, eax, 4 {climov eax, cr0and eax, not 10000hmov cr0, eax}__asm{push eaxpush ebxpush ecxpush edxmov eax, KeServiceDescriptorTablesub eax, 0x40add eax, 0x10mov eax, [eax]mov ecx, eaxmov eax, 0x211imul eax, eax, 4add ecx, eaxmov edx, NtUserSendInput_Ord
cdq sub eax,edx sar eax, B 还原方法: 除数的还原 = 2^b次方 被除数的还原: = 被除数就是eax 如果是补码,则是负数. sar eax, n 向下取整 代入公式: 向下取整((eax + eax - edx(-1 or 0)) / 2^n) b > 0,那么使用第一条公式即可. cdq sub eax,edx sar eax, n 还原方法: a + b - 1 (-1 or 0) 向下取整(eax + 2^n - edx) / 2^n) 根据公式还原. 不使用公式: 除数: 2^n 被除数: eax 商: 被除数为正: eax / 2^n 被除数为负数: (eax -1) / 2^n次方. 2.除数为2的幂 高级代码: int main(int cdq sub eax,edx sar eax, n 除数进行还原: 2^n 被除数: eax eax是补码,则商为负,则 sub eax,edx会执行.
,BYTE PTR [edx]mov _bKey,eax;原始字节长度mov ax,WORD PTR [edx + 1]mov _dwCodeLen,eax;压缩后的长度mov ax,WORD PTR [edx + 3]mov _dwCompressLen,eax;判断执行类型;dll时,第一个参数 和父的[esi + 0Ch]相等mov eax,[ebp + 08h]test eax,eaxje _ ,eax_HashLoop:lodsbtest al,alje _HashEndrol cl,1add ecx,eaxjmp _HashLoop_HashEnd:mov eax,ecxpop ecxcmp eax,[esp+4]jne _WalkNameTable_WalkNameFinish:pop esi;恢复esi = Hash Tablepop eax;修复堆栈_FindApiFinish:mov call _GetCodeAddrmov esi,eax;esi = code起始地址mov [edi].pOldCode,eax;修改负载为可读可写可执行lea eax,_dwProtectpush
mov cl, [eax] .text:00401098 inc eax .text:00401099 test cl [eax+1] 获取字符串首地址 + 1的值. 3. mov cl,[eax] 获取单个字符给cl 4. inc eax 地址递增 5. test cl,cl 判断单个字符是否为0也就是结尾.不是就上跳,上跳是循环.所以地址不断递增 6. sub eax,edx 循环过后.eax = 字符串的高地址. 因为strlen的特点就是遇到0结尾推出.所以汇编 sub eax,edx eax = 字符串0结尾的地址 edx = 首地址字符串+1的地址 两者相减就是字符串长度. 其实也可以换成下方汇编 如下: lea eax,字符串首地址 lea edx,字符串首地址 labale: mov cl,[eax] 取出单个字符 inc eax