整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
IF 语句与AND/OR IF中的AND语句的构造: and语句为等式两边只要一边返回假,则整个等式就不需要继续下去了,只有等式1成立的情况下才会继续判断等式2是否成立。
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int var1 = 20;
int var2 = 10;
int var3 = 50;
if (var1 >= 20 and var2 <= 100 and var3 == 50)
{
printf("xor eax,eax");
}
return 0;
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
flag DWORD ?
.code
main PROC
; if(var1 >= 20 and var2 <= 100 and var3 == 50)
cmp dword ptr ds:[var1],20 ; 判断是否大于20
jl L1 ; 不大于则跳转
cmp dword ptr ds:[var2],100 ; 判断是否小于100
jg L1 ; 不小于则跳转
cmp dword ptr ds:[var3],50 ; 判断是否等于50
jne L1 ; 不等于则跳转
mov dword ptr ds:[flag],1 ; 说明等式成立 flag=1
jmp L2
L1:mov dword ptr ds:[flag],0
L2:cmp dword ptr ds:[flag],0
je lop_end ; 为0则跳转,不为0则继续执行
xor eax,eax ; 此处是执行if语句内部
xor ebx,ebx
xor ecx,ecx
jmp lop_end
lop_end:
nop ; 直接结束
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF中OR语句的构造: OR语句的判断则是只要等式两边一边的结果返回为真,则整个表达式的后半部分直接跳过。
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int var1 = 20;
int var2 = 10;
int var3 = 50;
if (var1 > var2 || var2 <= var3)
{
printf("xor eax,eax");
}
else if(var3 == 50 || var2 > 10)
{
printf("xor ebx,ebx");
}
return 0;
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
; if (var1 > var2 || var2 <= var3)
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; var1 > var2
jg L1
mov eax,dword ptr ds:[var2]
cmp eax,dword ptr ds:[var3] ; var2 <= var3
jg L2 ; 条件是 var2 > var3 则跳转
L1:
xor eax,eax ; printf("xor eax,eax")
jmp lop_end
L2:
; else if(var3 == 50 || var2 > 10)
cmp dword ptr ds:[var3],50
je L3
cmp dword ptr ds:[var2],10 ; var2 > 10
jle lop_end
L3:
xor ebx,ebx ; printf("xor ebx,ebx")
jmp lop_end
lop_end:
nop
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF中AND/OR混合构造:
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int var1 = 20;
int var2 = 10;
int var3 = 50;
if ((var1 >= 10 && var2 <= 20) || (var2 == 10 && var3 >= 40))
{
printf("xor eax,eax");
}
else
{
printf("xor ebx,ebx");
}
return 0;
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
; if ((var1 >= 10 && var2 <= 20) && (var2 == 10 || var3 >= 40))
cmp dword ptr ds:[var1],10 ; var1 >= 10
jl L1
cmp dword ptr ds:[var2],20 ; var2 <= 20
jg L1
cmp dword ptr ds:[var2],10 ; var2 == 10
je L2
cmp dword ptr ds:[var3],40 ; var3 >= 40
jl L1
jmp L2
L1:
xor ebx,ebx ; else
jmp lop_end
L2:
xor eax,eax ; printf("xor eax,eax")
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF语句嵌套调用: 在编写这样子的嵌套语句时,应该由外到内逐层解析,这样能更容易写出优美的表达式。
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int x = 100, y = 200, z = 300;
int var1 = 20,var2 = 10,var3 = 50;
if (var1 >= var2)
{
if ((x<y) && (z>y))
{
printf("xor eax,eax");
}
else
{
printf("xor ebx,ebx");
}
}
else if (var2 > var3)
{
printf("xor ecx,ecx");
}
return 0;
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
x DWORD 100
y DWORD 200
z DWORD 300
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; if(var1 >= var2) ?
jl L1
mov eax,dword ptr ds:[x]
cmp eax,dword ptr ds:[y] ; if((x<y)) ?
jge L2
mov eax,dword ptr ds:[z] ; if((z>y)) ?
cmp eax,dword ptr ds:[y]
jle L2
xor eax,eax ; printf("xor eax,eax")
jmp lop_end
L1:
mov eax,dword ptr ds:[var2]
cmp eax,dword ptr ds:[var3]
jle lop_end
xor ecx,ecx ; printf("xor ecx,ecx")
jmp lop_end
L2:
xor ebx,ebx ; printf("xor ebx,ebx")
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF语句三层嵌套:
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int x = 100, y = 200, z = 300;
int var1 = 20,var2 = 10,var3 = 50;
int result = 1;
if ((var1 >= var2) && (var2 <= var3) || (var3 > var1))
{
if ((x % 2 == 0) || (y % 2 != 0))
{
if (result == 1)
printf("xor eax,eax");
}
}
return 0;
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
x DWORD 100
y DWORD 200
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
result DWORD 1
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; and var1 >= var2
jl lop_end
mov eax,dword ptr ds:[var2]
cmp eax,dword ptr ds:[var3] ; and var2 <= var3
jle L1
mov eax,dword ptr ds:[var3]
cmp eax,dword ptr ds:[var1] ; or var3 > var1
jle lop_end
L1:
mov eax,dword ptr ds:[x]
and eax,080000001h ; eax = eax % 2 = 0
jns L2 ; eax = 0 则跳转
dec eax
or eax,0fffffffeh ; eax = eax % 2 != 0
inc eax
L2:
mov eax,dword ptr ds:[result]
test eax,eax ; if(result == 1)
jne L3
jmp lop_end
L3:
xor eax,eax ; printf("xor eax,eax")
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF语句中的TEST: 这里有多种写法,第一种是比较好的写法,不需要增加太多编号,第二种是正常人的思维方式.
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int x = 100, y = 200, z = 300;
int var1 = 20,var2 = 10,var3 = 50;
int result = 1;
if (var1 >= var2 && var2 <= var3)
{
if (x == 100 || y == 200 || z == 300)
{
if (result == 1)
printf("xor eax,eax");
}
}
return 0;
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
x DWORD 100
y DWORD 200
z DWORD 300
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
result DWORD 1
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; var1 >= var2
jl lop_end
mov eax,dword ptr ds:[var2]
cmp eax,dword ptr ds:[var3] ; var2 <= var3
jg lop_end
mov eax,dword ptr ds:[x]
cmp eax,100 ; x == 100
jne lop_end
mov eax,dword ptr ds:[y]
cmp eax,200 ; y == 200
jne lop_end
mov eax,dword ptr ds:[z]
cmp eax,300 ; z = 300
jne lop_end
mov eax,dword ptr ds:[result]
test eax,eax ; eax = 0 ?
jz lop_end
xor eax,eax
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
以下是人的逻辑方式.
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
x DWORD 100
y DWORD 200
z DWORD 300
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
result DWORD 1
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; var1 >= var2
jge L1
jmp lop_end
L1:
mov eax,dword ptr ds:[var2] ; var2 <= var3
cmp eax,dword ptr ds:[var3]
jle L2
L2:
mov eax,dword ptr ds:[x]
cmp eax,100 ; x == 100 ?
je L3
mov eax,dword ptr ds:[y] ; y == 200 ?
cmp eax,200
je L3
mov eax,dword ptr ds:[y]
cmp eax,300 ; z == 300 ?
je L3
jmp lop_end
L3:
mov eax,dword ptr ds:[result] ; result == 1 ?
test eax,eax ; eax && eax != 0
jz lop_end
xor eax,eax
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF-ELSEIF-ELSE: 多层循环从何治,看我的,给我写。
#include <stdio.h>
#include <windows.h>
int main(int argc,char * argv[])
{
int var1 = 20,var2 = 10,var3 = 50;
if (var1 > 20)
printf("xor eax,eax");
else if (var2 > 10)
printf("xor ebx,ebx");
else if (var2 < var3)
printf("xor ecx,ecx");
else
printf("xor edx,edx");
return 0;
}
正常写法
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,20 ; var1 > 20
jg L1
mov eax,dword ptr ds:[var2]
cmp eax,10 ; var2 > 10
jg L2
cmp eax,dword ptr ds:[var3]
jl L3 ; var2 < var3
xor edx,edx ; printf("xor edx,edx")
jmp lop_end
L1:
xor eax,eax ; printf("xor eax,eax")
jmp lop_end
L2:
xor ebx,ebx ; printf("xor ebx,ebx")
jmp lop_end
L3:
xor ecx,ecx ; printf("xor ecx,ecx")
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
编译器是这样干的,我把他的思路写一下。
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,20
jle L1
xor eax,eax ; printf("xor eax,eax")
jmp lop_end
L1:
mov eax,dword ptr ds:[var2]
cmp eax,10
jle L2
xor ebx,ebx ; printf("xor ebx,ebx")
jmp lop_end
L2:
mov eax,dword ptr ds:[var2]
cmp eax,dword ptr ds:[var3]
jge L3
xor ecx,ecx ; printf("xor ecx,ecx")
jmp lop_end
L3:
xor edx,edx ; printf("xor edx,edx")
jmp lop_end
lop_end:
int 3
invoke ExitProcess,0
main ENDP
END main
编译器对于if-elseif-else是这样处理的.
int var1 = 20;
int var2 = 10;
int var3 = 50;
if (var1 > 20)
printf("xor eax,eax");
else if (var2 >= 20)
printf("xor ebx,ebx");
else if (var3 <= 20)
printf("xor ecx,ecx");
else
printf("xor edx,edx");
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,20 ; var1 > 20 ?
jle L1 ; 不大于则跳到L1继续判断
xor eax,eax
jmp lop_end ; 最后都要跳向结束
L1:mov eax,dword ptr ds:[var2]
cmp eax,20 ; var1 >= 20 ?
jl L2 ; 不大于则继续判断L2
xor ebx,ebx
jmp lop_end
L2:mov eax,dword ptr ds:[var3]
cmp eax,20 ; var3 <= 20 ?
jg L3 ; 大于则跳到L3
xor ecx,ecx
jmp lop_end
L3:xor edx,edx
jmp lop_end
lop_end:
xor esi,esi
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
IF的前期脑残写法: 写的烂,没编译器生成的代码有趣,垃圾保存。
脑残1
if(var1 > var2) and (var2 < var3)
{
xor eax,eax
}else if(var1 > var3)
{
xor ebx,ebx
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; if(var1 > var2)
jg L1
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var3] ; else if(var1 > var3)
jg L3
L1:
mov eax,dword ptr ds:[var2] ; if(var2 < var3)
cmp eax,dword ptr ds:[var3]
jl L2
L2:
xor eax,eax
jmp lop
L3:
xor ebx,ebx
jmp lop
lop:
nop
invoke ExitProcess,0
main ENDP
END main
脑残2
if var1 == var2
{
if x > y
{
xchg x,y
}
else
{
x=10
y=20
}
}else
{
var1 = 0
var2 = 0
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
x BYTE 6
y BYTE 5
var1 DWORD 10
var2 DWORD 10
.code
main PROC
mov eax,dword ptr ds:[var1]
cmp eax,dword ptr ds:[var2] ; var1 == var2 ?
jne L1 ; 不等于跳转到L1
mov al,byte ptr ds:[x]
cmp al,byte ptr ds:[y] ; x > y ?
jg L2 ; 大于跳到L2
mov byte ptr ds:[x],0 ; 不大于则执行x=10 y=20
mov byte ptr ds:[y],0
jmp lop
L1:
mov dword ptr ds:[var1],0 ; var1 != var2 则执行
mov dword ptr ds:[var2],0
L2:
mov al,byte ptr ds:[x]
mov bl,byte ptr ds:[y]
xchg al,bl ; x y 数值交换
mov byte ptr ds:[x],al
mov byte ptr ds:[y],bl
jmp lop
lop:
nop
invoke ExitProcess,0
main ENDP
END main
if 双层嵌套结构: 包含有and,or运算符的连用处理.
int var1 = 20;
int var2 = 10;
int var3 = 50;
if (var1++ > 5 && var2++ >= 10)
{
var3 = var3 + 10;
var3 << 2;
if (var3 <= 100 or var3 <= 1000)
xor eax,eax
else
xor ebx,ebx
}
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
.code
main PROC
inc dword ptr ds:[var1] ; var1++
mov eax,dword ptr ds:[var1]
cmp eax,5 ; var1 > 5 ?
jg L1
jmp lop_end
L1:
inc dword ptr ds:[var2] ; var2++
mov eax,dword ptr ds:[var2] ; var2 >=10 ?
cmp eax,10
jge L2
jmp lop_end
L2:
mov eax,dword ptr ds:[var3] ; 获取 var3
add eax,10 ; var3 = var3 + 10
shl eax,2 ; var3 << 2
cmp eax,100
jle L3 ; var3 <= 100 ?
cmp eax,1000 ; eax or
jle L3 ; var3 <= 1000 ?
jmp L4 ; else
L3:
xor eax,eax
jmp lop_end
L4:
xor ebx,ebx
jmp lop_end
lop_end:
nop
invoke ExitProcess,0
main ENDP
END main
Win32汇编 - 各种语句的构造
编译器对于此类嵌套出处理结果是这样的,由于and指令左面如果成立则继续执行右面的判断,如果不成立右面的直接掠过,这样的话就比较有趣了,如下是我根据汇编代码推测的一段片段,。
.386p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
var1 DWORD 20
var2 DWORD 10
var3 DWORD 50
tmp DWORD ?
flag DWORD ?
.code
main PROC
mov eax,dword ptr ds:[var1]
mov dword ptr ds:[tmp],eax ; 将var1原值备份到tmp
mov ecx,dword ptr ds:[var1]
add ecx,1 ; 递增var1并会写到变量中
mov dword ptr ds:[var1],ecx
cmp dword ptr ds:[tmp],5 ; 用原值与5做比较
jle L1 ; 如果 var1 < var2
mov dword ptr ds:[flag],1
jmp L2
L1:mov dword ptr ds:[flag],0 ; 判断的是and的第一个等式
L2:cmp dword ptr ds:[flag],0
je lop_end
mov eax,dword ptr ds:[var2]
mov dword ptr ds:[tmp],eax ; 备份var2
mov ecx,dword ptr ds:[var2]
add ecx,1 ; 递增运算++
mov dword ptr ds:[var2],ecx
cmp dword ptr ds:[tmp],10 ; 判断 var2>=10 ?
jl L3 ; 不大于则跳到L3
mov dword dword ptr ds:[flag],1 ; 大于则标志flag=1
jmp L4
L3:mov dword ptr ds:[flag],0
L4:cmp dword ptr ds:[flag],0
je lop_end ; 不跳转则执行内部if
mov eax,dword ptr ds:[var3]
add eax,10
mov dword ptr ds:[var3],eax ; 递增var3
mov eax,dword ptr ds:[var3]
shl eax,2
mov dword ptr ds:[var3],eax ; var3 = var3 << 2
cmp dword ptr ds:[var3],100 ; var3 <= 100
jle L5
cmp dword ptr ds:[var3],1000 ; var3<=1000
jg L6 ; 跳转到内层else
L5:
xor eax,eax
nop
jmp lop_end
L6:
xor ebx,ebx
nop
jmp lop_end
lop_end:
xor eax,eax
invoke ExitProcess,0
main ENDP
END main
While /For 语句构建Switch/break 语句构建常用数据结构算法
|