-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3a95cee
Showing
12 changed files
with
2,278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*.local | ||
*.res | ||
*.dres | ||
*.identcache | ||
__history/ | ||
__recovery/ | ||
Win32/ | ||
Win64/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
program GoWin7Fixer; | ||
|
||
{$R *.dres} | ||
|
||
uses | ||
Vcl.Forms, | ||
Main in 'Main.pas' {frmMain}, | ||
Patcher in 'Patcher.pas', | ||
Vcl.Themes, | ||
Vcl.Styles; | ||
|
||
{$R *.res} | ||
|
||
begin | ||
Application.Initialize; | ||
Application.MainFormOnTaskbar := True; | ||
TStyleManager.TrySetStyle('Windows10 SlateGray'); | ||
Application.CreateForm(TfrmMain, frmMain); | ||
Application.Run; | ||
end. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dll32 RCDATA "acryptprimitives32.dll" | ||
dll64 RCDATA "acryptprimitives64.dll" |
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
unit Main; | ||
|
||
interface | ||
|
||
uses | ||
Winapi.Windows, Winapi.Messages, System.SysUtils, | ||
System.Classes, Vcl.Graphics, | ||
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Imaging.jpeg, | ||
ShellApi, Vcl.ExtCtrls; | ||
|
||
type | ||
TfrmMain = class(TForm) | ||
txtLog: TMemo; | ||
cmdOpen: TButton; | ||
imgPic: TImage; | ||
dlgOpen: TOpenDialog; | ||
procedure imgPicClick(Sender: TObject); | ||
procedure cmdOpenClick(Sender: TObject); | ||
procedure FormCreate(Sender: TObject); | ||
procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES; | ||
procedure TryPatch(fileName: string); | ||
private | ||
{ Private declarations } | ||
public | ||
{ Public declarations } | ||
end; | ||
|
||
var | ||
frmMain: TfrmMain; | ||
|
||
implementation | ||
|
||
{$R *.dfm} | ||
|
||
uses | ||
Patcher; | ||
|
||
var | ||
filesDropped: boolean = False; | ||
|
||
function ChangeWindowMessageFilterEx(HWND: integer; Msg: Cardinal; | ||
Action: Dword; pChangeFilterStruct: pointer): BOOL; stdcall; external 'user32.dll'; | ||
|
||
procedure TfrmMain.cmdOpenClick(Sender: TObject); | ||
begin | ||
if not dlgOpen.Execute then | ||
Exit; | ||
txtLog.Clear; | ||
TryPatch(dlgOpen.fileName); | ||
end; | ||
|
||
procedure TfrmMain.FormCreate(Sender: TObject); | ||
begin | ||
DragAcceptFiles(frmMain.Handle, True); | ||
// enable drag and drop files for an elevated process | ||
ChangeWindowMessageFilterEx(frmMain.Handle, WM_DROPFILES, 1, nil); | ||
ChangeWindowMessageFilterEx(frmMain.Handle, WM_COPYDATA, 1, nil); | ||
ChangeWindowMessageFilterEx(frmMain.Handle, WM_COPYGLOBALDATA, 1, nil); | ||
end; | ||
|
||
procedure TfrmMain.imgPicClick(Sender: TObject); | ||
begin | ||
ShellExecute(Self.Handle, 'open', 'https://github.com/rolandshoemaker', nil, | ||
nil, SW_SHOWNORMAL); | ||
end; | ||
|
||
procedure TfrmMain.TryPatch(fileName: string); | ||
var | ||
res: boolean; | ||
begin | ||
res := Patch(fileName); | ||
txtLog.Lines.AddStrings(Patcher.Log); | ||
txtLog.Lines.Add(''); | ||
if (not filesDropped) and res then | ||
begin | ||
DropDLLs; | ||
filesDropped := True; | ||
txtLog.Lines.AddStrings(Patcher.Log); | ||
txtLog.Lines.Add(''); | ||
end; | ||
end; | ||
|
||
procedure TfrmMain.WMDropFiles(var Msg: TWMDropFiles); | ||
var | ||
DropH: HDROP; // drop handle | ||
DroppedFileCount: integer; // number of files dropped | ||
FileNameLength: integer; // length of a dropped file name | ||
fileName: string; // a dropped file name | ||
i: integer; // loops thru all dropped files | ||
begin | ||
txtLog.Clear; | ||
inherited; | ||
// Store drop handle from the message | ||
DropH := Msg.Drop; | ||
try | ||
// Get count of files dropped | ||
DroppedFileCount := DragQueryFile(DropH, $FFFFFFFF, nil, 0); | ||
// Get name of each file dropped and process it | ||
for i := 0 to Pred(DroppedFileCount) do | ||
begin | ||
// get length of file name | ||
FileNameLength := DragQueryFile(DropH, I, nil, 0); | ||
// create string large enough to store file | ||
SetLength(fileName, FileNameLength); | ||
// get the file name | ||
DragQueryFile(DropH, I, PChar(fileName), FileNameLength + 1); | ||
// process file | ||
if LowerCase(ExtractFileExt(fileName)) <> '.exe' then | ||
begin | ||
txtLog.Lines.Add(ExtractFileName(fileName) + ' is not an .EXE file'); | ||
end | ||
else | ||
TryPatch(fileName); | ||
end; | ||
finally | ||
DragFinish(DropH); | ||
end; | ||
// Note we handled the message | ||
Msg.Result := 0; | ||
end; | ||
|
||
end. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
unit Patcher; | ||
|
||
interface | ||
|
||
uses | ||
WinApi.Windows, System.SysUtils, System.Classes, System.Hash; | ||
|
||
function Patch(fileName: string): boolean; | ||
function DropDLLs: boolean; | ||
|
||
var | ||
Log: TStringList; | ||
|
||
implementation | ||
|
||
function FileSize(const aFilename: String): Int64; | ||
var | ||
info: TWin32FileAttributeData; | ||
begin | ||
result := -1; | ||
if not GetFileAttributesEx(PChar(aFilename), GetFileExInfoStandard, @info) then | ||
exit; | ||
Result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32); | ||
end; | ||
|
||
function PatchMem(pattern, buf: PAnsiChar; patternlen, buflen: integer): boolean; | ||
var | ||
i: integer; | ||
begin | ||
Result := False; | ||
for i := 0 to buflen - patternlen - 1 do | ||
begin | ||
if CompareMem(pattern, @buf[i], patternlen) then | ||
begin | ||
Log.Add('patching at: 0x' + i.ToHexString(8)); | ||
buf[i] := 'a'; | ||
Result := True; | ||
end; | ||
end; | ||
end; | ||
|
||
function WriteFromResource(resName, fileName: string): boolean; | ||
var | ||
rs: TResourceStream; | ||
fs: TFileStream; | ||
begin | ||
Result := False; | ||
rs := TResourceStream.Create(HInstance, resName, RT_RCDATA); | ||
try | ||
if FileExists(fileName) then | ||
begin | ||
if THashMD5.GetHashString(rs) = THashMD5.GetHashStringFromFile(fileName) then | ||
begin | ||
Log.Add(fileName + ' is correct version, no change required.'); | ||
Result := True; | ||
exit; | ||
end; | ||
// update the file | ||
if not DeleteFile(fileName) then | ||
begin | ||
Log.Add('file ' + fileName + ' cannot be deleted, probably in use, trying to rename...'); | ||
if not RenameFile(fileName, fileName.Substring(0, fileName.Length - 1) + '_') then | ||
begin | ||
Log.Add('cannot rename it to ' + fileName.Substring(0, fileName.Length - 1) + '. check if it''s opened my another program.'); | ||
exit; | ||
end; | ||
end; | ||
end; | ||
|
||
rs.Seek(0, soFromBeginning); | ||
try | ||
{$WARNINGS OFF} | ||
fs := TFileStream.Create(fileName, fmCreate or fmShareDenyRead); | ||
{$WARNINGS ON} | ||
except | ||
Log.Add('cannot create file for writing: ' + fileName); | ||
exit; | ||
end; | ||
fs.CopyFrom(rs); | ||
fs.Free; | ||
Log.Add('file written ok: ' + fileName); | ||
|
||
Result := True; | ||
finally | ||
rs.Free; | ||
end; | ||
end; | ||
|
||
function DropDLLs: boolean; | ||
var | ||
wd: string; | ||
size1, size2: int64; | ||
os64: boolean; | ||
begin | ||
Result := False; | ||
Log.Clear; | ||
Log.Add('checking additional files...'); | ||
|
||
SetLength(wd, MAX_PATH); | ||
GetWindowsDirectory(PChar(wd), MAX_PATH); | ||
wd := string(pchar(wd)); | ||
|
||
size1 := FileSize(wd + '\System32\kernel32.dll'); | ||
size2 := FileSize(wd + '\Sysnative\kernel32.dll'); | ||
if size1 = -1 then | ||
begin | ||
Log.Add('cannot get system DLL size.'); | ||
exit; | ||
end; | ||
|
||
os64 := size2 > size1; | ||
if not WriteFromResource('dll32', wd + '\System32\acryptprimitives.dll') then | ||
exit; | ||
if os64 then | ||
if not WriteFromResource('dll64', wd + '\Sysnative\acryptprimitives.dll') then | ||
exit; | ||
|
||
Log.Add('additional files are ok.'); | ||
Result := True; | ||
end; | ||
|
||
function Patch(fileName: string): boolean; | ||
var | ||
fs, bs: TFileStream; | ||
ms: TMemoryStream; | ||
buf: PAnsiChar; | ||
c1, c2: PAnsiChar; | ||
begin | ||
Result := False; | ||
Log.Clear; | ||
Log.Add('checking file: ' + ExtractFileName(fileName) + '...'); | ||
try | ||
{$WARNINGS OFF} | ||
fs := TFileStream.Create(fileName, fmOpenReadWrite or fmShareDenyRead); | ||
{$WARNINGS ON} | ||
GetMem(buf, fs.Size); | ||
fs.Read(buf^, fs.Size); | ||
except | ||
Log.Add('couldn''t read the file, check if it''s opened by another program.'); | ||
exit; | ||
end; | ||
|
||
ms := TMemoryStream.Create; | ||
ms.CopyFrom(fs); | ||
ms.Seek(0, soFromBeginning); | ||
|
||
try | ||
c1 := 'bcryptprimitives.dll'; | ||
c2 := @string(c1)[1]; | ||
if not(PatchMem(c1, buf, Length(c1), fs.Size) and PatchMem(c2, buf, | ||
Length(c1) * 2, fs.Size)) then | ||
begin | ||
Log.Add('couldn''t find the required data to patch. file not changed.'); | ||
exit; | ||
end; | ||
|
||
// write the changes | ||
fs.Seek(0, soFromBeginning); | ||
fs.Write(buf^, fs.Size); | ||
Log.Add('saved ok.'); | ||
|
||
// save file backup | ||
try | ||
{$WARNINGS OFF} | ||
bs := TFileStream.Create(fileName + '.bak', fmCreate or fmShareDenyRead); | ||
{$WARNINGS ON} | ||
except | ||
Log.Add('couldn''t save backup file ' + fileName + '.bak'); | ||
exit; | ||
end; | ||
bs.CopyFrom(ms); | ||
bs.Free; | ||
Log.Add('backup saved ok.'); | ||
finally | ||
fs.Free; | ||
ms.Free; | ||
end; | ||
Result := True; | ||
Log.Add('file successfully patched.'); | ||
end; | ||
|
||
initialization | ||
|
||
Log := TStringList.Create; | ||
|
||
finalization | ||
|
||
Log.Free; | ||
|
||
end. |
Oops, something went wrong.