├── img ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 8.png ├── 9.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 20.png ├── 21.png ├── 20190708165355_1.jpg ├── 20190708170006_1.jpg ├── 20190708170008_1.jpg ├── 20190708170009_1.jpg └── 20190708170056_1.jpg ├── README.md └── LICENSE /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/1.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/2.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/4.png -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/5.png -------------------------------------------------------------------------------- /img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/6.png -------------------------------------------------------------------------------- /img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/8.png -------------------------------------------------------------------------------- /img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/9.png -------------------------------------------------------------------------------- /img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/10.png -------------------------------------------------------------------------------- /img/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/11.png -------------------------------------------------------------------------------- /img/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/12.png -------------------------------------------------------------------------------- /img/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/13.png -------------------------------------------------------------------------------- /img/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/14.png -------------------------------------------------------------------------------- /img/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/15.png -------------------------------------------------------------------------------- /img/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/16.png -------------------------------------------------------------------------------- /img/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/17.png -------------------------------------------------------------------------------- /img/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/18.png -------------------------------------------------------------------------------- /img/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/19.png -------------------------------------------------------------------------------- /img/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/20.png -------------------------------------------------------------------------------- /img/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/21.png -------------------------------------------------------------------------------- /img/20190708165355_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/20190708165355_1.jpg -------------------------------------------------------------------------------- /img/20190708170006_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/20190708170006_1.jpg -------------------------------------------------------------------------------- /img/20190708170008_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/20190708170008_1.jpg -------------------------------------------------------------------------------- /img/20190708170009_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/20190708170009_1.jpg -------------------------------------------------------------------------------- /img/20190708170056_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CasterWx/Plug-in-R/HEAD/img/20190708170056_1.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 如何打造一款游戏外挂 2 | 3 | 4 | ###### 欢迎关注公众号,开启和我的交流 5 | 6 | ![weix](https://www.cnblogs.com/images/cnblogs_com/LexMoon/1391533/o_qrcode_for_gh_f3457f4f73a1_258.jpg) 7 | 8 | ### 前言 9 | 10 | 记得小学的时候玩页游把家里电脑弄坏了(怎么回事,页游还能弄坏电脑?),然后我爸拿去重新装了系统,回来之后电脑里有了两个新的单机游戏,植物大战僵尸和大鱼吃小鱼。 11 | 12 | 那个年代周围的小学生都是赛尔号/奥比岛/洛克王国/天书奇谭/龙之刃/梦幻西游,玩摩尔庄园的小学生说出来都不是九年义务教育的。植物大战僵尸虽然现在看来比较久远,但他的游戏元素却是推生出许多游戏音乐文化,比如Billie Eilish的《bad guy》,节奏简直就是植物大战僵尸的`灯 灯 灯 灯 灯灯~`了。 13 | 14 | 当时因为生存模式被虐,在网上找了修改器,可以修改阳光点数,那时候虽然没学计算机专业,但对修改器的运行机制还是有所猜测的,当时小学因为不知道内存这回事,所以是觉得修改的文件中的数据。 15 | 16 | 这个猜测如今看起来很搞笑,但也不失道理(要开始狡辩了),有些游戏的数据可能是先放在文件中的,在游戏启动之后把文件中的数据读取到游戏的内存区域,所以我们需要先修改数据所在的文件内容,然后启动游戏,但是很多游戏的数据文件是加密的(出大问题,骑马与砍杀就没有加密),我们没办法从文件进行修改,所以需要让游戏进程先把它读到内存,然后从内存修改,然后再退出游戏的时候游戏进程自动把它保存下来,之后也就是这个数据了。 17 | 18 | 所以综上可以发现有这几类修改对象: 19 | 20 | 1. 游戏数据在本地未加密文件,直接修改它来修改游戏数据 21 | 22 | * 这一类的代表就是骑马与砍杀,它的角色数据在文档中,可以肆意修改玩家属性,但是不要修改太大,因为数据会溢出。 23 | 此外它的游戏数据,如NPC对话,NPC姓名,国家名称,城堡名称都是明文给出的(还是用Excel保存的???),最可怕的是它的内部机制,如兵种上限/士气/围攻时间/酒馆花费等都是明文的,怪不得骑砍会有各种版本。 24 | 25 | 2. 数据封装,通过修改内存来修改游戏数据 26 | 27 | 3. 网络游戏,数据在对方服务器,无法直接修改,通过模拟网络请求表单来模拟自己获得游戏物品(看对方服务器逻辑严密程度了) 28 | 29 | * 举几个例子(腾讯游戏全部忽略,这个不在新手教程里面),你正在玩一个网页游戏龙之刃,打死了一个小怪,获得了15银币,这时你的网页需要给服务器发送给你银币数据+15的信息,你可以用浏览器自带的工具开发者调试看看这个数据的格式,然后模仿一个相似的,发送的服务器,比较菜的游戏厂商当然无法完善这方面的逻辑了。(另外我有一个想法,steam在我们玩游戏的时候应该会有一个线程监控我们正在玩什么游戏,所以我们可以监控这个线程发出的网络表单,然后我们自己不断发出,这不是卡套刷满?) 30 | 31 | 下面开始实战部分,因为不想再下载骑砍,而且这种修改文件的教程在骑砍官网很多,所以我就跳过啦。 32 | 33 | ### 一. 内存数据排查 34 | 35 | 游戏作为进程运行在我们的电脑中,所以要修改它的数据我们可以在内存进行搜索修改。 36 | 37 | 拿植物大战僵尸为例,我们要修改的是他的阳光数量。假如我们现在的阳光值是75,我们需要在内存中查找75的数字。 38 | 39 | ![1](img/1.png) 40 | 41 | 先用内存工具打开植物大战僵尸的进程。 42 | 43 | ![2](img/2.png) 44 | 45 | 然后查找25这个数字,下图只找到一个,所以阳光的数据就存储在21BF10C8这个地址了,但很多游戏搜索出来可能不止这一个地址,我们需要将查询的那个道具(阳光)花费掉一点,变成另一个值再次扫描一次才能精准定位。 46 | 47 | ![4](img/4.png) 48 | 49 | 修改这个地址的数值。 50 | 51 | ![5](img/5.png) 52 | 53 | 在游戏中查看阳光数量。 54 | 55 | ![6](img/6.png) 56 | 57 | 是不是太简单了?! 这是因为这个游戏本身设计已经和这个时代脱轨了,如今的游戏制造商不仅要考虑内容,还需要在安全上和高玩斗智斗勇。 58 | 59 | 接下来再拿一个游戏练练手,就是最近非常火的宫崎英高老贼作品只狼。 60 | 61 | ##### Sekiro : Shadows Die Twice 62 | 63 | 作为一个九周目下忍,这款游戏真的让我知道了死字怎么写。 64 | 65 | 先来看看我当前的金币,2323。 66 | 67 | ![20191](img/20190708165355_1.jpg) 68 | 69 | 然后按照惯例选择只狼的进程,搜索2323这个数据,可以发现出现了很多。 70 | 71 | ![9](img/9.png) 72 | 73 | 我去杀了一个小怪,把金币加到了2360。 74 | 75 | ![20191](img/20190708170006_1.jpg) 76 | 77 | ![20191](img/20190708170008_1.jpg) 78 | 79 | 再次搜索发现还有5个地址存在,直接修改会发现不会改变,有一种猜测是它用了一种类似于病毒中多进程相互守护一样的方法,会让数据保持一致,所以我们可以直接全部选中同事修改,会发现第三个没有修改成功,因为这个值不是背包中金币数量,而是战斗界面的数量,你可以自己试试。 80 | 81 | ![9](img/10.png) 82 | 83 | ![20191](img/20190708170056_1.jpg) 84 | 85 | 金币顺利添加了两万,其它数据在本地的都是如此,可以自己尝试,但这种方法效率总是不高,我们可以使用代码的形式来把这个修改过程自动化。 86 | 87 | 这里多说一句,代码的方式是把数据的地址编码到代码中,如果游戏的更新导致这个地址改变话,代码里面也要同步修改,所以需要频繁更新的游戏其实修改器很多会失效。 88 | 89 | ### 二. 外挂程序编写 90 | 91 | 先来了解几个Windows的API。 92 | 93 | HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName); 94 | 通过类名或窗口名查找,返回窗口句柄 95 | DWORD GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId); 96 | 得到窗口句柄后通过GetWindowThreadProcessId这个函数来获得窗口所属进程ID和线程ID 97 | HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId) 98 | 打开一个已存在的进程对象,并返回进程的句柄 99 | bool WriteProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpBuffer,DWORD nSize,LPDWORD lpNumberOfBytesWritten ); 100 | 能写入某一进程的内存区域。入口区必须可以访问,否则操作将失败 101 | 102 | 附上代码: 103 | 104 | ```c 105 | #include 106 | #include 107 | int main() { 108 | HWND h = ::FindWindow(NULL, "植物大战僵尸中文版"); // 寻找并打开进程 109 | DWORD processid; 110 | GetWindowThreadProcessId(h, &processid); 111 | HANDLE hprocess = 0; 112 | hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processid); 113 | if (hprocess == 0) { // 对应处理 114 | printf("打开进程失败!\n"); 115 | return 1; 116 | } else { 117 | printf("打开进程成功!\n"); 118 | DWORD hp = 3000; // 要修改的游戏数据最大值 119 | LPCVOID addr = (LPVOID)0x21BF10C8; // 通过CE找到的游戏数据地址 120 | DWORD res = WriteProcessMemory(hprocess, (LPVOID)addr, &hp, 4, 0); // 写入内存修改游戏数据 121 | return 0; 122 | } 123 | } 124 | ``` 125 | ![11](img/11.png) 126 | 127 | 这样一个代码,可以让我们随时调用,把阳光修改为2000,这个程序没有做图形化界面,因为太简单了,所以当做入门Demo吧。 128 | 129 | 我们修改了通过地址直接游戏的数据,那么能不能说做一个游戏助手,读出游戏的某些数据来辅助玩家呢? CE工具虽然可以搜索读取,但是效率太差,接下来介绍一个新的API,来读取固定地址的数据。 130 | 131 | HWND ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); 132 | 根据进程句柄读入该进程的某个内存空间lpBaseAddress的nSize字节,并写入缓冲区lpBuffer,多次计算基址和偏移即可 133 | 134 | 尝试读取 : 135 | 136 | ![11](img/12.png) 137 | 138 | 附上代码实现: 139 | ```c 140 | #include 141 | #include 142 | int main() { 143 | HWND h = ::FindWindow(NULL, "植物大战僵尸中文版"); // 寻找并打开进程 144 | DWORD processid; 145 | GetWindowThreadProcessId(h, &processid); 146 | HANDLE processh = 0; 147 | processh = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processid); 148 | 149 | if (processh == 0) { // 对应处理 150 | printf("打开进程失败!\n"); 151 | return 1; 152 | } else { 153 | printf("打开进程成功!\n"); 154 | int sun; // 用于存放阳光数据 155 | LPCVOID mbase = (LPCVOID)0x1E0CF020; 156 | LPVOID mbuffer = (LPVOID)&sun; 157 | ::ReadProcessMemory(processh, mbase, mbuffer, 4, 0); 158 | printf("您有阳光:%d\n", sun); 159 | return 0; 160 | } 161 | ``` 162 | 163 | ### 三. 挂机自动外挂 164 | 165 | 上述都是一些修改数据的外挂,此外还有一种是自动操作类的修改器,比如自动玩连连看(雾),自动下棋(雾),自动拼图(笑)。 166 | 167 | 例如下面这样的连连看,当你用CE观察内存时,会发现它的数据奇妙在于这是一个二维数组,在内存中不同牌有不同数值。 168 | 169 | ![13](img/13.png) 170 | 171 | 想要自动消除连连看,肯定需要先模拟鼠标的操作,介绍一个API,它可以模拟鼠标操作,但不会移动我们的物理鼠标(虚无点击?)。 172 | 173 | LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam); 174 | 其中Msg为WM_LBUTTONDOWN,WM_LBUTTONUP,表示对鼠标的软件模拟操作(虽然兼容性和安全性不如硬件模拟的mouse_event,但不改变移动鼠标指针) 175 | 176 | 除此之外,对一个二维数组寻找可以消除的两幅牌,可以使用BFS算法实现。 177 | 178 | ```c 179 | void clearapair() { //找到可消去的两个点并点击 180 | POINT p1, p2; 181 | int x1, y1, x2, y2; 182 | for (y1=0; y1<11; y1++) 183 | for (x1=0; x1<19; x1++) { 184 | if (!chessdata[y1][x1]) 185 | continue; 186 | for (y2=0; y2<11; y2++) 187 | for (x2=0; x2<19; x2++) 188 | if (chessdata[y2][x2] && (chessdata[y1][x1]==chessdata[y2][x2]) && (x1!=x2 || y1!=y2) ) { 189 | p1.x=x1; p1.y=y1; 190 | p2.x=x2; p2.y=y2; 191 | readchess(); 192 | if (llk_bfs(y1, x1, y2, x2) != -1) { 193 | click2p(p1, p2); 194 | return; 195 | } 196 | } 197 | } 198 | } 199 | ``` 200 | 201 | ### 四. 网络游戏修改 202 | 203 | 这个是我从小学四年级开始玩的游戏,因为时间很长没有登录,这里累积了很多经验,在领取之前我们可以先观察一下。 204 | 205 | ![14](img/14.png) 206 | 207 | 抓到了一条表单。 208 | 209 | ![14](img/16.png) 210 | 211 | 初步分析,经验数据不是直接明文规定的,而是从了其他数值代替,并且获取经验这一类型也是有其他数字代替,这里初步猜测为age。 212 | 213 | ![14](img/17.png) 214 | 215 | 好吧,可能种类太多,抓不出来相同的Age。 216 | 217 | 但是我换了一种方式,对宠物使用了两次经验包,抓下来的两次包,都是叫fcode1f3....的这个包。 218 | 219 | 其中Age类型也是一样。 220 | 221 | ![14](img/18.png) 222 | 223 | ![14](img/19.png) 224 | 225 | 现在过了几分钟,我们把第三个包也使用掉。 226 | 227 | ![14](img/20.png) 228 | 229 | 囊达? 难道,这个Age真的是...(小声bb) 230 | 231 | 还是不确定,让我们用爬虫来模拟这次表单吧,刷爆(封号)!!! 232 | 233 | 测试N次过后... 234 | 235 | ![21](img/21.png) 236 | 237 | 成功啦!!! 238 | 239 | 需要注意的是,这个游戏服务器以及几年没更新了,上一条公告还是十年前的。 240 | 241 | 如果你要使用爬虫来模拟使用道具,非常关键的一个信息就是cookie,这是确认你登录的账号的判断信息。 242 | 243 | 下面贴出代码(我的cookie肯定要删除掉啦) 244 | 245 | ```java 246 | import java.util.ArrayList; 247 | import java.util.List; 248 | import org.apache.http.Header; 249 | import org.apache.http.HttpResponse; 250 | import org.apache.http.NameValuePair; 251 | import org.apache.http.client.ResponseHandler; 252 | import org.apache.http.client.entity.UrlEncodedFormEntity; 253 | import org.apache.http.client.methods.HttpGet; 254 | import org.apache.http.client.methods.HttpPost; 255 | import org.apache.http.impl.client.BasicResponseHandler; 256 | import org.apache.http.impl.client.CloseableHttpClient; 257 | import org.apache.http.impl.client.HttpClients; 258 | import org.apache.http.message.BasicNameValuePair; 259 | import org.apache.http.protocol.HTTP; 260 | 261 | public class Renren { 262 | private static String renRenLoginURL = "http://resourcemop.l.imop.com/res/fc/fcde1f39034b164a0d5fe7e455b0c32e"; 263 | private HttpResponse response; 264 | private CloseableHttpClient httpclient = HttpClients.createDefault(); 265 | private boolean login() { 266 | HttpGet httpGet = new HttpGet(renRenLoginURL); 267 | httpGet.setHeader("Accept-Ranges", "bytes"); 268 | httpGet.setHeader("Age", "74342"); 269 | httpGet.setHeader("Cache-Control", ""); 270 | httpGet.setHeader("Content-Length", "3266"); 271 | httpGet.setHeader("Content-Type", "text/plain"); 272 | httpGet.setHeader("Date", "Thu, 23 May 2019 08:41:58 GMT"); 273 | httpGet.setHeader("Expires", "Sun, 20 May 2029 08:41:58 GMT"); 274 | httpGet.setHeader("Last-Modified", "Wed, 22 May 2019 08:13:20 GMT"); 275 | httpGet.setHeader("Server", "Apache"); 276 | httpGet.setHeader("Via", "1.0 Static1.lzr.squid1:80 (squid/2.6.STABLE7)"); 277 | httpGet.setHeader("X-Cache", "HIT from Static1.lzr.squid1"); 278 | httpGet.setHeader("Referer", "http://s34.l.imop.com/"); 279 | httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"); 280 | try { 281 | response = httpclient.execute(httpGet); 282 | } catch (Exception e) { 283 | e.printStackTrace(); 284 | return false; 285 | } finally { 286 | httpGet.abort(); 287 | } 288 | return true; 289 | } 290 | 291 | public static void main(String[] args) { 292 | Renren renRen = new Renren(); 293 | renRen.login(); 294 | } 295 | } 296 | ``` 297 | 298 | 这个其实是两年前写的人人网爬虫,改了改表单数据就可以用啦。 299 | 300 | 篇幅有限,所以暂时就写这么多。之后可能会继续更新其他的修改教程,steam挂卡这个我是一定要写的。 301 | 302 | 敲代码是热爱,敲到世界充满爱! 撤退! 303 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------