2009-11-11 2 views
12

Java VM을 대상으로 유사한 질문이 있지만 .net에 대한 질문을 찾지 못했습니다. (뭔가를 놓친 경우 닫고 중복으로 표시하십시오.).순수 NET에서 .NET 공용 언어 런타임 (CLR)을 충돌시키는 방법

그래서 관리가 불편한 interop없이 가능합니까? 그리고 충돌과 함께 나는 "xxx.exe가 작동을 멈췄다"는 것을 의미하지 않는다. StackOverflow 나 OutOfMemoryException이 아니다.

VM 자체에 버그가있는 경우를 제외하고는 불가능하다고 생각합니다.

+2

닷넷 CLR의 요점은 그런 일 경우 – Earlz

+1

CLR은 내부 스택 오버 플로우 및 기타 버그를 유지하고 (심지어 버그가 OS로) 실제 컴퓨터를 충돌하지, 컴퓨터에서 멀리 추상적이다 가능하다면, 정의 상 "VM 자체의 버그"범주에 해당하지 않습니까? –

+0

네 .. CLR 런타임 내부에서 중요한 파일 등을 지우지 않는다면 – Earlz

답변

15

음 ... "pure .NET"을 어떻게 정의 하시겠습니까? 본인은 "JVM을 충돌하는 방법"게시물을 읽을 때 CLR2/대표/GCHandle/배열을 연주하고,이 같은 내놓았다 :

단지 CLR2 32 비트 Windows XP에서 작동하도록 알려져
using System; 
using System.Reflection; 
using System.Runtime.InteropServices; 

namespace TestCLR2Crash { 
     static void Main(string[ ] args) { 
      // declare a delegate that refers to a static method, 
      // in this case it's a static method generated from the 
      // anonymous delegate. 
      Action action = delegate() { }; 

      // "generate" code into an array of uint 
      var fakeDelegate = new uint[ ] { 
       // dummy values 
       0x00000000, 0x00000000, 
       // fake _methodPtrAux 
       0x00000000, 
       // native code/string 
       0x6AEC8B55, 0x2FD9B8F5, 0xD0FF7C81, 0x006A006A, 
       0x00E81F6A, 0x83000000, 0x50102404, 0x81CC5DBA, 
       0x8BD2FF7C, 0x47C35DE5, 0x74656572, 0x73676E69, 
       0x6F726620, 0x6567206D, 0x6172656E, 0x20646574, 
       0x65646F63, 0x00000A21 
      }; 

      // fill in the fake _methodPtrAux, 
      // make it point to the code region in fakeDelegate 
      var handle = GCHandle.Alloc(fakeDelegate, GCHandleType.Pinned); 
      var addr = handle.AddrOfPinnedObject(); 
      const int sizeOfUInt32 = sizeof(uint); // 4 
      const int indexOfCode = 3; 
      fakeDelegate[ 2 ] = Convert.ToUInt32(addr.ToInt32() + sizeOfUInt32 * indexOfCode); 

      var targetInfo = typeof(Action) 
       .GetField("_target", BindingFlags.NonPublic | BindingFlags.Instance); 
      targetInfo.SetValue(action, fakeDelegate); 
      action();  // Greetings from generated code! 
      Console.WriteLine("Greetings from managed code!"); 

      handle.Free(); 
     } 
    } 
} 

x86에서; 또한 DEP + ASLR이 기본적으로 켜져있는 Vista 및 Windows 7 등에서는 작동하지 않는 것으로 알려져 있습니다.

위의 코드에 대한 재미있는 점은 GCHandle.Alloc (..., GCHandleType.Pinned)이 보안 권한을 요구하지만 안전하지 않은 코드를 명시 적으로 사용하지 않았지만 배열을 가짜로 관리한다는 것입니다. 인스턴스를 위임하고 배열 내의 x86 컴퓨터 코드로 호출합니다. 임베디드 x86 코드를 "외국어"로 계산하지 않으면 코드 자체는 순수한 C#입니다. 기본적으로 정적 메서드에 대한 CLR2의 대리자의 내부 구현을 사용하며 대리인의 일부 비공개 멤버가 실제로는 내부 포인터. 나는 x86 코드를 관리 힙에 할당 된 배열에 채웠다. 따라서 DEP를 작동시키지 않아야하며 그렇지 않으면 해당 메모리 페이지에 대한 실행 권한을 얻으려면 다른 방법을 찾아야합니다.

는 x86 코드는 다음과 같다 : (의사 MASM 구문)

