CRC32-Patches
This commit is contained in:
parent
f2c3b79c2d
commit
a257a21e30
17
src/hookcrc32/Makefile
Normal file
17
src/hookcrc32/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
CC=gcc -m32
|
||||
CFLAGS = -g -O0 -fPIC -m32 -Wall -Werror -Wno-unused-variable -Wno-unused-function
|
||||
LD = g++ -m32
|
||||
LDFLAGS = -Wl,-z,defs -rdynamic -static-libstdc++ -static-libgcc -lc -ldl -lGL -lglut -lX11 -lm -lpthread -shared -nostdlib
|
||||
|
||||
BUILD = build
|
||||
|
||||
OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
|
||||
all: hookcrc32.so
|
||||
|
||||
hookcrc32.so: $(OBJS)
|
||||
$(LD) $(OBJS) $(LDFLAGS) $(CFLAGS) -o hookcrc32.so
|
||||
rm -f *.o
|
||||
|
||||
clean:
|
||||
rm -f hookcrc32.so
|
95
src/hookcrc32/hookcrc32.c
Normal file
95
src/hookcrc32/hookcrc32.c
Normal file
@ -0,0 +1,95 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static struct {
|
||||
ElfW(Addr) start, end;
|
||||
} *segments;
|
||||
static int n;
|
||||
static int (*real_main)(int argc,char **argv);
|
||||
|
||||
uint32_t __crc32(const char *s,size_t n) {
|
||||
uint32_t crc=0xFFFFFFFF;
|
||||
|
||||
for(size_t i=0;i<n;i++) {
|
||||
char ch=s[i];
|
||||
for(size_t j=0;j<8;j++) {
|
||||
uint32_t b=(ch^crc)&1;
|
||||
crc>>=1;
|
||||
if(b) crc=crc^0xEDB88320;
|
||||
ch>>=1;
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
static int callback(struct dl_phdr_info *info, size_t size, void *data) {
|
||||
/*n = info->dlpi_phnum;
|
||||
segments = malloc(n * sizeof *segments);
|
||||
for(int i = 0; i < n; ++i) {
|
||||
segments[i].start = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr;
|
||||
segments[i].end = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr + info->dlpi_phdr[i].p_memsz;
|
||||
}
|
||||
char *type;
|
||||
int p_type;
|
||||
printf("Name: \"%s\" (%d segments)\n", info->dlpi_name, info->dlpi_phnum);
|
||||
for (int j = 0; j < info->dlpi_phnum; j++) {
|
||||
p_type = info->dlpi_phdr[j].p_type;
|
||||
type = (p_type == PT_LOAD) ? "PT_LOAD" :
|
||||
(p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
|
||||
(p_type == PT_INTERP) ? "PT_INTERP" :
|
||||
(p_type == PT_NOTE) ? "PT_NOTE" :
|
||||
(p_type == PT_INTERP) ? "PT_INTERP" :
|
||||
(p_type == PT_PHDR) ? "PT_PHDR" :
|
||||
(p_type == PT_TLS) ? "PT_TLS" :
|
||||
(p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
|
||||
(p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
|
||||
(p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;
|
||||
|
||||
printf(" %2d: [%14p; memsz:0x%7x; size:0x%7x] flags: 0x%x; ", j,
|
||||
(void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr),
|
||||
info->dlpi_phdr[j].p_memsz, info->dlpi_phdr[j].p_filesz ,info->dlpi_phdr[j].p_flags);
|
||||
if (type != NULL)
|
||||
printf("%s\n", type);
|
||||
else
|
||||
printf("[other (0x%x)]\n", p_type);*/
|
||||
if((info->dlpi_phnum >= 3) && (info->dlpi_phdr[2].p_type == PT_LOAD) && (info->dlpi_phdr[2].p_flags == 5))
|
||||
{
|
||||
// printf("Aca voy a dumpear el codigo:\n");
|
||||
//FILE *file = fopen("dump.bin","w+b");
|
||||
|
||||
//fwrite((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr)+10,128,1,file);
|
||||
//fclose(file);
|
||||
int crc = 0;
|
||||
crc = __crc32((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr+10),128);
|
||||
printf("Crc32: 0x%x\n",crc);
|
||||
}
|
||||
//}
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((__constructor__))
|
||||
static void setup(void) {
|
||||
dl_iterate_phdr(callback, NULL);
|
||||
//real_main = dlsym(RTLD_NEXT, "main");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
__attribute__((__destructor__))
|
||||
static void teardown(void) {
|
||||
free(segments);
|
||||
}
|
||||
/*
|
||||
__attribute__((__noinline__))
|
||||
int main(int argc,char **argv) {
|
||||
ElfW(Addr) addr = (ElfW(Addr))__builtin_extract_return_addr(__builtin_return_address(0));
|
||||
for(int i = 0; i < n; ++i) {
|
||||
if(addr >= segments[i].start && addr < segments[i].end) {
|
||||
// Do Nothing
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return real_main(argc, argv);
|
||||
}*/
|
Binary file not shown.
@ -28,7 +28,7 @@ static char *getNextToken(char *buffer, char *seperator, char **saveptr)
|
||||
return token;
|
||||
}
|
||||
|
||||
static int detectGame()
|
||||
static int detectGame(uint32_t elf_crc)
|
||||
{
|
||||
|
||||
// For a better way of doing this, we should look for strings inside the game
|
||||
@ -36,19 +36,25 @@ static int detectGame()
|
||||
// strings %s | grep "RIDE TURN TEST" && strings %s | grep "PLEASE SHOOT GRID"
|
||||
// shows you its hotd4S for example
|
||||
|
||||
if (strstr(program_invocation_name, "segaboot"))
|
||||
if (elf_crc == 0x93ea7e11)
|
||||
{
|
||||
config.game = SEGABOOT;
|
||||
config.game = SEGABOOT_2_4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "hod4"))
|
||||
if (elf_crc == 0xbc0c9ffa)
|
||||
{
|
||||
config.game = THE_HOUSE_OF_THE_DEAD_4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "Jennifer"))
|
||||
if (elf_crc == 0x7235bda8)
|
||||
{
|
||||
config.game = THE_HOUSE_OF_THE_DEAD_4_TEST;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (elf_crc == 0x6d055308)
|
||||
{
|
||||
config.game = OUTRUN;
|
||||
config.emulateDriveboard = 1;
|
||||
@ -56,7 +62,7 @@ static int detectGame()
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "JenTest"))
|
||||
if (elf_crc == 0xffdccaaa)
|
||||
{
|
||||
config.game = OUTRUN_TEST;
|
||||
config.emulateDriveboard = 1;
|
||||
@ -64,33 +70,43 @@ static int detectGame()
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "lgj"))
|
||||
if (elf_crc == 0xd4726d61)
|
||||
{
|
||||
config.game = LETS_GO_JUNGLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "abc1080"))
|
||||
if (elf_crc == 0xcc02de7d)
|
||||
{
|
||||
config.game = ABC;
|
||||
config.game = ABC_2006;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "drive"))
|
||||
if (elf_crc == 0x152530dd)
|
||||
{
|
||||
config.game = ABC_2007;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (elf_crc == 0xfb096f81)
|
||||
{
|
||||
config.game = SRTV;
|
||||
config.emulateDriveboard = 1;
|
||||
config.emulateMotionboard = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "dsr"))
|
||||
if (elf_crc == 0xb05d9bbe)
|
||||
{
|
||||
config.game = RTUNED;
|
||||
config.emulateDriveboard = 1;
|
||||
config.emulateMotionboard = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(program_invocation_name, "vf5"))
|
||||
|
||||
if (elf_crc == 0xc4b7e89)
|
||||
{
|
||||
config.game = VF5;
|
||||
config.game = VT3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -112,16 +128,19 @@ char *getGameName()
|
||||
return "Outrun 2 SP";
|
||||
case THE_HOUSE_OF_THE_DEAD_4:
|
||||
return "The House of the Dead 4";
|
||||
case THE_HOUSE_OF_THE_DEAD_4_TEST:
|
||||
return "The House of the Dead 4 - Test Menu";
|
||||
case LETS_GO_JUNGLE:
|
||||
return "Let's Go Jungle! Lost on the Island of Spice";
|
||||
case ABC:
|
||||
case ABC_2006:
|
||||
case ABC_2007:
|
||||
return "After Burner Climax";
|
||||
case SRTV:
|
||||
return "SEGA Race TV";
|
||||
case RTUNED:
|
||||
return "R-Tuned Ultimate Street Racing";
|
||||
case VF5:
|
||||
return "Virtua Fighter 5";
|
||||
case VT3:
|
||||
return "Virtua Tennis 3";
|
||||
default:
|
||||
return "Unknown Game";
|
||||
}
|
||||
@ -187,7 +206,7 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initConfig()
|
||||
int initConfig(uint32_t elf_crc)
|
||||
{
|
||||
config.emulateRideboard = 0;
|
||||
config.emulateDriveboard = 0;
|
||||
@ -203,17 +222,20 @@ int initConfig()
|
||||
strcpy(config.rideboardPath, "none");
|
||||
config.width = 1024;
|
||||
config.height = 768;
|
||||
|
||||
if (detectGame() != 0)
|
||||
if (detectGame(elf_crc) != 0)
|
||||
{
|
||||
printf("Warning: Unsure what game this is, using default configuration values\n");
|
||||
printf("Warning: Unsure what game this is, using default configuration values.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Game Detected: %s\n", getGameName());
|
||||
}
|
||||
|
||||
configFile = fopen(CONFIG_PATH, "r");
|
||||
|
||||
if (configFile == NULL)
|
||||
{
|
||||
printf("Warning: Cannot open %s, using default values\n", CONFIG_PATH);
|
||||
printf("Warning: Cannot open %s, using default values.\n", CONFIG_PATH);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -9,13 +9,15 @@ typedef enum
|
||||
SEGABOOT_2_4,
|
||||
SEGABOOT_2_6,
|
||||
THE_HOUSE_OF_THE_DEAD_4,
|
||||
THE_HOUSE_OF_THE_DEAD_4_TEST,
|
||||
OUTRUN,
|
||||
OUTRUN_TEST,
|
||||
LETS_GO_JUNGLE,
|
||||
ABC,
|
||||
ABC_2006,
|
||||
ABC_2007,
|
||||
SRTV,
|
||||
RTUNED,
|
||||
VF5
|
||||
VT3
|
||||
} Game;
|
||||
|
||||
typedef enum
|
||||
|
@ -1,3 +1,5 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <linux/sockios.h>
|
||||
@ -13,6 +15,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <cpuid.h>
|
||||
|
||||
#include "hook.h"
|
||||
|
||||
@ -38,19 +41,33 @@
|
||||
int hooks[5] = {-1, -1, -1, -1};
|
||||
FILE *fileHooks[2] = {NULL, NULL};
|
||||
int fileRead[2] = {0, 0};
|
||||
uint32_t elf_crc = 0;
|
||||
|
||||
cpuvendor cpu_vendor = {0};
|
||||
|
||||
static int callback(struct dl_phdr_info *info, size_t size, void *data);
|
||||
|
||||
uint16_t basePortAddress = 0xFFFF;
|
||||
|
||||
/**
|
||||
* Signal handler for the SIGSEGV signal, which is triggered when a process tries to access an illegal memory location.
|
||||
* @param signal
|
||||
* @param info
|
||||
* @param ptr
|
||||
*/
|
||||
static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
{
|
||||
ucontext_t *ctx = ptr;
|
||||
|
||||
// Get the address of the instruction causing the segfault
|
||||
uint8_t *code = (uint8_t *)ctx->uc_mcontext.gregs[REG_EIP];
|
||||
|
||||
printf("Code: 0x%08x - Port: 0x%08x\n", *code, (ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF));
|
||||
switch (*code)
|
||||
{
|
||||
case 0xED:
|
||||
{
|
||||
// Get the port number from the EDX register
|
||||
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
|
||||
|
||||
// The first port called is usually random, but everything after that
|
||||
@ -60,9 +77,11 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
if (basePortAddress == 0xFFFF)
|
||||
basePortAddress = port;
|
||||
|
||||
// Adjust the port number if necessary
|
||||
if (port > 0x38)
|
||||
port = port - basePortAddress;
|
||||
|
||||
// Call the security board input function with the port number and data
|
||||
securityBoardIn(port, (uint32_t *)&(ctx->uc_mcontext.gregs[REG_EAX]));
|
||||
|
||||
ctx->uc_mcontext.gregs[REG_EIP]++;
|
||||
@ -70,15 +89,17 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE7: // OUT IMMIDIATE
|
||||
case 0xE7: // OUT IMMEDIATE
|
||||
{
|
||||
// Increment the instruction pointer by two to skip over this instruction
|
||||
ctx->uc_mcontext.gregs[REG_EIP] += 2;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE6: // OUT IMMIDIATE
|
||||
case 0xE6: // OUT IMMEDIATE
|
||||
{
|
||||
// Increment the instruction pointer by two to skip over this instruction
|
||||
ctx->uc_mcontext.gregs[REG_EIP] += 2;
|
||||
return;
|
||||
}
|
||||
@ -108,9 +129,14 @@ static void handleSegfault(int signal, siginfo_t *info, void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((constructor)) hook_init()
|
||||
{
|
||||
printf("SEGA Lindbergh Loader\nRobert Dilley 2022\nNot for public consumption\n\n");
|
||||
// Get offsets of the Game's ELF and calculate CRC32.
|
||||
dl_iterate_phdr(callback, NULL);
|
||||
// Get CPU ID
|
||||
getCPUID();
|
||||
|
||||
// Implement SIGSEGV handler
|
||||
struct sigaction act;
|
||||
@ -118,9 +144,9 @@ void __attribute__((constructor)) hook_init()
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
sigaction(SIGSEGV, &act, NULL);
|
||||
|
||||
initConfig();
|
||||
initConfig(elf_crc);
|
||||
|
||||
if (initPatch() != 0)
|
||||
if(initPatch() != 0)
|
||||
exit(1);
|
||||
|
||||
if (initEeprom() != 0)
|
||||
@ -206,18 +232,30 @@ int open64(const char *pathname, int flags)
|
||||
return open(pathname, flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
{
|
||||
FILE *(*_fopen)(const char *restrict pathname, const char *restrict mode) = dlsym(RTLD_NEXT, "fopen");
|
||||
// printf("fopen %s\n", pathname);
|
||||
|
||||
if (strcmp(pathname, "/root/lindbergrc") == 0)
|
||||
{
|
||||
return _fopen("lindbergrc", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0)
|
||||
{
|
||||
return _fopen("logo.tga", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/LucidaConsole_12.tga") == 0)
|
||||
{
|
||||
return _fopen("LucidaConsole_12.tga", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/LucidaConsole_12.abc") == 0)
|
||||
{
|
||||
return _fopen("LucidaConsole_12.abc", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/proc/cpuinfo") == 0)
|
||||
{
|
||||
fileRead[CPUINFO] = 0;
|
||||
@ -242,6 +280,25 @@ FILE *fopen64(const char *pathname, const char *mode)
|
||||
return fileHooks[OSRELEASE];
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/logo_red.tga") == 0)
|
||||
{
|
||||
return _fopen64("logo_red.tga", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0)
|
||||
{
|
||||
return _fopen64("logo.tga", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.tga") == 0)
|
||||
{
|
||||
return _fopen64("SEGA_KakuGothic-DB-Roman_12.tga", mode);
|
||||
}
|
||||
|
||||
if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.abc") == 0)
|
||||
{
|
||||
return _fopen64("SEGA_KakuGothic-DB-Roman_12.abc", mode);
|
||||
}
|
||||
return _fopen64(pathname, mode);
|
||||
}
|
||||
|
||||
@ -465,7 +522,7 @@ float powf(float base, float exponent)
|
||||
return (float)pow((double)base, (double)exponent);
|
||||
}
|
||||
|
||||
/** This might be required for some games
|
||||
/*
|
||||
int sem_wait(sem_t *sem)
|
||||
{
|
||||
int (*original_sem_wait)(sem_t * sem) = dlsym(RTLD_NEXT, "sem_wait");
|
||||
@ -476,6 +533,10 @@ int sem_wait(sem_t *sem)
|
||||
/**
|
||||
* Hook function used by Harley Davidson to change IPs to localhost
|
||||
* Currently does nothing.
|
||||
* @param sockfd
|
||||
* @param addr
|
||||
* @param addrlen
|
||||
* @return
|
||||
*/
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
@ -491,6 +552,45 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
return _connect(sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to calculate CRC32 checksum in memory.
|
||||
*/
|
||||
uint32_t get_crc32(const char *s,size_t n)
|
||||
{
|
||||
uint32_t crc=0xFFFFFFFF;
|
||||
|
||||
for(size_t i=0;i<n;i++) {
|
||||
char ch=s[i];
|
||||
for(size_t j=0;j<8;j++) {
|
||||
uint32_t b=(ch^crc)&1;
|
||||
crc>>=1;
|
||||
if(b) crc=crc^0xEDB88320;
|
||||
ch>>=1;
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to get the offset and size of the execution program in memory of the ELF we hook to.
|
||||
*/
|
||||
static int callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
if((info->dlpi_phnum >= 3) && (info->dlpi_phdr[2].p_type == PT_LOAD) && (info->dlpi_phdr[2].p_flags == 5))
|
||||
{
|
||||
elf_crc = get_crc32((void *)(info->dlpi_addr + info->dlpi_phdr[2].p_vaddr+10),128);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void getCPUID()
|
||||
{
|
||||
unsigned eax;
|
||||
eax = 0;
|
||||
__get_cpuid(0, &eax, &cpu_vendor.ebx, &cpu_vendor.ecx, &cpu_vendor.edx);
|
||||
printf("CPU Vendor: %.4s%.4s%.4s\n", (const char*)&cpu_vendor.ebx,(const char*)&cpu_vendor.edx,(const char*)&cpu_vendor.ecx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the game changing the DISPLAY environment variable
|
||||
*/
|
||||
|
@ -0,0 +1,9 @@
|
||||
uint32_t get_crc32(const char *s,size_t n);
|
||||
void getCPUID();
|
||||
typedef struct
|
||||
{
|
||||
unsigned ebx;
|
||||
unsigned edx;
|
||||
unsigned ecx;
|
||||
}cpuvendor;
|
||||
|
@ -5,6 +5,9 @@
|
||||
|
||||
#include "patch.h"
|
||||
#include "config.h"
|
||||
#include "hook.h"
|
||||
|
||||
extern cpuvendor cpu_vendor;
|
||||
|
||||
static void setVariable(uint32_t address, uint32_t value)
|
||||
{
|
||||
@ -14,7 +17,7 @@ static void setVariable(uint32_t address, uint32_t value)
|
||||
|
||||
void *toModify = (void *)(address - (address % pagesize));
|
||||
|
||||
int prot = mprotect(toModify, pagesize, PROT_WRITE);
|
||||
int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE);
|
||||
if (prot != 0)
|
||||
{
|
||||
printf("Error: Cannot unprotect memory region to change variable (%d)\n", prot);
|
||||
@ -70,75 +73,116 @@ int initPatch()
|
||||
|
||||
switch (game)
|
||||
{
|
||||
case RTUNED:
|
||||
{
|
||||
detourFunction(0x08366846, amDongleInit);
|
||||
detourFunction(0x08365301, amDongleIsAvailable);
|
||||
detourFunction(0x08365cf7, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
|
||||
case SRTV:
|
||||
{
|
||||
detourFunction(0x084d5b40, amDongleInit);
|
||||
detourFunction(0x084d45f9, amDongleIsAvailable);
|
||||
detourFunction(0x084d4fef, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
|
||||
case ABC:
|
||||
{
|
||||
detourFunction(0x081e3424, amDongleInit);
|
||||
detourFunction(0x081e3772, amDongleIsAvailable);
|
||||
detourFunction(0x081e369e, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
case OUTRUN:
|
||||
{
|
||||
setVariable(0x0893a24c, 2); // amBackupDebugLevel
|
||||
setVariable(0x0893a260, 2); // amCreditDebugLevel
|
||||
setVariable(0x0893a4b8, 2); // amDipswDebugLevel
|
||||
setVariable(0x0893a4bc, 2); // amDongleDebugLevel
|
||||
setVariable(0x0893a4c0, 2); // amEepromDebugLevel
|
||||
setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel
|
||||
setVariable(0x0893a4c8, 2); // amJvsDebugLevel
|
||||
setVariable(0x0893a4cc, 2); // amLibDebugLevel
|
||||
setVariable(0x0893a4d0, 2); // amMiscDebugLevel
|
||||
setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel
|
||||
setVariable(0x0893a4d8, 2); // amSysDataDebugLevel
|
||||
setVariable(0x0893a4e0, 2); // bcLibDebugLevel
|
||||
detourFunction(0x08190e80, amDongleInit);
|
||||
detourFunction(0x08191201, amDongleIsAvailable);
|
||||
detourFunction(0x08191125, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
case RTUNED:
|
||||
{
|
||||
detourFunction(0x08366846, amDongleInit);
|
||||
detourFunction(0x08365301, amDongleIsAvailable);
|
||||
detourFunction(0x08365cf7, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
|
||||
case THE_HOUSE_OF_THE_DEAD_4:
|
||||
{
|
||||
setVariable(0x0a737c60, 2); // amBackupDebugLevel
|
||||
setVariable(0x0a737c64, 2); // amChunkDataDebugLevel
|
||||
setVariable(0x0a737c80, 2); // amCreditDebugLevel
|
||||
setVariable(0x0a737ed8, 2); // amDipswDebugLevel
|
||||
setVariable(0x0a737edc, 2); // amDiskDebugLevel
|
||||
setVariable(0x0a737ee0, 2); // amDongleDebugLevel
|
||||
setVariable(0x0a737ee4, 2); // amEepromDebugLevel
|
||||
setVariable(0x0a737ee8, 2); // amHmDebugLevel
|
||||
setVariable(0x0a737ef0, 2); // amJvsDebugLevel
|
||||
setVariable(0x0a737f14, 2); // amLibDebugLevel
|
||||
setVariable(0x0a737f18, 2); // amMiscDebugLevel
|
||||
setVariable(0x0a737f1c, 2); // amSysDataDebugLevel
|
||||
setVariable(0x0a737f20, 2); // bcLibDebugLevel
|
||||
setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask
|
||||
detourFunction(0x08320178, amDongleInit);
|
||||
detourFunction(0x08320459, amDongleIsAvailable);
|
||||
detourFunction(0x083203c0, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
case SRTV:
|
||||
{
|
||||
detourFunction(0x084d5b40, amDongleInit);
|
||||
detourFunction(0x084d45f9, amDongleIsAvailable);
|
||||
detourFunction(0x084d4fef, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
case ABC_2006:
|
||||
{
|
||||
setVariable(0x0a0a37e4, 2); // amBackupDebugLevel
|
||||
setVariable(0x0a0a3800, 2); // amCreditDebugLevel
|
||||
setVariable(0x0a0a3a58, 2); // amDipswDebugLevel
|
||||
setVariable(0x0a0a3a5c, 2); // amDongleDebugLevel
|
||||
setVariable(0x0a0a3a60, 2); // amEepromDebugLevel
|
||||
setVariable(0x0a0a3a64, 2); // amHwmonitorDebugLevel
|
||||
setVariable(0x0a0a3a68, 2); // amJvsDebugLevel
|
||||
setVariable(0x0a0a3a6c, 2); // amLibDebugLevel
|
||||
setVariable(0x0a0a3a70, 2); // amMiscDebugLevel
|
||||
setVariable(0x0a0a3a74, 2); // amOsinfoDebugLevel
|
||||
setVariable(0x0a0a3a78, 2); // amSysDataDebugLevel
|
||||
setVariable(0x0a0a3a80, 2); // bcLibDebugLevel
|
||||
detourFunction(0x081e4980, amDongleInit);
|
||||
detourFunction(0x081e4cce, amDongleIsAvailable);
|
||||
detourFunction(0x081e4bfa, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
case ABC_2007:
|
||||
{
|
||||
setVariable(0x0a0a0d24, 2); // amBackupDebugLevel
|
||||
setVariable(0x0a0a0d40, 2); // amCreditDebugLevel
|
||||
setVariable(0x0a0a0f98, 2); // amDipswDebugLevel
|
||||
setVariable(0x0a0a0f9c, 2); // amDongleDebugLevel
|
||||
setVariable(0x0a0a0fa0, 2); // amEepromDebugLevel
|
||||
setVariable(0x0a0a0fa4, 2); // amHwmonitorDebugLevel
|
||||
setVariable(0x0a0a0fa8, 2); // amJvsDebugLevel
|
||||
setVariable(0x0a0a0fac, 2); // amLibDebugLevel
|
||||
setVariable(0x0a0a0fb0, 2); // amMiscDebugLevel
|
||||
setVariable(0x0a0a0fb4, 2); // amOsinfoDebugLevel
|
||||
setVariable(0x0a0a0fb8, 2); // amSysDataDebugLevel
|
||||
setVariable(0x0a0a0fc0, 2); // bcLibDebugLevel
|
||||
detourFunction(0x081e3424, amDongleInit);
|
||||
detourFunction(0x081e3772, amDongleIsAvailable);
|
||||
detourFunction(0x081e369e, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
case OUTRUN:
|
||||
{
|
||||
setVariable(0x0893a24c, 2); // amBackupDebugLevel
|
||||
setVariable(0x0893a260, 2); // amCreditDebugLevel
|
||||
setVariable(0x0893a4b8, 2); // amDipswDebugLevel
|
||||
setVariable(0x0893a4bc, 2); // amDongleDebugLevel
|
||||
setVariable(0x0893a4c0, 2); // amEepromDebugLevel
|
||||
setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel
|
||||
setVariable(0x0893a4c8, 2); // amJvsDebugLevel
|
||||
setVariable(0x0893a4cc, 2); // amLibDebugLevel
|
||||
setVariable(0x0893a4d0, 2); // amMiscDebugLevel
|
||||
setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel
|
||||
setVariable(0x0893a4d8, 2); // amSysDataDebugLevel
|
||||
setVariable(0x0893a4e0, 2); // bcLibDebugLevel
|
||||
detourFunction(0x08190e80, amDongleInit);
|
||||
detourFunction(0x08191201, amDongleIsAvailable);
|
||||
detourFunction(0x08191125, amDongleUpdate);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Don't do any patches for random games
|
||||
case THE_HOUSE_OF_THE_DEAD_4:
|
||||
{
|
||||
setVariable(0x0a737c60, 2); // amBackupDebugLevel
|
||||
setVariable(0x0a737c64, 2); // amChunkDataDebugLevel
|
||||
setVariable(0x0a737c80, 2); // amCreditDebugLevel
|
||||
setVariable(0x0a737ed8, 2); // amDipswDebugLevel
|
||||
setVariable(0x0a737edc, 2); // amDiskDebugLevel
|
||||
setVariable(0x0a737ee0, 2); // amDongleDebugLevel
|
||||
setVariable(0x0a737ee4, 2); // amEepromDebugLevel
|
||||
setVariable(0x0a737ee8, 2); // amHmDebugLevel
|
||||
setVariable(0x0a737ef0, 2); // amJvsDebugLevel
|
||||
setVariable(0x0a737f14, 2); // amLibDebugLevel
|
||||
setVariable(0x0a737f18, 2); // amMiscDebugLevel
|
||||
setVariable(0x0a737f1c, 2); // amSysDataDebugLevel
|
||||
setVariable(0x0a737f20, 2); // bcLibDebugLevel
|
||||
setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask
|
||||
detourFunction(0x08320178, amDongleInit);
|
||||
detourFunction(0x08320459, amDongleIsAvailable);
|
||||
detourFunction(0x083203c0, amDongleUpdate);
|
||||
setVariable(0x0837d6aa, cpu_vendor.ebx);
|
||||
setVariable(0x0837d6ba, cpu_vendor.edx);
|
||||
setVariable(0x0837d6c5, cpu_vendor.ecx);
|
||||
}
|
||||
break;
|
||||
case THE_HOUSE_OF_THE_DEAD_4_TEST:
|
||||
{
|
||||
detourFunction(0x080677a0, amDongleInit);
|
||||
detourFunction(0x08067a81, amDongleIsAvailable);
|
||||
detourFunction(0x080679e8, amDongleUpdate);
|
||||
setVariable(0x0807217a, cpu_vendor.ebx);
|
||||
setVariable(0x0807218a, cpu_vendor.edx);
|
||||
setVariable(0x08072195, cpu_vendor.ecx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Don't do any patches for random games
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user