make it so certain options can be customized at runtime

This commit is contained in:
Cheat Engine 2022-11-02 15:24:00 +01:00
parent e79eae7fb2
commit af6ec97d0d
6 changed files with 314 additions and 12 deletions

View File

@ -327,7 +327,7 @@
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.961414452" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/ceserver/Debug-linux}" enableAutoBuild="true" id="cdt.managedbuild.target.gnu.builder.base.251682825" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<builder buildPath="${workspace_loc:/ceserver/Debug-linux}" enableAutoBuild="false" id="cdt.managedbuild.target.gnu.builder.base.251682825" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.197361360" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>

View File

@ -11,6 +11,7 @@ C_SRCS += \
../extensionfunctions.c \
../extensionloader.c \
../native-api.c \
../options.c \
../porthelp.c \
../symbols.c \
../threads.c
@ -23,6 +24,7 @@ OBJS += \
./extensionfunctions.o \
./extensionloader.o \
./native-api.o \
./options.o \
./porthelp.o \
./symbols.o \
./threads.o
@ -35,6 +37,7 @@ C_DEPS += \
./extensionfunctions.d \
./extensionloader.d \
./native-api.d \
./options.d \
./porthelp.d \
./symbols.d \
./threads.d

View File

@ -34,6 +34,9 @@
#include "symbols.h"
#include "extensionfunctions.h"
#include "native-api.h"
#include "extensionloader.h"
#include "options.h"
pthread_t pth;
pthread_t identifierthread;
volatile int done;
@ -45,6 +48,11 @@ __thread int debugfd;
__thread char* threadname;
#define CESERVERVERSION 4
char versionstring[]="CHEATENGINE Network 2.2";
ssize_t recvall (int s, void *buf, size_t size, int flags)
@ -126,6 +134,48 @@ ssize_t sendall (int s, void *buf, size_t size, int flags)
return totalsent;
}
ssize_t sendstring16(int s, char *str, int flags)
{
uint16_t l;
if (str)
l=strlen(str);
else
l=0;
sendall(s, &l,sizeof(l),l?MSG_MORE:flags);
if (l)
sendall(s, str, l,flags);
return l;
}
int sendinteger(int s, int val, int flags)
{
return sendall(s, &val,sizeof(val),flags);
}
char* receivestring16(int s)
/* Receives a string that is preceded by a 16 bit length identifier (Allocates a string. Clean it up yourself)
* returns NULL if the length is 0 bytes
*/
{
char *str;
uint16_t l;
recvall(s, &l, sizeof(l),0);
if (l)
{
str=malloc(l+1);
recvall(s, str, l,0);
str[l+1]=0;
return str;
}
else
return NULL;
}
int DispatchCommand(int currentsocket, unsigned char command)
{
@ -139,11 +189,20 @@ int DispatchCommand(int currentsocket, unsigned char command)
//debug_log("version request");
fflush(stdout);
int versionsize=strlen(versionstring);
#ifdef SHARED_LIBRARY
versionsize+=3;
#endif
v=(PCeVersion)malloc(sizeof(CeVersion)+versionsize);
v->stringsize=versionsize;
v->version=CESERVERVERSION;
#ifdef SHARED_LIBRARY
memcpy((char *)v+sizeof(CeVersion),"lib",3);//tell ce it's the lib version
memcpy((char *)v+sizeof(CeVersion)+3, versionstring, versionsize);
#else
memcpy((char *)v+sizeof(CeVersion), versionstring, versionsize);
#endif
//version request
sendall(currentsocket, v, sizeof(CeVersion)+versionsize, 0);
@ -225,7 +284,7 @@ int DispatchCommand(int currentsocket, unsigned char command)
fflush(stdout);
close(currentsocket);
return NULL;
return 0;
}
case CMD_TERMINATESERVER:
@ -895,7 +954,6 @@ case CMD_SETTHREADCONTEXT:
case CMD_VIRTUALQUERYEXFULL:
{
CeVirtualQueryExFullInput c;
CeVirtualQueryExFullOutput o;
r=recvall(currentsocket, &c, sizeof(c), MSG_WAITALL);
if (r>0)
@ -985,7 +1043,7 @@ case CMD_SETTHREADCONTEXT:
debug_log("Error\n");
fflush(stdout);
close(currentsocket);
return NULL;
return 0;
}
break;
}
@ -1006,7 +1064,6 @@ case CMD_SETTHREADCONTEXT:
if (recvall(currentsocket, symbolpath, symbolpathsize, MSG_WAITALL)>0)
{
unsigned char *output=NULL;
int outputsize;
//debug_log("symbolpath=%s\n", symbolpath);
@ -1173,13 +1230,13 @@ case CMD_SETTHREADCONTEXT:
newprotection=0;
switch (c.windowsprotection)
{
newprotection=0;
case PAGE_EXECUTE_READWRITE: newprotection=PROT_WRITE | PROT_READ | PROT_EXEC; break;
case PAGE_EXECUTE_READ: newprotection=PROT_READ | PROT_EXEC; break;
case PAGE_EXECUTE: newprotection=PROT_EXEC; break;
case PAGE_READWRITE: newprotection=PROT_READ | PROT_WRITE; break;
case PAGE_READONLY: newprotection=PROT_READ; break;
default:
newprotection=0;
}
r=ext_changememoryprotection(c.hProcess, c.address, c.size, newprotection);
@ -1194,6 +1251,24 @@ case CMD_SETTHREADCONTEXT:
break;
}
case CMD_GETOPTIONS:
{
handleGetOptions(currentsocket);
break;
}
case CMD_GETOPTIONVALUE:
{
handleGetOption(currentsocket);
break;
}
case CMD_SETOPTIONVALUE:
{
handleSetOption(currentsocket);
break;
}
case CMD_AOBSCAN:
{
CeAobScanInput c;
@ -1203,7 +1278,7 @@ case CMD_SETTHREADCONTEXT:
int n = c.scansize;
char* data = (char*)malloc(n*2);
uint64_t* match_addr = (int*)malloc(sizeof(uint64_t) * MAX_HIT_COUNT);
uint64_t* match_addr = (uint64_t*)malloc(sizeof(uint64_t) * MAX_HIT_COUNT);
if (recvall(currentsocket, data, n*2, 0)>0)
{
@ -1234,6 +1309,8 @@ case CMD_SETTHREADCONTEXT:
}
return 10000; //got to here
}
int CheckForAndDispatchCommand(int currentsocket)

