Problem: [zzz26]NSSCTF2025入门题目-认识asm
从跳转可以看出loc_1400014B9是循环内容
以下是部分注释
text:00000001400014B9 mov eax, [rbp+10h+i]
.text:00000001400014BC cdqe
.text:00000001400014BE mov rdx, [rbp+10h+flag]
.text:00000001400014C2 add rax, rdx
.text:00000001400014C5 movzx eax, byte ptr [rax];eax=flag[i]
.text:00000001400014C8 mov ecx, eax;ecx=flag[i]
.text:00000001400014CA mov eax, [rbp+10h+i]
.text:00000001400014CD cdqe
.text:00000001400014CF lea rdx, [rax+1];rdx=i+1
.text:00000001400014D3 mov rax, [rbp+10h+flag]
.text:00000001400014D7 add rax, rdx
.text:00000001400014DA movzx eax, byte ptr [rax];eax=flag[i+1]
.text:00000001400014DD add eax, 1;eax=flag[i+1]+1
.text:00000001400014E0 xor ecx, eax;flag[i]^=(flag[i+1]+1)
这道题不是特别难,如果看不懂的话可以根据运算符去猜
.text:00000001400014FC mov rcx, [rbp+10h+flag] ; Str
.text:0000000140001500 call strlen
.text:0000000140001505 sub rax, 2
.text:0000000140001509 cmp rbx, rax
.text:000000014000150C jb short loc_1400014B9
这里表明异或只进行到(strlen - 2),最前面可以看到索引是从0开始的,说明是没有处理最后一个字符的,也就是'}'
.text:00000001400014B0 mov [rbp+10h+i], 0
描述说flag格式为NSSCTF{},那么flag[0] = 'N'
#include <stdio.h>
#include <string.h>
int main(){
int enc[]={0x1a,0x7,0x17,0x16,0x13,0x3a,0x39,0x15,0x1d,0x2d,0x35,0x1d,0x13,0x3b,0x10,0x4,0x11,0x9,0xb,0xc,0xc,0x2a,0x4,0xf,0x1c,0x28,0x6,0xc,0x12,0x8,0x6,0x7e,0x7d};
char flag[33]={0};
flag[0]='N';
for(int i=0;i<32;i++){
flag[i+1] = (flag[i]^enc[i]) -1;
}
for(int i=0;i<32;i++){
printf("%c",flag[i]);
}
printf("%c",0x7d);
}
最后附上ai给的解释(仅供参考):
;初始化
push rbp
push rbx
sub rsp, 38h
lea rbp, [rsp+30h]
mov [rbp+10h+flag], rcx ; 保存 flag 指针
mov [rbp+10h+i], 0 ; 初始化循环变量 i=0
jmp short loc_1400014F6 ; 进入循环
;主循环
loc_1400014B9:
; 获取 flag[i]
mov eax, [rbp+10h+i] ; eax = i
cdqe ; 符号扩展 eax → rax
mov rdx, [rbp+10h+flag]
add rax, rdx ; rax = &flag[i]
movzx eax, byte ptr [rax] ; eax = flag[i]
; 获取 flag[i+1] + 1
mov ecx, eax ; ecx = flag[i]
mov eax, [rbp+10h+i] ; eax = i
cdqe
lea rdx, [rax+1] ; rdx = i+1
mov rax, [rbp+10h+flag]
add rax, rdx ; rax = &flag[i+1]
movzx eax, byte ptr [rax] ; eax = flag[i+1]
add eax, 1 ; eax = flag[i+1] + 1
; 计算 flag[i] ^ (flag[i+1] + 1)
xor ecx, eax ; ecx = flag[i] ^ (flag[i+1] + 1)
mov edx, ecx ; edx = 结果
mov eax, [rbp+10h+i] ; eax = i
cdqe
mov rcx, [rbp+10h+flag]
add rax, rcx ; rax = &flag[i]
mov [rax], dl ; flag[i] = dl(异或结果)
; i++
add [rbp+10h+i], 1 ; i += 1
;循环条件
loc_1400014F6:
; 检查是否继续循环 (i < strlen(flag) - 2)
mov eax, [rbp+10h+i] ; eax = i
movsxd rbx, eax ; rbx = i
mov rcx, [rbp+10h+flag] ; rcx = flag
call strlen ; rax = strlen(flag)
sub rax, 2 ; rax = strlen(flag) - 2
cmp rbx, rax ; if (i < strlen(flag) - 2)
jb short loc_1400014B9 ; 继续循环
;函数返回
add rsp, 38h
pop rbx
pop rbp
retn

加载中...