-
-
Notifications
You must be signed in to change notification settings - Fork 33
/
FlushMappedCacheBlock.asm
514 lines (491 loc) · 21.2 KB
/
FlushMappedCacheBlock.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
;/*** FLAT assembler source
;
; This is larger disassembly of VMM.VXD at file position 0x1eaf0
; main bug is in function "FlushMappedCacheBlock" at aprox. line 371
;
; after assembly binary size should be exactly 1040 bytes
; NOTE that after assembly with defined -Doriginalcode code isn't binary same as
; original code - thanks to Intel, x86 have multiple opcodes for same instruc-
; tion. On other hand thanks Intel to keep 8 and 16bit instructions so I could
; make enough space to inject modification of CR3 register.
;
; NOTE that some "symbols" are relocated and you'll need to modify relocation
; table in VMM.VXD if they're move. Define -Drelocate and compare binary to
; see if some of this symbols moved.
;
; Origin of this bug is described there:
; https://blog.stuffedcow.net/2015/08/pagewalk-coherence/
; and THIS bug is described there:
; https://blog.stuffedcow.net/2015/08/win9x-tlb-invalidation-bug/
; Big thanks to Henry Wong (www.stuffedcow.net) for discovered specific
; code sequence.
;
; Compilation: this file has to be preprocessed by CPP (C preprocessor).
; Example #1:
; preprocess:
; cpp -nostdinc -E -P FlushMappedCacheBlock.asm -o patched.gen
; compilation:
; fasm patched.gen patched.bin
;
; Example #2 (generate original code):
; cpp -nostdinc -E -P -Doriginalcode FlushMappedCacheBlock.asm -o patched.gen
; compilation:
; fasm patched.gen patched.bin
;
; variants: version_1: all vanilla 98/98 SE
; version_2: Q242161 (Win 98), Q288430 (Win 98 SE)
;
;
; ***/
use32
org 0xC0013070
#ifdef relocate
dptr equ not
#else
dptr equ 0+
#endif
#ifdef vmmbugfix1
#define dfunc(_ptr) _ptr
#else
#if defined(relocate) && !defined(nofuncrelocate)
#define dfunc(_ptr) not _ptr
#else
#define dfunc(_ptr) _ptr
#endif
#endif
func0:
push esi ; 56
push edi ; 57
mov esi,[esp+0xc] ; 8B74240C
mov dl,[esi+0x2] ; 8A5602
test dl,0x80 ; F6C280
jnz L0 ; 7505
sub eax,eax ; 2BC0
pop edi ; 5F
jmp short L1 ; EB42
L0:
mov eax,esi ; 8BC6
shr eax,byte 0xa ; C1E80A
xor eax,esi ; 33C6
and eax,0x1fe0 ; 25E01F0000
shr eax,byte 0x5 ; C1E805
lea edi,[eax*4+(dptr 0x15a98)] ; 8D3C85985A0100
mov eax,[edi] ; 8B07
L2:
cmp [eax+0x4],esi ; 397004
jz L3 ; 7406
mov edi,eax ; 8BF8
mov eax,[edi] ; 8B07
jmp short L2 ; EBF5
L3:
cmp dword [esp+0x10],0x0 ; 837C241000
jz L4 ; 7417
and dl,0x7f ; 80E27F
mov [esi+0x2],dl ; 885602
mov ecx,[eax] ; 8B08
mov [edi],ecx ; 890F
mov ecx,[dword (dptr 0x14f50)] ; 8B0D504F0100
dec ecx ; 49
mov [dword (dptr 0x14f50)],ecx ; 890D504F0100
L4:
pop edi ; 5F
L1:
pop esi ; 5E
ret 0x8 ; C20800
func1:
push esi ; 56
mov edx, (dptr 0x15a98) ; BA985A0100
mov ecx,[esp+0x8] ; 8B4C2408
L8:
mov esi,edx ; 8BF2
mov eax,[esi] ; 8B06
L7:
or eax,eax ; 0BC0
jz L5 ; 740B
cmp [eax+0x8],ecx ; 394808
jz L6 ; 7417
mov esi,eax ; 8BF0
mov eax,[esi] ; 8B06
jmp short L7 ; EBF1
L5:
add edx, 0x4 ; 83C204
cmp edx, (dptr 0x15e98) ; 81FA985E0100
jc L8 ; 72E2
sub eax,eax ; 2BC0
L9:
pop esi ; 5E
ret 0x8 ; C20800
L6:
cmp dword [esp+0xc],0x0 ; 837C240C00
jz L9 ; 74F5
mov ecx,[eax+0x4] ; 8B4804
and byte [ecx+0x2],0x7f ; 8061027F
mov edx,[eax] ; 8B10
mov [esi],edx ; 8916
mov ecx,[dword (dptr 0x14f50)] ; 8B0D504F0100
dec ecx ; 49
mov [dword (dptr 0x14f50)],ecx ; 890D504F0100
jmp short L9 ; EBDB
func2:
sub esp,0x8 ; 83EC08
push ebx ; 53
push esi ; 56
push edi ; 57
push ebp ; 55
mov eax,[esp+0x1c] ; 8B44241C
mov ebx,[eax+0x8] ; 8B5808
mov eax,[ebx+0x10] ; 8B4310
shr eax,byte 0xc ; C1E80C
lea ecx,[eax*4-0x800000] ; 8D0C85000080FF
mov ebp,[dword (dptr 0x14fa4)] ; 8B2DA44F0100
mov [esp+0x14],ecx ; 894C2414
mov ecx,[ecx] ; 8B09
shr ecx,byte 0xc ; C1E90C
imul ecx,ecx,0xd ; 6BC90D
add ebp,ecx ; 03E9
mov ecx,[ebp+0x0] ; 8B4D00
mov [esp+0x10],ecx ; 894C2410
test byte [ecx+0x3],0x8 ; F6410308
jz L10 ; 7429
cmp [dword (dptr 0x1507c)],ebp ; 392D7C500100
jnz L11 ; 750A
mov eax,[dptr 0x15ed0] ; A1D05E0100
mov [dptr 0x1507c],eax ; A37C500100
L11:
push ebp ; 55
call dfunc(0xc0005e7a) ; E80E2DFFFF
push ebx ; 53
call dfunc(0xc0008a28) ; E8B658FFFF
mov eax,[dptr 0x14f54] ; A1544F0100
inc eax ; 40
mov [dptr 0x14f54],eax ; A3544F0100
L10:
mov word [ebp+0x8],0xf188 ; 66C7450888F1
push dword [dword (dptr+0x15078)] ; FF3578500100
call dfunc(0xc0004210) ; E88210FFFF
mov esi,[esp+0x1c] ; 8B74241C
mov edi,eax ; 8BF8
add esi,0xc ; 83C60C
movsd ; A5
movsd ; A5
movsw ; 66A5
mov ecx,[esp+0x14] ; 8B4C2414
and dword [ecx],0xfffff7ff ; 8121FFF7FFFF
push ebx ; 53
mov [ebp+0x0],eax ; 894500
mov edx,[eax+0x6] ; 8B5006
mov eax,[esp+0x14] ; 8B442414
mov word [ebp+0xa],0x1 ; 66C7450A0100
mov [ebp+0x4],edx ; 895504
and byte [eax+0x3],0xe7 ; 806003E7
call dfunc(0xc0008a19) ; E85758FFFF
mov eax,[dptr 0x14f54] ; A1544F0100
push ebx ; 53
dec eax ; 48
mov [dptr 0x14f54],eax ; A3544F0100
call dfunc(0xc0008a46) ; E87358FFFF
push 0x0 ; 6A00
push dword [esp+0x20] ; FF742420
call dfunc(0xc00143dd) ; E8FF110000
pop ebp ; 5D
pop edi ; 5F
pop esi ; 5E
pop ebx ; 5B
add esp,0x8 ; 83C408
ret 0x4 ; C20400
_ReleaseMappedCacheBlock:
push ebx ; 53
push esi ; 56
push edi ; 57
push ebp ; 55
mov ebx,[dword (dptr 0x14f54)] ; 8B1D544F0100
mov edi,[dword (dptr 0x15f6c)] ; 8B3D6C5F0100
mov esi,ebx ; 8BF3
mov eax,edi ; 8BC7
imul eax,[dword (dptr 0x12718)] ; 0FAF0518270100
mov ebp,0x64 ; BD64000000
sub edx,edx ; 2BD2
div ebp ; F7F5
sub edi,eax ; 2BF8
cmp ebx,edi ; 3BDF
jna L12 ; 7611
L13:
push 0x0 ; 6A00
call dfunc(0xc0005f31) ; E8182DFFFF
mov ebx,[dword (dptr 0x14f54)] ; 8B1D544F0100
cmp ebx,edi ; 3BDF
ja L13 ; 77EF
L12:
sub ebx,esi ; 2BDE
pop ebp ; 5D
cmp ebx,0x1 ; 83FB01
pop edi ; 5F
sbb eax,eax ; 1BC0
pop esi ; 5E
inc eax ; 40
pop ebx ; 5B
ret ; C3
_FlushMappedCacheBlock:
sub esp,0x10 ; 83EC10
push ebx ; 53
push esi ; 56
push edi ; 57
push ebp ; 55
mov eax,[dptr 0x14f64] ; A1644F0100
mov esi,[esp+0x24] ; 8B742424
inc eax ; 40
mov [dptr 0x14f64],eax ; A3644F0100
mov eax,[dptr 0x14f6c] ; A16C4F0100
inc eax ; 40
mov [dptr 0x14f6c],eax ; A36C4F0100
L16:
push 0x0 ; 6A00
push esi ; 56
call func1 ; E870FEFFFF
mov ebp,eax ; 8BE8
or ebp,ebp ; 0BED
jz near L14 ; 0F84A6010000
mov ebx,[ebp+0x4] ; 8B5D04
push ebx ; 53
call dfunc(0xc0003e7c) ; E8100CFFFF
cmp eax,0x1 ; 83F801
sbb edi,edi ; 1BFF
neg edi ; F7DF
or edi,edi ; 0BFF
jz L15 ; 7415
push ebx ; 53
call dfunc(0xc0003e9d) ; E8200CFFFF
mov eax,[dptr 0x14f70] ; A1704F0100
inc eax ; 40
or edi,edi ; 0BFF
mov [dptr 0x14f70],eax ; A3704F0100
jnz L16 ; 75C5
L15:
push 0x1 ; 6A01
push ebx ; 53
call func0 ; E8DCFDFFFF
mov eax,[ebp+0x8] ; 8B4508
mov [esp+0x10],eax ; 89442410
mov edi,[eax+0x10] ; 8B7810
shr edi,byte 0xc ; C1EF0C
lea esi,[edi*4-0x800000] ; 8D34BD000080FF
mov eax,[esi] ; 8B06
mov [esp+0x14],eax ; 89442414
mov ecx,eax ; 8BC8
shr ecx,byte 0xc ; C1E90C
imul ecx,ecx, 0xd ; 6BC90D
mov eax,[dptr 0x14fa4] ; A1A44F0100
add eax,ecx ; 03C1
test byte [ebx+0x3],0x8 ; F6430308
mov [esp+0x18],eax ; 89442418
jz near L17 ; 0F8486000000
push dword [esp+0x10] ; FF742410
call dfunc(0xc0008a28) ; E85457FFFF
mov eax,[dptr 0x14f54] ; A1544F0100
inc eax ; 40
mov [dptr 0x14f54],eax ; A3544F0100
mov al,[ebx+0x2] ; 8A4302
and eax, 0x7f ; 83E07F
push dword [eax*4+(dptr 0x16080)] ; FF348580600100
push ebx ; 53
call dfunc(0xc00071be) ; E8CC3EFFFF
mov ecx,[esp+0x18] ; 8B4C2418
push ebp ; 55
mov esi,[ecx+0x4] ; 8B7104
call func2 ; E819FEFFFF
mov eax,[dptr 0x14f98] ; A1984F0100
inc eax ; 40
mov [dptr 0x14f98],eax ; A3984F0100
mov eax,[dptr 0x1622c] ; A12C620100
mov [eax*4+(dptr 0x161c4)],ebx ; 891C85C4610100
inc eax ; 40
mov [dptr 0x1622c],eax ; A32C620100
cmp eax, 0x1a ; 83F81A
jl L18 ; 7C0A
mov dword [dword (dptr 0x1622c)],0x00000 ; C7052C6201000000
L18:
and byte [ebx+0x3],0xe7 ; 806303E7
mov [ebx+0x6],esi ; 897306
push ebx ; 53
call dfunc(0xc0003e9d) ; E8650BFFFF
push dword [esp+0x10] ; FF742410
call dfunc(0xc0008a19) ; E8D856FFFF
mov eax,[dptr 0x14f54] ; A1544F0100
dec eax ; 48
mov [dptr 0x14f54],eax ; A3544F0100
jmp L14 ; E9B8000000
L17:
lea eax,[esp+0x1c] ; 8D44241C
push eax ; 50
push 0x1 ; 6A01
push edi ; 57
call dfunc(0xc00040e0) ; E8820DFFFF
sub eax,[dword (dptr 0x15f5c)] ; 2B055C5F0100
#ifdef vmmbugfix1
push 0xc ; 6a0c
pop ecx ; 59 ; +2
sub edx,edx ;
; arguments for procedure PageCommit (using 0 in edx = save 1 byte)
push 0x8 ; 6A08
push edx ; ; +1
div ecx ;
shl eax,cl ;
mov ecx,[esp+0x14] ; 8B4C2414
and ch,0x0f ; 80e50f ; +3
or ax,cx ; 6609c8 ; -1
mov [esi],eax ; 8906
and byte [esi+0x1],0xfd ; 806601f5 ; +3
and byte [esi+0x1],0xf7 ; 806601f7 ; +3
jmp skip_injected ; EBXX ; -2
load_ecx_edi:
xor ecx,ecx ; ; -2
mov ch,0x4 ; ; -2
mov edi,[eax+0x10] ; 8B7810 ; -3
jmp load_ecx_edi_back ; ; -2
skip_injected:
call dfunc(0xc0003ef0) ; E8600BFFFF
#else
mov ecx,0xc ; B90C000000
sub edx,edx ; 2BD2
div ecx ; F7F1
shl eax,cl ; D3E0
mov ecx,[esp+0x14] ; 8B4C2414
#ifdef originalcode
and ecx,0xfff ; 81E1FF0F0000
or eax,ecx ; 0BC1
mov [esi],eax ; 8906
and eax,0xfffffdff ; 25FFFDFFFF
mov [esi],eax ; 8906
and eax,0xfffff7ff ; 25FFF7FFFF
; code length = 22 bytes
#else
and ch,0x0f ; 80e50f
or ax,cx ; 6609c8
and ah,0xf5 ; 80e4f5
; code length = 9 bytes (13 bytes saved)
#endif
mov [esi],eax ; 8906
#ifndef originalcode
jmp skip_injected ; eb0b
flushtable:
mov ecx,cr3 ; 0f20d9
mov cr3,ecx ; 0f22d9
nop ; 90
xor ecx,ecx ; 31c9
jmp flushtable_back ; ebxx
skip_injected:
; code length = 12 bytes (+1 byte padded with NOP)
#endif
call dfunc(0xc0003ef0) ; E8600BFFFF
push 0x8 ; 6A08
push 0x0 ; 6A00
#endif
push 0x3 ; 6A03
push 0x1 ; 6A01
push edi ; 57
call dfunc(0xbffe1420) ; E882E0FCFF (_PageCommit)
add esp, 0x14 ; 83C414
#if defined(version_2)
dec dword [dword (dptr 0x126f8)] ; FF0DF8260100
dec dword [dword (dptr 0x12658)] ; FF0D58260100
#endif
mov ecx,0xd ; B90D000000
mov eax,[ebx+0x6] ; 8B4306
sub edx,edx ; 2BD2
sub eax,[dword (dptr 0x14fa4)] ; 2B05A44F0100
div ecx ; F7F1
shl eax,byte 0xc ; C1E00C
mov ecx,[dword (dptr 0x15098)] ; 8B0D98500100
mov edx,[ecx] ; 8B11
xor edx,eax ; 33D0
and edx,0xfff ; 81E2FF0F0000
xor edx,eax ; 33D0
mov eax,[esp+0x10] ; 8B442410
mov [ecx],edx ; 8911
; TLB BUG here, needs to insert something like this:
; mov eax,cr3
; mov cr3,eax
#ifdef vmmbugfix1
call flushtable ; -5
jmp load_ecx_edi ; -2
nop
load_ecx_edi_back:
#else
#ifdef originalcode
mov ecx,0x400 ; B900040000
; ^ could be writen as "XOR ECX, ECX \n MOV CH, 0x4"
; which is one byte shorter and is splitten between
; two short instructions
; code length = 5 bytes
#else
jmp flushtable ; ebxx
nop ; 90
flushtable_back:
mov ch,0x4 ; b504
; code length = 4 bytes (+1 byte padded with NOP)
#endif
mov edi,[eax+0x10] ; 8B7810
#endif
mov esi,[dword (dptr 0x16178)] ; 8B3578610100
rep movsd ; F3A5
push dword [esp+0x10] ; FF742410
call dfunc(0xc0008a19) ; E83256FFFF
mov eax,[dptr 0x14f54] ; A1544F0100
push dword [esp+0x10] ; FF742410
dec eax ; 48
mov [dptr 0x14f54],eax ; A3544F0100
call dfunc(0xc0008a46) ; E84B56FFFF
push ebx ; 53
call dfunc(0xc0003e9d) ; E89C0AFFFF
push 0x0 ; 6A00
push ebp ; 55
call dfunc(0xc00143dd) ; E8D40F0000
L14:
mov eax,[dptr 0x14f64] ; A1644F0100
pop ebp ; 5D
dec eax ; 48
pop edi ; 5F
mov [dptr 0x14f64],eax ; A3644F0100
pop esi ; 5E
pop ebx ; 5B
add esp, 0x10 ; 83C410
ret ; C3
func3:
push ebx ; 53
push esi ; 56
mov ecx,0x2 ; B902000000
call dfunc(0xc000bac1) ; E89986FFFF
mov bl,al ; 8AD8
push 0x0 ; 6A00
push 0x0 ; 6A00
push 0x0 ; 6A00
push 0x1e ; 6A1E
call dfunc(0xc0014824) ; E8ED130000
mov esi,eax ; 8BF0
mov ecx,ebx ; 8BCB
call dfunc(0xc000bae6) ; E8A686FFFF
mov eax,[esp+0xc] ; 8B44240C
mov [esi+0x4],eax ; 894604
mov ecx,eax ; 8BC8
shr ecx,byte 0xa ; C1E90A
xor ecx,eax ; 33C8
and ecx,0x1fe0 ; 81E1E01F0000
shr ecx,byte 0x5 ; C1E905
mov eax,[ecx*4+(dptr 0x15a98)] ; 8B048D985A0100
mov [esi],eax ; 8906
mov eax,[dptr 0x14f50] ; A1504F0100
mov [ecx*4+(dptr 0x15a98)],esi ; 89348D985A0100
inc eax ; 40
mov [dptr 0x14f50],eax ; A3504F0100
mov eax,esi ; 8BC6
pop esi ; 5E
pop ebx ; 5B
ret 0x4 ; C20400
#ifdef vmmbugfix1
flushtable:
mov ecx,cr3 ; -3
mov cr3,ecx ; -3
ret ; -1
#else
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00
#endif