Add signature offset byte check support for gdc-psyfork (NPOTB).
Add signature offset byte check support for gdc-psyfork (NPOTB).
1.1 --- a/tools/gdc-psyfork/gdc.cpp Thu Jul 18 19:40:42 2013 -0400
1.2 +++ b/tools/gdc-psyfork/gdc.cpp Thu Jul 18 20:34:11 2013 -0400
1.3 @@ -19,6 +19,8 @@
1.4 char *symbols_file = NULL;
1.5
1.6 bool use_symtab = true;
1.7 +CGameConfig symbols;
1.8 +CGameConfig gc;
1.9
1.10 inline bool IsDigit( char c )
1.11 {
1.12 @@ -138,7 +140,6 @@
1.13 return 0;
1.14 }
1.15
1.16 - CGameConfig gc;
1.17 char err[512];
1.18 if (!gc.EnterFile(gamedata, err, sizeof(err)))
1.19 {
1.20 @@ -146,7 +147,6 @@
1.21 return 0;
1.22 }
1.23
1.24 - CGameConfig symbols;
1.25 if (!symbols.EnterFile(symbols_file ? symbols_file : "symbols.txt", err, sizeof(err)))
1.26 {
1.27 printf("symbols.txt: %s\n", err);
1.28 @@ -238,7 +238,7 @@
1.29 }
1.30 }
1.31
1.32 - printf("\nWindows offsets are (semi-)wild guesses!\n\n");
1.33 + printf("\nWindows offsets are (semi-)wild guesses!\n\nSignature offsets are wild guesses!\n\n");
1.34
1.35 for (list<Sig>::iterator it = gc.m_Sigs.begin(); it != gc.m_Sigs.end(); it++)
1.36 {
1.37 @@ -296,6 +296,11 @@
1.38 it->name,
1.39 (it->lib == Server) ? "server" : "engine"
1.40 );
1.41 +
1.42 + //Check if they signature has a matching offset
1.43 + CheckWindowsSigOffset(it->name, winSymbol, winFile);
1.44 + CheckLinuxSigOffset(it->name, linSymbol, linHandle);
1.45 +
1.46 }
1.47 else
1.48 {
1.49 @@ -367,7 +372,206 @@
1.50
1.51 return 0;
1.52 }
1.53 +void CheckWindowsSigOffset(char* name, const char* symbol, int file)
1.54 +{
1.55 + void *ptr = GetWindowsSigPtr(file, symbol);
1.56 + if(!ptr)
1.57 + {
1.58 + return;
1.59 + }
1.60 + const char* sigOffsetKey = NULL;
1.61 + const char* sigOffsetByte = NULL;
1.62 + int sigOffset = -1;
1.63 + char sigOffsetName[128];
1.64 + char sigByteName[128];
1.65
1.66 + snprintf(sigOffsetName, sizeof(sigOffsetName), "%s_Offset", name);
1.67 + snprintf(sigByteName, sizeof(sigByteName), "%s_Byte_Win", name);
1.68 +
1.69 + sigOffsetKey = symbols.GetKeyValue((const char *)sigOffsetName);
1.70 + if(sigOffsetKey == NULL)
1.71 + {
1.72 +
1.73 + //Maybe it has multiple?
1.74 + for(unsigned int i = 1; i <= 4; i++)
1.75 + {
1.76 + snprintf(sigOffsetName, sizeof(sigOffsetName), "%s_Offset%i", name, i);
1.77 + snprintf(sigByteName, sizeof(sigByteName), "%s_Byte_Win%i", name, i);
1.78 + sigOffsetKey = symbols.GetKeyValue((const char *)sigOffsetName);
1.79 +
1.80 + if(sigOffsetKey == NULL)
1.81 + {
1.82 + break;
1.83 + }
1.84 +
1.85 + sigOffset = GetOffset(sigOffsetKey, true);
1.86 + sigOffsetByte = symbols.GetKeyValue((const char *)sigByteName);
1.87 +
1.88 + if(sigOffset != -1 && sigOffsetByte != NULL)//Got the offset in the function
1.89 + {
1.90 + uint8_t iByte = strtoul(sigOffsetByte, NULL, 16);
1.91 +
1.92 + if(iByte == *(uint8_t *)((intptr_t)ptr + sigOffset))
1.93 + {
1.94 + printf(" w: %s -> %s (%4d) == \\x%s GOOD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.95 + }
1.96 + else
1.97 + {
1.98 + printf("! w: %s -> %s (%4d) != \\x%s BAD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.99 + }
1.100 + }
1.101 + }
1.102 + }
1.103 + else
1.104 + {
1.105 + sigOffset = GetOffset(sigOffsetKey, true);
1.106 + sigOffsetByte = symbols.GetKeyValue((const char *)sigByteName);
1.107 +
1.108 + if(sigOffset != -1 && sigOffsetByte != NULL)//Got the offset in the function
1.109 + {
1.110 + uint8_t iByte = strtoul(sigOffsetByte, NULL, 16);
1.111 +
1.112 + if(iByte == *(uint8_t *)((intptr_t)ptr + sigOffset))
1.113 + {
1.114 + printf(" w: %s -> %s (%4d) == \\x%s GOOD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.115 + }
1.116 + else
1.117 + {
1.118 + printf("! w: %s -> %s (%4d) != \\x%s BAD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.119 + }
1.120 + }
1.121 + }
1.122 +}
1.123 +void CheckLinuxSigOffset(char* name, const char* symbol, void * handle)
1.124 +{
1.125 + void *ptr = GetLinuxSigPtr(handle, symbol);
1.126 + if(!ptr)
1.127 + {
1.128 + return;
1.129 + }
1.130 + const char* sigOffsetKey = NULL;
1.131 + const char* sigOffsetByte = NULL;
1.132 + int sigOffset = -1;
1.133 + char sigOffsetName[128];
1.134 + char sigByteName[128];
1.135 +
1.136 + snprintf(sigOffsetName, sizeof(sigOffsetName), "%s_Offset", name);
1.137 + snprintf(sigByteName, sizeof(sigByteName), "%s_Byte_Lin", name);
1.138 +
1.139 + sigOffsetKey = symbols.GetKeyValue((const char *)sigOffsetName);
1.140 +
1.141 + if(sigOffsetKey == NULL)
1.142 + {
1.143 +
1.144 + //Maybe it has multiple?
1.145 + for(unsigned int i = 1; i <= 4; i++)
1.146 + {
1.147 + snprintf(sigOffsetName, sizeof(sigOffsetName), "%s_Offset%i", name, i);
1.148 + snprintf(sigByteName, sizeof(sigByteName), "%s_Byte_Lin%i", name, i);
1.149 + sigOffsetKey = symbols.GetKeyValue((const char *)sigOffsetName);
1.150 +
1.151 + if(sigOffsetKey == NULL)
1.152 + {
1.153 + break;
1.154 + }
1.155 +
1.156 + sigOffset = GetOffset(sigOffsetKey, false);
1.157 + sigOffsetByte = symbols.GetKeyValue((const char *)sigByteName);
1.158 +
1.159 + if(sigOffset != -1 && sigOffsetByte != NULL)//Got the offset in the function
1.160 + {
1.161 + uint8_t iByte = strtoul(sigOffsetByte, NULL, 16);
1.162 +
1.163 + if(iByte == *(uint8_t *)((intptr_t)ptr + sigOffset))
1.164 + {
1.165 + printf(" l: %s -> %s (%4d) == \\x%s GOOD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.166 + }
1.167 + else
1.168 + {
1.169 + printf("! l: %s -> %s (%4d) != \\x%s BAD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.170 + }
1.171 + }
1.172 + }
1.173 + }
1.174 + else
1.175 + {
1.176 + sigOffset = GetOffset(sigOffsetKey, true);
1.177 + sigOffsetByte = symbols.GetKeyValue((const char *)sigByteName);
1.178 +
1.179 + if(sigOffset != -1 && sigOffsetByte != NULL)//Got the offset in the function
1.180 + {
1.181 + uint8_t iByte = strtoul(sigOffsetByte, NULL, 16);
1.182 +
1.183 + if(iByte == *(uint8_t *)((intptr_t)ptr + sigOffset))
1.184 + {
1.185 + printf(" l: %s -> %s (%4d) == \\x%s GOOD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.186 + }
1.187 + else
1.188 + {
1.189 + printf("! l: %s -> %s (%4d) != \\x%s BAD\n", name, sigOffsetKey, sigOffset, sigOffsetByte);
1.190 + }
1.191 + }
1.192 + }
1.193 +}
1.194 +int GetOffset(const char* key, bool windows)
1.195 +{
1.196 + for (list<Offset>::iterator it = gc.m_Offsets.begin(); it != gc.m_Offsets.end(); it++)
1.197 + {
1.198 + if (strcmp(it->name, key) == 0)
1.199 + {
1.200 + if(windows)
1.201 + return it->win;
1.202 + else
1.203 + return it->lin;
1.204 + }
1.205 + }
1.206 + return -1;
1.207 +}
1.208 +void *GetWindowsSigPtr(int file, const char* symbol)
1.209 +{
1.210 + int matches = 0;
1.211 + bool atFuncStart = true;
1.212 + bool isAt = (symbol[0] == '@');
1.213 + // we can't support this on windows from here
1.214 + if (isAt)
1.215 + return NULL;
1.216 +
1.217 + unsigned char real_sig[511];
1.218 + size_t real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), symbol);
1.219 +
1.220 + if (real_bytes >= 1)
1.221 + {
1.222 + return mu.FindPatternInFile(file, (char*)real_sig, real_bytes, matches, atFuncStart);
1.223 + }
1.224 + return NULL;
1.225 +
1.226 +}
1.227 +void *GetLinuxSigPtr(void *handle, const char* symbol)
1.228 +{
1.229 + bool isAt = (symbol[0] == '@' && symbol[1] != '\0');
1.230 + int matches = 0;
1.231 + bool dummy;
1.232 +
1.233 + if (isAt)
1.234 + {
1.235 + if( use_symtab && mu.ResolveSymbol(handle, &symbol[1]) )
1.236 + return mu.ResolveSymbol(handle, &symbol[1]);
1.237 + else if( !use_symtab && dlsym(handle, &symbol[1]) )
1.238 + return dlsym(handle, &symbol[1]);
1.239 + }
1.240 + else
1.241 + {
1.242 + unsigned char real_sig[511];
1.243 + size_t real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), symbol);
1.244 +
1.245 + if (real_bytes >= 1)
1.246 + {
1.247 + return mu.FindPattern(handle, (char*)real_sig, real_bytes, matches, dummy);
1.248 + }
1.249 + }
1.250 +
1.251 + return NULL;
1.252 +}
1.253 int checkSigStringW(int file, const char* symbol)
1.254 {
1.255 int matches = 0;
2.1 --- a/tools/gdc-psyfork/gdc.h Thu Jul 18 19:40:42 2013 -0400
2.2 +++ b/tools/gdc-psyfork/gdc.h Thu Jul 18 20:34:11 2013 -0400
2.3 @@ -18,5 +18,10 @@
2.4 size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
2.5 size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr);
2.6 unsigned int strncopy(char *dest, const char *src, size_t count);
2.7 +void CheckLinuxSigOffset(char* name, const char* symbol, void * handle);
2.8 +void CheckWindowsSigOffset(char* name, const char* symbol, int file);
2.9 +void *GetLinuxSigPtr(void *handle, const char* symbol);
2.10 +void *GetWindowsSigPtr(int file, const char* symbol);
2.11 +int GetOffset(const char* key, bool windows);
2.12
2.13 #endif // _INCLUDE_GDC_MAIN_H_