VOGONS


The Soundblaster DSP project

Topic actions

Reply 160 of 1053, by georgel

User metadata
Rank Member
Rank
Member
Maelgrum wrote on 2023-09-25, 12:49:
I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in productio […]
Show full quote

I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in production.
But from user point of view severity is low - it depends on many factors.
First of all - software (game) must send commands to SB. And this commands must be vulnerable (dependant on flags in codeflow).
Not all commands are vulnerable.
Game that uses auto-init DMA can send no commands at all after init (and during init things are safe - no interrupts are triggered).
And occurence of this bug depends on timings.
So dont expect from this patch something noticeable - you need combination of many factors for bug to occure.

To tell what this affects is much more difficult (not fully possible) than to correct it. Probably it can correct the "DMA clicking" mentioned above. The programmers/designers were not lame, you still cannot fully understand their code, they made millions of $$$ back then. I guess they were more used to x86 code where interrupt mechanism by default saves and restores the flags register.

Reply 161 of 1053, by maxtherabbit

User metadata
Rank l33t
Rank
l33t
Maelgrum wrote on 2023-09-25, 12:49:
I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in productio […]
Show full quote

I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in production.
But from user point of view severity is low - it depends on many factors.
First of all - software (game) must send commands to SB. And this commands must be vulnerable (dependant on flags in codeflow).
Not all commands are vulnerable.
Game that uses auto-init DMA can send no commands at all after init (and during init things are safe - no interrupts are triggered).
And occurence of this bug depends on timings.
So dont expect from this patch something noticeable - you need combination of many factors for bug to occure.

What about single cycle DMA...

Reply 162 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member
maxtherabbit wrote on 2023-09-25, 13:12:
Maelgrum wrote on 2023-09-25, 12:49:
I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in productio […]
Show full quote

I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in production.
But from user point of view severity is low - it depends on many factors.
First of all - software (game) must send commands to SB. And this commands must be vulnerable (dependant on flags in codeflow).
Not all commands are vulnerable.
Game that uses auto-init DMA can send no commands at all after init (and during init things are safe - no interrupts are triggered).
And occurence of this bug depends on timings.
So dont expect from this patch something noticeable - you need combination of many factors for bug to occure.

What about single cycle DMA...

From this piece of code, Single cycle DMA (cmd 0x14) codepath is vulnerable to PSW bug :
X0af1: jnb p2.4,X0b08
mov r0,#9
mov a,37h
cjne a,#5ah,X0afe
ljmp X0b00
X0afe: jnc X0b05
X0b00: setb p2.5
ljmp X0b07
X0b05: clr p2.5
X0b07: movx @r0,a
X0b08: ret

But it depends on state of p2.4 pin, and effects of wrong setting of p2.5 is unknown.

Reply 163 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member
georgel wrote on 2023-09-25, 13:09:

The programmers/designers were not lame, you still cannot fully understand their code, they made millions of $$$ back then. I guess they were more used to x86 code where interrupt mechanism by default saves and restores the flags register.

They can have millions of $$$, but don't bother to hire even ONE experienced programmer.
No one bothered to look though code.
Change register in interrupt handler before pushing to stack - no problem.
Forget to push psw in interrupt handler - no problem.
Write a wrong samplerate calculation routine (bug what seen immediately then i try to analize this routine) - no problem.
This is not complex, elaborate bugs, deeply hidden in code - its obvious bugs.
And this bugs lives in fw for years - no problem.

Reply 164 of 1053, by georgel

User metadata
Rank Member
Rank
Member
Maelgrum wrote on 2023-09-25, 14:02:
They can have millions of $$$, but don't bother to hire even ONE experienced programmer. No one bothered to look though code. Ch […]
Show full quote
georgel wrote on 2023-09-25, 13:09:

The programmers/designers were not lame, you still cannot fully understand their code, they made millions of $$$ back then. I guess they were more used to x86 code where interrupt mechanism by default saves and restores the flags register.

