mov esi,
0xbf9f2758
; 第二个操作数为real_key
fcmovu st5 ; 目的是将FPUDataPointer填充到上述结构体. (执行任意fpu指令都可达到此目的)
fnstenv [esp
-
0xc
] ; 把FpuSaveState结构体保存到栈上的esp
-
0xC
处, 则栈顶会保存FPUDataPointer, 即上面fcmovu指令的地址
pop ebx ;
sub ecx,ecx ; ecx置零, 作为循环计数器
mov cl,
0x4b
; 偏移
0x10
, 循环体的开始处
xor [ebx
+
0x12
],esi ;
0x12
即是上面fcmovu指令的地址到这段存根的下一个字节的地址的距离, 所以这条指令即是对编码部分的前
4
个字节开始解码
add ebx,byte
+
0x4
db
0x03
; 这段存根少了loop指令, 会在上面xor后还原出来, 如下:
; add esi, [ebx
+
0x12
] ; 原始数据和第一个key相加, 得到下一个key
; loop
0x10
; 机器码是\xe2\xf5, \xf5应该是表示从loop指令的下一条指令的地址开始减去
11
, 得到的地址即为循环头部