(1):easyasm

​ 题目: https://pan.baidu.com/s/1MA-OeBpQ2DNe1th9AfbWQQ

​ 提取码:tuyt

题解:

1.首先用exe去看有没有壳,发现没壳用IDA打开,发现不可以F5看反编译,于是就开始看汇编代码,它在干嘛

seg001:0000 seg001          segment byte public 'UNK' use16
seg001:0000 assume cs:seg001
seg001:0000 assume es:nothing, ss:nothing, ds:dseg, fs:nothing, gs:nothing
seg001:0000 db 91h
seg001:0001 db 61h ; a
seg001:0002 db 1
seg001:0003 db 0C1h
seg001:0004 db 41h ; A
seg001:0005 db 0A0h
seg001:0006 db 60h ; `
seg001:0007 db 41h ; A
seg001:0008 db 0D1h
seg001:0009 db 21h ; !
seg001:000A db 14h
seg001:000B db 0C1h
seg001:000C db 41h ; A
seg001:000D db 0E2h
seg001:000E db 50h ; P
seg001:000F db 0E1h
seg001:0010 db 0E2h
seg001:0011 db 54h ; T
seg001:0012 db 20h
seg001:0013 db 0C1h
seg001:0014 db 0E2h
seg001:0015 db 60h ; `
seg001:0016 db 14h
seg001:0017 db 30h ; 0
seg001:0018 db 0D1h
seg001:0019 db 51h ; Q
seg001:001A db 0C0h
seg001:001B db 17h
seg001:001C db 0
seg001:001D db 0
seg001:001E db 0
seg001:001F db 0
seg001:001F seg001 ends
seg001:001F
seg002:0000 ; ===========================================================================
seg002:0000
seg002:0000 ; Segment type: Uninitialized
seg002:0000 seg002 segment byte stack 'STACK' use16
seg002:0000 assume cs:seg002
seg002:0000 assume es:nothing, ss:nothing, ds:dseg, fs:nothing, gs:nothing
seg002:0000 db 80h dup(0)
seg002:0000 seg002 ends
seg002:0000
seg003:0000 ; ===========================================================================
seg003:0000
seg003:0000 ; Segment type: Pure code
seg003:0000 seg003 segment byte public 'CODE' use16
seg003:0000 assume cs:seg003
seg003:0000 assume es:nothing, ss:seg002, ds:nothing, fs:nothing, gs:nothing
seg003:0000
seg003:0000 ; =============== S U B R O U T I N E =======================================
seg003:0000
seg003:0000 ; Attributes: noreturn
seg003:0000
seg003:0000 public start //开始程序
seg003:0000 start proc near
seg003:0000 mov ax, seg dseg
seg003:0003 mov ds, ax
seg003:0005 assume ds:dseg
seg003:0005 mov ax, seg seg001
seg003:0008 mov es, ax //ax的值传入es
seg003:000A assume es:seg001 //引用seg001的东西给es
seg003:000A mov si, 0
seg003:000D
seg003:000D loc_100DD: ; CODE XREF: start+38↓j
seg003:000D cmp si, 1Ch
seg003:0010 jz short loc_10135
seg003:0012 xor ax, ax //将ax寄存器清0
seg003:0014 mov al, [si] //al为低4位
seg003:0016 shl al, 1
seg003:0018 shl al, 1
seg003:001A shl al, 1
seg003:001C shl al, 1 //shl为左移指令 ,这里左移4次
seg003:001E push ax
seg003:001F xor ax, ax
seg003:0021 mov al, [si]
seg003:0023 shr al, 1
seg003:0025 shr al, 1
seg003:0027 shr al, 1
seg003:0029 shr al, 1 //shr为右移指令 , 这里右移4次
seg003:002B pop bx
seg003:002C add ax, bx
seg003:002E xor ax, 17h //将ax与17h进行异或处理
seg003:0031 add si, 1
seg003:0034 cmp al, es:[si-1]
seg003:0038 jz short loc_100DD
seg003:003A mov ax, 0B800h
seg003:003D mov es, ax
seg003:003F assume es:nothing
seg003:003F mov byte ptr es:0, 77h ; 'w'
seg003:0045 mov byte ptr es:2, 72h ; 'r'
seg003:004B mov byte ptr es:4, 6Fh ; 'o'
seg003:0051 mov byte ptr es:6, 6Eh ; 'n'
seg003:0057 mov byte ptr es:8, 67h ; 'g'
seg003:005D mov byte ptr es:0Ah, 21h ; '!'
seg003:0063
seg003:0063 loc_10133: ; CODE XREF: start:loc_10133↓j
seg003:0063 jmp short loc_10133
seg003:0065 ; ---------------------------------------------------------------------------
seg003:0065
seg003:0065 loc_10135: ; CODE XREF: start+10↑j
seg003:0065 mov ax, 0B800h
seg003:0068 mov es, ax
seg003:006A mov byte ptr es:0, 72h ; 'r'
seg003:0070 mov byte ptr es:2, 69h ; 'i'
seg003:0076 mov byte ptr es:4, 67h ; 'g'
seg003:007C mov byte ptr es:6, 68h ; 'h'
seg003:0082 mov byte ptr es:8, 74h ; 't'
seg003:0088 mov byte ptr es:0Ah, 21h ; '!'
seg003:008E
seg003:008E loc_1015E: ; CODE XREF: start:loc_1015E↓j
seg003:008E jmp short loc_1015E
seg003:008E start endp
seg003:008E
seg003:008E seg003 ends
seg003:008E
seg003:008E
seg003:008E end start

​ 它的逻辑是将输入的字符左移四位再右移四位再相加,然后再将每一位与0x17异或运算,如果每一位结果都等于seg001中的值对应相等就输出right,那么我们就逆着来写个脚本

#include<stdio.h>
int main()
{
int a[28] = {0x91,0x61,0x1,0xc1,0x41,0xa0,0x60,0x41,0xd1,0x21,0x14,0xc1,0x41,0xe2,0x50,0xe1,0xe2,0x54,0x20,0xc1,0xe2,0x60,0x14,0x30,0xd1,0x51,0xc0,0x17};
for(int i=0;i<28;i++)
{
a[i] = a[i] ^ 23;
}
for(int i=0;i<28;i++)
{
a[i] = (a[i]>>4)+ (a[i]<<4);
printf("%c",a[i]);

}
return 0;
}

这里要注意一个细节,就是在程序中,我们的值是先进行左移再进行右移的,所以我们在写脚本的时候要注意,要先右移再左移,这样的结果才是对的.

最后得到flag:hgame{welc0me_to_4sm_w0rld}