0%

[P7064]官方解题思路

2025-08-01 15:23By
zzz26
REVERSE

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
还没有人赞赏,快来当第一个赞赏的人吧!
  
© 著作权归作者所有

加载中...

加载失败
广告
×
评论区
添加新评论

加载中...