From b08165db20e051092792cb99495fbfb442c10239 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 5 Sep 2017 19:10:58 -0500 Subject: [PATCH] Updated Maintaining OOVPA's for HLE function detection (markdown) --- ...ning-OOVPA's-for-HLE-function-detection.md | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/Maintaining-OOVPA's-for-HLE-function-detection.md b/Maintaining-OOVPA's-for-HLE-function-detection.md index d238319..3cc8763 100644 --- a/Maintaining-OOVPA's-for-HLE-function-detection.md +++ b/Maintaining-OOVPA's-for-HLE-function-detection.md @@ -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`) \ No newline at end of file +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; +```