View File

@ -54,7 +54,11 @@
#define CMD_CREATETOOLHELP32SNAPSHOTEX 35
#define CMD_CHANGEMEMORYPROTECTION 36
#define CMD_CHANGEMEMORYPROTECTION 36
#define CMD_GETOPTIONS 37
#define CMD_GETOPTIONVALUE 38
#define CMD_SETOPTIONVALUE 39
#define CMD_AOBSCAN 200
@ -62,9 +66,6 @@
#define CMD_COMMANDLIST2 255
//extern char *versionstring;
#pragma pack(1)
@ -263,6 +264,12 @@ typedef struct {
ssize_t sendall (int s, void *buf, size_t size, int flags);
ssize_t recvall (int s, void *buf, size_t size, int flags);
ssize_t sendstring16(int s, char *str, int flags);
char* receivestring16(int s);
int sendinteger(int s, int val, int flags);
int DispatchCommand(int currentsocket, unsigned char command);
int CheckForAndDispatchCommand(int currentsocket);

View File

@ -0,0 +1,187 @@
/*
* options.c
*
* Created on: Oct 31, 2022
* Author: eric
*/
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include "api.h"
#include "options.h"
#include "ceserver.h"
//OPTIONS
#define optioncount 3
CEServerOption optMRO={.optname="optMSO", .parent=NULL, .description="Memory search option", .acceptablevalues="0=/proc/pid/mem reads;1=ptrace read;2=process_vm_readv", .type=2, .data=&MEMORY_SEARCH_OPTION}; //base for read memory options
CEServerOption optATAM={.optname="optATAM", .parent=NULL, .description="Attach to access memory", .acceptablevalues=NULL, .type=1, .data=&ATTACH_TO_ACCESS_MEMORY}; //base for read memory options
CEServerOption optATWM={.optname="optATWM", .parent=NULL, .description="Attach to write memory", .acceptablevalues=NULL, .type=1, .data=&ATTACH_TO_WRITE_MEMORY}; //base for read memory options
PCEServerOption options[optioncount] = {&optMRO, &optATAM, &optATWM};
//0=file, 1=ptrace, 2=use process_vm_readv
void handleGetOptions(int currentsocket)
{
int i;
uint16_t count=optioncount;
debug_log("handleGetOptions\n");
sendall(currentsocket, &count, sizeof(count),MSG_MORE);
for (i=0; i<count; i++)
{
char *currentValue=getOptionValue(options[i]);
sendstring16(currentsocket, options[i]->optname, MSG_MORE);
sendstring16(currentsocket, options[i]->parent, MSG_MORE);
sendstring16(currentsocket, options[i]->description, MSG_MORE);
sendstring16(currentsocket, options[i]->acceptablevalues, MSG_MORE);
sendstring16(currentsocket, currentValue, MSG_MORE);
sendinteger(currentsocket, options[i]->type, (i==count-1)?0:MSG_MORE);
free(currentValue);
}
}
PCEServerOption getOption(char *name)
{
int i;
for (i=0; i<optioncount; i++)
if (strcmp(name, options[i]->optname)==0)
return options[i];
return NULL;
}
void handleSetOption(int currentsocket)
{
char *optname=receivestring16(currentsocket);
char *newvalue=receivestring16(currentsocket);
char r=0;
int i;
if (optname && newvalue)
{
PCEServerOption o=getOption(optname);
if (o)
{
switch (o->type)
{
case 1: //boolean
i=atoi(newvalue);
if (i)
*(BOOL *)(o->data)=1;
else
*(BOOL *)(o->data)=0;
break;
case 2: //int
*(int *)(o->data)=atoi(newvalue);
break;
case 3: //float
*(float *)(o->data)=atof(newvalue);
break;
case 4: //double
*(double *)(o->data)=atof(newvalue);
break;
case 5: //text
{
char *olds=*(char **)(o->data);
*(char **)(o->data)=strdup(newvalue);
free(olds);
break;
}
case 0:
default:
sendall(currentsocket, &r,1,0);
}
}
else
sendall(currentsocket, &r,1,0);
free(optname);
free(newvalue);
}
}
char *getOptionValue(PCEServerOption o)
//allocates a new string with the given value. Free this yourself when done using
{
int i;
float f;
double d;
char *str;
switch (o->type)
{
case 1: //boolean
i=*(BOOL *)(o->data);
if (i)
return strdup("1");
else
return strdup("0");
case 2: //int
i=*(int *)(o->data);
str=malloc(32);
snprintf(str,31,"%d", i);
return str;
case 3: //float
f=*(float *)(o->data);
str=malloc(64);
snprintf(str,63,"%f", f);
return str;
case 4: //double
d=*(double *)(o->data);
str=malloc(64);
snprintf(str,63,"%f", d);
return str;
case 5: //pointer to a pointer to a string
return strdup(*(char **)(o->data));
case 0: //label/parent. Invalid
default:
return NULL;
}
}
void handleGetOption(int currentsocket)
{
char *optname=receivestring16(currentsocket);
char *tempstring;
if (optname)
{
PCEServerOption o=getOption(optname);
if (o)
{
tempstring=getOptionValue(o);
sendstring16(currentsocket, tempstring, 0);
free(tempstring);
}
else
sendstring16(currentsocket, NULL,0); //invalid name
free(optname);
}
}

View File

@ -0,0 +1,28 @@
/*
* options.h
*
* Created on: Oct 31, 2022
* Author: eric
*/
#ifndef OPTIONS_H_
#define OPTIONS_H_
typedef struct {
char *optname;
char *parent;
char *description;
char *acceptablevalues; //contains a string of acceptable values, and their descriptions (value1=description;value2=description;value3=description;...) , if empty, the user can type in anything
int type; //way to parse the value. 0=parent (no values), 1=boolean, 2=int, 3=float, 4=double, 5=text
void *data;
//setter/getter customization?
} CEServerOption, *PCEServerOption;
void handleGetOptions(int currentsocket);
void handleGetOption(int currentsocket);
void handleSetOption(int currentsocket);
char *getOptionValue(PCEServerOption o);
#endif /* OPTIONS_H_ */