Updated Maintaining OOVPA's for HLE function detection (markdown)

RadWolfie 2017-09-05 19:10:58 -05:00
parent abeddaf536
commit b08165db20
1 changed files with 76 additions and 1 deletions

@ -1,3 +1,5 @@
[Go to TLDR section](#too-long-didnt-read)
# Introduction
Cxbx in it's current form, uses HLE (High Level Emulation). This roughly means, that code in an XBE ("XB"ox "E"xecutable) is executed as-is. However, any code that accesses Xbox hardware registers will cause problems, since this hardware is not present in the host system running Cxbx.
@ -43,4 +45,77 @@ An OOVPA is formed by choosing a few offsets in the machine code of that functio
The function an OOVPA scans for can be different between library versions. To get reliable emulation, Cxbx needs to contain unique OOVPA definitions that will match all existing versions of a function.
Sometimes, after a function changed in one version, it changes once more in another, later version. In some rare cases, a function might even re-appear in a prior form! In this case, the OOVPA for that re-appearance must not be copied over from an earlier version, but instead an alias must be registered. (Aliases are simply `#define function_new_version function_old_version`)
Sometimes, after a function changed in one version, it changes once more in another, later version. In some rare cases, a function might even re-appear in a prior form! In this case, the OOVPA for that re-appearance must not be copied over from an earlier version, but instead an alias must be registered. (Aliases are simply `#define function_new_version function_old_version`)
# Too Long, Didn't Read
To keep things simple.
- OOVPA_NO_XREF, since a signature is not requiring a reference to another OOVPA. However going down this path will give you a chance of false detection. It is recommend to keep it above 10 or 12 unique offset values. You can use the following method below.
```c
OOVPA_NO_XREF(/*Name of a function or address*/, /*XDK version*/,/*Total of "offset, value" array*/)
// { Offset, opcode value },
OOVPA_END;
```
For example
```c
OOVPA_NO_XREF(DirectSoundCreate, 3936, 10)
// DirectSoundCreate+0x23 : add eax, 8
{ 0x23, 0x83 },
{ 0x24, 0xC0 },
{ 0x25, 0x08 },
// DirectSoundCreate+0x34 : push 0x1C
{ 0x34, 0x6A },
{ 0x35, 0x1C },
// DirectSoundCreate+0x75 : sbb eax, eax
{ 0x75, 0x1B },
{ 0x76, 0xC0 },
// DirectSoundCreate+0x9B : retn 0x0C
{ 0x9B, 0xC2 },
{ 0x9C, 0x0C },
{ 0x9D, 0x00 },
OOVPA_END;
```
- OOVPA_XREF, doing this method will greatly decrease false detection over time. Plus ability to support earlier and later XDK builds. Unless something has changed over several XDK builds later.
```c
OOVPA_XREF(/*Name of a function or address*/, /*XDK version*/,/*Total of "offset, value" array*/,
/*Name of this OOVPA reference, see XRefDataBaseOffset enum for usage.*/,
/*Total of "XREF_ENTRY" used at the very top usage only. It cannot be in random location or will screw up the scan method you expect it to do.*/)
// { Offset, XRefDataBaseOffset value },
//...
// { Offset, opcode value },
//...
OOVPA_END;
```
For example
```c
OOVPA_XREF(CDirectSoundBuffer_GetStatus, 3936, 10,
XREF_CDirectSoundBuffer_GetStatus,
XRefOne)
// CDirectSoundBuffer_GetStatus+0x14 : call [CMcpxBuffer::GetStatus]
XREF_ENTRY( 0x15, XREF_CMcpxBuffer_GetStatus),
// CDirectSoundBuffer_GetStatus+0x07 : push [esp+0x10]
{ 0x07, 0xFF },
{ 0x08, 0x74 },
{ 0x09, 0x24 },
{ 0x0A, 0x10 },
// CDirectSoundBuffer_GetStatus+0x11 : mov ecx, [eax+0x20]
{ 0x11, 0x8B },
{ 0x12, 0x48 },
{ 0x13, 0x20 },
// CDirectSoundBuffer_GetStatus+0x2E : retn 0x08
{ 0x2E, 0xC2 },
{ 0x2F, 0x08 },
{ 0x30, 0x00 },
OOVPA_END;
```