55    push ebp 
8BEC   mov ebp,esp 
6A F5   push -0B       ; /DevType = STD_OUTPUT_HANDLE 
B8 D92F817C  mov eax,KERNEL32.GetStdHandle ; | 
FFD0   call eax       ; \GetStdHandle 
6A 00   push 0       ; /pReserved = NULL 
6A 00   push 0       ; |pWritten = NULL 
6A 1F   push 1F       ; |CharsToWrite = 1F (31.) 
E8 00000000  call <&next_instruction>   ; | 
830424 10  add dword ptr ss:[esp],10  ; |Buffer 
50    push eax       ; |hConsole 
BA 5DCC817C  mov edx,KERNEL32.WriteConsoleA ; | 
FFD2   call edx       ; \WriteConsoleA 
8BE5   mov esp,ebp 
5D    pop ebp 
C3    ret 

이 CLI가 지정한 행동하지 않고, 같은 모노와 같은 다른 CLI 구현에서 작동하지 않습니다. 유사한 로직을 Mono에서 실행하게하는 다른 방법이 있습니다. 이미 우분투 9.04/Mono 2.4에서이를 시도하고 작동했습니다.

나는 여기에 대한 블로그 포스트를 작성했습니다 : http://rednaxelafx.javaeye.com/blog/461787

그것은 중국어,하지만 내가 무슨 짓을했는지 설명해야이 코드가 많이있다. 같은 트릭을 사용하여 블로그 게시물의 끝에서 나는 SEHException을 얻는 것과 같은 일이 잘못되도록 위의 코드를 조정할 수있는 몇 가지 예제를 보여주었습니다.

+0

이것이 "순수한 .net"인지 아직 확실하지 않습니다. 정의가 흐려집니다. 그러나, 그것은 확실히 좋은 아이디어 +1입니다! –

-1

.NET을 사용하여 전체 PC를 손상시킬 수 있다는 것을 알고 있습니다. 그러나 그것은 무한 루프와 RealTime 프로세스 우선 순위를 필요로합니다 ...

+0

프로세스 우선 순위 - 좋은 아이디어. 하지만 프로세스 내부에서 프로세스 우선 순위를 변경할 수 있습니까? 아니면 우리보다 우선 순위가 높은 다른 프로세스를 트리거 할 수 있습니까? 글쎄 ... .... –

+0

그냥 시도해 보았습니다. 작업 프로세스는 ProcessPriorityClass를 사용하는 다른 프로세스에 의해 시작된 동안 무한 루프 및 인스턴스화입니다.실시간. Machine의 성능이 저하되었지만 충돌은 발생하지 않습니다. –

+0

Process.GetCurrentProcess(). ProcessPriority 또는 이와 유사한 것을 사용하여 설정할 수 있습니다. 그러나 나는 결과가 엇갈 렸습니다. 예를 들어 내 컴퓨터가 완전히 얼었다. 중요한지는 모르지만 항상 관리자로 로그인합니다. – Vivelin

2

Oren Eini는 'ExecutionEngineException'을 유발하는 .net 프레임 워크의 버그를 발견했습니다. 이는 기본적으로 런타임 오류입니다. 당신은 여기에 대해 읽을 수 있습니다

(마이크로 소프트 연결) :

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=384781

그리고 버그의 '폐쇄'상태에도 불구하고 - 아직 고정 아니에요.

+0

해결 방법을 발견했기 때문에 버그 보고서가 닫혔습니다. MS는 보고서를 닫았지만 아무도 다른 문제가 없었기 때문에 문제를 해결하지 못했습니다. –

+0

... 그가 제공 한 해결책을 보지 못한 채 문제 자체가 어둠 속에 머물러 있습니다. 그러나 이것은 또한 "CLR의 버그"로 분류 될 것입니다. –

2

나는 오늘 그 일을했습니다. 나는 더 큰 .net 프로젝트의 설정을 테스트하고 있었다. 일부 인터페이스가 포함 된 어셈블리가 누락되어 exe가 작동을 멈 춥니 다. 런타임에서 예외가 발견되지 않았습니다.

당신은 런타임에서 거기에 더 많은 버그를 확신 할 수 있습니다 - 단지 코드 라인의 수백만 계산 ...

1
내가 Java 프로그램이 존재하지 않는 클래스를로드하여 JVM을 충돌 본 적이

ClassNotFoundError을 무시한 다음 아무 일도 일어나지 않는 것처럼 계속 실행합니다. .NET 클래스를 동적으로로드 할 때 비슷한 것을 할 수 있습니다.

+0

.net에서 클래스를로드 할 수 없지만 어셈블리만으로는 상황이 조금 다릅니다. 우리가 어셈블리를로드하지 못하고 예외를 삼킨 경우, 우리가 시도 할 수있는 유일한 방법은 리플렉션으로 클래스 및/또는 메소드를 찾는 것입니다. 그러나 최악은 어셈블리 자체를로드 한 후 일부 변수가 null이 아닌 것으로 예상 될 때 리플렉션 자체 (예 : TypeLoadException) 또는 NullReferenceException과 관련된 것입니다. 요약하면 다음과 같습니다. 그리고 당신이 옳다면 특정 JVM은 아마도 이것에 버그가있을 것이다. –

