-
Notifications
You must be signed in to change notification settings - Fork 0
/
patch.asm
156 lines (120 loc) · 3.11 KB
/
patch.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
bits 32
%macro CODE_START 0
pushfd ; save the flags
push ebp ; save
mov ebp, esp ; the stack ptr current state
; save the registers
push eax
push ebx
push ecx
push edx
push ebp
push esp
push esi
push edi
%endmacro
%macro CODE_END 0
; restore the registers
pop edi
pop esi
pop esp
pop ebp
pop edx
pop ecx
pop ebx
pop eax
; restore stack ptr
mov esp, ebp
pop ebp
popfd ; restore the flags
%endmacro
%define WORD 0x2
%define DWORD 0x4
; The starting memory is a free accessible memory space somewhere in the .data segment,
; we use this some kinda storage, because working with the heap in this case just a
; pain in the ass, therefore we use a CURSOR macro with others macros to increment and keep
; track of the value of it.
%define START_MEM 0x10A29429
%define CURSOR START_MEM ; free, accesible pointer in FSW.dll
%macro __IncrementCursor 1
%assign CURSOR CURSOR+%1
%endmacro
%define IncrementCursor(__size) __IncrementCursor __size
%macro var 2-3 ; var_name, var_size_in_bytes; init_value (optional)
%assign %1 CURSOR
IncrementCursor(%2)
%ifnempty %3
mov dword ds:[%1], %3
%endif
%endmacro
%define ASSERT() mov dword ds:[0x0], 0xFFFFF
; ////////////////////////////////////////////
; Simulating PrimaryBuffer->QueryInterace(REFID, (LPVOID*)&LPDIRECTSOUNDBUFFER8)
; 0x105F836A our start address
; where we're coming from
%define ComingFromAddress 0x102E74AF
%define ArgumentCount 0x3 ; +0x1, because of the *PrimaryBuffer
%define DirectSound 0x10747EA0
%define PrimaryBuffer 0x10747EA4
%define GlobalSecondaryBuffer 0x10747EAC
CODE_START
mov ecx, dword ds:[DirectSound]
and ecx, dword ds:[PrimaryBuffer]
jz _out ; at this point the directsound and the primarybuffer is not initialized yet
and ecx, dword ds:[GlobalSecondaryBuffer]
jnz _out ; initialized once already!
; Make some space for the comparison as you can see above,
; basically just skipping (reserve) the first 4 byte
IncrementCursor(DWORD)
; Prepare to call the CreateSoundBuffer
var HRESULT, DWORD, 0
var wFormatTag, WORD, 0x1 ; WAVE_FORMAT_PCM
var nChannels, WORD, 0x2
var nSamplesPerSec, DWORD, 48000
var nAvgBytesPerSec, DWORD, 192000
var nBlockAlign, WORD, 4
var wBitsPerSample, WORD, 16
var cbSize, WORD, 0
%define WaveFormat wFormatTag
var dwSize, DWORD, 0x24
var dwFlags, DWORD, 0x00010000 ; DSBCAPS_GETCURRENTPOSITION2
var dwBufferBytes, DWORD, 192000
var dwReserved, DWORD, 0
var lpwfxFormat, DWORD, WaveFormat
var _GUID, (0x24-(CURSOR-dwSize)), 0x0
%define BufferDescription dwSize
; DirectSound->CreateSoundBuffer(...)
_create_sound_buffer:
push 0
push GlobalSecondaryBuffer
push BufferDescription
mov ecx, dword ds:[DirectSound]
push ecx
mov ecx, [ecx]
call [ecx+0x0c]
mov dword ds:[HRESULT], eax
cmp eax, 0x0
je _play
int3
ASSERT()
; GlobalSecondaryBuffer->Play()
_play:
push 0x1 ; DSBPLAY_LOOPING
push 0x0
push 0x0
mov ecx, dword ds:[GlobalSecondaryBuffer]
push ecx
mov ecx, [ecx]
call [ecx+0x30]
mov dword ds:[HRESULT], eax
cmp eax, 0x0
je _done
int3
ASSERT()
_done:
mov dword ds:[START_MEM], 0x1 ; see above
_out:
CODE_END
; iyhh
mov eax, dword ds:[HRESULT]
ret (ArgumentCount * DWORD)