Merge remote-tracking branch 'refs/remotes/Cxbx-Reloaded/master' into OOVPA_Refactoring

This commit is contained in:
PatrickvL 2016-12-22 01:15:04 +01:00
commit 9dacd95cc4
8 changed files with 292 additions and 25 deletions

View File

@ -226,6 +226,7 @@
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase.h" />
<ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" />
<ClInclude Include="..\..\src\Common\Win32\Mutex.h" />
<ClInclude Include="..\..\src\CxbxKrnl\LibRc4.h" />
<ClInclude Include="..\..\src\CxbxKrnl\nv2a_int.h" />
<ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h" />
<ClInclude Include="..\..\src\CxbxKrnl\ResourceTracker.h" />
@ -609,6 +610,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\LibRc4.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\ResourceTracker.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@ -185,8 +185,19 @@ XBSYSAPI EXPORTNUM(336) VOID NTAPI XcSHAUpdate(UCHAR *pbSHAContext, UCHAR *pbInp
// ******************************************************************
XBSYSAPI EXPORTNUM(337) VOID NTAPI XcSHAFinal(UCHAR *pbSHAContext, UCHAR *pbDigest);
XBSYSAPI EXPORTNUM(338) VOID *XcRC4Key;
XBSYSAPI EXPORTNUM(339) VOID *XcRC4Crypt;
XBSYSAPI EXPORTNUM(338) VOID XcRC4Key
(
IN PUCHAR pbKeyStruct,
IN ULONG dwKeyLength,
IN PUCHAR pbKey
);
XBSYSAPI EXPORTNUM(339) VOID XcRC4Crypt
(
IN PUCHAR pbKeyStruct,
IN ULONG dwInputLength,
IN PUCHAR pbInput
);
XBSYSAPI EXPORTNUM(340) VOID NTAPI XcHMAC
(

View File

@ -55,6 +55,12 @@ namespace NtDll
#include "EmuNtDll.h"
};
// ******************************************************************
// * Declaring this in a header causes errors with xboxkrnl
// * namespace, so we must declare it within any file that uses it
// ******************************************************************
xboxkrnl::KPCR* KeGetPcr();
// ******************************************************************
// * 0x0033 - InterlockedCompareExchange()
// ******************************************************************
@ -200,15 +206,8 @@ XBSYSAPI EXPORTNUM(160) xboxkrnl::UCHAR FASTCALL xboxkrnl::KfRaiseIrql
LOG_FUNC_ONE_ARG(NewIrql);
UCHAR OldIrql;
KPCR* Pcr = nullptr;
// Fetch KPCR data structure
__asm {
push eax
mov eax, fs:[0x14]
mov Pcr, eax
pop eax
}
KPCR* Pcr = KeGetPcr();
if (NewIrql < Pcr->Irql) {
// TODO: Enable this after KeBugCheck is implemented

View File

@ -57,6 +57,26 @@ namespace NtDll
#include <chrono>
#include <thread>
// ******************************************************************
// * KeGetPcr()
// * NOTE: This is a macro on the Xbox, however we implement it
// * as a function so it can suit our emulated KPCR structure
// ******************************************************************
xboxkrnl::KPCR* KeGetPcr()
{
xboxkrnl::KPCR* Pcr = nullptr;
__asm {
push eax
mov eax, fs:[0x14]
mov Pcr, eax
pop eax
}
return Pcr;
}
// ******************************************************************
// * 0x005C - KeAlertResumeThread()
// ******************************************************************
@ -222,12 +242,7 @@ XBSYSAPI EXPORTNUM(103) xboxkrnl::KIRQL NTAPI xboxkrnl::KeGetCurrentIrql(void)
KIRQL Irql;
// TODO : Untested :
__asm
{
mov al, byte ptr fs : [24h]
mov Irql, al
}
Irql = KeGetPcr()->Irql;
RETURN(Irql);
}
@ -439,13 +454,7 @@ XBSYSAPI EXPORTNUM(129) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToDpcLevel()
CxbxKrnlCleanup("Bugcheck: Caller of KeRaiseIrqlToDpcLevel is higher than DISPATCH_LEVEL!");
KIRQL kRet = NULL;
__asm
{
mov al, byte ptr fs:[24h]
mov kRet, al
mov al, DISPATCH_LEVEL
mov byte ptr fs:[24h], al
}
KeGetPcr()->Irql = DISPATCH_LEVEL;
#ifdef _DEBUG_TRACE
DbgPrintf("Raised IRQL to DISPATCH_LEVEL (2).\n");

View File

@ -44,6 +44,7 @@ namespace xboxkrnl
#include "Logging.h" // For LOG_FUNC()
#include "EmuKrnlLogging.h"
#include "EmuSha.h" // For A_SHAInit, etc.
#include "LibRc4.h" // For RC4 Functions
// prevent name collisions
namespace NtDll
@ -100,6 +101,44 @@ XBSYSAPI EXPORTNUM(337) xboxkrnl::VOID NTAPI xboxkrnl::XcSHAFinal
A_SHAFinal((SHA_CTX*)pbSHAContext, pbDigest);
}
// ******************************************************************
// * 0x0152 - XcRC4Key()
// ******************************************************************
XBSYSAPI EXPORTNUM(338) xboxkrnl::VOID xboxkrnl::XcRC4Key
(
IN PUCHAR pbKeyStruct,
IN ULONG dwKeyLength,
IN PUCHAR pbKey
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG_OUT(pbKeyStruct)
LOG_FUNC_ARG(dwKeyLength)
LOG_FUNC_ARG_OUT(pbKey)
LOG_FUNC_END;
Rc4Initialise((Rc4Context*)pbKeyStruct, pbKey, dwKeyLength, 0);
}
// ******************************************************************
// * 0x0153 - XcRC4Crypt
// ******************************************************************
XBSYSAPI EXPORTNUM(339) xboxkrnl::VOID xboxkrnl::XcRC4Crypt
(
IN PUCHAR pbKeyStruct,
IN ULONG dwInputLength,
IN PUCHAR pbInput
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG_OUT(pbKeyStruct)
LOG_FUNC_ARG(dwInputLength)
LOG_FUNC_ARG_OUT(pbInput)
LOG_FUNC_END;
Rc4Xor((Rc4Context*)pbKeyStruct, pbInput, pbInput, dwInputLength);
}
// ******************************************************************
// * 0x0154 - XcHMAC()
// ******************************************************************

