破解SQLServer for Linux预览版的3.5GB内存限制 (RHEL篇)
微软发布了SQLServer for Linux,但是安装竟然需要3.5GB内存,这让大部分云主机用户都没办法尝试这个新东西
这篇我将讲解如何破解这个内存限制
要看关键的可以直接跳到第6步,只需要替换4个字节就可以破解这个限制
首先按照微软的给出的步骤安装和配置
https://docs.microsoft.com/zh-cn/sql/linux/sql-server-linux-setup-red-hat到执行/opt/mssql/bin/sqlservr-setup时可以看到这个错误
sqlservr: This program requires a machine with at least 3250 megabytes of memory.
- 按错误文本查找消息在哪个文件里面
[root@localhost ~]# cd /opt/mssql/bin/
[root@localhost bin]# grep -irn "3250"
[root@localhost bin]# grep -irn "megabytes of memory"
Binary file sqlpackage matches
Binary file sqlpackage matches
Binary file sqlservr matches
[root@localhost bin]# strings sqlservr | grep "megabytes of memory"
%s: This program requires a machine with at least %zu megabytes of memory.
[root@localhost bin]# strings sqlpackage | grep "megabytes of memory"
%s: This program requires a machine with at least %zu megabytes of memory.
看来sqlservr和sqlpackage会检测这个限制,并且这个限制是一个常量
- 查找错误消息的位置
[root@localhost bin]# hexdump -C sqlservr | less
找到这里
0006baf0 72 69 6e 67 29 00 25 73 3a 20 54 68 69 73 20 70 |ring).%s: This p|
0006bb00 72 6f 67 72 61 6d 20 72 65 71 75 69 72 65 73 20 |rogram requires |
可以看到消息在0006baf6的位置
- 查找调用错误消息的位置
[root@localhost bin]# objdump -C -S sqlservr | less
找到这里
23940: 48 8d 35 af 81 04 00 lea 0x481af(%rip),%rsi # 6baf6
23947: 31 c0 xor %eax,%eax
23949: 48 89 ca mov %rcx,%rdx
2394c: 48 89 d9 mov %rbx,%rcx
2394f: e8 6c e4 fe ff callq 11dc0 <fprintf@plt>
23954: bf 01 00 00 00 mov $0x1,%edi
23959: e8 e2 e1 fe ff callq 11b40 <exit@plt>
判断的函数在这里
238e0: 55 push %rbp
238e1: 48 89 e5 mov %rsp,%rbp
238e4: 53 push %rbx
238e5: 48 83 ec 78 sub $0x78,%rsp
// 把这个函数接收的第二个参数放到rbx
// 参考 https://en.wikipedia.org/wiki/X86_calling_conventions (System V AMD64 ABI)
238e9: 48 89 f3 mov %rsi,%rbx
// 调用sysinfo获取内存大小
// rdi是第一个参数,是一个在堆栈中的struct sysinfo
// 参考 https://linux.die.net/man/2/sysinfo
238ec: 48 8d 7d 88 lea -0x78(%rbp),%rdi
238f0: e8 3b e3 fe ff callq 11c30 <sysinfo@plt>
// 偏移量的计算如下
// -0x78: uptime (struct sysinfo的开头地址)
// -0x70: loads[3]
// -0x58: totalram
// -0x50: freeram
// -0x48: sharedram
// -0x40: bufferram
// -0x38: totalswap
// -0x30: freeswap
// -0x28: procs (short为什么占8个字节?看https://en.wikipedia.org/wiki/Data_structure_alignment)
// -0x20: totalhigh
// -0x18: freehigh
// -0x10: mem_unit (同样,int 4个字节 align 4个字节)
// 计算出rax = totalram * mem_unit
238f5: 8b 45 f0 mov -0x10(%rbp),%eax
238f8: 48 0f af 45 a8 imul -0x58(%rbp),%rax
// 如果rax小于rbx则跳到23909,即显示内存不足并退出
238fd: 48 39 d8 cmp %rbx,%rax
23900: 72 07 jb 23909
23902: 48 83 c4 78 add $0x78,%rsp
23906: 5b pop %rbx
23907: 5d pop %rbp
23908: c3 retq
调用判断的函数的代码在这里
// 这里的第二个参数是3250000000,可以看到内存的限制值是一个常量
// 0xc1b71080 = 3250000000
1486a: be 80 10 b7 c1 mov $0xc1b71080,%esi
1486f: 4c 89 e7 mov %r12,%rdi
14872: e8 69 f0 00 00 callq 238e0
顺道再用hexdump查找一下有多少处地方用了80 10 b7 c1,结果是只有一处
00014860 00 00 48 89 df e8 66 15 00 00 be 80 10 b7 c1 4c |..H...f........L|
00014870 89 e7 e8 69 f0 00 00 0f 57 c0 0f 29 85 70 ff ff |...i....W..).p..|
- 使用python修改代码
改条件判断的jb或者改8010b7c1都可以,我这里把8010b7c1改成更小的值0080841e(512M)
[root@localhost bin]# mv sqlservr sqlservr.old
[root@localhost bin]# python
>>> a = open("sqlservr.old", "rb").read()
>>> b = a.replace("\x80\x10\xb7\xc1", "\x00\x80\x84\x1e")
>>> open("sqlservr", "wb").write(b)
[root@localhost bin]# chmod +x sqlservr
可以继续替换掉sqlpackage中的限制值,但是不替换也可以使用
- 继续配置sqlserver
[root@localhost bin]# /opt/mssql/bin/sqlservr-setup
[root@localhost bin]# systemctl status mssql-server
如果你执行完命令后没有看到服务正常启动,可能是之前的配置没有成功导致的
删除mssql的数据文件夹并重试即可
[root@localhost bin]# rm -rf /var/opt/mssql
[root@localhost bin]# /opt/mssql/bin/sqlservr-setup
正常启动后可以看到
● mssql-server.service - Microsoft(R) SQL Server(R) Database Engine
Loaded: loaded (/usr/lib/systemd/system/mssql-server.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2016-12-05 22:50:06 EST; 20s ago
Main PID: 2625 (sqlservr)
CGroup: /system.slice/mssql-server.service
├─2625 /opt/mssql/bin/sqlservr
└─2638 /opt/mssql/bin/sqlservr
Dec 05 22:50:10 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:10.85 spid17s Server is listening on [ 0.0.0.0 ...433].
Dec 05 22:50:10 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:10.87 Server Server is listening on [ 127.0.0....434].
Dec 05 22:50:10 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:10.89 Server Dedicated admin connection suppor...1434.
Dec 05 22:50:10 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:10.89 spid17s SQL Server is now ready for clien...ired.
Dec 05 22:50:11 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:11.77 spid6s Starting up database 'tempdb'.
Dec 05 22:50:12 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:12.02 spid6s The tempdb database has 1 data file(s).
Dec 05 22:50:12 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:12.02 spid20s The Service Broker endpoint is in...tate.
Dec 05 22:50:12 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:12.03 spid20s The Database Mirroring endpoint i...tate.
Dec 05 22:50:12 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:12.09 spid20s Service Broker manager has started.
Dec 05 22:50:12 localhost.localdomain sqlservr[2625]: 2016-12-06 03:50:12.14 spid5s Recovery is complete. This is an ...ired.
Hint: Some lines were ellipsized, use -l to show in full.
启动成功后使用微软提供的命令行工具连接也可以,使用windows上的客户端连接也可以
https://docs.microsoft.com/zh-cn/sql/linux/sql-server-linux-setup-tools
下图是2G内存上运行的mssql
Ubuntu上的破解会不一样,因为Ubuntu安装前会运行检测程序,如何破解将在下一篇讲解
题外话
- mssql for linux有日期限制和联网验证,预计正式版以后免费的可能性很小
- mssql在linux上编译开启了pie选项并且没有符号表导出,这让gdb跟踪变得很困难,但这次破解只需要静态分析
- mssql的本体封在了/opt/mssql/lib/sqlservr.sfp里面,如果需要破解其他限制可能还需要花功夫研究这个文件
破解SQLServer for Linux预览版的3.5GB内存限制 (RHEL篇)的更多相关文章
- 破解SQLServer for Linux预览版的3.5GB内存限制 (RHEL篇) 转
https://www.ancii.com/database/30842.html 微软发布了SQLServer for Linux,但是安装竟然需要3.5GB内存,这让大部分云主机用户都没办法尝试这 ...
- 破解SQLServer for Linux预览版的3.5GB内存限制 (UBUNTU篇)
在上一篇中我提到了如何破解RHEL上SQLServer的内存大小限制,但是Ubuntu上还有一道检查 这篇我将会讲解如何在3.5GB以下内存的Ubuntu中安装和运行SQLServer for Lin ...
- [干货来袭]MSSQL Server on Linux预览版安装教程(先帮大家踩坑)
前言 昨天晚上微软爸爸开了全国开发者大会,会上的内容,我就不多说了,园子里面很多.. 我们唐总裁在今年曾今透漏过SQL Server love Linux,果不其然,这次开发者大会上就推出了MSSQL ...
- 微软发布 Windows Server 2016 预览版第三版,开发者要重点关注Nano Server
微软已经发布 Windows Server 2016 和 System Center 2016 第三个技术预览版,已经提供下载.Windows Server 2016 技术预览版第三版也是首个包括了容 ...
- Win10桌面预览版14316更新内容大全
下载更新: 安装之后右下角: Win10桌面预览版14316更新内容: Windows上运行乌班图Bash:通过设置开启开发者模式,更新和安全>面向开发人员.然后搜索"Wi ...
- Windows 10预览版14316开启Bash命令支持
00x0 前言 4月7日凌晨,微软推送了最新的Windows 10一周年更新预览版14316,其中重要的是原生支持Linux Bash命令行支持. 00x1 问题 如何开启Linux Bash命令行? ...
- Swift 3.0首个开发者预览版将在5月12日释出
Swift团队在博客中宣布Swift 3.0语言首个开发者预览版将于5月12日释出,正式版将在4-6周之后推出.开发者预览阶段并无确定的更新周期和计划,不过Swift团队称努力将其控 制在4-6周内. ...
- 【译】Visual Studio 15 预览版更新说明
序:恰逢Build2016大会召开,微软发布了VS2015的update2更新包和VS2016预览版.本人正在提升英文水平中,于是在这里对VS2016预览版的官方文档进行了部分翻译.因为VS有些功能使 ...
- Visual Studio 2015 预览版 - 支持跨平台开发Android/iOS应用程序(内置安卓模拟器)
微软最近的惊人举动真多,对普通消费者Office 移动版宣布免费,对开发者也发布了完全免费的 VS2013 社区版! 不仅如此,就连 .Net 开发框架环境也竟然「开源」并且跨平台支持 Mac 及 L ...
随机推荐
- 在Ubuntu下搭建ASP.NET 5开发环境
在Ubuntu下搭建ASP.NET 5开发环境 0x00 写在前面的废话 年底这段时间实在太忙了,各种事情都凑在这个时候,没时间去学习自己感兴趣的东西,所以博客也好就没写了.最近工作上有个小功能要做成 ...
- Linux下服务器端开发流程及相关工具介绍(C++)
去年刚毕业来公司后,做为新人,发现很多东西都没有文档,各种工具和地址都是口口相传的,而且很多时候都是不知道有哪些工具可以使用,所以当时就想把自己接触到的这些东西记录下来,为后来者提供参考,相当于一个路 ...
- xamarin DependencyService源码阅读
xamarin在面对PCL无法实现的各平台特有功能时使用了一种叫[DependencyService]的方式来实现.它使得xamarin能像原生平台一样做平台能做到的事情!主要分四个部分 接口:定义功 ...
- webpack入门教程之Hello webpack(一)
webpack入门教程系列为官网Tutorials的个人译文,旨在给予想要学习webpack的小伙伴一个另外的途径.如有不当之处,请大家指出. 看完入门教程系列后,你将会学习到如下内容: 1.如何安装 ...
- (JS+CSS)实现图片放大效果
代码很简单,在这里就不过多阐述,先上示例图: 实现过程: html部分代码很简单 <div id="outer"> <p>点击图片</p> &l ...
- Emoji选项列表
一.需要的前提文件 从网上下载Emoji的表情包,当然是png的图片,因为WPF不支持彩色的Emoji,所以,做列表的时候,需要用图片. 随着压缩包一起的还有一个Emoji.xml文件,文件的层级结构 ...
- Android Ormlite 学习笔记1 -- 基础
Ormlite 是一个开源Java数据实体映射框架.其中依赖2个核心类库: 1.ormlite-android-4.48.jar 2.ormlite-core-4.48.jar 新建项目,引用上面2个 ...
- spring源码分析之<context:property-placeholder/>和<property-override/>
在一个spring xml配置文件中,NamespaceHandler是DefaultBeanDefinitionDocumentReader用来处理自定义命名空间的基础接口.其层次结构如下: < ...
- 原生javascript 固定表头原理与源码
我在工作中需要固定表头这个功能,我不想去找,没意思.于是就写了一个,我写的是angularjs 自定义指令 起了个 "fix-header" ,有人叫 "freeze- ...
- .NET应用程序域
在.NET平台下,可执行程序并没有直接承载在Windows进程中,而非托管程序是直接承载的..NET可执行程序承载在进程的一个逻辑分区中,称之为应用程序域(AppDomain).一个进程可以包含多个应 ...