首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

"同类软件的鼻祖” Seer 抄走了我的 GPL 代码去卖钱……

  xupefei · 323 天前 · 14749 次点击
这是一个创建于 323 天前的主题,其中的信息可能已经有所发展或是发生改变。

先放一张图:

lol

真的如此吗?

背景

我在几个月前做了一个类似苹果系统 Quick Look 的工具(Github 链接;当时在 V2EX 发的帖子在此),开发初衷正是因为我觉得 Seer 不太好用,且不开源&收费的模式让我有些不爽。

之后经过不断地改进,在 0.2.0 版本中(链接),我加入了预览打开 /保存对话框中文件的功能。其他同类的软件,包括 Seer,都没有实现这个功能(可能是因为他们的对 Windows 底层的了解太弱了)。同时,为了保护我的成果不被随意使用,我把项目的开源协议从 LGPL 换成了更严格的 GPL,以保证没人能闭源使用用我的代码。然而,这对收费的闭源软件 Seer 来说并没有什么用。

Seer 抄了啥?

先给个简单的列表:

  1. 对话框 Hook 注入部分的代码
  2. 对话框 Hook 被注入的 DLL 的代码
  3. Directory Opus 兼容部分的相关代码
  4. (不确定)UWP 判断代码

有啥证据?

刚刚发布的 Seer 1.5.0 包含了上述抄袭的代码,而且抄走的代码逻辑几乎完全没有变化,能看着他的汇编完美还原出(我的)包含变量定义的源代码。 我在截图中附加了我代码中的一些注释便于各位理解;截图汇编来自 Seer 1.5.0 的 Seer.exe (1E44DB795A8D4D7CBE5D2024ECF168FF) 和 DlgHook.dll (161471A6F9785EA4A35887060B8743E1) 。右侧的代码来自这里

1. 对话框注入代码

Seer 的作者看上去并不是十分理解我代码的意思,因为他抄过去的代码没什么用……

为什么这么说呢?首先,我的程序是 64 位的,为了注入到 32 位进程里,我用了 IsWowProcess API 来判断 (i) 自身是否在 32 位上运行 (ii) 目标程序是否是 32 位。如果 (i) 不成立且 (ii) 成立,就调用一个独立的 32 位 Helper.exe 把 DLL 注入到目标进程里。然而,Seer 本身是 32 位进程且没有 64 位的 Helper。也就是说,他判断了好几次,最后啥都没干直接 return 了。

不过,令人欣慰的是 Seer 把 if(!isTragetWoW64)条件改了,没有盲目粘贴。

Dialog Hook

2. 对话框被注入的 DLL 代码

懒得解释了,一看就明白。 那个 WM_USER+7 不是我发现的,是网上流传的未公开消息。 Dialog Hook DLL

3. Directory Opus 相关代码

Directory Opus 官方只给了一个独立的 exe 用以和第三方交互,而且这个 exe 只支持把结果写到文件里。于是乎,Seer 1.4.0 就每隔 0.x 秒运行那个 exe、写结果到文件、读文件,疯狂占用 CPU 和 IO。为了避免这个问题,我逆向了官方提供的那个 exe,发现了未公开的 WM_COPYDATA 消息(逆向结果在此)并用到了我的 QuickLook 里。

Seer 1.5.0 版本里就把它抄走了……哦不,没有完全照抄,作者把等待的 2000 毫秒改成了 800 毫秒。不过这也太明显了吧,连前四行 if 判断都没改就放进来了。

dopus

4. UWP 判断代码 (不确定)

我不确定 Seer 作者是不是自己发现判断 ERROR_INSUFFICIENT_BUFFER 就够了,而不用申请内存后再次调用(网上的代码大都是两次调用)。

IsUWP

发帖的诉求是啥?

看到这里,相信各位已经对是否抄袭这个事实有一个结论了。我的代码受 GPLv3 协议的保护:任何使用它的人都必须遵守协议,把所有相关代码以 GPLv3 协议开源。既然 “ decent ” 是 Seer 的作者 idealistcorey 非常看重的东西,那么请自觉遵守 GPLv3 协议,把 Seer 1.5.0 版本的代码以 GPLv3 协议开源,即使你接下来把相关代码完全重写