+0

그것은 Sun JVM 이었지만 몇 년 전만해도 아마도 버전 2.x 였을 것입니다. –

-1

기술적으로 올바르지 만 유효한 .net 프로그램으로 실행되지 않는 일부 C# 코드가 있습니다. 그것은 빈 메소드를 오버로드하는 인터페이스로 할 일이 있지만 실제로 기억할 수는 없습니다.

0

이 코드를/clr : pure로 컴파일하고 링커 강제 순수 옵션을 사용할 수도 있습니다.

그러나 런타임 오류와 비슷한 것으로 충돌합니다.

(1388.5e4): Access violation - code c0000005 (!!! second chance !!!) eax=8d00fea5 ebx=00000000 ecx=00253e50 edx=00253e50 esi=022ad3cc edi=00253e50 eip=6ae965c5 esp=0020edbc ebp=0020edc8 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b
efl=00010246 * WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\eb4e1e70734f6efb9c7de7ec5f452c9e\mscorlib.ni.dll mscorlib_ni+0x9365c5: 6ae965c5 ff10
call dword ptr [eax]
ds:002b:8d00fea5=????????

당신은/CLR을 컴파일하더라도 : 순수/CLR : 안전 및 이미지 같은자가 그것을 표현, 그것은 단지 때문에이 버그 (컴파일러 버그)를 잡기 검증에 완전 신뢰에서 작동합니다. 런타임 검증이 JIT'er와 함께 작동하기 때문에,이 방법으로 호출하고 검증의에 대한 게으른 때까지

이 전체 PE 파일을 구문 분석 peverify의 출력에서입니다
namespace Settings 
{ 
    public ref class RefType 
    {  
    public: 
     unsigned int I; 
     String^ S;  
     unsigned long L; 
    }; 
    public ref class aUseTemplate 
    { 
    public: 
     void CallTemplate() 
     { 
      array<RefType^>^ refarr = gcnew array<RefType^>(20); 
      for(int i=0; i < 20; i++) 
      { 
       RefType^ rt = gcnew RefType(); 
       rt->I = 0x42424242; 
       rt->L = 0x33333333; 
       refarr[i] = rt; 
      } 

      HasTemplate(refarr); 
     } 
     template<typename T> void HasTemplate(T input) 
     { 
      for each(T% x in input) 
       Console::WriteLine(x); 
     } 
    }; 
} 

이 오류가 감지되지 . 여기 검증을 우회 할 수 있다면

[IL]: Error: [C:\Users\files\Documents\Visual Studio 2010\Projects\testCli\bin\Release\PureSettings.dll : Settings.aUseTemplate::HasTemplate^>][off set 0x00000017][found ref 'Settings.RefType'][expected address of ref ] Unexpected type on the stack. 1 Error(s) Verifying PureSettings.dll

이는 CLR에 큰 버그와 unprivilaged 과정에서 당신에게 코드 실행을 줄 것이다.

다음은 MSIL입니다.

IL_000d: bge.s  IL_0021 
    IL_000f: ldloc.1 
    IL_0010: ldloc.0 
    IL_0011: ldelem.ref 
    IL_0012: castclass Settings.RefType 
    IL_0017: stloc.2 
    IL_0018: ldloc.2 
    IL_0019: ldind.ref 
    IL_001a: call  void [mscorlib]System.Console::WriteLine(object) 
    IL_001f: br.s  IL_0006 
    IL_0021: ret 

버그가 오프셋 IL_19에 있습니다.

CAS 또는 다른 유형 안전 모드에서 실행중인 경우이 코드는 유명한 "코드가 런타임을 일시적으로 중단시킬 수 있습니다"예외를 생성합니다.

2

안전하지 않은 코드 또는 대리자를 사용할 필요없이 (CLR을 크래시 할 수있는 아주 좋은 방법이라고 인정해야하는 경우에도) 간단한 마샬 함수를 사용하여 .NET에 충돌이 발생할 수 있습니다.

using System; 
using System.Runtime.InteropServices; 

namespace Crash 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      IntPtr p = Marshal.AllocHGlobal(1); 
      for (int i = 0; i < 10000000; ++i) 
      { 
       p = new IntPtr(p.ToInt64() + 1); 
       Marshal.WriteByte(p, 0xFF); 
      } 
     } 
    } 
} 

또한 항상 GCHandle을 사용하면 메모리 액세스 위반과 같은 오류가 발생합니다.

using System; 
using System.Runtime.InteropServices; 

namespace Crash 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      GCHandle.FromIntPtr(new IntPtr(32323)); 
     } 
    } 
} 
+0

나는 짧고 달콤한 것을 좋아한다. 내 충돌 테스트에 사용 했어. – SilverSideDown

관련 문제