疑似CPU或者内存故障致使进程崩溃

咱们有一个服务跑在微软云的全部宿主机上。最近发现某一台机器上该服务进程持续崩溃。
崩溃缘由是访问了一个无效指针,对应的代码以下函数


serviceListIniBuffer.AppendF("ServerList=%s\r\n",
                                               m_newServiceList.config->GetStringParameter("Manifest", "ServerList", "").c_str());this

从dump和live repo中发现,无效指针的来自AppendF函数的第一个参数。
但奇怪的,该参数是一个写死的字符串,这怎么会发生呢?spa

看汇编代码debug

00007ff6`36961907 4889442420 mov qword ptr [rsp+20h],rax
00007ff6`3696190c 4c8d0d45270b00 lea r9,[GetAndRunServices!`string'+0xfd8 (00007ff6`36a14058)]
00007ff6`36961913 4c8d054e270b00 lea r8,[GetAndRunServices!`string'+0xfe8 (00007ff6`36a14068)]
00007ff6`3696191a 488d5500 lea rdx,[rbp]
00007ff6`3696191e 488b8f98030000 mov rcx,qword ptr [rdi+398h]
00007ff6`36961925 e8f649f3ff call GetAndRunServices!apsdk::configuration::IConfiguration::GetStringParameter (00007ff6`36896320)
00007ff6`3696192a 90 nop
00007ff6`3696192b 4883781810 cmp qword ptr [rax+18h],10h
00007ff6`36961930 7203 jb GetAndRunServices!GetAndRunServices2::GenerateOMNewServiceListFile+0x9e5 (00007ff6`36961935)
00007ff6`36961932 488b00 mov rax,qword ptr [rax]
00007ff6`36961935 4c8bc0 mov r8,rax
00007ff6`36961938 488d1541270b01 lea rdx,[00007ff6`37a14080]
00007ff6`3696193f 488d4d20 lea rcx,[rbp+20h]
>>>>>>>>>>>>>>>>>>>>00007ff6`36961943 e8981ef3ff call GetAndRunServices!apsdk::DynStringT<127>::AppendF (00007ff6`368937e0)指针

具体的崩溃发生在AppendF里面。但问题是无效指针致使的,和被调函数AppendF无关。为了省略篇幅就略过AppendF部分了。进程

这里能够看到,rcx应该保存的是serviceListIniBuffer的this指针。由于C默认从右向左压参数,因此rdx对应的应该是第一个参数,r8对应的应该是第二个参数。内存

0:000> da r8
00000001`0a3a48c0 "25.66.164.187:25.66.164.4:25.66."
00000001`0a3a48e0 "164.251:25.66.165.4"字符串

0:000> da rdx
00007ff6`37a14080 "????????????????????????????????"get

果真,rdx就是无效啊。string

仔细看一下前面的汇编,好比在调用GetStringParameter的时候,也会用到写死的字符串。好比下面两句就是
00007ff6`3696190c 4c8d0d45270b00 lea r9,[GetAndRunServices!`string'+0xfd8 (00007ff6`36a14058)]
00007ff6`36961913 4c8d054e270b00 lea r8,[GetAndRunServices!`string'+0xfe8 (00007ff6`36a14068)]

能够看到,这些字符串都是从GetAndRunServices!`string'这个全局表里面读入的。 这两个地址也都准确落入了执行文件的地址范围:
0:000> lmf
start end module name
00007ff6`36880000 00007ff6`36bda000 GetAndRunServices C:\App\getandrunservices.ap_10_09_10_8_5003_2510\GetAndRunServices.exe

而出问题的地址是00007ff6`37a14080,的确也在执行文件地址范围外。
但仔细看一下,00007ff6`37a14080这个地址和合法区间比较,只有一个bit不同:
00007ff6`3[7]a14080 00007ff6`3[6]a14080
这里7和6在二进制上面就差了末尾的bit。 若是我手动换一成6看看呢:

0:000> da 00007ff6`36a14080
00007ff6`36a14080 "ServerList=%s.."

果真就和源代码match了。

这个迷如何解释呢?首先可能的是这个执行文件有损害。可是如今执行文件默认都有完整性和签名保护,可能性不大。把文件拷贝出来和其它没有问题的文件比,的确也如出一辙。
还多是病毒?可是云上的宿主机器都是绝对隔离的。从live debug过程当中看,没见到用户态有什么注入。
剩下的缘由是硬件问题。内存或者CPU读取流水线赶上某二进制规律的时候触发数据损坏。

这就是我目前的推断。下周和有经验的工程师聊一下看看这样分析对不对。之前也赶上过疑似硬件问题致使的崩溃,但今天是第一次现场抓住!
若是你有相似经历或者经验,请指点和分享。

相关文章
相关标签/搜索