주소를 변경할 수있는 방법이 있습니까? OpCodes.Ret가 점프합니까? 일리노이 메서드는 C#에서 사용하는 호출 스택을 변경할 수 있습니까?OpCodes.Ret의 주소는 어디에 저장되어 있습니까? 그것을 바꿀 수 있습니까?
내가 아는 한 C++에서는 스택의 값에 액세스하고 리턴 주소를 변경할 수 있습니다. 일리노이에서 "InvalidProgramException"예외로 현재 메소드를 넘어서 스택에 액세스하려고 시도한 모든 것이 실패합니다.
내 예제 코드 :
public static void Test2()
{
var ma = typeof(Program).GetMethod("Test2");
DynamicMethod meth = new DynamicMethod("", null, null, ma.Module, true);
ILGenerator il = meth.GetILGenerator();
il.EmitWriteLine("Start to run the IL method");
var t = il.DeclareLocal(typeof(int));
//take the top of the stack (from the caller method) and put it into the variable t
//this seems to be not possible?
il.Emit(OpCodes.Stloc, t);
//print the value from the stack
il.EmitWriteLine(t);
//load the value back from the field onto the stack to allow everything to preceed normally
il.Emit(OpCodes.Ldloc, t);
//return
il.Emit(OpCodes.Ret);
Action a = (Action)meth.CreateDelegate(typeof(Action));
a();
}
누가 'ret'가 주소로 이동한다고 말합니까? opcode 사양은 "주소로 점프"에 대해서는 아무 것도 말하지 않습니다. 그 문제에 대해서도 C++ 스펙은 그렇지 않습니다. C++에서 그렇게 할 수 있다면 구현 정의 된 동작입니다. –
예, 아마 컴파일러에 의존했습니다. C#에서는 이런 종류의 액세스가 불가능할 수도 있습니다. 나는 잘 모르겠다. 그러나 내부적으로 CLI는 메소드가 RET 명령에서 완료된 후에 어디로 가야 하는지를 저장해야합니다. 나는 실제 환경에서 사용해야하는 무언가가 아닌 해킹을 찾고있다. – Luz
스택은 CLR이 소유 한 데이터 구조입니다. 스택을 사용하는 방법은 구현 세부 사항이므로 해당 데이터 구조를 사용하는 방법에 대해 아무런 가정을 할 수 없습니다. 예를 들어 반송 주소를 변경 한 다음 보안 스택 워크가 발생하거나 예외가 발생했다고 가정합니다. 올바르게 수행하려면 CLR에서 스택의 데이터 구조가 올바른 것이 필요할 수 있습니다.그것을 바꾸지 마십시오. 그것은 당신의 것이 아닙니다. –