mirror of
https://github.com/martravi/wiiqt.git
synced 2024-11-22 00:59:18 +01:00
* symolizer: fix a couple bugs in list filtering and whatnot
This commit is contained in:
parent
ecea71b49d
commit
e90412c005
@ -21,6 +21,7 @@ struct KnownData
|
||||
// holds info about a function that is assumed correct
|
||||
struct KnownFunction
|
||||
{
|
||||
QString debug;// just for debugging this program
|
||||
const ElfParser::Function *function;
|
||||
const ElfParser::File *file;
|
||||
const quint32 addr;
|
||||
@ -311,7 +312,8 @@ void RemoveOverlaps()
|
||||
knownFunctions = knownFunctions2;
|
||||
}
|
||||
|
||||
void AddFunctionToKnownList( const ElfParser::Function *function, const ElfParser::File *file, quint32 addr )
|
||||
void AddFunctionToKnownList( const ElfParser::Function *function, const ElfParser::File *file, quint32 addr, const QString &debug = QString() );
|
||||
void AddFunctionToKnownList( const ElfParser::Function *function, const ElfParser::File *file, quint32 addr, const QString &debug )
|
||||
{
|
||||
foreach( const KnownFunction &kf, knownFunctions )
|
||||
{
|
||||
@ -325,10 +327,13 @@ void AddFunctionToKnownList( const ElfParser::Function *function, const ElfParse
|
||||
return;
|
||||
}
|
||||
}
|
||||
knownFunctions << KnownFunction( function, file, addr );
|
||||
KnownFunction kf( function, file, addr );
|
||||
kf.debug = debug;
|
||||
knownFunctions << kf;
|
||||
}
|
||||
|
||||
void AddFunctionToKnownList( const QString &name, quint32 addr )
|
||||
void AddFunctionToKnownList( const QString &name, quint32 addr, const QString &debug = QString() );
|
||||
void AddFunctionToKnownList( const QString &name, quint32 addr, const QString &debug )
|
||||
{
|
||||
foreach( const KnownFunction &kf, knownFunctions )
|
||||
{
|
||||
@ -342,7 +347,9 @@ void AddFunctionToKnownList( const QString &name, quint32 addr )
|
||||
return;
|
||||
}
|
||||
}
|
||||
knownFunctions << KnownFunction( NULL, NULL, addr, name );
|
||||
KnownFunction kf( NULL, NULL, addr, name );
|
||||
kf.debug = debug;
|
||||
knownFunctions << kf;
|
||||
}
|
||||
|
||||
int PatternSearch( const QString &needle, const QString &haystack, qint64 start = 0 );
|
||||
@ -499,83 +506,117 @@ bool ListContains( const QList< QPair< const ElfParser::Function *, quint32 > >
|
||||
void CleanupList( QList< QPair< const ElfParser::Function *, quint32 > > &list )
|
||||
{
|
||||
QList< const ElfParser::Function * >dupFunctions;
|
||||
QList< const ElfParser::Function * >foundFunctions;
|
||||
|
||||
QList< quint32 >dupAddrs;
|
||||
QList< quint32 >foundAddrs;
|
||||
|
||||
QList< QPair< const ElfParser::Function *, quint32 > > ret;
|
||||
|
||||
int s = list.size();
|
||||
|
||||
// search for stuff to remove
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< const ElfParser::Function *, quint32 > &p = list.at( i );
|
||||
if( foundFunctions.contains( p.first ) )
|
||||
const QPair< const ElfParser::Function *, quint32 > &p1 = list.at( i );
|
||||
for( int j = 0; j < s; j++ )
|
||||
{
|
||||
dupFunctions << p.first;
|
||||
const QPair< const ElfParser::Function *, quint32 > &p2 = list.at( j );
|
||||
if( p1.second == p2.second )// is address the same
|
||||
{
|
||||
if( p1.first != p2.first )// is function the same
|
||||
{
|
||||
dupAddrs << p1.second;// same address but 2 different functions
|
||||
}
|
||||
}
|
||||
else if( p1.first == p2.first )
|
||||
{
|
||||
dupFunctions << p1.first;// different address but same function
|
||||
}
|
||||
}
|
||||
foundFunctions << p.first;
|
||||
|
||||
if( foundAddrs.contains( p.second ) )
|
||||
{
|
||||
dupAddrs << p.second;
|
||||
}
|
||||
foundAddrs << p.second;
|
||||
}
|
||||
|
||||
// build a new list
|
||||
// now build a new list
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< const ElfParser::Function *, quint32 > &p = list.at( i );
|
||||
if( dupFunctions.contains( p.first ) || dupAddrs.contains( p.second ) )
|
||||
const QPair< const ElfParser::Function *, quint32 > &p1 = list.at( i );
|
||||
|
||||
// this one clashed with another function
|
||||
if( dupAddrs.contains( p1.second ) || dupFunctions.contains( p1.first ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ret << p;
|
||||
|
||||
// make sure this function isnt already in the list
|
||||
int t = ret.size();
|
||||
bool alreadyHaveIt = false;
|
||||
for( int j = 0; j < t; j++ )
|
||||
{
|
||||
const QPair< const ElfParser::Function *, quint32 > &p2 = ret.at( j );
|
||||
if( p1.second == p2.second )
|
||||
{
|
||||
alreadyHaveIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !alreadyHaveIt )
|
||||
{
|
||||
ret << p1;
|
||||
}
|
||||
}
|
||||
list = ret;
|
||||
}
|
||||
|
||||
void CleanupList( QList< QPair< QString, quint32 > > &list )
|
||||
{
|
||||
QStringList dupFunctions;
|
||||
QStringList foundFunctions;
|
||||
|
||||
QStringList dupNames;
|
||||
QList< quint32 >dupAddrs;
|
||||
QList< quint32 >foundAddrs;
|
||||
|
||||
QList< QPair< QString, quint32 > > ret;
|
||||
|
||||
int s = list.size();
|
||||
|
||||
// search for stuff to remove
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< QString, quint32 > &p = list.at( i );
|
||||
if( foundFunctions.contains( p.first ) )
|
||||
const QPair< QString, quint32 > &p1 = list.at( i );
|
||||
for( int j = 0; j < s; j++ )
|
||||
{
|
||||
dupFunctions << p.first;
|
||||
const QPair< QString, quint32 > &p2 = list.at( j );
|
||||
if( p1.second == p2.second )// is address the same
|
||||
{
|
||||
if( p1.first != p2.first )// is name the same
|
||||
{
|
||||
dupAddrs << p1.second;// same address but 2 different names
|
||||
}
|
||||
}
|
||||
else if( p1.first == p2.first )
|
||||
{
|
||||
dupNames << p1.first;// different address but same names
|
||||
}
|
||||
}
|
||||
foundFunctions << p.first;
|
||||
|
||||
if( foundAddrs.contains( p.second ) )
|
||||
{
|
||||
dupAddrs << p.second;
|
||||
}
|
||||
foundAddrs << p.second;
|
||||
}
|
||||
|
||||
// build a new list
|
||||
// now build a new list
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< QString, quint32 > &p = list.at( i );
|
||||
if( dupFunctions.contains( p.first ) || dupAddrs.contains( p.second ) )
|
||||
const QPair< QString, quint32 > &p1 = list.at( i );
|
||||
|
||||
// this one clashed with another function
|
||||
if( dupAddrs.contains( p1.second ) || dupNames.contains( p1.first ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ret << p;
|
||||
|
||||
// make sure this function isnt already in the list
|
||||
int t = ret.size();
|
||||
bool alreadyHaveIt = false;
|
||||
for( int j = 0; j < t; j++ )
|
||||
{
|
||||
const QPair< QString, quint32 > &p2 = ret.at( j );
|
||||
if( p1.second == p2.second )
|
||||
{
|
||||
alreadyHaveIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !alreadyHaveIt )
|
||||
{
|
||||
ret << p1;
|
||||
}
|
||||
}
|
||||
list = ret;
|
||||
}
|
||||
@ -745,7 +786,7 @@ void TryToMatchFunctions0()
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << " -- Matched by searching for patterns with no wildcards --";
|
||||
//qDebug() << " -- Matched by searching for patterns with no wildcards --";
|
||||
int ss = maybeMatches.size();
|
||||
for( int i = 0; i < ss; i++ )
|
||||
{
|
||||
@ -755,8 +796,8 @@ void TryToMatchFunctions0()
|
||||
//qDebug() << "tossing out" << p.first->Name() << "because addr" << hex << p.second << "is reused";
|
||||
continue;
|
||||
}
|
||||
qDebug() << hex << p.second << NStr( p.first->Pattern().size() / 2, 4 ) << p.first->Name();
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second );
|
||||
//qDebug() << hex << p.second << NStr( p.first->Pattern().size() / 2, 4 ) << p.first->Name();
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second, __FUNCTION__ );
|
||||
}
|
||||
RemoveOverlaps();
|
||||
}
|
||||
@ -812,7 +853,7 @@ void TryToMatchFunctions1()
|
||||
//qDebug() << " " << kd.name;
|
||||
if( kd.name == ref.name )
|
||||
{
|
||||
qDebug() << "function:" << fun.Name() << "references" << kd.name << kd.file->Name();
|
||||
//qDebug() << "function:" << fun.Name() << "references" << kd.name << kd.file->Name();
|
||||
//qDebug() << ref.name;
|
||||
maybeMatches << QPair< const ElfParser::Function *, const KnownData *>( &fun, &kd );
|
||||
doneWithFunction = true;
|
||||
@ -824,7 +865,7 @@ void TryToMatchFunctions1()
|
||||
bool ok = false;
|
||||
if( alias.containerName == kd.name && alias.name == ref.name )
|
||||
{
|
||||
qDebug() << "function:" << fun.Name() << "references" << kd.name << "through alias" << alias.name << " in" << kd.file->Name();
|
||||
//qDebug() << "function:" << fun.Name() << "references" << kd.name << "through alias" << alias.name << " in" << kd.file->Name();
|
||||
//qDebug() << "container str" << alias.containerName;
|
||||
QPair< const ElfParser::Function *, const KnownData *> np( &fun, &kd );
|
||||
maybeMatches << np;
|
||||
@ -966,7 +1007,7 @@ void TryToMatchFunctions1()
|
||||
{
|
||||
const QPair< const ElfParser::Function *, quint32 > &p = probablyMatches.at( i );
|
||||
//qDebug() << hex << p.second << NStr( p.first->Pattern().size() / 2, 4 ) << p.first->Name();
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second );
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second, __FUNCTION__ );
|
||||
}
|
||||
RemoveOverlaps();
|
||||
}
|
||||
@ -1136,7 +1177,7 @@ void FindGlobalVariables()
|
||||
// << NStr( ret.key()->Pattern().size() / 2, 4 )
|
||||
// << ret.key()->Name()
|
||||
// << fileMap.find( ret.key() ).value()->Name();
|
||||
AddFunctionToKnownList( ret.key(), fileMap.find( ret.key() ).value(), ret.value() );
|
||||
AddFunctionToKnownList( ret.key(), fileMap.find( ret.key() ).value(), ret.value(), __FUNCTION__ );
|
||||
}
|
||||
RemoveOverlaps();
|
||||
|
||||
@ -1159,8 +1200,9 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
continue;
|
||||
}
|
||||
const ElfParser::Function * fun = kf.function;
|
||||
|
||||
QStringList doneRefs;
|
||||
bool alreadyKnown = false;
|
||||
|
||||
foreach( const SymRef &ref, fun->References() )// look at each reference from each function
|
||||
{
|
||||
switch( ref.type )
|
||||
@ -1171,10 +1213,14 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if( doneRefs.contains( ref.name ) )// dont check branches to the same function from within the same calling function
|
||||
{
|
||||
continue;
|
||||
}
|
||||
doneRefs << ref.name;
|
||||
|
||||
bool alreadyKnown = false;
|
||||
foreach( const KnownFunction &kf, knownFunctions )// dont bother checking branches if we already know the function it is branching to
|
||||
{
|
||||
if( !kf.function )// wont have these for functions we dont have symbols for
|
||||
@ -1194,9 +1240,9 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
}
|
||||
if( alreadyKnown )
|
||||
{
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
doneRefs << ref.name;
|
||||
|
||||
|
||||
quint32 addr = kf.addr + ref.off;
|
||||
quint32 opcode = GetOpcodeFromAddr( addr );
|
||||
@ -1215,6 +1261,7 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
//qDebug() << hex << res << ref.name << "from" << kf.addr << fun->Name() << addr << opcode;
|
||||
|
||||
bool branchHasSymbols = false;
|
||||
bool skipIt = false;
|
||||
|
||||
foreach( const ElfParser::File &f, libFiles )
|
||||
{
|
||||
@ -1222,9 +1269,15 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
foreach( const ElfParser::Function &fun2, f.Functions() )
|
||||
{
|
||||
//qDebug() << " fun.Name():" << fun.Name() << ref.name;
|
||||
|
||||
if( fun2.Name() == ref.name )
|
||||
{
|
||||
branchHasSymbols = true;
|
||||
if( nonMatchingBranches.find( &fun2 ) != nonMatchingBranches.end() )// already looked for this one
|
||||
{
|
||||
skipIt = true;
|
||||
break;
|
||||
}
|
||||
qint64 textOffset = res - wholeDol.at( dolIdx ).addr;
|
||||
textOffset *= 2;
|
||||
if( PattenMatches( fun2.Pattern(), wholeDolHex.at( dolIdx ), textOffset ) )
|
||||
@ -1234,6 +1287,16 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if( fun2.Name() == "NANDPrivateCreateAsync" )
|
||||
{
|
||||
qDebug() << "expected" << fun2.Name() << "at" << hex << res << "but pattern didnt match";
|
||||
qDebug() << "being called from" << fun->Name() << "at" << hex << addr;
|
||||
qDebug() << "offset" << NStr( textOffset ) << "in section" << dolIdx;
|
||||
qDebug() << fun2.Pattern();
|
||||
qDebug() << wholeDolHex.at( dolIdx ).mid( textOffset, fun2.Pattern().size() );
|
||||
exit( 0 );
|
||||
|
||||
}*/
|
||||
//qDebug() << "expected" << fun2.Name() << "at" << hex << res << "but pattern didnt match";
|
||||
//qDebug() << "being called from" << fun->Name() << "at" << hex << addr;
|
||||
nonMatchingBranches[ &fun2 ] = res;
|
||||
@ -1241,6 +1304,11 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( skipIt )
|
||||
{
|
||||
break;
|
||||
//continue;
|
||||
}
|
||||
if( branchHasSymbols )
|
||||
{
|
||||
break;
|
||||
@ -1260,56 +1328,17 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
||||
{
|
||||
const QPair< const ElfParser::Function *, quint32 > &p = probablyMatches.at( i );
|
||||
//qDebug() << hex << p.second << p.first->Name();
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second );
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second, __FUNCTION__ );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QStringList dupFunctions;
|
||||
QStringList foundFunctions;
|
||||
|
||||
QList< quint32 >dupAddrs;
|
||||
QList< quint32 >foundAddrs;
|
||||
|
||||
QList< QPair< QString, quint32 > > cleanList;
|
||||
|
||||
s = probablyMatches2.size();
|
||||
|
||||
// search for stuff to remove
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< QString, quint32 > &p = probablyMatches2.at( i );
|
||||
if( foundFunctions.contains( p.first ) )
|
||||
{
|
||||
dupFunctions << p.first;
|
||||
}
|
||||
foundFunctions << p.first;
|
||||
|
||||
if( foundAddrs.contains( p.second ) )
|
||||
{
|
||||
dupAddrs << p.second;
|
||||
}
|
||||
foundAddrs << p.second;
|
||||
}
|
||||
|
||||
// build a new list
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< QString, quint32 > &p = probablyMatches2.at( i );
|
||||
if( dupFunctions.contains( p.first ) || dupAddrs.contains( p.second ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cleanList << p;
|
||||
}
|
||||
CleanupList( probablyMatches2 );
|
||||
//qDebug() << " -- Functions matched by branches from known functions --";
|
||||
s = cleanList.size();
|
||||
s = probablyMatches2.size();
|
||||
for( int i = 0; i < s; i++ )
|
||||
{
|
||||
const QPair< QString, quint32 > &p = cleanList.at( i );
|
||||
const QPair< QString, quint32 > &p = probablyMatches2.at( i );
|
||||
//qDebug() << hex << p.second << p.first;
|
||||
AddFunctionToKnownList( p.first, p.second );
|
||||
AddFunctionToKnownList( p.first, p.second, __FUNCTION__ );
|
||||
}
|
||||
RemoveOverlaps();
|
||||
}
|
||||
@ -1423,7 +1452,7 @@ QList< QPair< const ElfParser::Function *, quint32> > TryToMatchFunctions3( QLis
|
||||
const QPair< const ElfParser::Function *, quint32 > &p = maybeMatches.at( i );
|
||||
//qDebug() << hex << p.second << NStr( p.first->Pattern().size() / 2, 4 ) << p.first->Name();
|
||||
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second );
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second, __FUNCTION__ );
|
||||
}
|
||||
RemoveOverlaps();
|
||||
return maybeMatches;
|
||||
@ -1496,7 +1525,7 @@ QList< QPair< const ElfParser::Function *, quint32> > TryToMatchFunctions4( QLis
|
||||
const QPair< const ElfParser::Function *, quint32 > &p = maybeMatches.at( i );
|
||||
//qDebug() << hex << p.second << NStr( p.first->Pattern().size() / 2, 4 ) << p.first->Name();
|
||||
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second );
|
||||
AddFunctionToKnownList( p.first, fileMap.find( p.first ).value(), p.second, __FUNCTION__ );
|
||||
}
|
||||
RemoveOverlaps();
|
||||
return maybeMatches;
|
||||
@ -1615,6 +1644,8 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
||||
.arg( kf.addr, 8, 16, QChar( '0' ) ).arg( kf.file->Name() );
|
||||
}
|
||||
|
||||
line += " // " + kf.debug;
|
||||
|
||||
line += '\n';
|
||||
|
||||
// do something cool here with the r13/rtoc references
|
||||
@ -1630,9 +1661,13 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
||||
}
|
||||
else
|
||||
{
|
||||
line += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );\n" )
|
||||
line += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );" )
|
||||
.arg( kf.addr, 8, 16, QChar( '0' ) )
|
||||
.arg( CleanupNameString( kf.name ) );
|
||||
|
||||
line += " // " + kf.debug;
|
||||
|
||||
line += '\n';
|
||||
}
|
||||
ret += line;
|
||||
}
|
||||
@ -1652,9 +1687,8 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
||||
while( it.hasNext() )
|
||||
{
|
||||
it.next();
|
||||
ret += INDENT_TXT + QString( "CreateFunction( 0x%1, 0x%2, \"%3\" );\n" )
|
||||
ret += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );\n" ) // BADADDR because we cant trust the pattern size when it doesnt match the expected
|
||||
.arg( it.value(), 8, 16, QChar( '0' ) )
|
||||
.arg( it.key()->Pattern().size() / 2, 4, 16, QChar( '0' ) )
|
||||
.arg( CleanupNameString( it.key()->Name() ) );
|
||||
// do something cool here with the r13/rtoc references
|
||||
// these cant be trusted since the functions here dont match expected patterns
|
||||
@ -1714,14 +1748,6 @@ int main(int argc, char *argv[])
|
||||
QString libPath( argv[ 2 ] );
|
||||
QString outName( argv[ 3 ] );
|
||||
|
||||
// derp
|
||||
//dolPath = "/home/j/c/hackmiiHaxx/disassembly/mem1-decrypt_60.bin";
|
||||
//libPath = "/home/j/devkitPRO/libogc/lib/wii";
|
||||
|
||||
//dolPath = "/home/j/c/WiiQt/93/symbolizer/00000043_60.dol";
|
||||
//dolPath = "/home/j/c/WWE12_haxx/main.dol";
|
||||
//libPath = "/home/j/devkitPRO/libogc/lib/wii";
|
||||
//libPath += "/os.a";
|
||||
|
||||
qDebug() << "Loading dol...";
|
||||
if( !LoadDol( dolPath ) )
|
||||
@ -1748,7 +1774,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
// add functions by looking at rtoc and r13
|
||||
FindGlobalVariables();
|
||||
//exit( 0 );
|
||||
|
||||
// find branches from the first round of functions
|
||||
TryToMatchFunctions2( nonMatchingBranches );
|
||||
@ -1829,6 +1854,5 @@ int main(int argc, char *argv[])
|
||||
|
||||
WriteFile( outName, idc.toLatin1() );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user