Pre-Entry execution!!

This commit is contained in:
Aaron Robinson 2003-05-04 19:55:25 +00:00
parent 1e48c8ac80
commit 8bcae8acae
9 changed files with 205 additions and 241 deletions

View File

@ -47,7 +47,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuNoFunc();
// ******************************************************************
// * func: EmuInit
// ******************************************************************
extern "C" CXBXKRNL_API void NTAPI EmuInit(Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, char *szDebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)());
extern "C" CXBXKRNL_API void NTAPI EmuInit(void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, char *szDebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)());
// ******************************************************************
// * func: EmuCleanup
@ -74,4 +74,9 @@ extern "C" CXBXKRNL_API uint32 KernelThunkTable[367];
// ******************************************************************
extern Xbe::TLS *g_pTLS;
// ******************************************************************
// * data: pTLSData
// ******************************************************************
extern void *g_pTLSData;
#endif

View File

@ -83,7 +83,7 @@ static inline bool EmuIsXboxFS()
// ******************************************************************
// * func: EmuGenerateFS
// ******************************************************************
void EmuGenerateFS(Xbe::TLS *pTLS);
void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData);
// ******************************************************************
// * func: EmuCleanupFS

View File

@ -36,6 +36,7 @@
#include "OOVPA.h"
extern SOOVPA<9> __cinit_1_0_3911;
extern OOVPATable XAPI_1_0_3911[];
extern uint32 XAPI_1_0_3911_SIZE;

View File

@ -323,7 +323,9 @@ EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename) : Exe
// * generate .cxbxplg section virtual size / addr
// ******************************************************************
{
uint32 virt_size = RoundUp(m_OptionalHeader.m_image_base + 0x100 + x_Xbe->m_Header.dwSizeofHeaders + 260 + sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions + sizeof(Xbe::TLS), 0x1000);
uint32 virt_size = RoundUp(m_OptionalHeader.m_image_base + 0x100 + x_Xbe->m_Header.dwSizeofHeaders + 260
+ sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions + sizeof(Xbe::TLS)
+ (x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr), 0x1000);
uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN);
m_SectionHeader[i].m_virtual_size = virt_size;
@ -514,6 +516,8 @@ EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename) : Exe
{
memcpy(pWriteCursor, x_Xbe->m_TLS, sizeof(Xbe::TLS));
pWriteCursor += sizeof(Xbe::TLS);
memcpy(pWriteCursor, x_Xbe->GetTLSData(), (x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr));
pWriteCursor += (x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr);
}
// ******************************************************************
@ -524,24 +528,24 @@ EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename) : Exe
// Function Pointer
*(uint32 *)((uint32)m_bzSection[i] + 1) = (uint32)EmuInit;
// Param 7 : Entry
// Param 8 : Entry
*(uint32 *)((uint32)m_bzSection[i] + 6) = (uint32)ep;
// Param 6 : dwXbeHeaderSize
// Param 7 : dwXbeHeaderSize
*(uint32 *)((uint32)m_bzSection[i] + 11) = (uint32)x_Xbe->m_Header.dwSizeofHeaders;
// Param 5 : pXbeHeader
// Param 6 : pXbeHeader
*(uint32 *)((uint32)m_bzSection[i] + 16) = WriteCursor;
WriteCursor += x_Xbe->m_Header.dwSizeofHeaders;
// Param 4 : szDebugFilename
// Param 5 : szDebugFilename
*(uint32 *)((uint32)m_bzSection[i] + 21) = WriteCursor;
WriteCursor += 260;
// Param 3 : DbgMode
// Param 4 : DbgMode
*(uint32 *)((uint32)m_bzSection[i] + 26) = x_debug_mode;
// Param 2 : pLibraryVersion
// Param 3 : pLibraryVersion
if(x_Xbe->m_LibraryVersion != 0)
{
*(uint32 *)((uint32)m_bzSection[i] + 31) = WriteCursor;
@ -552,7 +556,7 @@ EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename) : Exe
*(uint32 *)((uint32)m_bzSection[i] + 31) = 0;
}
// Param 1 : pTLS
// Param 2 : pTLS
if(x_Xbe->m_TLS != 0)
{
*(uint32 *)((uint32)m_bzSection[i] + 36) = WriteCursor;
@ -563,6 +567,17 @@ EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename) : Exe
*(uint32 *)((uint32)m_bzSection[i] + 36) = 0;
}
// Param 1 : pTLSData
if(x_Xbe->m_TLS != 0)
{
*(uint32 *)((uint32)m_bzSection[i] + 41) = WriteCursor;
WriteCursor += (x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr);
}
else
{
*(uint32 *)((uint32)m_bzSection[i] + 41) = 0;
}
printf("OK\n");
}
}

