他人の空似自作物置場

tskUpdater.zip/tskUpdater.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

#pragma	comment(lib,"advapi32.lib")

void SetAppDir(void){
	int i;
	char AppDir[256];

	GetModuleFileName(NULL,AppDir,256);
	i = strlen(AppDir)-1;
	while(AppDir[i] != '\\' && AppDir[i] != '/' && i > 0)i--;
	AppDir[i] = '\0';
	SetCurrentDirectory(AppDir);
}

void *memmem(const void *_data, int dataLen, const void *_key, int keyLen){
	if(keyLen < 1){
		return NULL;
	}
	const unsigned char *data = static_cast<const unsigned char*>(_data);
	const unsigned char *key = static_cast<const unsigned char*>(_key);
	int i = 0;
	while(i < dataLen-keyLen){
		if(data[i]==key[0] && memcmp(reinterpret_cast<const void *>(&data[i+1]),reinterpret_cast<const void *>(&key[1]),keyLen-1)==0){
			return (void *)&data[i];
		}
		i++;
	}
	return NULL;
}

enum SEARCH_TYPE {
	STYPE_AFTER = 0,
	STYPE_AFTER_QWORD,
	STYPE_AFTER_DWORD,
	STYPE_AFTER_WORD,
	STYPE_AFTER_BYTE,
	STYPE_AHEAD,
	STYPE_AHEAD_QWORD,
	STYPE_AHEAD_DWORD,
	STYPE_AHEAD_WORD,
	STYPE_AHEAD_BYTE
};

long long search(unsigned char *data,int size, unsigned char *map, int mapSize,SEARCH_TYPE type){
	unsigned char *pos = static_cast<unsigned char *>(memmem(data, size, map, mapSize));
	if(pos == NULL){
		return -1;
	}
	if(type == STYPE_AFTER || type==STYPE_AFTER_DWORD){
		return *(int*)&pos[mapSize];
	} else if(type == STYPE_AFTER_QWORD){
		return *(long long*)&pos[mapSize];
	} else if(type == STYPE_AFTER_WORD){
		return *(short*)&pos[mapSize];
	} else if(type == STYPE_AFTER_BYTE){
		return *(char*)&pos[mapSize];
	} else if(type == STYPE_AHEAD || type==STYPE_AHEAD_QWORD){
		return *(int*)&pos[-4];
	} else if(type == STYPE_AHEAD_QWORD){
		return *(long long*)&pos[-8];
	} else if(type == STYPE_AHEAD_WORD){
		return *(short*)&pos[-2];
	} else if(type == STYPE_AHEAD_BYTE){
		return *(char*)&pos[-1];
	}
	return NULL;
}
char *strSearch(unsigned char *data,int size, char *str){
	char *pos = static_cast<char *>(memmem(data, size, str, strlen(str)));
	return pos;
}


