Delphi/C++Builder在没有做任何代码修改,只要重新编译后,再计算CRC,就会与原来不一致的。经同事的朋友查得是时间戳在做怪。解决方案见贴子:http://topic.youkuaiyun.com/u/20080613/11/9fa12d6b-473d-4ac9-a091-0b02f4ffcac6.html
下面只贴出代码:
- function FileDateToDateTime_UTC(FileDate: Integer): TDateTime;inline;
- var
- st: SYSTEMTIME;
- ft: FILETIME;
- begin
- if FileDate = 0 then
- Result := EncodeDate(1980,1,1) +
- EncodeTime(0,0,0, 0)
- else
- Result :=
- EncodeDate(
- LongRec(FileDate).Hi shr 9 + 1980,
- LongRec(FileDate).Hi shr 5 and 15,
- LongRec(FileDate).Hi and 31) +
- EncodeTime(
- LongRec(FileDate).Lo shr 11,
- LongRec(FileDate).Lo shr 5 and 63,
- LongRec(FileDate).Lo and 31 shl 1, 0);
- DateTimeToSystemTime(Result, st);
- SystemTimeToFileTime(st,ft);
- LocalFileTimeToFileTime(ft,ft);
- FileTimeToSystemTime(ft,st);
- Result := SystemTimeToDateTime(st)
- end;
- function FileDateToDateTime_(FileDate: Integer): TDateTime;inline;
- begin
- if FileDate = 0 then
- Result := EncodeDate(1980,1,1) +
- EncodeTime(0,0,0, 0)
- else
- Result :=
- EncodeDate(
- LongRec(FileDate).Hi shr 9 + 1980,
- LongRec(FileDate).Hi shr 5 and 15,
- LongRec(FileDate).Hi and 31) +
- EncodeTime(
- LongRec(FileDate).Lo shr 11,
- LongRec(FileDate).Lo shr 5 and 63,
- LongRec(FileDate).Lo and 31 shl 1, 0);
- end;
- function FileTime_2_UnixTime (const pft:FILETIME):DWORD;inline;
- begin
- Result := ((UInt64(pft.dwHighDateTime) shl 32) + UInt64(pft.dwLowDateTime) - UInt64(116444736000000000)) div UInt64(10000000);
- end;
- function DateTime_2_UnixTime(const dt: TDateTime):DWORD;inline;
- var
- st:SYSTEMTIME;
- ft:FILETIME;
- begin
- DateTimeToSystemTime(dt,st);
- SystemTimeToFileTime(st,ft);
- LocalFileTimeToFileTime(ft,ft);
- Result := FileTime_2_UnixTime(ft);
- end;
- procedure UnixTime_2_FileTime (const time_in:DWORD ; const pft:PFILETIME);inline;
- var
- X:Int64;
- begin
- x := LongLong(time_in) * 10000000 + 116444736000000000;//$19db1ded53ea710;
- pft^.dwHighDateTime := DWORD((x shr 32) and $0ffffffff);
- pft^.dwLowDateTime := DWORD(x and $0ffffffff);
- end;
- function UinxTime_2_FileTime_String(const time_in:DWORD):String;inline;
- var
- ft:FILETIME;
- st:SYSTEMTIME;
- begin
- UnixTime_2_FileTime(time_in,@ft);
- FileTimeToLocalFileTime(ft,ft);
- FileTimeToSystemTime(ft,st);
- result := FormatDateTime('yyyy-mm-dd hh:nn:ss',SystemTimeToDateTime(st));
- end;
- function UnixTime_2_FileTime_String_UTC(const time_in:DWORD):String;inline;
- var
- ft:FILETIME;
- st:SYSTEMTIME;
- begin
- UnixTime_2_FileTime(time_in,@ft);
- FileTimeToSystemTime(ft,st);
- result := FormatDateTime('yyyy-mm-dd hh:nn:ss',SystemTimeToDateTime(st));
- end;
- procedure DoIt(IsModify:Boolean);
- type
- _IMAGE_RESOURCE_DIRECTORY = record
- Characteristics: DWORD;
- TimeDateStamp: DWORD;
- MajorVersion: WORD;
- MinorVersion: WORD;
- NumberOfNamedEntries :WORD;
- NumberOfIdEntries: WORD;
- // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
- end;
- IMAGE_RESOURCE_DIRECTORY = _IMAGE_RESOURCE_DIRECTORY;
- TIMAGERESOURCEDIRECTORY = _IMAGE_RESOURCE_DIRECTORY;
- PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY;
- PIMAGERESOURCEDIRECTORY = ^TIMAGERESOURCEDIRECTORY;
- _IRDE_NAME = record
- case Integer of
- 0:
- //struct {
- // DWORD NameOffset:31;
- // DWORD NameIsString:1;
- // };
- (NameOffset: DWORD);
- 1: (Name: DWORD);
- 2: (Id: Word);
- end;
- _IRDE_OFFSET_DATA = record
- case Integer of
- 0:(OffsetToData: DWORD);
- //struct {
- // DWORD OffsetToDirectory:31;
- // DWORD DataIsDirectory:1;
- //};
- 1:(Directory: DWORD);
- end;
- _IMAGE_RESOURCE_DIRECTORY_ENTRY = record
- IRDE_NAME: _IRDE_NAME;
- IRDE_OFFSET_DATA: _IRDE_OFFSET_DATA;
- end;
- IMAGE_RESOURCE_DIRECTORY_ENTRY = _IMAGE_RESOURCE_DIRECTORY_ENTRY;
- PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY;
- TIMAGERESOURCEDIRECTORYENTRY = IMAGE_RESOURCE_DIRECTORY_ENTRY;
- PIMAGERESOURCEDIRECTORYENTRY = TIMAGERESOURCEDIRECTORYENTRY;
- const
- INVALID_SET_FILE_POINTER = DWORD(-1);
- var
- FileName: String;
- hFileSource: THandle;
- dwSourceSize, byte_write: Cardinal;
- pFileSource: PChar;
- I,J,K: Integer;
- dosHeadA: PImageDosHeader;
- ntHeadA: PIMAGENTHEADERS ;
- secHeadA: PIMAGESECTIONHEADER;
- dirResourceA: PIMAGERESOURCEDIRECTORY;
- entryResourceA: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
- dirTemp: PIMAGE_RESOURCE_DIRECTORY;
- entryTemp: PIMAGE_RESOURCE_DIRECTORY_ENTRY;
- dirTempICON: PIMAGE_RESOURCE_DIRECTORY;
- begin
- //打开文件
- if (Not OpenDialog1.Execute()) then Exit;
- //取得文件名
- FileName := OpenDialog1.FileName;
- //打开文件
- hFileSource := CreateFile( PChar(FileName),
- GENERIC_READ or GENERIC_WRITE,
- FILE_SHARE_READ ,
- Nil,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_ARCHIVE or
- FILE_ATTRIBUTE_HIDDEN or
- FILE_ATTRIBUTE_NORMAL or
- FILE_ATTRIBUTE_SYSTEM,
- 0
- );
- if (hFileSource = INVALID_HANDLE_VALUE) then begin
- MessageBox(Handle,'打开文件失败!', '文件时间戳修改器' ,MB_OK or MB_ICONERROR);
- Exit;
- end;
- dwSourceSize := GetFileSize(hFileSource,Nil);
- if (dwSourceSize = INVALID_FILE_SIZE) then begin
- CloseHandle(hFileSource);
- MessageBox(Handle,'无法取得文件大小!','文件时间戳修改器',MB_OK or MB_ICONERROR);
- exit;
- end;
- byte_write := 0;
- //讀取
- pFileSource := HeapAlloc(GetProcessHeap,HEAP_ZERO_MEMORY,dwSourceSize);
- if (pFileSource = Nil) then begin
- CloseHandle(hFileSource);
- MessageBox(Handle,'分配内存失败!','文件时间戳修改器',MB_OK or MB_ICONERROR);
- Exit;
- end;
- if (INVALID_SET_FILE_POINTER = SetFilePointer(hFileSource,0,NIL,FILE_BEGIN)) then begin
- HeapFree(GetProcessHeap,0, pFileSource);
- CloseHandle(hFileSource);
- MessageBox(Handle,'设置文件位置失败!','文件时间戳修改器',MB_OK or MB_ICONERROR);
- Exit;
- end;
- if(Not ReadFile( hFileSource, pFileSource^,dwSourceSize,byte_write,Nil)) then begin
- HeapFree(GetProcessHeap,0, pFileSource);
- CloseHandle(hFileSource);
- MessageBox(Handle,'读取文件失败!','文件时间戳修改器',MB_OK or MB_ICONERROR);
- Exit;
- end;
- if (StrLIComp( pFileSource,'MZ',2)<>0) then begin
- HeapFree(GetProcessHeap,0, pFileSource);
- CloseHandle(hFileSource);
- MessageBox(Handle,'文件非PE格式!','文件时间戳修改器',MB_OK or MB_ICONERROR);
- Exit;
- end;
- dosHeadA :=PImageDosHeader(pFileSource); //DOS Header
- ntHeadA := PIMAGENTHEADERS (PChar(Cardinal(pFileSource) + Cardinal( dosHeadA^._lfanew))); //NT Header
- if (ntHeadA^.Signature <> $4550) then begin
- HeapFree(GetProcessHeap,0, pFileSource);
- CloseHandle(hFileSource);
- MessageBox(Handle,'文件非PE格式!','文件时间戳修改器',MB_OK or MB_ICONERROR);
- Exit;
- end;
- ListView1.Items.Clear;
- secHeadA := PIMAGESECTIONHEADER (PChar(Cardinal(Pchar(ntHeadA))+ sizeof(IMAGE_NT_HEADERS))); //第一個節的首位址
- with ListView1.Items.Add do begin
- //IMAGE_NT_HEADERS.TimeDateStamp UnixTime 1970-1-1 0:0:0
- Caption := ':' + IntToHex(Integer(@(ntHeadA^.FileHeader.TimeDateStamp)),8);
- SubItems.Add('0x' + IntToHex(Integer((ntHeadA^.FileHeader.TimeDateStamp)),8));
- SubItems.Add(UnixTime_2_FileTime_String_UTC(ntHeadA^.FileHeader.TimeDateStamp));
- SubItems.Add(UinxTime_2_FileTime_String(ntHeadA^.FileHeader.TimeDateStamp));
- end;
- if IsModify then begin
- ntHeadA^.FileHeader.TimeDateStamp := DateTime_2_UnixTime(DateTimePicker1.DateTime); //镜像头时间戳
- end;
- //循環找出.rsrc節
- for i:=0 to ntHeadA^.FileHeader.NumberOfSections - 1 do begin
- //IMAGE_EXPORT_DIRECTORY 导出表变动
- //_IMAGE_IMPORT_DESCRIPTOR or _IMAGE_BOUND_IMPORT_DESCRIPTOR ->_IMAGE_BOUND_FORWARDER_REF
- //IMAGE_LOAD_CONFIG_DIRECTORY32 or IMAGE_LOAD_CONFIG_DIRECTORY64
- //IMAGE_DEBUG_DIRECTORY ->IMAGE_SEPARATE_DEBUG_HEADER ->NON_PAGED_DEBUG_INFO
- //if(strcmp((char *)secHeadA->Name,".rsrc")==0) //找到.rsrc節
- if (secHeadA^.VirtualAddress = ntHeadA^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) then begin//只对Resource感兴趣
- if(0 <> secHeadA^.SizeOfRawData ) then begin
- dirResourceA := PIMAGERESOURCEDIRECTORY(Pchar(Cardinal(PChar(pFileSource)) + secHeadA^.PointerToRawData)); //得到資源入口位址
- entryResourceA := PIMAGE_RESOURCE_DIRECTORY_ENTRY (PChar(DWORD(PChar(dirResourceA)) + sizeof (IMAGE_RESOURCE_DIRECTORY)));
- with ListView1.Items.Add do begin
- //IMAGE_RESOURCE_DIRECTORY.TimeDateStamp FileDate 1980
- Caption := ':' + IntToHex(Integer(@(dirResourceA^.TimeDateStamp)),8);
- SubItems.Add('0x' + IntToHex(Integer((dirResourceA^.TimeDateStamp)),8));
- SubItems.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss',FileDateToDateTime_UTC(dirResourceA^.TimeDateStamp)));
- SubItems.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss',FileDateToDateTime_(dirResourceA^.TimeDateStamp)));
- end;
- if IsModify then
- dirResourceA^.TimeDateStamp := DateTimeToFileDate(DateTimePicker1.DateTime);
- for J := 0 to (dirResourceA^.NumberOfIdEntries+dirResourceA^.NumberOfNamedEntries) - 1 do begin //所有資源
- if (0 <> ((entryResourceA^.IRDE_OFFSET_DATA.Directory shr 31) and 1)) then begin
- dirTemp := PIMAGE_RESOURCE_DIRECTORY (PChar(Cardinal(Pchar(dirResourceA))+(entryResourceA^.IRDE_OFFSET_DATA.Directory and $7fffffff)));
- with ListView1.Items.Add do begin
- //IMAGE_RESOURCE_DIRECTORY.TimeDateStamp FileDate 1980
- Caption := ':' + IntToHex(Integer(@(dirTemp^.TimeDateStamp)),8);
- SubItems.Add('0x' + IntToHex(Integer((dirTemp^.TimeDateStamp)),8));
- SubItems.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss',FileDateToDateTime_UTC(dirTemp^.TimeDateStamp)));
- SubItems.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss',FileDateToDateTime_(dirTemp^.TimeDateStamp)));
- end;
- if IsModify then
- dirTemp^.TimeDateStamp := DateTimeToFileDate(DateTimePicker1.DateTime);
- entryTemp := PIMAGE_RESOURCE_DIRECTORY_ENTRY (PChar(Cardinal(pchar(dirTemp))+sizeof(IMAGE_RESOURCE_DIRECTORY)));
- for k:=0 to (dirTemp^.NumberOfIdEntries+dirTemp^.NumberOfNamedEntries) - 1 do begin //子目錄
- if (((entryTemp^.IRDE_OFFSET_DATA.Directory shr 31) and 1) >0) then begin //還有子目錄
- dirTempICON :=PIMAGE_RESOURCE_DIRECTORY (PChar(Cardinal(PChar(dirResourceA)) + (entryTemp^.IRDE_OFFSET_DATA.Directory and $7fffffff )));
- with ListView1.Items.Add do begin
- //IMAGE_RESOURCE_DIRECTORY.TimeDateStamp FileDate 1980
- Caption := ':' + IntToHex(Integer(@(dirTempICON^.TimeDateStamp)),8);
- SubItems.Add('0x' + IntToHex(Integer((dirTempICON^.TimeDateStamp)),8));
- SubItems.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss',FileDateToDateTime_UTC(dirTempICON^.TimeDateStamp)));
- SubItems.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss',FileDateToDateTime_(dirTempICON^.TimeDateStamp)));
- end;
- if IsModify then
- dirTempICON^.TimeDateStamp := DateTimeToFileDate(DateTimePicker1.DateTime);
- end;
- Inc(entryTemp);
- end;
- end;
- Inc(entryResourceA);
- end;
- end;
- end;
- Inc(secHeadA)
- end;
- if IsModify then begin
- SetFilePointer(hFileSource,0,NIL,FILE_BEGIN);
- byte_write := 0;
- WriteFile( hFileSource,pFileSource^,dwSourceSize,byte_write,Nil);
- end;
- CloseHandle(hFileSource);
- HeapFree(GetProcessHeap,0, pFileSource);
- if IsModify then
- MessageBox(Handle,'修改完成!','文件时间戳修改器',MB_OK or MB_ICONINFORMATION);
- end;