View File

@ -62,6 +62,7 @@ __declspec(allocate(".cxbxplg")) uint08 Prolog[] =
0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3
0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3
0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3
0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3
0xFF, 0xD6, // call esi
0xC3 // ret
};

View File

@ -53,12 +53,14 @@ namespace xboxkrnl
// * global / static
// ******************************************************************
extern Xbe::TLS *g_pTLS = 0;
extern void *g_pTLSData = 0;
// ******************************************************************
// * static
// ******************************************************************
static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader);
static int ExitException(LPEXCEPTION_POINTERS e);
static void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper);
static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader);
static int ExitException(LPEXCEPTION_POINTERS e);
// ******************************************************************
// * func: DllMain
@ -104,6 +106,7 @@ static void EmuCleanThread()
// ******************************************************************
extern "C" CXBXKRNL_API void NTAPI EmuInit
(
void *pTLSData,
Xbe::TLS *pTLS,
Xbe::LibraryVersion *pLibraryVersion,
DebugMode DbgMode,
@ -113,6 +116,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
void (*Entry)())
{
g_pTLS = pTLS;
g_pTLSData = pTLSData;
// ******************************************************************
// * debug console allocation (if configured)
@ -157,6 +161,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
printf("Emu: EmuInit\n"
"(\n"
" pTLSData : 0x%.08X\n"
" pTLS : 0x%.08X\n"
" pLibraryVersion : 0x%.08X\n"
" DebugConsole : 0x%.08X\n"
@ -165,7 +170,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
" pXBEHeaderSize : 0x%.08X\n"
" Entry : 0x%.08X\n"
");\n",
pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry);
pTLSData, pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry);
#else
printf("CxbxKrnl (0x%.08X): _DEBUG_TRACE disabled.\n", GetCurrentThreadId());
@ -190,8 +195,6 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
memcpy(&MemXbeHeader->dwInitFlags, &pXbeHeader->dwInitFlags, sizeof(pXbeHeader->dwInitFlags));
printf("pXbeHeader->dwCertificateAddr : 0x%.08X -> 0x%.08X\n", pXbeHeader->dwCertificateAddr, pXbeHeader->dwCertificateAddr + sizeof(Xbe::Certificate));
memcpy((void*)pXbeHeader->dwCertificateAddr, &((uint08*)pXbeHeader)[pXbeHeader->dwCertificateAddr - 0x00010000], sizeof(Xbe::Certificate));
}
@ -201,7 +204,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
{
EmuInitFS();
EmuGenerateFS(pTLS);
EmuGenerateFS(pTLS, pTLSData);
}
// ******************************************************************
@ -210,6 +213,9 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
if(pLibraryVersion == 0)
printf("Emu: Detected OpenXDK application...\n");
uint32 xca;
uint32 xcz;
// ******************************************************************
// * Initialize Microsoft XDK emulation
// ******************************************************************
@ -249,11 +255,50 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit
if(!found)
printf("Skipped\n");
if(strcmp("XAPILIB", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 && (BuildVersion == 4627 || BuildVersion == 4361 || BuildVersion == 4034 || BuildVersion == 3911))
{
printf("Emu: Locating Pre-Entry Execution...");
uint32 lower = pXbeHeader->dwBaseAddr;
uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
void *pFunc = EmuLocateFunction((OOVPA*)&__cinit_1_0_3911, lower, upper);
if(pFunc == 0)
printf("Skipped\n");
else
{
xca = *(uint32*)((uint32)pFunc + 0x32);
xcz = *(uint32*)((uint32)pFunc + 0x39);
printf("Found! @ 0x%.08X -> 0x%.08X\n", xca, xcz);
}
}
}
EmuD3DInit(pXbeHeader, dwXbeHeaderSize);
}
// ******************************************************************
// * Static/Constructors
// ******************************************************************
for(uint32 v=xca;v<xcz; v+=4)
{
uint32 pFunc = *(uint32*)v;
if(pFunc != 0 && pFunc != -1)
{
printf("Emu (0x%.08X): Static/Constructor @ 0x%.08X\n", GetCurrentThreadId(), pFunc);
EmuSwapFS(); // Xbox FS
__asm call pFunc
EmuSwapFS(); // Win2k/XP FS
}
}
printf("Emu (0x%.08X): Initial thread starting.\n", GetCurrentThreadId());
// ******************************************************************
@ -346,11 +391,99 @@ inline void EmuInstallWrapper(void *FunctionAddr, void *WrapperAddr)
*(uint32*)&FuncBytes[1] = (uint32)WrapperAddr - (uint32)FunctionAddr - 5;
}
// ******************************************************************
// * func: EmuLocateFunction
// ******************************************************************
void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper)
{
uint32 count = Oovpa->Count;
// ******************************************************************
// * Large
// ******************************************************************
if(Oovpa->Large == 1)
{
LOOVPA<1> *Loovpa = (LOOVPA<1>*)Oovpa;
upper -= Loovpa->Lovp[count-1].Offset;
// ******************************************************************
// * Search all of the image memory
// ******************************************************************
for(uint32 cur=lower;cur<upper;cur++)
{
uint32 v=0;
// ******************************************************************
// * check all pairs, moving on if any do not match
// ******************************************************************
for(v=0;v<count;v++)
{
uint32 Offset = Loovpa->Lovp[v].Offset;
uint32 Value = Loovpa->Lovp[v].Value;
uint08 RealValue = *(uint08*)(cur + Offset);
if(RealValue != Value)
break;
}
// ******************************************************************
// * success if we found all pairs
// ******************************************************************
if(v == count)
return (void*)cur;
}
}
// ******************************************************************
// * Small
// ******************************************************************
else
{
SOOVPA<1> *Soovpa = (SOOVPA<1>*)Oovpa;
upper -= Soovpa->Sovp[count-1].Offset;
// ******************************************************************
// * Search all of the image memory
// ******************************************************************
for(uint32 cur=lower;cur<upper;cur++)
{
uint32 v=0;
// ******************************************************************
// * check all pairs, moving on if any do not match
// ******************************************************************
for(v=0;v<count;v++)
{
uint32 Offset = Soovpa->Sovp[v].Offset;
uint32 Value = Soovpa->Sovp[v].Value;
uint08 RealValue = *(uint08*)(cur + Offset);
if(RealValue != Value)
break;
}
// ******************************************************************
// * success if we found all pairs
// ******************************************************************
if(v == count)
return (void*)cur;
}
}
return 0;
}
// ******************************************************************
// * func: EmuInstallWrappers
// ******************************************************************
void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader)
{
uint32 lower = pXbeHeader->dwBaseAddr;
uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
// ******************************************************************
// * traverse the full OOVPA table
// ******************************************************************
@ -362,127 +495,19 @@ void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*En
OOVPA *Oovpa = OovpaTable[a].Oovpa;
uint32 count = Oovpa->Count;
uint32 lower = pXbeHeader->dwBaseAddr;
uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
void *pFunc = EmuLocateFunction(Oovpa, lower, upper);
// ******************************************************************
// * Large
// ******************************************************************
if(Oovpa->Large == 1)
if(pFunc != 0)
{
LOOVPA<1> *Loovpa = (LOOVPA<1>*)Oovpa;
#ifdef _DEBUG_TRACE
printf("Found @ 0x%.08X\n", pFunc);
#endif
upper -= Loovpa->Lovp[count-1].Offset;
bool found = false;
// ******************************************************************
// * Search all of the image memory
// ******************************************************************
for(uint32 cur=lower;cur<upper;cur++)
{
uint32 v=0;
// ******************************************************************
// * check all pairs, moving on if any do not match
// ******************************************************************
for(v=0;v<count;v++)
{
uint32 Offset = Loovpa->Lovp[v].Offset;
uint32 Value = Loovpa->Lovp[v].Value;
uint08 RealValue = *(uint08*)(cur + Offset);
if(RealValue != Value)
break;
}
// ******************************************************************
// * success if we found all pairs
// ******************************************************************
if(v == count)
{
#ifdef _DEBUG_TRACE
printf("Found! (0x%.08X)\n", cur);
#endif
EmuInstallWrapper((void*)cur, OovpaTable[a].lpRedirect);
found = true;
break;
}
}
// ******************************************************************
// * not found
// ******************************************************************
if(!found)
{
#ifdef _DEBUG_TRACE
printf("None (OK)\n");
#endif
}
EmuInstallWrapper(pFunc, OovpaTable[a].lpRedirect);
}
// ******************************************************************
// * Small
// ******************************************************************
else
{
SOOVPA<1> *Soovpa = (SOOVPA<1>*)Oovpa;
upper -= Soovpa->Sovp[count-1].Offset;
bool found = false;
// ******************************************************************
// * Search all of the image memory
// ******************************************************************
for(uint32 cur=lower;cur<upper;cur++)
{
uint32 v=0;
// ******************************************************************
// * check all pairs, moving on if any do not match
// ******************************************************************
for(v=0;v<count;v++)
{
uint32 Offset = Soovpa->Sovp[v].Offset;
uint32 Value = Soovpa->Sovp[v].Value;
uint08 RealValue = *(uint08*)(cur + Offset);
if(RealValue != Value)
break;
}
// ******************************************************************
// * success if we found all pairs
// ******************************************************************
if(v == count)
{
#ifdef _DEBUG_TRACE
printf("Found! (0x%.08X)\n", cur);
#endif
EmuInstallWrapper((void*)cur, OovpaTable[a].lpRedirect);
found = true;
break;
}
}
// ******************************************************************
// * not found
// ******************************************************************
if(!found)
{
#ifdef _DEBUG_TRACE
printf("None (OK)\n");
#endif
}
printf("None (OK)\n");
}
}
}