int tskExec(){
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	memset(&si,0,sizeof(si));
	memset(&pi,0,sizeof(pi));
	si.cb = sizeof(si);
	if(CreateProcess(NULL,"./tsk.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi)){
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		return 0;
	}
	return 1;
}


char *GetTouhouPath(const char *regkey, const char *name, const char *exe_name,char *ini_name){
	HKEY hKey;
	static char str[256]="";
	char temp[256];
	DWORD size = sizeof(temp);
	FILE *fp;

	if(ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey,0,KEY_READ,&hKey)){
		if(ERROR_SUCCESS==RegQueryValueEx(hKey,"Inno Setup: App Path",NULL,NULL,reinterpret_cast<LPBYTE>(temp),&size)){
			RegCloseKey(hKey);
			sprintf(str, "%s\\%s",temp,exe_name);
			fp = fopen(str,"rb");
			if(fp!=NULL){
				fclose(fp);
				return str;
			}
			str[0] = '\0';
		}
		RegCloseKey(hKey);
	}

	return NULL;
}
char *GetTh105Path(void){
	return GetTouhouPath("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F9942587-59C1-43CC-8B6A-A5DB09CBA735}_is1", "緋想天", "th105.exe","StartupTH105");
}
char *GetTh123Path(void){
	return GetTouhouPath("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{8E5CFA2B-8CC5-4C8D-88CB-C4A1D4AD9790}_is1", "非想天則", "th123.exe","StartupTH123");
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int nCmdShow){
	FILE *fp;
	unsigned char *data;
	int size;

	SetAppDir();
	fp = fopen("tsk.exe","rb");
	if(fp == NULL){
		MessageBox(NULL, "tskUpdaterはtsk.exeと同じフォルダに配置して使用してください", "配置位置不正", MB_OK);
		return 1;
	}
	fclose(fp);
	fp = fopen(GetTh123Path(),"rb");
	if(fp == NULL){
		MessageBox(NULL, "非想天則が見つかりませんでした\nインストール情報が存在しないか、インストール後に移動されている可能性があります。\n\nパッチを当てなおすなどしてインストール情報を修正してください", "インストール情報不正", MB_OK);
		return 1;
	}
	fseek(fp,0,SEEK_END);
	size = ftell(fp);
	fseek(fp,0,SEEK_SET);
	data = static_cast<unsigned char*>(malloc(size));
	if(size != fread(data,1,size,fp)){
		printf("fread error\n");
		return 1;
	}
	fclose(fp);

	#define NAMES_MAX	2
	char *swrsName[NAMES_MAX];
	char *swrsNameList[] = {
		"SWRS_WINDOW_CLASS",
		"SWRS_WINDOW_TEXT"
	};
	{
		char *str[] = {
			"th123_",
			"東方非想天則 〜 超弩級ギニョルの謎を追え Ver"
		};
		int i = 0;
		while(i < NAMES_MAX){
			swrsName[i] = strSearch(data,size,str[i]);
			i++;
		}
	}

	#define ADDR_MAX	15
	int addr[ADDR_MAX];
	char *swrsAddrList[] = {
		"SWRS_ADDR_PBATTLEMGR",
		"SWRS_ADDR_PNETOBJECT",
		"SWRS_ADDR_COMMMODE",
		"SWRS_ADDR_LCHARID",
		"SWRS_ADDR_RCHARID",
		"SWRS_ADDR_SCENEID",
		"SWRS_ADDR_LCHAROFS",
		"SWRS_ADDR_RCHAROFS",
		"SWRS_ADDR_BTLMODEOFS",
		"SWRS_ADDR_LPROFOFS",
		"SWRS_ADDR_RPROFOFS",
		"SWRS_ADDR_NETUDPOFS",
		"SWRS_ADDR_ADRBEGOFS",
		"SWRS_ADDR_TOADDROFS",
		"SWRS_ADDR_WINCNTOFS"
	};
	{
		unsigned char map[][30] = {
			{0xEB, 0x02, 0x33, 0xC0, 0x68, 0x88, 0x06, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0xA3},
			{0x85, 0xC9, 0x74, 0x12, 0x8B, 0x11, 0x8B, 0x02, 0x6A, 0x01, 0xFF, 0xD0, 0xC7, 0x05},
			{0x83, 0xEC, 0x08, 0x83, 0xF8, 0x08, 0x0F, 0x94, 0xC1, 0x83, 0xC0, 0xFF, 0x83, 0xF8, 0x07, 0xC6, 0x05},
			{0x6A, 0x02, 0x6A, 0x20, 0x68},
			{0x89, 0x1D, 0xF0, 0x6C, 0x88, 0x00, 0xC7, 0x05},
			{0x8B, 0x52, 0x10, 0x50, 0xFF, 0xD2, 0xA1},
			{0x83, 0xEC, 0x08, 0xA1, 0xC4, 0x55, 0x88, 0x00, 0x53, 0x8B, 0x58},
			{0x83, 0xEC, 0x08, 0xA1, 0xC4, 0x55, 0x88, 0x00, 0x53, 0x8B, 0x58, 0x0C, 0x55, 0x56, 0x8B, 0x70},
			{0xFF, 0xD2, 0x85, 0xC0, 0x7E, 0x05, 0x83, 0xF8, 0x02, 0x7E, 0x27, 0xA1, 0xC4, 0x55, 0x88, 0x00, 0x83, 0xB8},
			{0x8D, 0x50, 0x01, 0x8A, 0x08, 0x83, 0xC0, 0x01, 0x84, 0xC9, 0x75, 0xF7, 0x2B, 0xC2, 0x85, 0xC0},
			{0x01, 0x75, 0x61, 0xA1, 0x80, 0x56, 0x88, 0x00, 0x85, 0xC0, 0x74, 0x0F, 0x8D, 0x48},
			{0x56, 0x8B, 0x35, 0x80, 0x56, 0x88, 0x00, 0x85, 0xF6, 0x74, 0x49, 0x8D, 0x8E},
			{0x33, 0xFF, 0x33, 0xDB, 0xEB, 0x0A, 0x8D, 0xA4, 0x24, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x49, 0x00, 0x8B, 0x8E},
			{0x8B, 0x97, 0xA4, 0x00, 0x00, 0x00, 0x8B, 0x87, 0xA8, 0x00, 0x00, 0x00, 0x8D, 0x9F, 0xA0, 0x00, 0x00, 0x00, 0x89, 0x4F},
			{0x3B, 0xC3, 0x7F, 0x02, 0x8B, 0xC3, 0x89, 0x46, 0x10, 0xEB, 0x03, 0x89, 0x5E, 0x10, 0x33, 0xD2, 0x38, 0x91}
		};
		int mapSize[] = {
			18,
			14,
			17,
			5,
			8,
			7,
			11,
			16,
			18,
			16,
			14,
			13,
			18,
			20,
			18
		};
		SEARCH_TYPE type[] = {
			STYPE_AFTER,
			STYPE_AFTER,
			STYPE_AHEAD,
			STYPE_AFTER,
			STYPE_AFTER,
			STYPE_AHEAD,
			STYPE_AFTER_BYTE,
			STYPE_AFTER_BYTE,
			STYPE_AFTER,
			STYPE_AHEAD_BYTE,
			STYPE_AFTER_BYTE,
			STYPE_AFTER,
			STYPE_AFTER,
			STYPE_AFTER_BYTE,
			STYPE_AFTER
		};
		int i = 0;
		while(i < ADDR_MAX){
			if(i == 4){
				*(int*)&map[i][2] = addr[3];
			} else if(i == 6){
				*(int*)&map[i][4] = addr[0];
			} else if(i == 7){
				*(int*)&map[i][4] = addr[0];
				*(char*)&map[i][11] = addr[6];
			} else if(i == 8){
				*(int*)&map[i][12] = addr[0];
			} else if(i == 10){
				*(int*)&map[i][4] = addr[1];
			} else if(i == 11){
				*(int*)&map[i][3] = addr[1];
			}
			addr[i] = search(data,size,map[i],mapSize[i],type[i]);
			if(i == 12){
				addr[i] += addr[11];
			}
			if(i == 13){
				addr[i] += addr[11];
			}
			if(addr[i] == -1){
				char message[256];
				sprintf(message, "項目:%sの更新に失敗しました\n正常に動作しない可能性があります", swrsAddrList[i]);
				MessageBox(NULL, message, "解析失敗", MB_OK);
			}
			i++;
		}
	}

	fp = fopen("SWRSAddr.ini","w");
	if(fp == NULL){
		MessageBox(NULL, "SWRSAddr.iniが開けません\n読み取り専用属性が設定されているか、別のアプリが編集禁止属性を設定している可能性があります", "更新結果出力失敗", MB_OK);
		return 1;
	}

	fprintf(fp, "[SWRSName]\n");
	int i = 0;
	while(i < NAMES_MAX){
		fprintf(fp, "%s=%s\n", swrsNameList[i], swrsName[i]);
		i++;
	}
	fprintf(fp, "\n");

	fprintf(fp, "[SWRSAddress]\n");
	i = 0;
	while(i < ADDR_MAX){
		fprintf(fp, "%s = 0x%08x\n", swrsAddrList[i], addr[i]);
		i++;
	}
	fclose(fp);
	free(data);

	if(tskExec()){
		MessageBox(NULL, "天測観起動に失敗しました\ntsk.exeが破損しているか、本アプリがなんらかの制限を受けている可能性があります", "不明なエラー", MB_OK);
		return 1;
	}
	return 0;
}