pwn5-pwn12的题目全是关于汇编语言的知识,pwn5-pwn12的汇编文件的代码都是一样的。
我们将可执行文件和汇编文件托到ctfshow-pwn专用虚拟机里,给可执行文件加上执行权限并查看其信息。
32位的,直接扔到ida中去。
在虚拟机中使用cat命令读取下asm文件的源汇编代码。
section .data
msg db "Welcome_to_CTFshow_PWN", 0
section .text
global _start
_start:
; 立即寻址方式
mov eax, 11 ; 将11赋值给eax
add eax, 114504 ; eax加上114504
sub eax, 1 ; eax减去1
; 寄存器寻址方式
mov ebx, 0x36d ; 将0x36d赋值给ebx
mov edx, ebx ; 将ebx的值赋值给edx
; 直接寻址方式
mov ecx, [msg] ; 将msg的地址赋值给ecx
; 寄存器间接寻址方式
mov esi, msg ; 将msg的地址赋值给esi
mov eax, [esi] ; 将esi所指向的地址的值赋值给eax
; 寄存器相对寻址方式
mov ecx, msg ; 将msg的地址赋值给ecx
add ecx, 4 ; 将ecx加上4
mov eax, [ecx] ; 将ecx所指向的地址的值赋值给eax
; 基址变址寻址方式
mov ecx, msg ; 将msg的地址赋值给ecx
mov edx, 2 ; 将2赋值给edx
mov eax, [ecx + edx*2] ; 将ecx+edx*2所指向的地址的值赋值给eax
; 相对基址变址寻址方式
mov ecx, msg ; 将msg的地址赋值给ecx
mov edx, 1 ; 将1赋值给edx
add ecx, 8 ; 将ecx加上8
mov eax, [ecx + edx*2 - 6] ; 将ecx+edx*2-6所指向的地址的值赋值给eax
; 输出字符串
mov eax, 4 ; 系统调用号4代表输出字符串
mov ebx, 1 ; 文件描述符1代表标准输出
mov ecx, msg ; 要输出的字符串的地址
mov edx, 22 ; 要输出的字符串的长度
int 0x80 ; 调用系统调用
; 退出程序
mov eax, 1 ; 系统调用号1代表退出程序
xor ebx, ebx ; 返回值为0
int 0x80 ; 调用系统调用
ida反编译结果:
void __noreturn start()
{
int v0; // eax
int v1; // eax
v0 = sys_write(1, &dword_80490E8, 0x16u);
v1 = sys_exit(0);
}
运行文件计科输入flag,有这好事必须占便宜!
按照题目描述:flag为 ctfshow{Welcome_to_CTFshow_PWN}。
这道题问的是立即寻址结束后eax寄存器的值为多少?
那我们先看一下立即寻址的时候的汇编代码。
; 立即寻址方式
mov eax, 11 ; 将11赋值给eax
add eax, 114504 ; eax加上114504
sub eax, 1 ; eax减去1
mov eax,11这条汇编指令就是将11这个数值放到eax寄存器中,跟eax=11差不多。
OK,此时eax寄存器的值为11。
add eax,114504这条汇编指令是将eax中的内容加上114504,跟eax = eax+114504差不多,此时eax寄存器的值为114515
sub eax,1这条汇编指令是将eax中的内容减去1,相当于eax = eax-1,此时eax寄存器的置为114514。
所以本题flag为ctfshow{114514} 。
本题问的是寄存器寻址方式结束后edx寄存器的值为多少?
寄存器寻址方式的汇编代码:
; 寄存器寻址方式
mov ebx, 0x36d ; 将0x36d赋值给ebx
mov edx, ebx ; 将ebx的值赋值给edx
mov ebx,0x36d这条汇编指令是将0x36d赋给ebx,此时ebx寄存器的值为0x36d,edx寄存器的值未知。
mov edx,ebx这条汇编指令是将ebx寄存器中的值赋给edx,此前ebx的值为0x36d,所以此条指令执行后,edx寄存器中的值为0x36d。
所以本题的flag为:ctfshow{0x36D}注意这的D要大写哦。
本题问的直接寻址方式结束后ecx寄存器的值为多少?
找到直接寻址方式的相关汇编代码:
; 直接寻址方式
mov ecx, [msg] ; 将msg的地址赋值给ecx
只有一句指令,mov ecx,[msg] 将msg的地址赋给ecx,所以本条代码执行过后,ecx寄存器中的值为msg的地址。
那么msg的地址怎么获得呢?
我们可以将可执行文件丢进ida中
dword_80490E8其实就是[msg],我们点击dword_80490E8跟进就可以看到其地址了。
这个080490E8就是msg的地址。
所以本题的flag为:ctfshow{0x80490E8}
记得要加0x,代表是16进制,因为二进制代码的地址都是以16进制存储的,记得前面的080490E8的第一个0也要去掉哦。
本题问的是寄存器间接寻址方式结束后eax寄存器的值为多少?
找到寄存器间接寻址方式的相关汇编代码:
; 寄存器间接寻址方式
mov esi, msg ; 将msg的地址赋值给esi
mov eax, [esi] ; 将esi所指向的地址的值赋值给eax
mov esi,msg本条代码是将msg的地址赋值给esi,此时esi寄存器的值也就是上道题目的080490E8。
mov eax,[esi]本条代码是将esi中的值作为地址,然后将该地址单元的值赋给eax,即找到080490E8地址单元中的值赋给eax,我们在ida可以查看080490E8地址单元的值。
那么080490E8地址单元中的值就为:636C6557h,后面的h表示给数值是16进制。所以本条代码执行后eax寄存器中的值就为636C6557h。
所以本题的flag为:ctfshow{0x636C6557} 。
本题问的是寄存器相对寻址方式结束之后eax寄存器的值为多少?
找到寄存器相对寻址方式相关的汇编代码:
; 寄存器相对寻址方式
mov ecx, msg ; 将msg的地址赋值给ecx
add ecx, 4 ; 将ecx加上4
mov eax, [ecx] ; 将ecx所指向的地址的值赋值给eax
mov ecx.msg这条代码是将msg的地址赋给ecx,此时ecx寄存器中的值就是pwn8题目的flag值080490E8。
add ecx,4这条代码是将ecx寄存器中的值加4,即ecx = ecx+4,此时ecx寄存器中的值为080490EC。
mov eax,[ecx]这条代码是以ecx寄存器中的值作为地址,将该地址单元中的值赋给eax。
从ida中找到080490EC地址单元中的值。
所以,本条代码执行后eax寄存器的值为ome_to_CTFshow_PWN。
所以,本题的flag为:ctfshow{ome_to_CTFshow_PWN}
本题问的是基址变址寻址方式结束后的eax寄存器的值为多少?
找到基址变址寻址方式相关的代码:
; 基址变址寻址方式
mov ecx, msg ; 将msg的地址赋值给ecx
mov edx, 2 ; 将2赋值给edx
mov eax, [ecx + edx*2] ; 将ecx+edx*2所指向的地址的值赋值给eax
mov ecx,msg还是将msg的地址赋给ecx,即ecx寄存器中的值为pwn8的flag:080490E8。
mov edx,2本条代码是将2这个数值赋给edx,即edx寄存器中的值为2。
mov eax,[ecx+edx*2]本条代码是以ecx+edx*2作为地址,将该地址单元中的值赋给eax。我们先来看ecx+edx*2是多少。
ecx=080490E8,edx=2,edx*2 = 4,故ecx+edx*2 = 080490EC,这不跟上到题目的地址一样嘛,所以本条代码执行后也是ome_to_CTFshow_PWN。
所以本题的flag为:ctfshow{ome_to_CTFshow_PWN}
本题问的是相对基址变址寻址方式结束后eax寄存器的值为多少?
找到相对基址变址寻址方式相关的代码:
; 相对基址变址寻址方式
mov ecx, msg ; 将msg的地址赋值给ecx
mov edx, 1 ; 将1赋值给edx
add ecx, 8 ; 将ecx加上8
mov eax, [ecx + edx*2 - 6] ; 将ecx+edx*2-6所指向的地址的值赋值给eax
mov ecx,msg这条代码还是将msg的地址赋给ecx,此时ecx寄存器中的值还是pwn8题目的flag:080490E8
mov edx,1这条代码是将1这个数值赋给edx,此时edx寄存器的值为1。
add ecx,8这条代码是将ecx寄存器的值加8,即ecx = ecx+8,此时ecx寄存器的值为080490F0(16进制运算啊)。
mov eax,[ecx + edx*2 - 6] 这条代码是以ecx+edx*2-6的值作为地址,将该地址单元中的值赋给eax。
ecx = 080490F0,edx*2-6 = 1*2-6=-4,ecx + edx*2-6=080490F0-4=080490EC
所以代码执行后,eax寄存器的值为ome_to_CTFshow_PWN。
则本题的flag为:ctfshow{ome_to_CTFshow_PWN}