学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1157

主题
发表于 2020-8-30 16:54:04 | 查看: 4122| 回复: 0
  整理复习汇编语言的知识点,以前在学习《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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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汇编 - 各种语句的构造

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 语句构建常用数据结构算法

温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-4-19 23:49 , Processed in 0.130411 second(s), 42 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表