static PatchData_t *JKG_PlacePatch( int type, unsigned int address, unsigned int destination ) { PatchData_t *patch = malloc(sizeof(PatchData_t)); t_disasm dasm; int addr = address; int sz = 0; int opsz; // Disassemble the code and determine the size of the code we have to replace while (sz < 5) { opsz = Disasm((char*)addr, 16, addr, &dasm, DISASM_CODE); if (opsz == 0) { return NULL; // Should never happen } sz += opsz; addr += opsz; } if (sz == 0 || sz > 24) { // This really shouldnt ever happen, in the worst case scenario, // the block is 20 bytes (4 + 16), so if we hit 24, something went wrong return NULL; } patch->addr = address; patch->size = sz; memcpy(patch->origbytes, (const void *)address, sz); UnlockMemory(address, sz); // Make the memory writable *(unsigned char *)address = type == PATCH_JUMP ? 0xE9 : 0xE8; *(unsigned int *)(address+1) = destination - (address + 5); memset((void *)(address+5),0x90,sz-5); // Nop the rest LockMemory(address, sz); return patch; }
static void JKG_RemovePatch(PatchData_t **patch) { if (!*patch) return; UnlockMemory((*patch)->addr, (*patch)->size); memcpy((void *)(*patch)->addr, (*patch)->origbytes, (*patch)->size); LockMemory((*patch)->addr, (*patch)->size); *patch = 0; }
void * RLINGLock( void * mem ) { #ifdef _NO_CFIO return mem; #else return LockMemory(mem); #endif }
void RemoveHook( const hookEntry_t *hook ) { qboolean success = qfalse; if ( hook && (success = UnlockMemory( hook->hookPosition, 5 )) ) { memcpy( (void *)hook->hookPosition, hook->origBytes, 5 ); success = LockMemory( hook->hookPosition, 5 ); } #ifdef _DEBUG if ( hook ) Com_Printf( success ? va( " %s\n", hook->name ) : va( "^1Warning: Failed to remove hook: %s\n", hook->name ) ); #endif }
void PlaceHook( hookEntry_t *hook ) { qboolean success = qfalse; if ( hook && (success = UnlockMemory( hook->hookPosition, 5 )) ) { unsigned int forward = (unsigned int)((void*(*)())hook->hookForward)(); //i never want to see this line again if ( !memcmp( (const void *)&hook->origBytes[0], (const void *)hook->hookPosition, sizeof( hook->origBytes ) ) ) { // memcpy( &hook->origBytes[0], (void *)hook->hookPosition, 5 ); *(unsigned char *)(hook->hookPosition) = hook->hookOpcode; *(unsigned int *)(hook->hookPosition+1) = (forward) - ((unsigned int)(hook->hookPosition)+5); success = LockMemory( hook->hookPosition, 5 ); } else success = qfalse; } #ifdef _DEBUG if ( hook ) Com_Printf( success ? va( " %s\n", hook->name ) : va( "^1Warning: Failed to place hook: %s\n", hook->name ) ); #endif }
void JKG_PatchEngine() { Com_Printf(" ------- Installing Engine Patches -------- \n"); pIBFix = JKG_PlacePatch(PATCH_CALL, _IBFIX_PATCHPOS, (unsigned int)_Hook_InfoBoomFix()); // We'll be overwriting a call here if (!pIBFix) { Com_Printf("Warning: Failed to place hook 2: Q3infoboom fix\n"); } /////////////////////////////// // Patch 2: Revert the patch of Luigi (in case its patched) /////////////////////////////// UnlockMemory(_IBFIX_MSGPATCH,1); *(unsigned int *)_IBFIX_MSGPATCH = (unsigned int)0x3FF; LockMemory(_IBFIX_MSGPATCH,1); /////////////////////////////// // Hook 7: Download Hack Fix /////////////////////////////// pDHFIX = JKG_PlacePatch(PATCH_CALL, _DHFIX_PATCHPOS, (unsigned int)_Hook_DownloadHackFix()); // We'll be overwriting a call here if (!pDHFIX) { Com_Printf("Warning: Failed to place hook 7: Download Hack Fix\n"); } Com_Printf("Finished\n"); }
int SendFile (char *FileName) { WaitLoop (DelayToTransmit); int hFile; if ((hFile = open (FileName, O_BINARY | O_RDONLY, FILE_ACCESS)) == -1) { printf ("-Send file %s not found!\n", FileName); return hFile; } dword FileSize = lseek (hFile, 0, SEEK_END), FileOffset = 0; lseek (hFile, 0, SEEK_SET); byte *ClusterBuffer = new byte [SizeOrigCluster]; if (!ClusterBuffer) return (int)ClusterBuffer; LockMemory (ClusterBuffer, SizeOrigCluster, LOCK_MEMORY); // Make file header FileHdr *filehdr = (FileHdr*)ClusterBuffer; filehdr->FileID = get_time () + FileSize; // Is static parametr dword FileHeaderLen = strlen (FileName) + 1 + sizeof (FileAttr); dword FileBlockIndex = 0; // Insert empty frames vint Semaphore = SizeOrigCluster / SizeDataFrame; SendAFrames ((word*)ClusterBuffer, &Semaphore, ID_FRAME, NULL); while (Semaphore > 4) {} while (FileSize && !StopByUser) { CheckOnFreeComBuffer (); BlockHdr *pBH = (BlockHdr*) ((int)ClusterBuffer + sizeof (FileHdr)); dword BlockIndex = FileBlockIndex, BlockInCluster = 0; dword LastBytes = SizeOrigCluster - sizeof (FileHdr); // Divide cluster on blocks while (LastBytes) { if (LastBytes <= sizeof (BlockHdr)) break; BlockInCluster++; LastBytes -= sizeof (BlockHdr); if (BlockIndex) { if (LastBytes >= BLOCK_LEN) pBH->Len = BLOCK_LEN; else pBH->Len = LastBytes; LastBytes -= pBH->Len; } else if (FileHeaderLen <= LastBytes) { pBH->Len = FileHeaderLen; LastBytes -= pBH->Len; } else { BlockInCluster--; LastBytes = 0; break; } BlockIndex++; pBH++; } // Dinamyc part of file header modify filehdr->NumBlock = BlockInCluster; filehdr->HdrLen = sizeof (FileHdr) + BlockInCluster * sizeof (BlockHdr); byte *pClusterData = (byte*)((int)ClusterBuffer + filehdr->HdrLen); pBH = (BlockHdr *) ((int)ClusterBuffer + sizeof (FileHdr)); dword OffsetToData = filehdr->HdrLen; BlockIndex = 0; // Skeleton of cluster data fill while (BlockInCluster && FileSize) { BlockIndex++; if (!FileBlockIndex) { FileAttr *pFA = (FileAttr *)pClusterData; pFA->Size = FileSize; _dos_getfileattr (FileName, &pFA->Attr); #ifdef __GNUC__ _dos_getftime (hFile, &pFA->Date, &pFA->Time); #else _dos_getftime (hFile, (word*)&pFA->Date, (word*)&pFA->Time); #endif strcpy ((char*) ((int)pClusterData + sizeof (FileAttr)), FileName); } else { read (hFile, pClusterData, pBH->Len); pBH->FileOffset = FileOffset; FileOffset += pBH->Len; if (FileSize >= pBH->Len) FileSize -= pBH->Len; else { pBH->Len = FileSize; // truncate block FileSize = 0; // Correct file header filehdr->NumBlock = BlockIndex; filehdr->HdrLen = sizeof (FileHdr) + BlockIndex * sizeof (BlockHdr); } } pBH->Number = FileBlockIndex++; pBH->CRC = GetBlockCRC (pClusterData, pBH->Len); pBH->ClusterOffset = OffsetToData; OffsetToData += pBH->Len; pClusterData += pBH->Len; BlockInCluster--; pBH++; } printf ("BlockInCluster %d\n", BlockIndex); dword CountCluster; while ((CountCluster = SendACluster (1, ClusterBuffer, filehdr->FileID + FileBlockIndex)) != 1) {} } // end while FileSize delete ClusterBuffer; LockMemory (ClusterBuffer, SizeOrigCluster, UNLOCK_MEMORY); close (hFile); while ((SComFlag || RComFlag || StartFlag) && !StopByUser) CheckOnFreeComBuffer (); return 1; }