Skip to content

Commit

Permalink
added range check to readBlobHeapUncached
Browse files Browse the repository at this point in the history
Obfuscated assemblies can have a bogus extra reference to mscorlib which
has incorrect index in Blob heap for HashValue - index value was out
of range of the heap.I guess the assumption was that compiler will not
try to realize the whole set of information for this AssemblyRef entry
but decompiler will try to do. The problem was that F# compiler is
eagerly trying to populate information about referenced assemblies for the
given assembly so it crashes during the attempt to read this malformed entry.

fixes #517
closes #519

commit 326a7fc
Author: Vladimir Matveev <[email protected]>
Date:   Wed Jul 1 00:27:11 2015 -0700

    added tests

commit 1d8dd07
Author: Vladimir Matveev <[email protected]>
Date:   Mon Jun 29 00:14:27 2015 -0700

    fix incorrect condition

commit 0c0c696
Author: Vladimir Matveev <[email protected]>
Date:   Sun Jun 28 23:30:38 2015 -0700

    added range check to readBlobHeapUncached
  • Loading branch information
vladima authored and latkin committed Aug 7, 2015
1 parent 49bdfb0 commit e980c65
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/absil/ilread.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,7 @@ type ILReaderContext =
userStringsStreamPhysicalLoc: int32;
stringsStreamPhysicalLoc: int32;
blobsStreamPhysicalLoc: int32;
blobsStreamSize: int32;
readUserStringHeap: (int32 -> string);
memoizeString: string -> string;
readStringHeap: (int32 -> string);
Expand Down Expand Up @@ -1534,9 +1535,13 @@ let readStringHeapUncached ctxtH idx =
let readStringHeap ctxt idx = ctxt.readStringHeap idx
let readStringHeapOption ctxt idx = if idx = 0 then None else Some (readStringHeap ctxt idx)

let emptyByteArray: byte[] = [||]
let readBlobHeapUncached ctxtH idx =
let ctxt = getHole ctxtH
seekReadBlob ctxt.is (ctxt.blobsStreamPhysicalLoc + idx)
// valid index lies in range [1..streamSize)
// NOTE: idx cannot be 0 - Blob\String heap has first empty element that is one byte 0
if idx <= 0 || idx >= ctxt.blobsStreamSize then emptyByteArray
else seekReadBlob ctxt.is (ctxt.blobsStreamPhysicalLoc + idx)
let readBlobHeap ctxt idx = ctxt.readBlobHeap idx
let readBlobHeapOption ctxt idx = if idx = 0 then None else Some (readBlobHeap ctxt idx)

Expand Down Expand Up @@ -3973,6 +3978,7 @@ let rec genOpenBinaryReader infile is opts =
userStringsStreamPhysicalLoc = userStringsStreamPhysicalLoc;
stringsStreamPhysicalLoc = stringsStreamPhysicalLoc;
blobsStreamPhysicalLoc = blobsStreamPhysicalLoc;
blobsStreamSize = blobsStreamSize;
memoizeString = Tables.memoize id;
readUserStringHeap = cacheUserStringHeap (readUserStringHeapUncached ctxtH);
readStringHeap = cacheStringHeap (readStringHeapUncached ctxtH);
Expand Down
Binary file added tests/fsharp/core/ilread/Library.dll
Binary file not shown.
35 changes: 35 additions & 0 deletions tests/fsharp/core/ilread/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@if "%_echo%"=="" echo off

setlocal
REM Configure the sample, i.e. where to find the F# compiler and C# compiler.
if EXIST build.ok DEL /f /q build.ok

call %~d0%~p0..\..\..\config.bat
@if ERRORLEVEL 1 goto Error

if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" (
REM Skipping test for FSI.EXE
goto Skip
)

"%FSC%" %fsc_flags% /r:Library.dll /out:test.exe test.fs
@if ERRORLEVEL 1 goto Error

"%PEVERIFY%" test.exe
@if ERRORLEVEL 1 goto Error

:Ok
echo Built fsharp %~f0 ok.
echo. > build.ok
endlocal
exit /b 0

:Skip
echo Skipped %~f0
endlocal
exit /b 0


:Error
endlocal
exit /b %ERRORLEVEL%
22 changes: 22 additions & 0 deletions tests/fsharp/core/ilread/run.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@if "%_echo%"=="" echo off

setlocal
dir build.ok > NUL ) || (
@echo 'build.ok' not found.
goto :ERROR
)

call %~d0%~p0..\..\..\config.bat

%CLIX% .\test.exe
if ERRORLEVEL 1 goto Error

:Ok
echo Ran fsharp %~f0 ok.
endlocal
exit /b 0

:Error
endlocal
exit /b %ERRORLEVEL%

8 changes: 8 additions & 0 deletions tests/fsharp/core/ilread/test.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
open Library

[<EntryPoint>]
let main _ =
let cls = Class1()
let len = cls.GetLength("123")
printfn "%O" len
if len = 3 then 0 else 1
1 change: 1 addition & 0 deletions tests/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Core03 fsharp\core\innerpoly
Core03,Smoke fsharp\core\int32
Core03 fsharp\core\internalsvisible
Core03 fsharp\core\interop
Core03 fsharp\core\ilread
Core03 fsharp\core\lazy
Core03 fsharp\core\letrec
Core03,Smoke fsharp\core\libtest
Expand Down

0 comments on commit e980c65

Please sign in to comment.