PeerGuardian – Version for OS X Lion

So I was sick of PeerGuardian not being updated for Lion, so I thought I would give it a shot.

I’ve simply zipped the application and the uninstaller here:

http://dump.tanaris4.com/PeerGuardian_Lion.zip

Few simple changes, compiled from this source: http://sourceforge.net/projects/peerguardian/files/PeerGuardian%20OS%20X/1.5.1/

Let me know if there is a more recent version of the source somewhere I should have been using.

Enjoy!

Note: You can’t use the bluetack lists, I recommend using those posted here: https://sites.google.com/site/blocklist/

Is Glider done?

Here was the last post made by Mercury over at mmoglider.

Dumping Descriptors – WoW version 4.2.2 build 14545

Here is another IDA script I just finished! It’s (hopefully) a semi-patch proof way to dump the descriptors!

Let me know if you have any issues. Note: mac only!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// Visit http://forum.gamedeception.net/
#include <ida.idc>
 
static main()
{
	auto disasm, sPath, hFile, dwStartFunc, dwEndFunc, s_descriptor, disasmAddr, addr, dwStringPtr, string;
 
	// Function name: MirrorInitialize
	dwStartFunc = FindBinary( INF_BASEADDR, SEARCH_DOWN, "55 89 E5 57 56 53 81 EC 8C 00 00 00 C7 45 E4" );
 
	if ( dwStartFunc == BADADDR ){
		Message("Unable to find address for MirrorInitialize, aborting...\n");
		return;
	}
 
	// store it where our database file is!
	sPath = ExtractPath( GetIdbPath() ) + "Objects_Enum.h";
 
	hFile = fopen( sPath, "w" );
	if( hFile != -1 )
	{
		fprintf( hFile, "// %s\n", GetWoWVersionString() );
		fprintf( hFile, "/*----------------------------------\n" );
		fprintf( hFile, "WoW Offset Dumper 14545 - IDC Script\n" );
		fprintf( hFile, "by Tanaris4\n\n" );
		fprintf( hFile, "Credits:\n" );
		fprintf( hFile, "kynox, bobbysing, Patrick, Dominik, Azorbix\n" );
		fprintf( hFile, "-----------------------------------*/\n\n" );
 
		// find the end of the function (search for "retn")
		dwEndFunc = dwStartFunc;
		do{
			disasm = GetDisasm( dwEndFunc );
 
			if ( strstr( disasm, "retn" ) > -1 )
				break;
 
			dwEndFunc++;
		} while ( 1 );
 
		disasmAddr = dwStartFunc;
 
		do{
			auto i, dwEnumId, szPrefix, dwFieldAddr, lastIndex;
 
			disasm = GetDisasm( disasmAddr );
 
			if ( disasmAddr == BADADDR || disasmAddr > dwEndFunc ){
        		break;
        	}
 
			// searching for: mov     [ebp+var_1C], offset dword_10BAE88
			if ( strstr( disasm, "mov" ) > -1 && strstr( disasm, "off" ) > -1 ){
 
				addr = GetOperandValue(disasmAddr, 1);
 
				dwStringPtr = Dword(addr-0x8);
				string = GetString( dwStringPtr, -1, ASCSTR_C );
 
				// is this a match?
				if ( strlen(string) > 0 ){
 
					szPrefix = getPrefix( string );
					if ( strlen(szPrefix) == 0 ){
						continue;
					}
 
					s_descriptor = getStructNameForString(string);
 
					// invalid descriptor?
					if ( strlen(s_descriptor) == 0 ){
						continue;
					}
 
					fprintf( hFile, "// Descriptors: 0x%08X\nenum %s\n{\n", addr-0x8, s_descriptor );
					i = 0;
 
					// create our enum
					dwEnumId = AddEnum( -1, s_descriptor, 0x1100000 );
 
					// update the name in IDA
					MakeName( addr, s_descriptor );
 
					// re-initialize some stuff
					addr = addr - 0x8;
					lastIndex = -1;
 
					// loop through all descriptors
					while ( getPrefix( string ) != "" ){
 
						auto dwIndex;
 
						dwStringPtr = Dword(addr);
						string = GetString( dwStringPtr, -1, ASCSTR_C );
 
						if ( strlen(string) == 0 ){
							break;
						}
 
						dwIndex = Dword( addr + 4 );
 
						// this makes 0 sense, we're done!
						if ( dwIndex < lastIndex ){
							break;
						}
 
						// since IDA didn't do this for us!
						MakeDword(addr);
						MakeDword(addr-0x14);
 
						AddConstEx( dwEnumId, string, dwIndex * 4, -1 );
						fprintf( hFile, "\t%s = 0x%X,\n", string, dwIndex * 4 );
 
						addr = addr + 0x14;
						i++;
						lastIndex = dwIndex;
					}
 
					fprintf( hFile, "\tTOTAL_%s_FIELDS = 0x%X\n", szPrefix, i );
					fprintf( hFile, "};\n" );
 
				}
 
 
			}
 
			disasmAddr = NextHead( disasmAddr, dwEndFunc );
		} while( 1 );
	}
 
	fclose( hFile );
 
	Message( "Successfully dumped to %s\n", sPath );
}
 
