コード例 #1
0
ファイル: rebase.cpp プロジェクト: TheRyuu/ffdshow
int main(int argc, const char *argv[])
{
    if (argc <= 1) {
        return -1;
    }
    char dsk[MAX_PATH], dir[MAX_PATH];
    _splitpath(argv[1], dsk, dir, NULL, NULL);

    FILE *f = fopen(argv[1], "rt");
    if (!f) {
        return -2;
    }

    DWORD err = 0;
    ULONG_PTR newImageBase = 0x30000000;
    char file[MAX_PATH];
    while (fgets(file, MAX_PATH, f)) {
        if (char *eoln = strchr(file, '\n')) {
            *eoln = '\0';
        }
        ULONG_PTR oldImageSize = 0, oldImageBase = 0, newImageSize = 0;
        char flnm[MAX_PATH];
        _makepath(flnm, dsk, dir, file, NULL);
        BOOL ret = ReBaseImage(flnm, NULL, TRUE, FALSE, FALSE, 0, &oldImageSize, &oldImageBase, &newImageSize, &newImageBase, 0);
        err = GetLastError();
        if (err) {
            printf("rebase %s: error %i\n", file, err);
        } else {
            printf("rebase %s: %08x -> %08x, size %i\n", file, oldImageBase, newImageBase, newImageSize);
        }
        newImageBase = ((newImageBase + newImageSize)&~65535) + 65536;
    }

    fclose(f);
    return err;
}
コード例 #2
0
int main( int argc, char** argv )
{
	fprintf( stderr, "DLL base address scheduler v.1.2, copyright 2001-2002 (c) George Hazan.\n\n" );

   //----[ Command line parsing ]--------------------------------------------------------

   for ( int i=1; i < argc; i++ )
   {
      if ( argv[ i ][ 0 ] != '/' )
      {
LBL_Usage:
         fprintf( stderr, "Usage: Rebaser.exe [/BASE:<hex_digit>] [/CHECK]\n" );
		   return 200;
      }

      if ( memicmp( &argv[ i ][ 1 ], "BASE:", 5 ) == 0 )
         sscanf( &argv[ i ][ 6 ], "%08X", &glbOffset );
		else if ( memicmp( &argv[ i ][ 1 ], "CHECK", 5 ) == 0 )
		{
			glbCheckMode = true;
			glbOffset = 0x400000;
		}
      else goto LBL_Usage;
   }

   //----[ Command line ok, opening data files ]-----------------------------------------

	fprintf( stdout, "Scanning DLLs...\n" );

	int  locResult = 0;
	char locFileName[ MAX_PATH ];

	while ( fgets( locFileName, sizeof( locFileName ), stdin ) != NULL )
	{
		rtrim( locFileName );
		fprintf( stdout, "Processing '%s'...\n", locFileName );

		//----| If we need to check files only, check them |-------------------------------
		if ( glbCheckMode )
		{
			DWORD locOldImageSize, locOldBase, locNewSize, locNewBase;
			if ( !ReBaseImage( locFileName, NULL, FALSE, FALSE, FALSE, FALSE, &locOldImageSize,
																&locOldBase, &locNewSize, &locNewBase, 0 ))
				PrintWin32Error( GetLastError() );

			if ( locOldBase == glbOffset )
			{
				fprintf( stdout, "Image is not based\n\n" );
				locResult = 2;
			}

			continue;
		}

		//----| Preparing files |----------------------------------------------------------
LBL_Ok:
		HANDLE locFileHandle = CreateFile( locFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
		if ( locFileHandle == INVALID_HANDLE_VALUE )
		{
			fprintf( stdout, "File '%s' cannot be opened, skipped.\n\n", locFileName );
			locResult = 2;
			continue;
		}

		FILETIME locCreateTime, locAccessTime, locModifyTime;
		GetFileTime( locFileHandle, &locCreateTime, &locAccessTime, &locModifyTime );
		CloseHandle( locFileHandle );

		//----| Processing |---------------------------------------------------------------

		DWORD locOldImageSize, locOldBase, locNewSize;
		if ( !ReBaseImage( locFileName, NULL, TRUE, FALSE, FALSE, FALSE, &locOldImageSize,
															&locOldBase, &locNewSize, &glbOffset, 0 ))
		{
			PrintWin32Error( GetLastError() );
			locResult = 2;
		}

		glbOffset += locNewSize;

		//----| Write down the original file timestamp |-----------------------------------

		locFileHandle = CreateFile( locFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
		if ( locFileHandle != INVALID_HANDLE_VALUE )
		{
			SetFileTime( locFileHandle, &locCreateTime, &locAccessTime, &locModifyTime );
			CloseHandle( locFileHandle );
	}	}

   return locResult;
}
コード例 #3
0
ファイル: rebase.c プロジェクト: mingpen/OpenNT
VOID
ReBaseFile(
    LPSTR CurrentImageName,
    BOOL fReBase
    )
{
    DWORD dw;
    CHAR  Buffer[ MAX_PATH+1 ];
    LPSTR FilePart;
    ULONG ThisImageExpectedSize = 0;
    ULONG ThisImageRequestedBase = NewImageBase;
    ULONG TimeStamp;

    if ( !InitialBase && !BaseAddrFile ) {
        fprintf( stderr, "REBASE: -b switch must specify a non-zero base  --or--\n" );
        fprintf( stderr, "        -i must specify a filename\n" );
        exit( REBASE_ERR );
        }

    if ( BaseAddrFile && ( InitialBase || fGoingDown || CoffBaseDotTxt ) ) {
        fprintf( stderr, "REBASE: -i is incompatible with -b, -d, and -c\n" );
        exit( REBASE_ERR );
    }

    dw = GetFullPathName( CurrentImageName, sizeof(Buffer), Buffer, &FilePart );
    if ( dw == 0 || dw > sizeof(Buffer) ) {
        FilePart = CurrentImageName;
    }
    _strlwr( FilePart );  // Lowercase for consistency when displayed.

    if ( BaseAddrFile && !(ThisImageRequestedBase = FindInBaseAddrFile( FilePart, &ThisImageExpectedSize )) ) {
        fprintf( stdout, "REBASE: %-16s Not listed in %s\n", FilePart, BaseAddrFileName );
    }

    if (fSplitSymbols && !fSumOnly ) {

        if ( SplitSymbols( CurrentImageName, (PCHAR) SymbolPath, (PCHAR) DebugFilePath, SplitFlags ) ) {
            if ( fVerbose ) {
                fprintf( stdout, "REBASE: %16s symbols split into %s\n", FilePart, DebugFilePath );
            }
        }
        else if (GetLastError() != ERROR_ALREADY_ASSIGNED && GetLastError() != ERROR_BAD_EXE_FORMAT) {
            fprintf( stdout, "REBASE: %-16s - unable to split symbols (%u)\n", FilePart, GetLastError() );
        }
    }

    NewImageSize = (ULONG) -1;  // Hack so we can tell when system images are skipped.

    time( (time_t *) &TimeStamp );

    if (!ReBaseImage( CurrentImageName,
                      (PCHAR) SymbolPath,
                      fReBase && !fSumOnly,
                      fRebaseSysfileOk,
                      fGoingDown,
                      ThisImageExpectedSize,
                      &OriginalImageSize,
                      &OriginalImageBase,
                      &NewImageSize,
                      &ThisImageRequestedBase,
                      TimeStamp ) ) {

        if (ThisImageRequestedBase == 0) {
            fprintf(stderr,
                    "REBASE: %-16s ***Grew too large (Size=0x%x; ExpectedSize=0x%x)\n",
                    FilePart,
                    OriginalImageSize,
                    ThisImageExpectedSize);
        } else {
            if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
                if (fVerbose) {
                    fprintf( stderr,
                            "REBASE: %-16s DOS or OS/2 image ignored\n",
                            FilePart );
                }
            } else
            if (GetLastError() == ERROR_INVALID_ADDRESS) {
                if (fVerbose) {
                    fprintf( stderr,
                            "REBASE: %-16s Rebase failed.  Relocations are missing\n",
                            FilePart );
                }
                if (RebaseLog) {
                    fprintf( RebaseLog,
                             "%16s based at 0x%08x (size 0x%08x)  Unable to rebase.\n",
                             FilePart,
                             OriginalImageBase,
                             OriginalImageSize);
                }
            } else {
                fprintf( stderr,
                        "REBASE: *** RelocateImage failed (%s).  Image may be corrupted\n",
                        FilePart );
            }
        }

        ReturnCode = REBASE_ERR;
        return;

    } else {
        if (GetLastError() == ERROR_INVALID_DATA) {
            fprintf(stderr, "REBASE: Warning: DBG checksum did not match image.\n");
        }
    }

    // Keep track of the lowest base address.

    if (MinBase > NewImageBase) {
        MinBase = NewImageBase;
    }

    if ( fSumOnly || !fReBase ) {
        if (!fQuiet) {
            fprintf( stdout,
                     "REBASE: %16s mapped at %08x\n",
                     FilePart,
                     OriginalImageBase,
                     OriginalImageSize);
        }
    } else {
        if (RebaseLog) {
            fprintf( RebaseLog,
                     "%16s rebased to 0x%08x (size 0x%08x)\n",
                     FilePart,
                     fGoingDown ? ThisImageRequestedBase : NewImageBase,
                     NewImageSize);
        }

        if ((NewImageSize != (ULONG) -1) &&
            (OriginalImageBase != (fGoingDown ? ThisImageRequestedBase : NewImageBase)) &&
            ( fVerbose || fQuiet )
           ) {
            if ( fVerbose ) {
                fprintf( stdout,
                         "REBASE: %16s initial base at 0x%08x (size 0x%08x)\n",
                         FilePart,
                         OriginalImageBase,
                         OriginalImageSize);
            }

            fprintf( stdout,
                     "REBASE: %16s rebased to 0x%08x (size 0x%08x)\n",
                     FilePart,
                     fGoingDown ? ThisImageRequestedBase : NewImageBase,
                     NewImageSize);

            if ( fVerbose && fSplitSymbols) {
                fprintf( stdout,
                         "REBASE: %16s updated image base in %s\n",
                         FilePart,
                         DebugFilePath );
            }
        }

        if (fRemoveRelocs) {
            RemoveRelocations(CurrentImageName);
        }
    }

    if ( CoffBaseDotTxt ) {
        if ( !fCoffBaseIncExt ) {
            char *n;
            if ( n  = strrchr(FilePart,'.') ) {
                *n = '\0';
            }
        }

        fprintf( CoffBaseDotTxt,
                 "%-16s 0x%08x 0x%08x\n",
                 FilePart,
                 fSumOnly ? OriginalImageBase : (fGoingDown ? ThisImageRequestedBase : NewImageBase),
                 NewImageSize);
    }

    NewImageBase = ThisImageRequestedBase;   // Set up the next one...
}
コード例 #4
0
ファイル: vista_hash.c プロジェクト: j616/DynamoRIO-for-ARM
int
main(int argc, char *argv[])
{
    byte *dll_1, *dll_2, *p1, *p2, *iat_start1, *iat_end1, *iat_start2, *iat_end2;
    bool has_iat = false;
    MEMORY_BASIC_INFORMATION info;
    void *drcontext = dr_standalone_init();
    uint writable_pages = 0, reserved_pages = 0, IAT_pages = 0;
    uint matched_pages = 0, second_matched_pages = 0, unmatched_pages = 0;
    uint exact_match_pages = 0, exact_no_match_pages = 0;
    char reloc_file[MAX_PATH] = {0}, orig_file[MAX_PATH], *input_file;
    uint old_size = 0, new_size = 0;
    uint old_base = 0, new_base = 0x69000000; /* unlikely to collide */

    /* user specified option defaults */
    uint arg_offs = 1;
    bool use_second_pass = true;
    bool assume_header_match = true;
    uint second_pass_offset = 16; /* FIXME arbitrary, what's a good choice? */
    bool assume_IAT_written = true;
    bool spin_for_debugger = false;

    if (argc < 2)
        return usage(argv[0]);
    while (argv[arg_offs][0] == '-') {
        if (strcmp(argv[arg_offs], "-vv") == 0) {
            vv = true;
        } else if (strcmp(argv[arg_offs], "-v") == 0) {
            v = true;
        } else if (strcmp(argv[arg_offs], "-no_second_pass") == 0) {
            use_second_pass = false;
        } else if (strcmp(argv[arg_offs], "-second_pass_offset") == 0) {
            if ((uint)argc <= arg_offs+1)
                return usage(argv[0]);
            second_pass_offset = atoi(argv[++arg_offs]);
        } else if (strcmp(argv[arg_offs], "-no_assume_IAT_written") == 0) {
            assume_IAT_written = false;
        } else if (strcmp(argv[arg_offs], "-spin_for_debugger") == 0) {
            spin_for_debugger = true;
        } else {
            return usage(argv[0]);
        }
        arg_offs++;
    }   
    input_file = argv[arg_offs++];
    if (arg_offs != argc)
        return usage(argv[0]);
    
    _snprintf(reloc_file, sizeof(reloc_file), "%s.reloc.dll", input_file);
    reloc_file[sizeof(reloc_file)-1] = '\0';
    if (!CopyFile(input_file, reloc_file, FALSE)) {
        LPSTR msg = NULL;
        uint error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
                      0, GetLastError(), 0, msg, 0, NULL);
        VERBOSE_PRINT("Copy Error %d (0x%x) = %s\n", error, error, msg);
        return 1;
    }
    snprintf(orig_file, sizeof(orig_file), "%s.orig.dll", input_file);
    orig_file[sizeof(orig_file)-1] = '\0';
    if (!CopyFile(input_file, orig_file, FALSE)) {
        LPSTR msg = NULL;
        uint error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
                      0, GetLastError(), 0, msg, 0, NULL);
        VERBOSE_PRINT("Copy Error %d (0x%x) = %s\n", error, error, msg);
        return 1;
    }
    if (ReBaseImage(reloc_file, "", TRUE, FALSE, FALSE, 0, &old_size, &old_base,
                    &new_size, &new_base, 0)) {
        VERBOSE_PRINT("Rebased imsage \"%s\" from 0x%08x to 0x%08x\n"
                      "Size changed from %d bytes to %d bytes\n",
                      input_file, old_base, new_base, old_size, new_size);
    } else {
        LPSTR msg = NULL;
        uint error = GetLastError();
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
                      0, GetLastError(), 0, msg, 0, NULL);
        VERBOSE_PRINT("Rebase Error %d (0x%x) = %s\n", error, error, msg);
        return 1;
    }
    
    dll_1 = (byte *)ALIGN_BACKWARD(LoadLibraryExA(orig_file, NULL,
                                                  DONT_RESOLVE_DLL_REFERENCES),
                                   PAGE_SIZE);
    p1 = dll_1;
    dll_2 = (byte *)ALIGN_BACKWARD(LoadLibraryExA(reloc_file, NULL,
                                                  DONT_RESOLVE_DLL_REFERENCES),
                                   PAGE_SIZE);
    p2 = dll_2;
    VVERBOSE_PRINT("Loaded dll @ 0x%08x and 0x%08x\n", dll_1, dll_2);

    if (dll_1 == NULL || dll_2 == NULL) {
        VERBOSE_PRINT( "Error loading %s\n", input_file);
        return 1;
    }
    
    /* Handle the first page specially since I'm seeing problems with a handful of
     * dlls that aren't really getting rebased. mcupdate_GenuineIntel.dll for ex.
     * (which does have relocations etc.) not sure what's up, but it's only a couple of
     * dlls so will ignore them. If we really rebased the header should differ. */
    if (memcmp(dll_1, dll_2, PAGE_SIZE) == 0) {
        printf("%s - ERROR during relocating\n", input_file);
        return 1;
    } else {
        exact_no_match_pages++;
        if (assume_header_match)
            /* We could modify the hash function to catch header pages. */
            matched_pages++;
        else 
            unmatched_pages++;
    }
    p1 += PAGE_SIZE;
    p2 += PAGE_SIZE;

    if (assume_IAT_written && get_IAT_section_bounds(dll_1, &iat_start1, &iat_end1)) {
        has_iat = true;
        ASSERT(get_IAT_section_bounds(dll_2, &iat_start2, &iat_end2) &&
               iat_start1 - dll_1 == iat_start2 - dll_2 &&
               iat_end1 - dll_1 == iat_end2 - dll_2);
    }

    while (dr_virtual_query(p1, &info, sizeof(info)) == sizeof(info) &&
           info.State != MEM_FREE && info.AllocationBase == dll_1) {
        /* we only check read-only pages (assumption writable pages aren't shareable) */
        ASSERT(p1 == info.BaseAddress);
        if (info.State != MEM_COMMIT) {
            reserved_pages += info.RegionSize / PAGE_SIZE;
            VVERBOSE_PRINT("skipping %d reserved pages\n", info.RegionSize / PAGE_SIZE);
            p1 += info.RegionSize;
            p2 += info.RegionSize;
        } else if (!prot_is_writable(info.Protect)) {
            uint i;
            for (i = 0; i < info.RegionSize / PAGE_SIZE; i++) {
                bool exact = false;
                if (assume_IAT_written && has_iat &&
                    iat_end1 > p1 && iat_start1 < p1 + PAGE_SIZE) {
                    /* overlaps an IAT page */
                    IAT_pages++;
                    p1 += PAGE_SIZE;
                    p2 += PAGE_SIZE;
                    continue;
                }
                if (memcmp(p1, p2, PAGE_SIZE) == 0) {
                    VVERBOSE_PRINT("Page Exact Match\n");
                    exact_match_pages++;
                    exact = true;
                } else {
                    VVERBOSE_PRINT("Page Exact Mismatch\n");
                    exact_no_match_pages++;
                }
                if (compare_pages(drcontext, p1, p2, 0)) {
                    VVERBOSE_PRINT("Matched page\n");
                    matched_pages++;
                } else { 
                    VVERBOSE_PRINT("Failed to match page\n");
                    if (use_second_pass &&
                        compare_pages(drcontext, p1, p2, second_pass_offset)) {
                        second_matched_pages++;
                    } else {
                        unmatched_pages++;
                    }
                    ASSERT(!exact);
                }
                p1 += PAGE_SIZE;
                p2 += PAGE_SIZE;
            }
        } else {
            writable_pages += info.RegionSize / PAGE_SIZE;
            VVERBOSE_PRINT("skipping %d writable pages\n", info.RegionSize / PAGE_SIZE);
            p1 += info.RegionSize;
            p2 += info.RegionSize;
        }
    }

    VERBOSE_PRINT("%d exact match, %d not exact match\n%d hash_match, %d second_hash_match, %d hash_mismatch\n",
                  exact_match_pages, exact_no_match_pages, matched_pages, second_matched_pages, unmatched_pages); 

    printf("%s : %d pages - %d w %d res %d IAT = %d same %d differ : %d hash differ %d first hash differ : %d%% found, %d%% found first hash\n",
           input_file, writable_pages + reserved_pages + IAT_pages + exact_match_pages + exact_no_match_pages,
           writable_pages, reserved_pages, IAT_pages,
           exact_match_pages, exact_no_match_pages,
           unmatched_pages, unmatched_pages + second_matched_pages,
           (100 * (matched_pages + second_matched_pages - exact_match_pages))/exact_no_match_pages,
           (100 * (matched_pages - exact_match_pages))/exact_no_match_pages);

    while (spin_for_debugger)
        Sleep(1000);

    return 0;
}