另外要告诫 Seer 作者:别人的代码不是复制粘贴就可以的

最后作为对比,人家 Sekai Project 就很有版权意识,就算是想要用用 LGPL 协议的 Locale Emulator 都先来发个邮件问问:

Sekai

更别说大企业了:

apng

谢谢各位读到这里。

PS:某人的水平也太差了吧,对话框 HOOK 的 Helper.exe 源代码都在那儿,你都抄不走?

第 1 条附言  ·  322 天前
Seer 的作者决定把 1.5.0 版本(去除公司代码和侵权代码后)开源: https://github.com/ccseer/Seer

此事件完美结束。谢谢各位的支持。

157 回复  |  直到 2018-01-30 14:33:51 +08:00
1  2  
    101
maemolee   322 天前
支持维权,依法追责
    102
xupefei   322 天前
@tomczhen 说的对。GPL 是赋予用户的权利。例如:A 下载了 Seer 1.5 的安装包,那么 A 就可以以 GPL 为理由向作者索要源代码。除此之外,A 有权把拿到的源代码以 GPL 协议公开给任何人。
    103
yangff   322 天前
@tomczhen 可以私下操作,开源的代码依旧是 copyright

作者可以基于自身意愿的前提下将这个代码以另一个形式授权给某人,与开源协议无关,可以是任何一种形式

这里的作者指的是 contributors
    104
yangff   322 天前
有一点要注意,当他违反 GPL 使用你的代码的时候,他并不仅仅是违反了协议(这是小事),而是侵犯了楼主的著作权(违反协议的后果,相当于他在没取得你授权的情况下使用了你的代码)……

语境是美帝 Jacobsen v. Katzer 国内我不清楚
    105
yangff   322 天前
如果像 LZ 贴的图所说的,对方是在工作时间写的他的软件的话,他会被公司怎么处理这不好说,但是只要对方公司不肯松口,对方是不可能(合法地)公开代码的…… 不管通过什么途径……
    106
xupefei   322 天前
@yangff 这很简单啊。既然公司拥有那些代码,那么就是公司违反了 GPL。
    107
yangff   322 天前   ♥ 1
@xupefei

不明白吗? GPL 是你有条件地开放你的一部分权力的一个协议,而违反 GPL 的本质是侵犯了著作权。(这是美帝语境,我不大确定在国内开源协议能否有这样的认定,但是原作者对其代码拥有著作权这是毋庸置疑的)

而你只能主张你自己拥有的权力,比如就侵权代码依法索取赔偿之类的。

**如果事实如他所说,公司持有他剩下代码的著作权的话。**

1. 公开销售这个软件是他个人的行为,公司并没有侵犯著作权,所以你找不了公司的麻烦,也没法让公司开放代码
2. 他没有公开公司所持有代码的权力,因而他无法做出决定开放代码了结这件事

用个通俗一些的比喻,

一个小偷,偷了你的金项链和我的金表,打包拿到市场上去卖,被警察叔叔发现了。

这时候我说,警察叔叔,我的金表是按照 GPL 协议授权的,只要把金表项链两件套也按照 GPL 开放,就可以合法地使用我的金表,所以我要求他把金项链也按照 GPL 协议开放!

你觉得合理吗?
    108
tomczhen   322 天前 via Android
@yangff 简单来说以国内环境看,如果对方不在意名声的话就很难对侵权者造成实质性的“惩罚”了。
    109
Citrus   322 天前 via iPhone
@yangff 个人观点,仅供参考。欢迎指正。。。
说白了,现在有两件事情
1. 将著作权属于公司的代码私自商用并销售
2. 将 GPL 代码用在非开源商业版本中

@xupefei 有权利要求开源金项链和金表,只要开源了,第二件事情就解决了。

至于金项链的来源,这是其他事情了。这个按照著作权相关法律,公司应该是可以起诉这个人使用公司拥有著作权的代码私自商用。

如果原作者能说通公司开源代码并不追责,那么啥事没有。如果公司起诉但作者开源,第二件事情解决。如果公司要求作者不能开源相关代码,而作者选择不开源,责 @xupefei 和用户有权起诉该作者。

不过,国内对开源软件的法律似乎还不完善,最后一种情况也没啥好处。。。
    110