View File

@ -60,13 +60,36 @@ void EmuInitFS()
// ******************************************************************
// * func: EmuGenerateFS
// ******************************************************************
void EmuGenerateFS(Xbe::TLS *pTLS)
void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData)
{
NT_TIB *OrgNtTib;
xboxkrnl::KPCR *NewPcr;
uint16 NewFS = -1, OrgFS = -1;
// ******************************************************************
// * Dump Raw TLS data
// ******************************************************************
{
#ifdef _DEBUG_TRACE
printf("CxbxKrnl (0x%.08X) : Dumping TLS Raw Data... \n 0x%.08X: ", GetCurrentThreadId(), pTLSData);
uint32 stop = (pTLS->dwDataEndAddr - pTLS->dwDataStartAddr);
for(uint32 v=0;v<stop;v++)
{
uint08 *bByte = (uint08*)pTLSData + v;
printf("%.01X", (uint32)*bByte);
if((v+1) % 0x10 == 0)
printf("\n 0x%.08X: ", ((uint32)pTLSData + v));
}
printf("\n");
#endif
}
// ******************************************************************
// * Obtain "OrgFS"
// ******************************************************************
@ -122,7 +145,7 @@ void EmuGenerateFS(Xbe::TLS *pTLS)
NewPcr->Prcb = &NewPcr->PrcbData;
NewPcr->PrcbData.CurrentThread->TlsData = (void*)pTLS->dwTLSIndexAddr;
NewPcr->PrcbData.CurrentThread->TlsData = (void*)pTLSData;
}
// ******************************************************************
@ -148,11 +171,9 @@ void EmuGenerateFS(Xbe::TLS *pTLS)
// * Save "TLSPtr" inside NewFS.StackBase
// ******************************************************************
{
uint32 dwTLSIndexAddr = pTLS->dwTLSIndexAddr;
__asm
{
mov eax, dwTLSIndexAddr
mov eax, pTLSData
mov fs:[0x04], eax
}
}

