WCTF 2018 binja Editorial
rswc
Author: @Charo_IT
Overview
● A simple memo manager which uses original heap allocator
● You are dropped into an unprivileged shell
● Can you exploit the binary and gain your privilege?
About the original allocator
Initializing the heap
1. mmap(NULL, 0x1000, PROT_NONE, ...);
// map guard page
lower higher
libs
guard
Initializing the heap
2. arena =
mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, ...);
// map area for arena
lower higher
libs
guard
arena
Initializing the heap
3. arena->heap_base =
mmap(NULL, heap_size, PROT_READ | PROT_WRITE,
...); // map data area
lower higher
libs
guard
arena
heapdata
On malloc
1. Round up requested size to multiple of 0x10
2. Scan arena->chunks and find a chunk which satisfies
(chunk->size & 1) == 0 // chunk is not in use
&& aligned_requested_size <= arena->chunk[idx].size
3. If found, set LSB of arena->chunks[idx].size and return
arena->chunks[idx].ptr
4. If not found, create a new chunk at arena->top
5. Add new chunk to arena->chunks
6. Return the address of new chunk
On free
1. Find target chunk from arena->chunks
2. Clear LSB of arena->chunks[idx].size
Vulnerability
On malloc:
1. Round up requested size to multiple of 0x10
2. Scan arena->chunks and find a chunk which satisfies
(chunk->size & 1) == 0 // chunk is not in use
&& aligned_requested_size <= arena->chunk[idx].size
3. If found, set LSB of arena->chunks[idx].size and return
arena->chunks[idx].ptr
4. If not found, create a new chunk at arena->top
5. Add new chunk to arena->chunks
6. Return the address of new chunk
Vulnerability
allocating many chunks will make
arena->chunks overflow
Is this exploitable?
arena->chunks will overflow but we can't overwrite anything
because of guard page :(
lower higher
libs
guard
arena
heapdata
But wait...
The initialization process relies on the assumption that
mmap tries to allocate pages from higher to lower address.
Can we break it?
lower higher
libs
guard
arena
heapdata
1st2nd3rd
About mmap layout
About mmap layout
If some condition is met, use bottom-up
(from lower to higher address) layout
About mmap layout
If not, use top-down (from higher to
lower address) layout
About mmap layout
Let's confirm it
$ ./test
[mmap 1] 0x7fc03cd9b000
[mmap 2] 0x7fc03cd9a000
[mmap 3] 0x7fc03cd99000
[mmap 4] 0x7fc03cd98000
[mmap 5] 0x7fc03cd97000
$ ulimit -s unlimited; ./test
[mmap 1] 0x2b0b265a1000
[mmap 2] 0x2b0b265a2000
[mmap 3] 0x2b0b265a3000
[mmap 4] 0x2b0b265a4000
[mmap 5] 0x2b0b265a5000
higher to lower
lower to higher
Note: This behavior has been removed in Linux 4.13
(The challenge was running on Linux 4.4)
Is this challenge exploitable?
We can change mmap layout to bottom-up style since we can do
"ulimit -s unlimited".
So yes, it is exploitable!
lower higher
libs
guard
arena
heapdata
Solution
1. ulimit -s unlimited
2. Launch the binary
3. Allocate many chunks to make arena->chunks overflow
4. Break link list of memo
5. GOT leak & GOT overwrite (eg. atoi -> gets)
6. Hijack the control flow and read the flag file
Truth
Author: @Charo_IT
Overview
● .NET reversing challenge which looks very easy at a first
glance
Static analysis with dnSpy
Static analysis with dnSpy
Read and decrypt resource
Deconstructing resource
IV (0x10 bytes)
key (0x10 bytes)
encrypted data
(0xc40 bytes)
A (0x400 bytes)
B (0x400 bytes)
C (0x400 bytes)
d (0x20 bytes)
y (0x20 bytes)
AES-128-CBC
32 × 32
matrix
column
vector
Static analysis with dnSpy
Func3: x1
:= Ax0
Func4: x2
:= Bx1
Func5: x3
:= Cx2
+d
x0
:= input
is x3
== y ?
Pretty easy, eh?
According to static analysis, the input x should satisfy:
C B Ax + d = y
So, we should be able to get the flag by:
flag = A-1
B-1
C-1
(y - d)
Pretty easy, eh?
According to static analysis, the input x should satisfy:
C B Ax + d = y
So, we should be able to get the flag by:
flag = A-1
B-1
C-1
(y - d)
$ sage -python solver.py
Pretty easy, eh?
According to static analysis, the input x should satisfy:
C B Ax + d = y
So, we should be able to get the flag by:
flag = A-1
B-1
C-1
(y - d)
$ sage -python solver.py
flag: FAKEFLAGFAKEFLAGFAKEFLAGFAKEFLAG
$ challenge.exe
Enter your flag: FAKEFLAGFAKEFLAGFAKEFLAGFAKEFLAG
Wrong :(
The truth
About MethodDesc
In .NET, each method has a structure called "MethodDesc"
(Method Descriptor).
MethodDesc holds informations like:
● Lower bytes of MethodToken
● Has the method been already JITted?
● Is the method static?
● Method's entry point etc.
There are several types of MethodDesc, but this time we will only
focus on the basic one which is used for regular IL methods.
About MethodDesc
0:003> !DumpMT -md 00007fff180e5b00
(snip)
MethodDesc Table
Entry MethodDesc JIT Name
00007fff181f0090 00007fff180e5a98 NONE WCTF2018Rev.Lib.Verify(System.String)
00007fff181f0098 00007fff180e5aa8 NONE WCTF2018Rev.Lib.Func(Int32)
00007fff181f00a0 00007fff180e5ab8 NONE WCTF2018Rev.Lib.Func2()
00007fff181f00a8 00007fff180e5ac8 NONE WCTF2018Rev.Lib.Func3(Byte[], Byte[])
00007fff181f00b0 00007fff180e5ad8 NONE WCTF2018Rev.Lib.Func4(Byte[], Byte[])
00007fff181f00b8 00007fff180e5ae8 NONE WCTF2018Rev.Lib.Func5(Byte[], Byte[])
0:003> dq 00007fff180e5a98 l 6
00007fff`180e5a98 00280005`20000003 00007fff`181f0090 <- MethodDesc for Verify
00007fff`180e5aa8 00280006`20020004 00007fff`181f0098 <- MethodDesc for Func
00007fff`180e5ab8 00280007`20040005 00007fff`181f00a0 <- MethodDesc for Func2
Entry pointMethodTokens etc.
Precode to JITted code
PrecodeForFunc1:
call PrecodeFixupThunk
pop rsi ; dummy instruction
db m_MethodDescChunkIndex_Func1
db m_PrecodeChunkIndex_Func1
PrecodeForFunc2:
call PrecodeFixupThunk
pop rsi ; dummy instruction
db m_MethodDescChunkIndex_Func2
db m_PrecodeChunkIndex_Func2
dq MethodDescBase ; pointer to the first element of
MethodDesc array
Precode to JITted code
PrecodeForFunc1:
=> call PrecodeFixupThunk
pop rsi ; dummy instruction
db m_MethodDescChunkIndex_Func1
db m_PrecodeChunkIndex_Func1
dq MethodDescBase
PrecodeFixupThunk:
pop rax
movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex
movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex
mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase
lea r10, [rax+r11*8] ; r10=&MethodDesc[r11]
jmp ThePreStub
Precode to JITted code
PrecodeForFunc1:
call PrecodeFixupThunk
pop rsi ; dummy instruction <= rax
db m_MethodDescChunkIndex_Func1
db m_PrecodeChunkIndex_Func1
dq MethodDescBase
PrecodeFixupThunk:
=> pop rax
movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex
movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex
mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase
lea r10, [rax+r11*8] ; r10=&MethodDesc[r11]
jmp ThePreStub
Precode to JITted code
PrecodeForFunc1:
call PrecodeFixupThunk
pop rsi ; dummy instruction <= rax
db m_MethodDescChunkIndex_Func1
db m_PrecodeChunkIndex_Func1
dq MethodDescBase
PrecodeFixupThunk:
pop rax
=> movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex
movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex
mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase
lea r10, [rax+r11*8] ; r10=&MethodDesc[r11]
jmp ThePreStub
Precode to JITted code
PrecodeForFunc1:
call PrecodeFixupThunk
pop rsi ; dummy instruction
db m_MethodDescChunkIndex_Func1
db m_PrecodeChunkIndex_Func1
dq MethodDescBase
PrecodeFixupThunk:
pop rax
movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex
movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex
=> mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase
lea r10, [rax+r11*8] ; r10=&MethodDesc[r11]
jmp ThePreStub
Precode to JITted code
PrecodeForFunc1:
call PrecodeFixupThunk
pop rsi ; dummy instruction
db m_MethodDescChunkIndex_Func1
db m_PrecodeChunkIndex_Func1
dq MethodDescBase
PrecodeFixupThunk:
pop rax
movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex
movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex
mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase
=> lea r10, [rax+r11*8] ; r10=&MethodDesc[r11]
jmp ThePreStub
Precode to JITted code
ThePreStub:
; save registers to stack
; (snip)
; call PreStubWorker
lea rcx, [rsp+0x68]
mov rdx, r10 ; MethodDesc
call PreStubWorker ; do JIT compilation and update MethodDesc
; restore registers
; (snip)
jmp rax ; jump to compiled code
JITted Func2
Precodes
What Resources.cctor() does
1. Get the entry point of Func1 (which is not JITted yet) by using
MSIL ldftn instruction
2. Simulate PrecodeFixupThunk and calculate the address of
MethodDesc array
3. Overwrite the beginning of JITted Func2
4. Modify entry points for Func3, 4, and 5
Func3 entry point
Func4 entry point
Func5 entry point
Func2 entry point
MethodDesc array
What Resources.cctor() does
1. Get the entry point of Func1 (which is not JITted yet) by using
MSIL ldftn instruction
2. Simulate PrecodeFixupThunk and calculate the address of
MethodDesc array
3. Overwrite the beginning of JITted Func2
4. Modify entry points for Func3, 4, and 5
Precodes
JITted Func2
loader
Func3 entry point
Func4 entry point
Func5 entry point
Func2 entry point
MethodDesc array
JITted Func2
The real behavior of Func3, 4, and 5
● Func3
○ Extract the real code of Func4 and Func5 from resource
○ X1
= AX0
● Func4: X2
= Bt
5
X1
^ [0x5a, 0x5a, ..., 0x5a]
● Func5: 10.times{ X3
= C (X2
^ [B1,1
, B1,2
, ..., B1,32
]) }
real Func5
real Func4
Precodes
real Func3
Func3 entry point
Func4 entry point
Func5 entry point
Func2 entry point
MethodDesc array
Fin.

More Related Content

PPTX
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
PDF
Dafunctor
DOC
C - aptitude3
PDF
Create your own PHP extension, step by step - phpDay 2012 Verona
PDF
Ruby : Block, Proc and, lambda
PDF
Writing good std::future&lt;c++>
PDF
Multithreading done right
PDF
TLPI - 6 Process
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Dafunctor
C - aptitude3
Create your own PHP extension, step by step - phpDay 2012 Verona
Ruby : Block, Proc and, lambda
Writing good std::future&lt;c++>
Multithreading done right
TLPI - 6 Process

What's hot (19)

PPTX
Exploit exercises.com stack-overflows
PDF
LLVM Register Allocation
PDF
LLVM Register Allocation (2nd Version)
PPTX
Getting started cpp full
PPT
Introduction to Data Oriented Design
PPTX
Basic C++ 11/14 for Python Programmers
PPTX
A Step Towards Data Orientation
PDF
The Ring programming language version 1.7 book - Part 83 of 196
PPTX
Дмитрий Нестерук, Паттерны проектирования в XXI веке
PPT
OpenMP
PDF
Machine Trace Metrics
PDF
Debug Line Issues After Relaxation.
PDF
Python Programming: Data Structure
PDF
Debugger Principle Overview & GDB Tricks
ODP
OpenGurukul : Language : PHP
PPT
JavaScript Functions
PDF
PDF
DWARF Data Representation
PDF
The Ring programming language version 1.5.2 book - Part 78 of 181
Exploit exercises.com stack-overflows
LLVM Register Allocation
LLVM Register Allocation (2nd Version)
Getting started cpp full
Introduction to Data Oriented Design
Basic C++ 11/14 for Python Programmers
A Step Towards Data Orientation
The Ring programming language version 1.7 book - Part 83 of 196
Дмитрий Нестерук, Паттерны проектирования в XXI веке
OpenMP
Machine Trace Metrics
Debug Line Issues After Relaxation.
Python Programming: Data Structure
Debugger Principle Overview & GDB Tricks
OpenGurukul : Language : PHP
JavaScript Functions
DWARF Data Representation
The Ring programming language version 1.5.2 book - Part 78 of 181
Ad

Similar to WCTF 2018 binja Editorial (20)

PDF
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
PDF
A compact bytecode format for JavaScriptCore
PDF
Write an MPI program that implements a shell-sort like parallel algo.pdf
PDF
r2con 2017 r2cLEMENCy
PPT
Happy To Use SIMD
PDF
Windbg랑 친해지기
PPTX
MySQLinsanity
PDF
Please convert the following C code to assembly Y86int i,j; ......pdf
PPTX
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
PDF
Please convert the following C code to assembly Y86int j,k; .....pdf
PDF
Pragmatic Optimization in Modern Programming - Demystifying the Compiler
PDF
NYU hacknight, april 6, 2016
PDF
Scale17x buffer overflows
PDF
Tiling matrix-matrix multiply, code tuning
TXT
Exploit techniques - a quick review
PPT
Swug July 2010 - windows debugging by sainath
PDF
A taste of GlobalISel
PDF
Qemu JIT Code Generator and System Emulation
PDF
Accelerated .NET Memory Dump Analysis training public slides
PDF
Heap overflows for humans – 101
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
A compact bytecode format for JavaScriptCore
Write an MPI program that implements a shell-sort like parallel algo.pdf
r2con 2017 r2cLEMENCy
Happy To Use SIMD
Windbg랑 친해지기
MySQLinsanity
Please convert the following C code to assembly Y86int i,j; ......pdf
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
Please convert the following C code to assembly Y86int j,k; .....pdf
Pragmatic Optimization in Modern Programming - Demystifying the Compiler
NYU hacknight, april 6, 2016
Scale17x buffer overflows
Tiling matrix-matrix multiply, code tuning
Exploit techniques - a quick review
Swug July 2010 - windows debugging by sainath
A taste of GlobalISel
Qemu JIT Code Generator and System Emulation
Accelerated .NET Memory Dump Analysis training public slides
Heap overflows for humans – 101
Ad

Recently uploaded (20)

PDF
August 2025 - Top 10 Read Articles in Network Security & Its Applications
PDF
UNIT no 1 INTRODUCTION TO DBMS NOTES.pdf
PPTX
Feature types and data preprocessing steps
PDF
Soil Improvement Techniques Note - Rabbi
PPTX
Software Engineering and software moduleing
PDF
Level 2 – IBM Data and AI Fundamentals (1)_v1.1.PDF
PDF
Accra-Kumasi Expressway - Prefeasibility Report Volume 1 of 7.11.2018.pdf
PPTX
tack Data Structure with Array and Linked List Implementation, Push and Pop O...
PPTX
"Array and Linked List in Data Structures with Types, Operations, Implementat...
PDF
III.4.1.2_The_Space_Environment.p pdffdf
PDF
737-MAX_SRG.pdf student reference guides
PPTX
Amdahl’s law is explained in the above power point presentations
PPT
INTRODUCTION -Data Warehousing and Mining-M.Tech- VTU.ppt
PDF
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
PDF
ChapteR012372321DFGDSFGDFGDFSGDFGDFGDFGSDFGDFGFD
PDF
Improvement effect of pyrolyzed agro-food biochar on the properties of.pdf
PDF
Abrasive, erosive and cavitation wear.pdf
PPTX
CyberSecurity Mobile and Wireless Devices
PPTX
Management Information system : MIS-e-Business Systems.pptx
PPTX
Fundamentals of safety and accident prevention -final (1).pptx
August 2025 - Top 10 Read Articles in Network Security & Its Applications
UNIT no 1 INTRODUCTION TO DBMS NOTES.pdf
Feature types and data preprocessing steps
Soil Improvement Techniques Note - Rabbi
Software Engineering and software moduleing
Level 2 – IBM Data and AI Fundamentals (1)_v1.1.PDF
Accra-Kumasi Expressway - Prefeasibility Report Volume 1 of 7.11.2018.pdf
tack Data Structure with Array and Linked List Implementation, Push and Pop O...
"Array and Linked List in Data Structures with Types, Operations, Implementat...
III.4.1.2_The_Space_Environment.p pdffdf
737-MAX_SRG.pdf student reference guides
Amdahl’s law is explained in the above power point presentations
INTRODUCTION -Data Warehousing and Mining-M.Tech- VTU.ppt
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
ChapteR012372321DFGDSFGDFGDFSGDFGDFGDFGSDFGDFGFD
Improvement effect of pyrolyzed agro-food biochar on the properties of.pdf
Abrasive, erosive and cavitation wear.pdf
CyberSecurity Mobile and Wireless Devices
Management Information system : MIS-e-Business Systems.pptx
Fundamentals of safety and accident prevention -final (1).pptx

WCTF 2018 binja Editorial

  • 1. WCTF 2018 binja Editorial
  • 3. Overview ● A simple memo manager which uses original heap allocator ● You are dropped into an unprivileged shell ● Can you exploit the binary and gain your privilege?
  • 4. About the original allocator
  • 5. Initializing the heap 1. mmap(NULL, 0x1000, PROT_NONE, ...); // map guard page lower higher libs guard
  • 6. Initializing the heap 2. arena = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, ...); // map area for arena lower higher libs guard arena
  • 7. Initializing the heap 3. arena->heap_base = mmap(NULL, heap_size, PROT_READ | PROT_WRITE, ...); // map data area lower higher libs guard arena heapdata
  • 8. On malloc 1. Round up requested size to multiple of 0x10 2. Scan arena->chunks and find a chunk which satisfies (chunk->size & 1) == 0 // chunk is not in use && aligned_requested_size <= arena->chunk[idx].size 3. If found, set LSB of arena->chunks[idx].size and return arena->chunks[idx].ptr 4. If not found, create a new chunk at arena->top 5. Add new chunk to arena->chunks 6. Return the address of new chunk
  • 9. On free 1. Find target chunk from arena->chunks 2. Clear LSB of arena->chunks[idx].size
  • 10. Vulnerability On malloc: 1. Round up requested size to multiple of 0x10 2. Scan arena->chunks and find a chunk which satisfies (chunk->size & 1) == 0 // chunk is not in use && aligned_requested_size <= arena->chunk[idx].size 3. If found, set LSB of arena->chunks[idx].size and return arena->chunks[idx].ptr 4. If not found, create a new chunk at arena->top 5. Add new chunk to arena->chunks 6. Return the address of new chunk
  • 11. Vulnerability allocating many chunks will make arena->chunks overflow
  • 12. Is this exploitable? arena->chunks will overflow but we can't overwrite anything because of guard page :( lower higher libs guard arena heapdata
  • 13. But wait... The initialization process relies on the assumption that mmap tries to allocate pages from higher to lower address. Can we break it? lower higher libs guard arena heapdata 1st2nd3rd
  • 15. About mmap layout If some condition is met, use bottom-up (from lower to higher address) layout
  • 16. About mmap layout If not, use top-down (from higher to lower address) layout
  • 18. Let's confirm it $ ./test [mmap 1] 0x7fc03cd9b000 [mmap 2] 0x7fc03cd9a000 [mmap 3] 0x7fc03cd99000 [mmap 4] 0x7fc03cd98000 [mmap 5] 0x7fc03cd97000 $ ulimit -s unlimited; ./test [mmap 1] 0x2b0b265a1000 [mmap 2] 0x2b0b265a2000 [mmap 3] 0x2b0b265a3000 [mmap 4] 0x2b0b265a4000 [mmap 5] 0x2b0b265a5000 higher to lower lower to higher Note: This behavior has been removed in Linux 4.13 (The challenge was running on Linux 4.4)
  • 19. Is this challenge exploitable? We can change mmap layout to bottom-up style since we can do "ulimit -s unlimited". So yes, it is exploitable! lower higher libs guard arena heapdata
  • 20. Solution 1. ulimit -s unlimited 2. Launch the binary 3. Allocate many chunks to make arena->chunks overflow 4. Break link list of memo 5. GOT leak & GOT overwrite (eg. atoi -> gets) 6. Hijack the control flow and read the flag file
  • 22. Overview ● .NET reversing challenge which looks very easy at a first glance
  • 24. Static analysis with dnSpy Read and decrypt resource
  • 25. Deconstructing resource IV (0x10 bytes) key (0x10 bytes) encrypted data (0xc40 bytes) A (0x400 bytes) B (0x400 bytes) C (0x400 bytes) d (0x20 bytes) y (0x20 bytes) AES-128-CBC 32 × 32 matrix column vector
  • 26. Static analysis with dnSpy Func3: x1 := Ax0 Func4: x2 := Bx1 Func5: x3 := Cx2 +d x0 := input is x3 == y ?
  • 27. Pretty easy, eh? According to static analysis, the input x should satisfy: C B Ax + d = y So, we should be able to get the flag by: flag = A-1 B-1 C-1 (y - d)
  • 28. Pretty easy, eh? According to static analysis, the input x should satisfy: C B Ax + d = y So, we should be able to get the flag by: flag = A-1 B-1 C-1 (y - d) $ sage -python solver.py
  • 29. Pretty easy, eh? According to static analysis, the input x should satisfy: C B Ax + d = y So, we should be able to get the flag by: flag = A-1 B-1 C-1 (y - d) $ sage -python solver.py flag: FAKEFLAGFAKEFLAGFAKEFLAGFAKEFLAG $ challenge.exe Enter your flag: FAKEFLAGFAKEFLAGFAKEFLAGFAKEFLAG Wrong :(
  • 31. About MethodDesc In .NET, each method has a structure called "MethodDesc" (Method Descriptor). MethodDesc holds informations like: ● Lower bytes of MethodToken ● Has the method been already JITted? ● Is the method static? ● Method's entry point etc. There are several types of MethodDesc, but this time we will only focus on the basic one which is used for regular IL methods.
  • 32. About MethodDesc 0:003> !DumpMT -md 00007fff180e5b00 (snip) MethodDesc Table Entry MethodDesc JIT Name 00007fff181f0090 00007fff180e5a98 NONE WCTF2018Rev.Lib.Verify(System.String) 00007fff181f0098 00007fff180e5aa8 NONE WCTF2018Rev.Lib.Func(Int32) 00007fff181f00a0 00007fff180e5ab8 NONE WCTF2018Rev.Lib.Func2() 00007fff181f00a8 00007fff180e5ac8 NONE WCTF2018Rev.Lib.Func3(Byte[], Byte[]) 00007fff181f00b0 00007fff180e5ad8 NONE WCTF2018Rev.Lib.Func4(Byte[], Byte[]) 00007fff181f00b8 00007fff180e5ae8 NONE WCTF2018Rev.Lib.Func5(Byte[], Byte[]) 0:003> dq 00007fff180e5a98 l 6 00007fff`180e5a98 00280005`20000003 00007fff`181f0090 <- MethodDesc for Verify 00007fff`180e5aa8 00280006`20020004 00007fff`181f0098 <- MethodDesc for Func 00007fff`180e5ab8 00280007`20040005 00007fff`181f00a0 <- MethodDesc for Func2 Entry pointMethodTokens etc.
  • 33. Precode to JITted code PrecodeForFunc1: call PrecodeFixupThunk pop rsi ; dummy instruction db m_MethodDescChunkIndex_Func1 db m_PrecodeChunkIndex_Func1 PrecodeForFunc2: call PrecodeFixupThunk pop rsi ; dummy instruction db m_MethodDescChunkIndex_Func2 db m_PrecodeChunkIndex_Func2 dq MethodDescBase ; pointer to the first element of MethodDesc array
  • 34. Precode to JITted code PrecodeForFunc1: => call PrecodeFixupThunk pop rsi ; dummy instruction db m_MethodDescChunkIndex_Func1 db m_PrecodeChunkIndex_Func1 dq MethodDescBase PrecodeFixupThunk: pop rax movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase lea r10, [rax+r11*8] ; r10=&MethodDesc[r11] jmp ThePreStub
  • 35. Precode to JITted code PrecodeForFunc1: call PrecodeFixupThunk pop rsi ; dummy instruction <= rax db m_MethodDescChunkIndex_Func1 db m_PrecodeChunkIndex_Func1 dq MethodDescBase PrecodeFixupThunk: => pop rax movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase lea r10, [rax+r11*8] ; r10=&MethodDesc[r11] jmp ThePreStub
  • 36. Precode to JITted code PrecodeForFunc1: call PrecodeFixupThunk pop rsi ; dummy instruction <= rax db m_MethodDescChunkIndex_Func1 db m_PrecodeChunkIndex_Func1 dq MethodDescBase PrecodeFixupThunk: pop rax => movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase lea r10, [rax+r11*8] ; r10=&MethodDesc[r11] jmp ThePreStub
  • 37. Precode to JITted code PrecodeForFunc1: call PrecodeFixupThunk pop rsi ; dummy instruction db m_MethodDescChunkIndex_Func1 db m_PrecodeChunkIndex_Func1 dq MethodDescBase PrecodeFixupThunk: pop rax movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex => mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase lea r10, [rax+r11*8] ; r10=&MethodDesc[r11] jmp ThePreStub
  • 38. Precode to JITted code PrecodeForFunc1: call PrecodeFixupThunk pop rsi ; dummy instruction db m_MethodDescChunkIndex_Func1 db m_PrecodeChunkIndex_Func1 dq MethodDescBase PrecodeFixupThunk: pop rax movzx r10, byte ptr [rax+2] ; m_PrecodeChunkIndex movzx r11, byte ptr [rax+1] ; m_MethodDescChunkIndex mov rax, qword ptr [rax+r10*8+3] ; MethodDescBase => lea r10, [rax+r11*8] ; r10=&MethodDesc[r11] jmp ThePreStub
  • 39. Precode to JITted code ThePreStub: ; save registers to stack ; (snip) ; call PreStubWorker lea rcx, [rsp+0x68] mov rdx, r10 ; MethodDesc call PreStubWorker ; do JIT compilation and update MethodDesc ; restore registers ; (snip) jmp rax ; jump to compiled code
  • 40. JITted Func2 Precodes What Resources.cctor() does 1. Get the entry point of Func1 (which is not JITted yet) by using MSIL ldftn instruction 2. Simulate PrecodeFixupThunk and calculate the address of MethodDesc array 3. Overwrite the beginning of JITted Func2 4. Modify entry points for Func3, 4, and 5 Func3 entry point Func4 entry point Func5 entry point Func2 entry point MethodDesc array
  • 41. What Resources.cctor() does 1. Get the entry point of Func1 (which is not JITted yet) by using MSIL ldftn instruction 2. Simulate PrecodeFixupThunk and calculate the address of MethodDesc array 3. Overwrite the beginning of JITted Func2 4. Modify entry points for Func3, 4, and 5 Precodes JITted Func2 loader Func3 entry point Func4 entry point Func5 entry point Func2 entry point MethodDesc array
  • 42. JITted Func2 The real behavior of Func3, 4, and 5 ● Func3 ○ Extract the real code of Func4 and Func5 from resource ○ X1 = AX0 ● Func4: X2 = Bt 5 X1 ^ [0x5a, 0x5a, ..., 0x5a] ● Func5: 10.times{ X3 = C (X2 ^ [B1,1 , B1,2 , ..., B1,32 ]) } real Func5 real Func4 Precodes real Func3 Func3 entry point Func4 entry point Func5 entry point Func2 entry point MethodDesc array
  • 43. Fin.