xupefei   322 天前
@yangff 你的金表被 GPL 保护这是小偷造成的,而不是我造成的。我可以要求小偷开源金表部分(注意,不是要求警察开源)。
如果你不想让你的金表开源,你可以去找小偷的麻烦,而这和我无关。
    111
tnx2014   322 天前
@Citrus
@yangff
@tomczhen
@xupefei

原本我不打算发表观点,因为理确实是在被侵权的楼主一方,但是几位既然有所讨论,那我也说几句吧。

我始终认为,出了问题,我们无论用法律还是用和解之类的其他手段,目的都应该是解决问题,而不是出气。无论谁告侵权方最后也就是赔偿了结。现在假设侵权方说的内容是真的,楼主和支持楼主的人当然可以要求对方开源,但这会把第三方(公司)也强行拉入与其无关的的问题中,没错,公司最后也可以告这位员工,但第一,会不会导致公司的有些本不该泄露的东西泄露呢?第二,侵权方必然很惨(如果泄露了什么不得了的东西那后果可能不止民事赔偿),虽然他是自作自受,但是这是激化矛盾的最坏下策。

如果楼主能接受恰当地赔偿不把这件事情扩大化,其实对三方都有好处。

个人愚见,仅供参考。
    112
yangff   322 天前
@Citrus 他有提出一项主张的权力,但是法院不一定会支持。 我之前说的意思是,在我看来即便忽略了国情这个语境,上了法院,法院也不大可能支持这么一项主张……

我觉得我的比喻应该很好理解…… 或者这样吧,如果这么做可行的话,那想象一下,比如我加入 M$, 然后随便找一个 GPL 项目,把他的代码加入 Windows 当中,做一个 release,私底下把这个 release 丢到网上或者卖给别人。

难道,M$对他操作系统的版权的一部分,就被我这样卖掉了?
其他人,在我被 M$料理完之后,就可以 **合法地** 以 GPL 协议使用某个版本的 Windows 的源代码了?

---不怎么靠谱的充满恶意的个人小想法的分界线---
工作时间的产出确实是属于公司(没有这种合同的公司简直无法想象……)
但是我个人是觉得他搬出公司来纯粹是个藉口扯大旗,本质是他还是不想公开除了直接使用了公司代码之外的那部分代码。
具体判断还是 LZ 自己进行吧……
    113
xupefei   322 天前
@tnx2014 其实我已经在邮件里作出让步了。
1 )对方首先说 “其中有一部分公司项目的代码”。
2 )我在回复中作出让步,只要求开源和公司代码无关的部分。
3 )对方在回复里把 “公司代码” 扩大到整个软件。说无法开源。
还能让我怎么让步?难道要说 “好,那就算了”?

我只认协议,不接受赔偿。就算我接受了,其他人(用户)仍然有权利索要源代码。
    114
yangff   322 天前
@xupefei

对对方比较好的做法自然是接受一个合理的赔偿了结此事…… 附带的要求撤回版本,不再使用,公开道歉之类的……

“其他人(用户)仍然有权利索要源代码” 这个观点是不成立的。其他人并没有你的代码的著作权,无法主张任何权力。

一般情况下还是认为 GPL 是许可证,也就是说,GPL 是在说这么一件事:“如果你 XXXX,我就给你 XXXX 权力,而且给出去的权力我绝对不收回( GPL )”

那么违反 GPL 意味着,他没能通过 GPL 这个渠道得到这些权力(但它可以通过其他渠道获得这些权力,比如塞钱)

对方开源可以马上解决问题是因为,只要一开源,它就自动获得了这些权力(因为 GPL ),不管你乐不乐意……

反过来说,这里如果对方不拥有这些的代码的著作权,那对方公开代码也没用

GPL 并不仅仅要求开放源码,还要求这些源码要同样以 GPL 授权。

但是他没法把他公开的代码以 GPL 协议授权给别人,因为他本来就不拥有相应的权力。

还是满足不了 GPL 协议的要求,于是他还是违反了 GPL

也就是说,如果他说的是真的,那他莽一波公开代码的结果就是,GPL 照样违反,还顺带招惹另一个纠纷…… /滑稽
    115