View File

@ -115,7 +115,7 @@ static DWORD WINAPI PCSTProxy
}
#endif
EmuGenerateFS(g_pTLS);
EmuGenerateFS(g_pTLS, g_pTLSData);
// ******************************************************************
// * use the special calling convention

View File

@ -50,56 +50,6 @@ namespace xapi
#include "EmuD3D8.h"
#include "EmuDInput.h"
// ******************************************************************
// * EmuCreateThreadProxyParam
// ******************************************************************
typedef struct _EmuCreateThreadProxyParam
{
LPVOID lpParameter;
LPTHREAD_START_ROUTINE lpStartAddress;
}
EmuCreateThreadProxyParam;
// ******************************************************************
// * func: EmuCreateThreadProxy
// ******************************************************************
static DWORD WINAPI EmuCreateThreadProxy
(
LPVOID lpParameter
)
{
EmuCreateThreadProxyParam *iEmuCreateThreadProxyParam = (EmuCreateThreadProxyParam*)lpParameter;
LPTHREAD_START_ROUTINE ilpStartAddress = iEmuCreateThreadProxyParam->lpStartAddress;
LPVOID ilpParam = iEmuCreateThreadProxyParam->lpParameter;
delete iEmuCreateThreadProxyParam;
EmuGenerateFS(g_pTLS);
// ******************************************************************
// * debug trace
// ******************************************************************
#ifdef _DEBUG_TRACE
{
printf("EmuXapi (0x%.08X): EmuCreateThreadProxy\n"
"(\n"
" lpParameter : 0x%.08X\n"
");\n",
GetCurrentThreadId(), lpParameter);
}
#endif
EmuSwapFS(); // XBox FS
DWORD ret = ilpStartAddress(ilpParam);
EmuSwapFS(); // Win2k/XP FS
return ret;
}
// ******************************************************************
// * func: EmuXInitDevices
// ******************************************************************
@ -287,60 +237,6 @@ DWORD WINAPI xapi::EmuXInputGetState
return ret;
}
// ******************************************************************
// * func: EmuCreateThread
// ******************************************************************
HANDLE WINAPI xapi::EmuCreateThread
(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
)
{
EmuSwapFS(); // Win2k/XP FS
// ******************************************************************
// * debug trace
// ******************************************************************
#ifdef _DEBUG_TRACE
{
printf("EmuXapi (0x%.08X): EmuCreateThread\n"
"(\n"
" lpThreadAttributes : 0x%.08X\n"
" dwStackSize : 0x%.08X\n"
" lpStartAddress : 0x%.08X\n"
" lpParameter : 0x%.08X\n"
" dwCreationFlags : 0x%.08X\n"
" lpThreadId : 0x%.08X\n"
");\n",
GetCurrentThreadId(), lpThreadAttributes, dwStackSize, lpStartAddress,
lpParameter, dwCreationFlags, lpThreadId);
}
#endif
EmuCreateThreadProxyParam *iEmuCreateThreadProxyParam = new EmuCreateThreadProxyParam();
iEmuCreateThreadProxyParam->lpParameter = lpParameter;
iEmuCreateThreadProxyParam->lpStartAddress = lpStartAddress;
HANDLE RetHandle = CreateThread
(
NULL,
dwStackSize,
EmuCreateThreadProxy,
iEmuCreateThreadProxyParam,
dwCreationFlags,
lpThreadId
);
EmuSwapFS(); // XBox FS
return RetHandle;
}
// ******************************************************************
// * func: EmuCloseHandle
// ******************************************************************