参考https://tkazer.github.io/2025/03/06/GHCTF2025WP/中的FIshingKIt
一个简单的 assemble
签到题
将基本的运算都包括进去,加减乘除 异或
HXCTF{@ss4mb14_1s_V4ry_1mp0rt@nt^_^}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
uint8_t str2[] = {0x58,0x69,0x4F,0x5F,0x52,0x8C,0x56,0x8A,0x89,0x4D,
0x75,0x7D,0x4B,0x49,0x5F,0x30,0x71,0x5C,0x54,0x2F,
0x76,0x7E,0x57,0x38,0x83,0x79,0x3A,0x7D,0x78,0x6D,
0x80,0x63,0x8E,0x8C,0x8C,0x68,};
int main(void){
unsigned char str1[40];
memset(str1 , 0 , sizeof(str1));
puts("Input your flag: ");
scanf("%s",str1);
int len = strlen((char*)str1);;
for(int i = 0 ; i < len ; i++){
str1[i] ^= (i+1);
str1[i] -= 0x12;
str1[i] *= 2;
str1[i] /= 2;
str1[i] += 0x21;
}
if(!memcmp(str1 , str2 , len)){
puts("Congratulation!!!!!");
} else{
puts("Wrong 😫😫😫");
}
}
汇编代码将str2改成字节形式了,之前的是 .ascii
str2:
.byte 0x58, 0x69, 0x4F, 0x5F, 0x52, 0x8C, 0x56, 0x8A, 0x89, 0x4D,
0x75, 0x7D, 0x4B, 0x49, 0x5F, 0x30, 0x71, 0x5C, 0x54, 0x2F,
0x76, 0x7E, 0x57, 0x38, 0x83, 0x79, 0x3A, 0x7D, 0x78, 0x6D,
0x80, 0x63, 0x8E, 0x8C, 0x8C, 0x68
.LC0:
.string "Input your flag: "
.LC1:
.string "%s"
.LC2:
.string "Congratulation!!!!!"
.LC3:
.string "Wrong \\360\\237\\230\\253\\360\\237\\230\\253\\360\\237\\230\\253"
main:
push rbp
mov rbp, rsp
sub rsp, 48
lea rax, [rbp-48]
mov edx, 40
mov esi, 0
mov rdi, rax
call memset
mov edi, OFFSET FLAT:.LC0
call puts
lea rax, [rbp-48]
mov rsi, rax
mov edi, OFFSET FLAT:.LC1
mov eax, 0
call __isoc99_scanf
lea rax, [rbp-48]
mov rdi, rax
call strlen
mov DWORD PTR [rbp-8], eax
mov DWORD PTR [rbp-4], 0
jmp .L2
.L3:
mov eax, DWORD PTR [rbp-4]
cdqe
movzx eax, BYTE PTR [rbp-48+rax]
mov edx, eax
mov eax, DWORD PTR [rbp-4]
add eax, 1 ; 对应 i+1
xor eax, edx ; str1[i] ^= (i+1)
mov edx, eax
mov eax, DWORD PTR [rbp-4]
cdqe
mov BYTE PTR [rbp-48+rax], dl
mov eax, DWORD PTR [rbp-4]
cdqe
movzx eax, BYTE PTR [rbp-48+rax]
lea edx, [rax-18] ; str1[i] -= 18
mov eax, DWORD PTR [rbp-4]
cdqe
mov BYTE PTR [rbp-48+rax], dl
mov eax, DWORD PTR [rbp-4]
cdqe
movzx eax, BYTE PTR [rbp-48+rax]
lea edx, [rax+rax] ; str1[i] *= 2
mov eax, DWORD PTR [rbp-4]
cdqe
mov BYTE PTR [rbp-48+rax], dl
mov eax, DWORD PTR [rbp-4]
cdqe
movzx eax, BYTE PTR [rbp-48+rax]
shr al ; str1[i] /= 2
mov edx, eax
mov eax, DWORD PTR [rbp-4]
cdqe
mov BYTE PTR [rbp-48+rax], dl
mov eax, DWORD PTR [rbp-4]
cdqe
movzx eax, BYTE PTR [rbp-48+rax]
lea edx, [rax+33] ; str1[i] += 33
mov eax, DWORD PTR [rbp-4]
cdqe
mov BYTE PTR [rbp-48+rax], dl
add DWORD PTR [rbp-4], 1
.L2:
mov eax, DWORD PTR [rbp-4]
cmp eax, DWORD PTR [rbp-8]
jl .L3
mov eax, DWORD PTR [rbp-8]
movsx rdx, eax
lea rax, [rbp-48]
mov esi, OFFSET FLAT:str2
mov rdi, rax
call memcmp
test eax, eax
jne .L4
mov edi, OFFSET FLAT:.LC2
call puts
jmp .L5
.L4:
mov edi, OFFSET FLAT:.LC3
call puts
.L5:
mov eax, 0
leave
ret
注意乘除有抵消,如果在逆向脚本中完全复现运算,那么会存在单字节整形溢出。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
unsigned char str2[] = {0x58,0x69,0x4F,0x5F,0x52,0x8C,0x56,0x8A,0x89,0x4D,0x75,0x7D,0x4B,0x49,0x5F,0x30,0x71,0x5C,0x54,0x2F,0x76,0x7E,0x57,0x38,0x83,0x79,0x3A,0x7D,0x78,0x6D,0x80,0x63,0x8E,0x8C,0x8C,0x68,};
int main(void){
unsigned char str1[40];
memset(str1 , 0 , sizeof(str1));
// for(int i = 0 ; i < len ; i++){
// str1[i] ^= (i+1);
// str1[i] += 0x12;
// str1[i] *= 2;
// str1[i] /= 2;
// str1[i] -= 0x21;
// }
int len = strlen((char*)str2);
for(int i = 0 ; i < len; i++){
str2[i] -= 0xF;
str2[i] ^= (i+1);
}
for(int i = 0 ; i < len ; i++){
printf("%c",str2[i]); // HXCTF{@ss4mb14_1s_V4ry_1mp0rt@nt^_^}
}
}
思路和省赛那个彩蛋题目一致
<aside> 💡
Base64换表 + RC4
</aside>