They can have millions of $$$, but don't bother to hire even ONE experienced programmer.
No one bothered to look though code.
Change register in interrupt handler before pushing to stack - no problem.
Forget to push psw in interrupt handler - no problem.
Write a wrong samplerate calculation routine (bug what seen immediately then i try to analize this routine) - no problem.
This is not complex, elaborate bugs, deeply hidden in code - its obvious bugs.
And this bugs lives in fw for years - no problem.

This firmware was huge part of their copy protection. The less people know the secret, the less the chances of leakage. 😉 Bugs are just nuisance. Bugs "lived for years" that means Creative did their job well enough.

Reply 165 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member
georgel wrote on 2023-09-25, 14:16:

This firmware was huge part of their copy protection. The less people know the secret, the less the chances of leakage. 😉 Bugs are just nuisance. Bugs "lived for years" that means Creative did their job well enough.

Sensitive parts of code can be removed before code review.

How many cards they sell with hanging note bug ?
Nice marketing, poor tech.

Last edited by Maelgrum on 2023-09-25, 14:30. Edited 1 time in total.

Reply 166 of 1053, by Gmlb256

User metadata
Rank l33t
Rank
l33t
Maelgrum wrote on 2023-09-25, 14:02:
They can have millions of $$$, but don't bother to hire even ONE experienced programmer. No one bothered to look though code. Ch […]
Show full quote

They can have millions of $$$, but don't bother to hire even ONE experienced programmer.
No one bothered to look though code.
Change register in interrupt handler before pushing to stack - no problem.
Forget to push psw in interrupt handler - no problem.
Write a wrong samplerate calculation routine (bug what seen immediately then i try to analize this routine) - no problem.
This is not complex, elaborate bugs, deeply hidden in code - its obvious bugs.
And this bugs lives in fw for years - no problem.

I think that the "geniuses" at Creative didn't allot enough time to perform verification and validation on their DSP v4.xx code. 🤣

VIA C3 Nehemiah 1.2A @ 1.46 GHz | ASUS P2-99 | 256 MB PC133 SDRAM | GeForce3 Ti 200 64 MB | Voodoo2 12 MB | SBLive! | AWE64 | SBPro2 | GUS

Reply 167 of 1053, by georgel

User metadata
Rank Member
Rank
Member
Gmlb256 wrote on 2023-09-25, 14:29:

I think that the "geniuses" at Creative didn't allot enough time to perform verification and validation on their DSP v4.xx code. 🤣

Actually they seem to corrected bugs in V4.16 which they used on cards integrated 8051s from which firmware dumping was and even today is much more difficult. They knew their firmware was leaking so I guess were reluctant to correct it on cards with discrete 8051s. They had ongoing lawsuits everything was rapidly emerging on the market for just a couple of years, they fought to be afloat. The software for their cards was also emerging so the bugs were hard to be revealed fast. Imagine there was no internet or web sites/forums like today. The development tools were not as advanced as today's are. I can also mock on contemporary buggy android and other fatware but I am not doing it.
Still asking for confirmation if this leaked V4.13 firmware is capable of generating NMIs , e.g. to successfully work with AWEUTIL for DOS as AWE MIDI synthesizer.

Reply 168 of 1053, by Gmlb256

User metadata
Rank l33t
Rank
l33t
georgel wrote on 2023-09-25, 17:01:
Gmlb256 wrote on 2023-09-25, 14:29:

I think that the "geniuses" at Creative didn't allot enough time to perform verification and validation on their DSP v4.xx code. 🤣

Actually they seem to corrected bugs in V4.16 which they used on cards integrated 8051s from which firmware dumping was and even today is much more difficult. They knew their firmware was leaking so I guess were reluctant to correct it on cards with discrete 8051s. They had ongoing lawsuits everything was rapidly emerging on the market for just a couple of years, they fought to be afloat. The software for their cards was also emerging so the bugs were hard to be revealed fast. Imagine there was no internet or web sites/forums like today. The development tools were not as advanced as today's are. I can also mock on contemporary buggy android and other fatware but I am not doing it.
Still asking for confirmation if this leaked V4.13 firmware is capable of generating NMIs , e.g. to successfully work with AWEUTIL for DOS as AWE MIDI synthesizer.

Yes, they have corrected most of the issues with DSP v4.16.

