SlideShare a Scribd company logo
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
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
PDF
Heap overflows for humans – 101
PDF
Marat-Slides
PDF
My old security advisories on HMI/SCADA and industrial software released betw...
PPTX
Advanced Windows Debugging
PPT
Writing Metasploit Plugins
PDF
Smash the Stack: Writing a Buffer Overflow Exploit (Win32)
PDF
CNIT 127 14: Protection Mechanisms
PPTX
44CON London 2015 - How to drive a malware analyst crazy
PPTX
How to drive a malware analyst crazy
PDF
printf tricks
PPTX
Exploring billion states of a program like a pro. How to cook your own fast a...
PPTX
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
PDF
The walking 0xDEAD
PDF
Protostar VM - Heap3
PDF
CNIT 127 14: Protection Mechanisms
PPT
Reverse engineering20151112
PPTX
Guardians of your CODE
ODP
Debugging With Id
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
Heap overflows for humans – 101
Marat-Slides
My old security advisories on HMI/SCADA and industrial software released betw...
Advanced Windows Debugging
Writing Metasploit Plugins
Smash the Stack: Writing a Buffer Overflow Exploit (Win32)
CNIT 127 14: Protection Mechanisms
44CON London 2015 - How to drive a malware analyst crazy
How to drive a malware analyst crazy
printf tricks
Exploring billion states of a program like a pro. How to cook your own fast a...
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
The walking 0xDEAD
Protostar VM - Heap3
CNIT 127 14: Protection Mechanisms
Reverse engineering20151112
Guardians of your CODE
Debugging With Id
Ad

Recently uploaded (20)

PDF
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
PDF
Well-logging-methods_new................
PDF
Categorization of Factors Affecting Classification Algorithms Selection
PPTX
Internet of Things (IOT) - A guide to understanding
PPTX
CYBER-CRIMES AND SECURITY A guide to understanding
PPTX
Fundamentals of Mechanical Engineering.pptx
PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PPTX
Fundamentals of safety and accident prevention -final (1).pptx
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PPTX
Current and future trends in Computer Vision.pptx
PDF
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
PDF
PPT on Performance Review to get promotions
PPTX
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PDF
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
PPTX
Geodesy 1.pptx...............................................
PDF
737-MAX_SRG.pdf student reference guides
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PPTX
UNIT 4 Total Quality Management .pptx
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
Well-logging-methods_new................
Categorization of Factors Affecting Classification Algorithms Selection
Internet of Things (IOT) - A guide to understanding
CYBER-CRIMES AND SECURITY A guide to understanding
Fundamentals of Mechanical Engineering.pptx
Embodied AI: Ushering in the Next Era of Intelligent Systems
Fundamentals of safety and accident prevention -final (1).pptx
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
Automation-in-Manufacturing-Chapter-Introduction.pdf
Current and future trends in Computer Vision.pptx
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
PPT on Performance Review to get promotions
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
Geodesy 1.pptx...............................................
737-MAX_SRG.pdf student reference guides
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
UNIT 4 Total Quality Management .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.