yangff   322 天前
以上内容包含一个个人观点就是 GPL 以许可证的形式,但是有人告诉我 GPL 在国内是以合同的形式来实现的,那样的话情况并不完全一样。
加之国内对这些开源协议的相关资料也比较少,我也不是专业人士不好做出判断,因此以上内容仅供 LZ 参考,希望能帮助到 LZ 就是了^ ^
    116
tomczhen   322 天前 via Android
@tnx2014
我的看法是只要被侵权方的诉求合理合法,那么不用考虑侵权方的利益。

当然,可以追求三方利益最大化,但这不应该作为说服被害者妥协的理由—侵权方才是最需要了解自己所需要付出代价的一方,毕竟如果没有做出侵权行为就没有这些问题了。

换句话说,既然选择以侵权的方式获取利益,那么就要承担相应的后果。

退一步讲,如果楼主没有发现侵权行为,侵权者难道会因为考虑三方的利益最大化主动找楼主和解?

当然,这一切的选择权在于楼主自己。
    117
tnx2014   322 天前
@tomczhen 所谓承担后果是多方面的,对方的名声也是一种(无论对方在乎与否,这件事的坏影响已经造成),当然可以做到极致,让对方最大程度赔偿甚至坐牢。但我说过,这是下策,事实上对方在行为已经道歉,并且愿意赔偿,最后打一场官司的结果依然是赔偿的可能性大,那为什么还要绕一大圈引起官司最后获赔呢?

人总有失足,没有谁保证自己不犯错误,应当承担后果,但未必应该承担最大的后果,虽然从道德上说,他活该。
    118
xupefei   322 天前   ♥ 2
刚收到作者的邮件,Seer 1.5.0 现在开源了(不含公司代码): https://github.com/ccseer/Seer/tree/master/1.5.0



此贴完结。
    119
tnx2014   322 天前
@xupefei

还算是一个不错的结果,当然我对你坚持不要赔偿的清廉也表示钦佩。如果有后续请不要忘记继续反馈。感谢。
    120
anheiyouxia   322 天前 via Android
这件事最后的结果挺好,大家都做出还算理性的让步,再一次支持楼主维权!
    121
cchange   322 天前 via iPhone
支持 quicklook 很高兴得到完美的解决

同时请问逆向用的是什么工具 我也想 hook 一些 windows 程序,同时像你一样查看别人的代码是否抄袭了开源代码

谢谢
    122
wenzhoou   322 天前 via Android
支持楼主。楼主情商高,做得很对。手动赞。
    123
harry890829   322 天前
@ysc3839 #94
@tomczhen #100
我现在需要捕获的都是 usb 扫码枪,也就是都是模拟键盘输入的方式。
我现在的处理方法是,捕获所有的键盘消息,利用时间间隔来处理,如果两次输入的时间在 50ms 以内,我就当是扫码枪输入的,当出现结束符,或者超出 50ms 的话,我这边进行验证,如果不是我需要的字段,就利用 api 将 key 值返回去。

后来发布之后遇到了问题,有的机器上,捕获了键盘消息后,key 值还不回去,表现就是键盘上所有的输入都无效了。还不知道什么原因……出现问题的机器都是客户的机器,不方便调试。

根据现在的表现来看,hook 本身应该是成功的,将所有的键盘消息都抓了出来,但是将 key 值还回去的 api 出现了问题。
对于捕获扫码枪的消息,还有什么好的方法么?感觉用时间间隔来做有点蠢的
    124
congeec   322 天前
楼主你这么叼,我赶紧去 GayHub 给你来个 star😝
    125
congeec   322 天前
不考虑来个微信捐赠按钮么?想支持下楼主啊
    126
izgnod   322 天前 via Android
支持开源者的辛苦劳动,支持维权!
    127
zylll520   322 天前
还好看到最后有一个不错的结局了
    128
wormcy   322 天前
不错的结果
    129
FanWall   322 天前
@cchange ida 正版可贵了
    130
timwei   322 天前   ♥ 1
对楼主维权表示钦佩

也对 Corey 负责的态度表示钦佩

不论是有心还是无心踩线,这是个成熟的处理方式
    131