Still, the development tools at the time doesn't excuse Creative for the sloppy code they left with older DSP versions based on v4.xx and should have offered an option for affected owners.

VIA C3 Nehemiah 1.2A @ 1.46 GHz | ASUS P2-99 | 256 MB PC133 SDRAM | GeForce3 Ti 200 64 MB | Voodoo2 12 MB | SBLive! | AWE64 | SBPro2 | GUS

Reply 169 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member

Thinking on matter of dumping DSP v4.16, i have some ideas:
1. We have a command to read or write into internal DSP memory. But this memory is all registers and stack pointer.
2. Any subroutine (or interrupt handler) what writes to memory at fixed address and afterwards returns by RET/RETI can be used to divert execution flow. And by step 1 we can set SP to any value, just before written byte.
One of the most useful subroutines is recieving MIDI IN byte:
mov @r1,a
inc r1
dec r4
cjne r1,#0c0h,X0c85
mov r1,#40h
ret
we can set R1 to point to return address in stack, create hardware loopback from midi out to midi in, send byte to midi out, and on recieving it modifies return adress to needed value, high byte or low byte of PC.

3. If we divert execution flow to middle of interupt handler, at the end of each handler we have following code:
pop rb0r0
pop dph
pop dpl
pop acc
reti
so all registers will be filled with values what can be previously prepared in stack.
Most important is DPTR and return address, which can be arbitrarily set.
Such returns from interrupt are numerous, so we have many attack points.
4. Then we can divert execution flow to code what reads byte pointed by DPTR from code memory and sends it to PC. Two perfect functions exists - read DSP version and read copyright commands.
5. Repeat for all bytes of ROM. We're done ))

PS. This technique can be used to dump all 4.XX fw in universal dumper

Reply 170 of 1053, by georgel

User metadata
Rank Member
Rank
Member
Maelgrum wrote on 2023-09-25, 17:58:
Thinking on matter of dumping DSP v4.16, i have some ideas: 1. We have a command to read or write into internal DSP memory. But […]
Show full quote

Thinking on matter of dumping DSP v4.16, i have some ideas:
1. We have a command to read or write into internal DSP memory. But this memory is all registers and stack pointer.
2. Any subroutine (or interrupt handler) what writes to memory at fixed address and afterwards returns by RET/RETI can be used to divert execution flow. And by step 1 we can set SP to any value, just before written byte.
One of the most useful subroutines is recieving MIDI IN byte:
mov @r1,a
inc r1
dec r4
cjne r1,#0c0h,X0c85
mov r1,#40h
ret
we can set R1 to point to return address in stack, create hardware loopback from midi out to midi in, send byte to midi out, and on recieving it modifies return adress to needed value, high byte or low byte of PC.

3. If we divert execution flow to middle of interupt handler, at the end of each handler we have following code:
pop rb0r0
pop dph
pop dpl
pop acc
reti
so all registers will be filled with values what can be previously prepared in stack.
Most important is DPTR and return address, which can be arbitrarily set.
Such returns from interrupt are numerous, so we have many attack points.
4. Then we can divert execution flow to code what reads byte pointed by DPTR from code memory and sends it to PC. Two perfect functions exists - read DSP version and read copyright commands.
5. Repeat for all bytes of ROM. We're done ))

PS. This technique can be used to dump all 4.XX fw in universal dumper

As far as I understand your approach the program execution must be diverted to locations with known program code in order to dump unknown program code. Isn't that controversial?

Reply 171 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member
georgel wrote on 2023-09-25, 21:03:

As far as I understand your approach the program execution must be diverted to locations with known program code in order to dump unknown program code. Isn't that controversial?

Not at all. Because you can try all 8192 addresses until you address guess is right. It's only matter of time.
You MUST see at location 0x0000 first byte of LJMP.
And in locations of interrupt vector handlers you must see LJMP.
And so on.
If it is not - you can try other address of DSP version command.
Address is unknown, but you can search it, and validate results.

Reply 172 of 1053, by georgel

User metadata
Rank Member
Rank
Member
Maelgrum wrote on 2023-09-25, 21:38:
Not at all. Because you can try all 8192 addresses until you address guess is right. It's only matter of time. You MUST see at […]
Show full quote
georgel wrote on 2023-09-25, 21:03:

