你真的是大学生吗
一道8086逆向题的分析
![[DOSBox_icon.png]]
你是冤种大学生吗?
难度:easy
出题人:@dev1l
源文件{:download="______.EXE"}
扔进DIE(Detect It Easy)里
操作系统: MS-DOS(-)[8086, 16 位, EXE]
扔进IDA x32,分析程序
lea dx, unk_10000 ; Load Effective Address
mov ah, 9
int 21h ; DOS - PRINT STRING
; DS:DX -> string terminated by "$"
dseg:0000 unk_10000 db 0Dh ; DATA XREF: start+5↓o
dseg:0001 db 0Ah
dseg:0002 db 69h ; i
dseg:0003 db 6Eh ; n
dseg:0004 db 70h ; p
dseg:0005 db 75h ; u
dseg:0006 db 74h ; t
dseg:0007 db 20h
dseg:0008 db 73h ; s
dseg:0009 db 74h ; t
dseg:000A db 72h ; r
dseg:000B db 69h ; i
dseg:000C db 6Eh ; n
dseg:000D db 67h ; g
dseg:000E db 3Ah ; :
dseg:000F db 24h ; $
0x0D 0x0A
是Windows的换行符,相当于\r\n
,
小知识#
- 0x0D - \r 是“回车符” carriage return (CR)
- 0x0A - \n 是“换行符” line feed (LF)
回车按键包含两个操作,字车归位,然后换行。
对应的计算机文本中的两个转义字符分别是\r和\n ,
对应它们的缩写(Carriage Return (CR)和Line Feed (LF)),合起来叫换行符。
Windows中是
\r\n
,Mac或者类Unix是\n
,老Mac是\r
8086中的字符串以 $
结尾,IDA中按 A 自动转换成字符串
这里是传递字符串首字符地址给dx,然后调用系统的PRINT函数(21h号中断,9号子函数)
lea dx, unk_1002D ; Load Effective Address
mov ah, 0Ah
int 21h ; DOS - BUFFERED KEYBOARD INPUT
; DS:DX -> buffer
unk_1002D db 15h
经过Debug,这里的执行流程如下
- 读取 [dx],作为缓冲区最大值
- 这里是15h,即最大输入14h个字符,最后一个字符需要保留——
\r
- 这里是15h,即最大输入14h个字符,最后一个字符需要保留——
- 获取用户字符,以 [dx+2] 为起点存字符串,直到回车(即
\r
)- 每收到一个按键都会放入缓冲区
- 字符串长度存到了 [dx+1]
小知识#
退格按键看起来删掉了字符,实际上缓冲区中的内容并没变
例如:输入11111,然后退格全删掉,再输入222,再删掉,再输入3和回车,最后缓冲区数据为:
33,0D,32,31,31 | 3.211
lea dx, asc_10010
mov ah, 9
int 21h
打印换行符
之后的代码逐步分析就OK,有几个需要注意的点
到底跳不跳转?#
cmp al, bl ; Compare Two Operands
jnz short loc_100AA ; Jump if (Result is) Not Zero (ZF=0)
这里 CMP 相当于 al-bl
,如果结果为0,就把ZF(Zero Flag,零标志位)置1
所以这里是不相等跳转
这是什么算法#
loc_1007C:
sub si, 1 ; Integer Subtraction
xor [si], al ; Logical Exclusive OR
mov al, [si]
dec cx ; Decrement by 1
cmp cx, 0 ; Compare Two Operands
jnz short loc_1007C ; Jump if Not Zero (ZF=0)
简单的异或运算,在纸上写几下就可以知道逆向算法是什么了
EXP#
# 加密后的数据
enc = [0x76,0x0E,0x77,0x14,0x60,0x06,0x7D,0x04,0x6B,0x1E,0x41,0x2A,0x44,0x2B,0x5C,0x03,0x3B,0x0B,0x33,0x05]
result = [0] * len(enc)
for i in range(len(enc) - 1):
result[i] = enc[i] ^ enc[i+1]
result[len(enc) - 1] = result[0] ^ enc[len(enc) - 1]
r = ''
for v in result:
r += chr(v)
print(r)