FreeFileSync (官网: https://freefilesync.org/) 是一款免费、开源的文件夹比较和同步软件,跨平台、多协议、双向文件夹对比同步工具,支持 Google Driver、SFTP(SSH)、FTP 等协议,十分好用,支持 Windows、Linux、Mac OS X,它也适用于64位操作系统。

  程序安装默认可选择一个标准的安装程序或作为一个便携式应用程序。采用一个干净、简单、直观的界面,以同步为目标,提供了多种功能。

  核总(https:/lcx.cc/)曾经在“全球几款免费的文件对比同步工具简单测评”一文中对该工具做过简单介绍。

  核总用这个软件也有好几年了,官方虽然说有便携版功能(无需安装、即开即用),但是限定了只有捐赠版才有,你懂的,要银子~

  注意!这是个免费开源软件!为了软件的持续发展,还是希望有钱的大佬购买捐赠版

如果您发现FreeFileSync很有用,请考虑通过捐赠来支持该项目。

您的捐款将资助新功能的开发,并有助于保持持续的计划维护。这可确保FreeFileSync保持最新,并始终在不断变化的硬件和软件上提供最佳性能。

支持该项目:https://freefilesync.org/donate.php

  然而像核总(https:/lcx.cc/)这种穷逼怎么可能买得起捐赠版……

  So……

  泽东同志说得好,自己动手、丰衣足食~

  于是核总(https:/lcx.cc/)对软件研究了一番,主要想实现以下几个功能:

  1. 绿色便携版功能
  2. 禁止强制自动更新

  (只有捐赠版才能选择是否自动更新,普通版无论选什么都是强制更新,很烦人)

便携版

  首先便携版功能比较好实现,官方普通版直接随便安装到一个路径,然后把安装好的文件打包就可以了,也就是说官方程序默认支持不安装运行,也没有注册表依赖什么的,无需进行修改。

文件结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 以最新的 10.8 版本做例子
# 其他版本大同小异,没写到的文件是无用文件,例如 uninstall.exe 之类的
FreeFileSync v10.8
│
│  ding.wav # 提示音
│  gong.wav # 提示音
│  harp.wav # 提示音 
│  Install.dat # 安装记录(仅卸载的时候清理文件用,没啥用)
│  Resources.zip # 图标资源文件
│  LastRun.ffs_gui # 最近的同步任务记录(配置文件)
│  HideConsole.vbs # 隐藏启动器
│  FreeFileSync.exe # 启动器,根据系统版本启动 Bin 目录中对应的主程序
│  RealTimeSync.exe # 启动器,启动后台实时同步任务进程(同上)
│  GlobalSettings.xml # 全局设置(配置文件)
│
├─Bin # 存放真正主程序的文件夹,主程序根据系统类型分为各个版本
│      FreeFileSync_Win32.exe # Windows x86 主程序
│      FreeFileSync_x64.exe # Windows x64 主程序
│      FreeFileSync_XP.exe # Windows XP 主程序
│      RealTimeSync_Win32.exe # Windows x86 实时同步任务进程
│      RealTimeSync_x64.exe # Windows x64 实时同步任务进程
│      RealTimeSync_XP.exe # Windows XP 实时同步任务进程
│      Shadow_Server2003_Win32.dll # 依赖组件(界面效果相关)
│      Shadow_Windows7_Win32.dll # 依赖组件(界面效果相关)
│      Shadow_Windows7_x64.dll # 依赖组件(界面效果相关)
│      Shadow_XP_Win32.dll # 依赖组件(界面效果相关)
│      Taskbar7_Win32.dll # 依赖组件(界面效果相关)
│      Taskbar7_x64.dll # 依赖组件(界面效果相关)
│
├─GoogleDrive # 谷歌云盘相关目录
├─Languages # 语言文件(官方提供了几十种语言文件,只保留简体中文就够用了)
│      chinese_simple.lng
│
└─Logs # 一些执行日志文件,没啥用

禁用自动更新

  对程序进行了简单的逆向破解分析后,发现主程序使用了自校验保护,直接修改主程序打补丁的话比较麻烦,于是采用了 dll 注入打内存补丁的方案,简单、粗暴、直接、高效!

更新原理

  官方采用的自动更新方法很简单,直接 http 请求:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
http://www.freefilesync.org/get_latest_version_number.php

POST /get_latest_version_number.php HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
User-Agent: FFS-Update-Check
Host: freefilesync.org
Content-Length: 125
Cache-Control: no-cache

ffs_version=10.8&installation_type=Portable&ffs_variant=Free&os_name=Windows&os_version=6.1&os_arch=64&language=zh&country=CN

HTTP/1.1 200 OK
Date: Mon, 28 Jan 2019 06:17:54 GMT
Server: Apache
Content-Length: 4
Cache-Control: max-age=3600
Expires: Mon, 28 Jan 2019 07:17:54 GMT
Vary: Accept-Encoding,User-Agent
Content-Type: application/octet-stream

10.8

  如果有新版本的话,则执行以下请求获取新版本更新说明(以 9.5 版本为例):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
POST /get_latest_changes.php HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
User-Agent: FFS-Update-Check
Host: www.freefilesync.org
Content-Length: 9
Cache-Control: no-cache

since=9.4

HTTP/1.1 200 OK
Date: Sun, 12 Nov 2017 08:19:47 GMT
Server: Apache
Cache-Control: max-age=3600
Expires: Sun, 12 Nov 2017 09:19:47 GMT
Vary: Accept-Encoding,User-Agent
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

2c0
FreeFileSync 9.5 [2017-11-05]
-----------------------------
Allow to change error handling option on progress dialogs
Set up shutdown behavior during sync (summary, exit, sleep)
Conditional execution of the post sync command line
Directly use native shutdown/sleep API
Run post sync command even when fail on first error was set
Merged batch and GUI error handling options
Write post sync command to log file
Update GUI-specific options when saving as batch job
Progress graph area matches processed data ratio
Delete files permanently with Shift+Del
Apply correct quotation for CSV-exported folder list
Use Unicode arrow chars with ASCII for variant description
Updated libcurl, OpenSSL to latest builds
0

  最后提示用户更新软件(官方更新频率很高,所以神烦)。

  升级请求主要出现在以下文件中:

1
2
3
\Bin\FreeFileSync_Win32.exe
\Bin\FreeFileSync_x64.exe
\Bin\FreeFileSync_XP.exe

破解方案

  所以屏蔽自动升级方案就很简单了,直接注入一个 dll 到主程序中,然后直接修改内存 API 函数调用地址,拦截 http 更新请求,也就是内存补丁。

  观察了一下 HTTP 请求调用的函数,发现主要使用以下几个 API:

1
2
3
InternetOpenW
InternetConnectW
InternetReadFile

  于是使用 PowerBASIC 简单的写了个 dll,核心源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#compile dll "hook.dll"
#dim all

#include "Win32API.inc"
#include "HookApi.inc"

%SE_DEBUG_PRIVILEGE = &H14
declare function RtlAdjustPrivilege lib "ntdll.dll" alias "RtlAdjustPrivilege"(byval Privilege as long, byval enable as long, byval CurrentThread as long, WasEnabled as long) as long

global ghInstance as dword
global hThread as dword '线程id
global nextHook as dword

function libmain (byval hInstance as long, byval fwdReason as long, byval lpvReserved as long) as long
    select case fwdReason
        case %DLL_PROCESS_ATTACH
            ghInstance = hInstance
            RtlAdjustPrivilege(%SE_DEBUG_PRIVILEGE, 1, 0, 0) '提升进程权限
            thread create LoadHook(0) to hThread '创建一个线程加载hook
            function = 1 'success!
        case %DLL_PROCESS_DETACH
            '----------
            local lresult as long
            thread close hThread to lresult '销毁线程
            UnHookAPI(nextHook) '卸载 hook
            '----------
            function = 1 'success!
        case %DLL_THREAD_ATTACH
            function = 1 'success!
        case %DLL_THREAD_DETACH
            function = 1 'success!
    end select
end function

thread function LoadHook(byval n as long) as long
    ' HookAPI("USER32.dll", "MessageBoxA", codeptr(functionCallback), nextHook)
    HookAPI("WININET.dll", "InternetOpenW", codeptr(Callback_InternetOpenW), nextHook)
    ' HookAPI("WININET.dll", "InternetConnectW", codeptr(Callback_InternetConnectW), nextHook)
    ' HookAPI("WININET.dll", "InternetReadFile", codeptr(Callback_InternetReadFile), nextHook)
end function

function Callback_InternetOpenW(byref lpszAgent as wstringz, byval dwAccessType as dword, byref lpszProxy as wstringz, byref lpszProxyBypass as wstringz, byval dwFlags as dword) as dword
    ' msgbox "InternetOpenW"
    function = %false
end function

function Callback_InternetConnectW( _
    byval hInternet as dword, byref lpszServerName as wstringz, byval nServerPort as word, _
    byref lpszUserName as wstringz, byref lpszPassword as wstringz, _
    byval dwService as dword, byval dwFlags as dword, optional byval dwContext as dword) as dword
    ' msgbox "InternetConnectW"
    function = %false
end function

function Callback_InternetReadFile(byval hFile as dword, byval lpBuffer as byte ptr, byval dwNumberOfBytesToRead as dword, byref lpdwNumberOfBytesRead as dword) as long
    ' msgbox "InternetReadFile"
    function = %false
end function

使用方法

  然后只需要在主程序启动时注入这个 dll 即可屏蔽所有更新请求。

  虽然主程序有多个版本(见 bin 文件夹),但是 win32 版本是通用的,所以只需要启动着一个即可,使用核总很早以前写的 dll 注射器实现启动注入(可使用批处理实现一键启动):

1
inject.exe "\Bin\FreeFileSync_Win32.exe"

  至此,完美屏蔽自动更新。

相关说明

  以上破解思路、代码及程序是核总(https:/lcx.cc/)在 2017 年底记录、开发的,今天没事整理了一下发出来,相关程序见底下下载。

  当时破解的版本是 9.5,但是破解补丁是通用的(只要官方没有很大的结构性更新),也就是说 FreeFileSync 9.x、10.x 及以后全版本通杀。

相关下载

  FreeFileSync 全版本屏蔽自动升级破解补丁.rar