tools/gdc-psyfork/gdc.cpp
changeset 3954 f98bbd1892df
parent 3742 80034eb49c32
child 3956 1ccbc1dfa814
     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;