static getPrefix( string ){
 
		// unique case
	if ( strstr( string, "OBJECT_FIELD_CREATED_BY" ) == 0 ){
		return "GAMEOBJECT";
	}
	else if ( strstr( string, "ITEM_" ) > -1 ){
		return "ITEM";
	}
	else if ( strstr( string, "CONTAINER_" ) > -1 ){
		return "CONTAINER";
	}
	else if ( strstr( string, "UNIT_" ) > -1 ){
		return "UNIT";
	}
	else if ( strstr( string, "PLAYER_" ) > -1 ){
		return "PLAYER";
	}
	else if ( strstr( string, "GAMEOBJECT_" ) > -1 ){
		return "GAMEOBJECT";
	}
	else if ( strstr( string, "DYNAMICOBJECT_" ) > -1 ){
		return "DYNAMICOBJECT";
	}
	else if ( strstr( string, "CORPSE_" ) > -1 ){
		return "CORPSE";
	}
	else if ( strstr( string, "OBJECT_" ) > -1 ){
		return "OBJECT";
	}
 
	return "";
}
 
static getStructNameForString( string ){
 
	// unique case
	if ( strstr( string, "OBJECT_FIELD_CREATED_BY" ) == 0 ){
		return "eGameObjectFields";
	}
	else if ( strstr( string, "ITEM_" ) > -1 ){
		return "eItemFields";
	}
	else if ( strstr( string, "CONTAINER_" ) > -1 ){
		return "eContainerFields";
	}
	else if ( strstr( string, "UNIT_" ) > -1 ){
		return "eUnitFields";
	}
	else if ( strstr( string, "PLAYER_" ) > -1 ){
		return "ePlayerFields";
	}
	else if ( strstr( string, "GAMEOBJECT_" ) > -1 ){
		return "eGameObjectFields";
	}
	else if ( strstr( string, "DYNAMICOBJECT_" ) > -1 ){
		return "eDynamicObjectFields";
	}
	else if ( strstr( string, "CORPSE_" ) > -1 ){
		return "eCorpseFields";
	}
	else if ( strstr( string, "OBJECT_" ) > -1 ){
		return "eObjectFields";
	}
 
	return "";
}
 
static ExtractPath( sPath ){
	auto dwIndex;
	for ( dwIndex = strlen( sPath ); strstr( substr( sPath, dwIndex, -1 ), "/" ) && dwIndex > 0; dwIndex-- );
	return substr( sPath, 0, dwIndex + 1 );
}
 
