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;
}