View File

@ -403,8 +403,8 @@ extern "C" CXBXKRNL_API uint32 CxbxKrnl_KernelThunkTable[379] =
(uint32)FUNC(&xboxkrnl::XcSHAInit), // 0x014F (335)
(uint32)FUNC(&xboxkrnl::XcSHAUpdate), // 0x0150 (336)
(uint32)FUNC(&xboxkrnl::XcSHAFinal), // 0x0151 (337)
(uint32)PANIC(0x0152), // 0x0152 (338) XcRC4Key
(uint32)PANIC(0x0153), // 0x0153 (339) XcRC4Crypt
(uint32)FUNC(&xboxkrnl::XcRC4Key), // 0x0152 (338)
(uint32)FUNC(&xboxkrnl::XcRC4Crypt), // 0x0153 (339)
(uint32)FUNC(&xboxkrnl::XcHMAC), // 0x0154 (340)
(uint32)PANIC(0x0155), // 0x0155 (341) XcPKEncPublic
(uint32)PANIC(0x0156), // 0x0156 (342) XcPKDecPrivate

129
src/CxbxKrnl/LibRc4.cpp Normal file
View File

@ -0,0 +1,129 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LibRC4
//
// An implementation of RC4 stream cipher
//
// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTS
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "LibRc4.h"
#include <stdlib.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// INTERNAL FUNCTIONS
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define SwapBytes( Value1, Value2 ) \
{ \
uint8_t temp = Value1; \
Value1 = Value2; \
Value2 = temp; \
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Initialise
//
// Initialises an RC4 cipher and discards the specified number of first bytes.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
Rc4Initialise
(
Rc4Context* Context,
void* Key,
uint32_t KeySize,
uint32_t DropN
)
{
uint32_t i;
uint32_t j;
uint32_t n;
// Setup key schedule
for( i=0; i<256; i++ )
{
Context->S[i] = (uint8_t)i;
}
j = 0;
for( i=0; i<256; i++ )
{
j = ( j + Context->S[i] + ((uint8_t*)Key)[i % KeySize] ) % 256;
SwapBytes( Context->S[i], Context->S[j] );
}
i = 0;
j = 0;
// Drop first bytes (if requested)
for( n=0; n<DropN; n++ )
{
i = ( i + 1 ) % 256;
j = ( j + Context->S[i] ) % 256;
SwapBytes( Context->S[i], Context->S[j] );
}
Context->i = i;
Context->j = j;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Output
//
// Outputs the requested number of bytes from the RC4 stream
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
Rc4Output
(
Rc4Context* Context,
void* Buffer,
uint32_t Size
)
{
uint32_t n;
for( n=0; n<Size; n++ )
{
Context->i = ( Context->i + 1 ) % 256;
Context->j = ( Context->j + Context->S[Context->i] ) % 256;
SwapBytes( Context->S[Context->i], Context->S[Context->j] );
((uint8_t*)Buffer)[n] = Context->S[ (Context->S[Context->i] + Context->S[Context->j]) % 256 ];
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Xor
//
// XORs the RC4 stream with an input buffer and puts the results in an output buffer. This is used for encrypting
// and decrypting data. InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
Rc4Xor
(
Rc4Context* Context,
void* InBuffer,
void* OutBuffer,
uint32_t Size
)
{
uint32_t n;
for( n=0; n<Size; n++ )
{
Context->i = ( Context->i + 1 ) % 256;
Context->j = ( Context->j + Context->S[Context->i] ) % 256;
SwapBytes( Context->S[Context->i], Context->S[Context->j] );
((uint8_t*)OutBuffer)[n] = ((uint8_t*)InBuffer)[n]
^ ( Context->S[ (Context->S[Context->i] + Context->S[Context->j]) % 256 ] );
}
}

78
src/CxbxKrnl/LibRc4.h Normal file
View File

@ -0,0 +1,78 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LibRC4
//
// An implementation of RC4 stream cipher
//
// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _LibRc4_h_
#define _LibRc4_h_
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTS
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdint.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TYPES
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Context - This must be initialised using Rc4Initialised. Do not modify the contents of this structure directly.
typedef struct
{
uint8_t S[256];
uint32_t i;
uint32_t j;
} Rc4Context;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Initialise
//
// Initialises an RC4 cipher and discards the specified number of first bytes.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
Rc4Initialise
(
Rc4Context* Context,
void* Key,
uint32_t KeySize,
uint32_t DropN
);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Output
//
// Outputs the requested number of bytes from the RC4 stream
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
Rc4Output
(
Rc4Context* Context,
void* Buffer,
uint32_t Size
);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rc4Xor
//
// XORs the RC4 stream with an input buffer and puts the results in an output buffer. This is used for encrypting
// and decrypting data. InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
Rc4Xor
(
Rc4Context* Context,
void* InBuffer,
void* OutBuffer,
uint32_t Size
);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif //_LibRc4_h_