As far as I understand your approach the program execution must be diverted to locations with known program code in order to dump unknown program code. Isn't that controversial?

Not at all. Because you can try all 8192 addresses until you address guess is right. It's only matter of time.
You MUST see at location 0x0000 first byte of LJMP.
And in locations of interrupt vector handlers you must see LJMP.
And so on.
If it is not - you can try other address of DSP version command.
Address is unknown, but you can search it, and validate results.

What would be the results that you intend to validate? How will you reset the 8051 after each bad jump? How will you "see"?

Reply 173 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member

Number of variants is small - it's less then 5*8192. High byte of return address of first inject is 0..4 (on 4.13 this range gives 4 hits in a middle of interrupt handler). And at most 8192 guessing of right DSP version command address.
It's matter of time.

Reply 174 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member
georgel wrote on 2023-09-25, 22:00:

What would be the results that you intend to validate? How will you reset the 8051 after each bad jump? How will you "see"?

See - in sound blaster data port.
If you execute DSP version command, where you see result?))
Reset - by sound blaster reset port. It's resets 8051.
Validate - by knowing what must be on addresses of interrupt handlers.

Reply 176 of 1053, by Maelgrum

User metadata
Rank Member
Rank
Member
georgel wrote on 2023-09-25, 22:49:

First try if you can make it jump to a known address in a known firmware by the undocumented RAM/pushed SP modification.

With Midi out to midi in loop back you don't even need to modify SP, just R1.
But of course, it much easier to try on known firmware, as proof of concept.
It just looks to me as viable attack path.

Reply 177 of 1053, by maxtherabbit

User metadata
Rank l33t
Rank
l33t
Maelgrum wrote on 2023-09-25, 13:42:
From this piece of code, Single cycle DMA (cmd 0x14) codepath is vulnerable to PSW bug : X0af1: jnb p2.4,X0b08 mov r0,#9 mov a […]
Show full quote
maxtherabbit wrote on 2023-09-25, 13:12:
Maelgrum wrote on 2023-09-25, 12:49:
I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in productio […]
Show full quote

I must tell that from programmers point of view severity of this bug is huge - it is totally lame code, not allowed in production.
But from user point of view severity is low - it depends on many factors.
First of all - software (game) must send commands to SB. And this commands must be vulnerable (dependant on flags in codeflow).
Not all commands are vulnerable.
Game that uses auto-init DMA can send no commands at all after init (and during init things are safe - no interrupts are triggered).
And occurence of this bug depends on timings.
So dont expect from this patch something noticeable - you need combination of many factors for bug to occure.

What about single cycle DMA...

From this piece of code, Single cycle DMA (cmd 0x14) codepath is vulnerable to PSW bug :
X0af1: jnb p2.4,X0b08
mov r0,#9
mov a,37h
cjne a,#5ah,X0afe
ljmp X0b00
X0afe: jnc X0b05
X0b00: setb p2.5
ljmp X0b07
X0b05: clr p2.5
X0b07: movx @r0,a
X0b08: ret

But it depends on state of p2.4 pin, and effects of wrong setting of p2.5 is unknown.

If you care to patch a version with the spaghetti jumps to test what correcting this does, I'll be happy to test it out. The potential of fixing the single cycle DMA clicking is even more appealing to me than the hanging notes.

Reply 178 of 1053, by SaxxonPike

User metadata
Rank Member
Rank
Member
maxtherabbit wrote on 2023-09-23, 22:46:

One thing that doesn't work on CT1747 based cards with DSP 4.05 is ADPCM (duke2)

The digital sound driver in Master of Magic also causes the game to hang briefly after every sound effect using DSP 4.05 on CT1747 based cards.

Sound device guides:
Sound Blaster
Aztech
OPL3-SA

Reply 179 of 1053, by maxtherabbit

User metadata
Rank l33t
Rank
l33t

If no one else has a socketed AWE32, I've got a CT2760 I can socket the 8051 on and try the patched code for NMI compatibility. Will be a couple weeks before I get around to pulling that system on to the bench though.