NoAnyLove   322 天前
不错,软件看起来挺有趣的。很多年没写 Win32 API 的程序了,看到 Windows 钩子真是一种浓浓的怀念之情(很多年以前用 Windows 消息钩子写过一个截取对话框图片的小程序),抽空学习研究一下。
    132
rswl   322 天前
观摩了一个维权直播
    133
cchange   322 天前 via iPhone
@FanWall 谢谢 貌似生成了伪代码 这个怎么实现呢 给个关键词就好了

ida 确实很贵……
    134
xupefei   322 天前
@cchange 你可以用免费的 OllyDbg。
伪代码是我自己写的,IDA 自带的也有个从汇编生成 C 代码功能,很强大。
    135
catror   322 天前 via Android
@harry890829 我有一种不用挂钩子的想法…用 libusb 把设备的 IO 透到应用层,然后自己看 USB-HID 的协议规范去解析数据包,libusb 可以控制到具体的设备
    136
wenssh   322 天前
看到 WM_COPYDATA 是未公开的消息感觉这么多年客户端白做了。。。
非利益相关,纯吐槽这一个点。
    137
yangff   322 天前   ♥ 1
@xupefei 现在是 x64dbg 的天下了…… ollydbg 2.0 简直鬼故事(
    138
cchange   322 天前
@xupefei 非常感谢,我去看看
汇编生成 C 代码只要一部分即可,有时候这个功能是必须的
    139
cchange   322 天前
@yangff 刚刚搜索了一下 x64dbg 确实好用 谢谢
    140
harry890829   322 天前
@catror #135 这个我以前写过一点,不过我这里设计到的是各种扫码枪,设备号什么的都是不知道的……有办法解析么?
    141
ysc3839   322 天前 via Android
@wenssh 他的意思可能是,那个程序通过 WM_COPYDATA 传输数据,其中的数据结构是未公开的。
    142
ysc3839   322 天前 via Android
@harry890829 这种情况有点麻烦啊,我第一想到的就是写驱动来解决,但是难度很大。而且驱动要数字签名,买一个也很贵。
    143
ysc3839   322 天前 via Android
@harry890829 也许可以试试 Raw Input。我台式机只有一块键盘,找时间用笔电试试。
    144
catror   322 天前 via Android
@harry890829 这样的话确实不好弄。匹配常见厂商的 VID 应该可以识别大部分,但是做不到 100%,那就还需要提供选择设备的功能去避免这么问题。感觉工作量更大了,不如挂钩子来得简单,😀还是好好查一查 Bug 吧
    145
harry890829   322 天前
@ysc3839 #143 多谢,晚点研究研究
    146
yangff   322 天前
@harry890829 逆向一下扫码枪的程序咯,我估计要么模拟键盘要么 hid
    147
harry890829   322 天前
@yangff #146 usb 扫码枪通常都是模拟键盘的。

@catror #144 之前我跟产品说,要么就让客户端选择,但是怎么教育客户选择呢?感觉也很麻烦,晚点查查 bug 吧,听说市场那边有电脑和客户那边一样,可以在上面看看问题
    148
xupefei   322 天前 via Android
@wenssh 我指的是 WM_USER+7 是未公开消息。
    149
xupefei   322 天前 via Android
@xupefei 说错了,我指的是 listsel 是 dopus 官方未公开的消息。
    150
xifangczy   322 天前
所以说 你们这些搞开发的 为什么不多宣传。这么好的东西 到吵架了我才发现。
    151
PythonAnswer   321 天前 via Android
学习下上述长帖
    152
mscofield   321 天前
观摩了一个维权直播
    153
sxul07   321 天前
hhh 谢谢大佬 默默把 SEER 卸掉换这个了
    154
xupefei   321 天前
@xifangczy 懒。
    155
sagood   320 天前
    156
xupefei   319 天前
@sagood 不能。链接里的代码只能拿到桌面和资源管理器窗口的 IShellBrowser。
在对话框使用现在似乎只有 WM_USER+7 这个办法。
    157
e9e499d78f   140 天前
@xupefei #118 github 仓库进去没有源码了
1  2  
关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   2189 人在线   最高记录 3541   ·  
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.1 · 25ms · UTC 10:51 · PVG 18:51 · LAX 03:51 · JFK 06:51
♥ Do have faith in what you're doing.
沪ICP备16043287号-1