Its a bit hard to explain in english how to change the imported dll name in PE
(there're quite a few levels of indirection and RVAs), but
accidentally, I have a library that can be used for stuff like that.
PE32 only, though.
So here's the utility which you can use: http://nishi.dreamhosters.com/dllrepl_v0.rar
(with source).
And here's how it works:
(UpdateImports() does the thing)
struct PE_Hdr1 : PE_Hdr {
void UpdateImports( char* s1, char* s2 ) {
int c,i,j;
int p = 0;
uint ofs = 0x50;
printf( "Redirecting <%s> to <%s>\n", s1, s2 );
// store the target dll name to some place in MZ header
memcpy( &exedata[ofs], s2, strlen(s2)+1 );
uint idtrva = tbl[1].VA;
PE_IDRec* idt = (PE_IDRec*)&exedata[ RVA2Ofs(idtrva) ];
for( i=0; i<nIDRec; i++ ) {
char* dllname = (char*)&exedata[ RVA2Ofs( idt[i].DLLName ) ];
printf( "dllname=<%s>", dllname );
if( stricmp( dllname, s1 )==0 ) {
printf( " -> <%s>", s2 );
idt[i].DLLName = ofs;
}
printf( "\n" );
}
}
};
// Usage: dllrepl file.exe file_out.exe msvcrt.dll msvcrt32.dll
int main( int argc, char** argv ) {
if( argc<5 ) return 1;
FILE* f = fopen( argv[1], "rb" ); if( f==0 ) return 1;
FILE* g = fopen( argv[2], "wb" ); if( g==0 ) return 1;
MZ_Hdr mz; PE_Hdr pe;
PE_Open( mz, pe, f );
((PE_Hdr1&)pe).UpdateImports( argv[3], argv[4] );
fwrite( pe.exedata, 1,pe.exesize, g );
}
The new location for dll name is somewhat hackish, but with allocation of
a safe area in a PE it would get much more complicated.