static GetWoWVersionString(){
	auto sVersion, sBuild, sDate;
 
	sVersion = FindBinary( INF_BASEADDR, SEARCH_DOWN, "\"=> WoW Version %s (%s) %s\"" );
 
	if( sVersion == BADADDR )
	{
		Message( "Version format string not found" );
		return 0;
	}
 
	sVersion = DfirstB( sVersion );
 
	if( sVersion == BADADDR )
	{
		Message( "Version string unreferences" );
		return 0;
	}
 
	sVersion = PrevHead( sVersion, 0 );
	sBuild = PrevHead( sVersion, 0 );
	sDate = PrevHead( sBuild, 0 );
 
	sVersion = GetOperandValue( sVersion, 1 );
	sBuild = GetOperandValue( sBuild, 1 );
	sDate = GetOperandValue( sDate, 1 );
 
	sVersion = GetString( sVersion, -1, ASCSTR_C );
	sBuild = GetString( sBuild, -1, ASCSTR_C );
	sDate = GetString( sDate, -1, ASCSTR_C );
 
	return form( "Version: %s  Build number: %s  Build date: %s\n", sVersion, sBuild, sDate );
}{

Identifying DBCs – 4.2.2 Build 14545

So I haven’t made a post in while, nor shared a cool IDA script, so I thought I would!

This script currently works for 4.2.2 Build 14545 (and hopefully newer).

All it does is find the client DBC tables within the wow binary and dumps them to a header file. Let me know if you have any questions, pretty straightforward.

Note: MAC ONLY!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Script adapted from Kynox's solution
#include <ida.idc>
 
static main(){
    auto curAddr, xref, count, sPath, hFile;
 
	// WowClientDB_Common__Load - 4.2.2 build 14545
	curAddr = FindBinary( 0, SEARCH_DOWN, "55 89 E5 57 56 53 81 EC 3C 01 00 00 8B 7D 0C 8D 45 E4 89 44 24 04 8B 07 89 04 24 E8" );
 
    if ( curAddr == BADADDR ){
        Message("Can't find WowClientDB_Common__Load, aborting...\n");
        return;
    }
 
	// store it where our database file is!
	sPath = ExtractPath( GetIdbPath() ) + "ClientDBCTables.h";
 
	// open our header file
	hFile = fopen( sPath, "w" );
	if ( hFile != -1 ){
		fprintf( hFile, "// %s\n", GetWoWVersionString() );
		fprintf( hFile, "/*----------------------------------\n" );
		fprintf( hFile, "Client DB Dumper 14545 - IDC Script\n" );
		fprintf( hFile, "by Tanaris4\n\n" );
		fprintf( hFile, "Credits:\n" );
		fprintf( hFile, "Kynox\n" );
		fprintf( hFile, "-----------------------------------*/\n\n" );
		fprintf( hFile, "typedef enum ClientDB{\n\n" );
	}
 
    // time to loop through and find all cross references to the wow DB_Common_Load function we found above!
    for ( xref = RfirstB(curAddr); xref != BADADDR; xref = RnextB(curAddr, xref) ) {
        auto prevFunc, disasm, disasmAddr, listStart;
 
        prevFunc = PrevFunction( xref );
        disasmAddr = xref;
 
        // search for the correct offset
        do{
       	 	disasm = GetDisasm( disasmAddr );
 
        	if ( disasm == BADADDR ){
        		break;
        	}
        	if ( disasmAddr < prevFunc ){
        		break;
        	}
 
        	// match yay!
			if ( strstr( disasm, "mov" ) > -1 && strstr( disasm, "off" ) > -1 && strstr( disasm, "dword" ) == -1 )
            	break;
 
        	disasmAddr = PrevHead( disasmAddr, prevFunc );
   		} while ( 1 );
 
   		listStart = GetOperandValue(disasmAddr, 1);
 
   		if ( listStart == BADADDR ){
   			continue;
   		}
 
   		// was this a pointer to the real list?
   		if ( strstr( disasm, "ds:" ) > -1 ){
   			listStart = Dword(listStart);
   		}
 
   		do{
			auto dbNameOffset, dbStruct, dbName;
 
			dbStruct = Dword(listStart);
	    	dbNameOffset = Dword(listStart + 0x4);
 
	    	// invalid :(  /tear
        	if ( dbStruct == 0 || dbNameOffset == 0 || dbStruct == 0xFFFFFFFF || dbNameOffset == 0xFFFFFFFF ){
            	break;
            }
 
			// grab the name of this table
        	dbName = WoWDb_GetName(dbNameOffset);
 
        	if ( strlen(dbName) == 0 ){
        		break;
        	}
 
			// save to file!
			if ( hFile != -1 ){
				fprintf( hFile, "\t%sDBTable = 0x%X,\n", dbName, dbStruct );
			}
 
			// IDA doesn't make these dwords dammit! Let's do it!
			MakeDword(xref);
			MakeDword(xref+0x4);
			MakeDword(dbStruct);
			MakeDword(dbNameOffset);
			MakeDword(dbNameOffset+0xC);
 
			listStart = listStart + 8;
        	count++;
 
   		} while( 1 );
    }
 
    Message("Saved %u tables to %s\n", count, sPath);
 
	if ( hFile != -1 ){
		fprintf( hFile, "} ClientDB;\n" );
	}
 
	fclose(hFile);
}
 
static ExtractPath( sPath ){
	auto dwIndex;
	for ( dwIndex = strlen( sPath ); strstr( substr( sPath, dwIndex, -1 ), "/" ) && dwIndex > 0; dwIndex-- );
	return substr( sPath, 0, dwIndex + 1 );
}
 
static WoWDb_GetName( dbBase ){
    auto dbName;
 
    // mov     eax, offset aDbfilesclientA ; "DBFilesClient\\Achievement.dbc"
    dbName = GetString( Dword(dbBase), -1, ASCSTR_C );
 
    // Return the the token after \ and before .
    return substr( dbName, strstr( dbName, "\\" ) + 1, -5 );
}
 
static GetWoWVersionString(){
	auto sVersion, sBuild, sDate;
 
	sVersion = FindBinary( INF_BASEADDR, SEARCH_DOWN, "\"=> WoW Version %s (%s) %s\"" );
 
	if( sVersion == BADADDR )
	{
		Message( "Version format string not found" );
		return 0;
	}
 
	sVersion = DfirstB( sVersion );
 
	if( sVersion == BADADDR )
	{
		Message( "Version string unreferences" );
		return 0;
	}
 
	sVersion = PrevHead( sVersion, 0 );
	sBuild = PrevHead( sVersion, 0 );
	sDate = PrevHead( sBuild, 0 );
 
	sVersion = GetOperandValue( sVersion, 1 );
	sBuild = GetOperandValue( sBuild, 1 );
	sDate = GetOperandValue( sDate, 1 );
 
	sVersion = GetString( sVersion, -1, ASCSTR_C );
	sBuild = GetString( sBuild, -1, ASCSTR_C );
	sDate = GetString( sDate, -1, ASCSTR_C );
 
	return form( "Version: %s  Build number: %s  Build date: %s\n", sVersion, sBuild, sDate );
}