문제

나는 msil을 겪고 있고 많은 NOP 지침. MSDN 기사에 따르면 조치를 취하지 않고 OPCODE가 패치 된 경우 공간을 채우는 데 사용된다고 말합니다. 릴리스 빌드보다 디버그 빌드에서 훨씬 더 많이 사용됩니다. 이러한 종류의 진술은 어셈블리 언어로 사용되어 Opcode가 단어 경계에 맞는지 확인하지만 MSIL에 필요한 이유는 무엇입니까?

도움이 되었습니까?

해결책

NOP는 몇 가지 목적을 제공합니다.

  • 그들은 디버거가 생성 된 코드에서 다른 사람들과 결합 되더라도 라인에 중단 점을 배치 할 수 있도록합니다.
  • 로더가 다른 크기의 대상 오프셋으로 점프를 패치 할 수 있습니다.
  • 그것은 특정 경계에서 코드 블록을 정렬 할 수있게하므로 캐싱에 좋습니다.
  • 전반적인 기능 변경 크기에 대해 걱정하지 않고 새 섹션으로 호출하여 코드 청크를 덮어 쓰는 점진적인 링크가 가능합니다.

다른 팁

디버깅으로 NOP를 사용하는 방법은 다음과 같습니다.

NOP는 언어 컴파일러 (C#, VB 등)에서 사용하여 암시 적 시퀀스 포인트를 정의합니다. 이들은 JIT 컴파일러에게 기계 지침을 IL 명령에 다시 매핑 할 수 있도록하는 위치를 알려줍니다.

Rick Byer의 블로그 항목 디버깅 모델, 몇 가지 세부 사항을 설명합니다.

C#은 또한 통화 지침 후 NOPS를 배치하여 소스의 반환 사이트 위치가 통화 후 줄이 아닌 호출 아웃이되도록합니다.

릴리스 빌드가 방출되는 코드에서 라인 기반 마커 (예 : 브레이크 포인트)에 대한 기회를 제공합니다.

또한 특정 프로세서 또는 아키텍처를 최적화 할 때 코드를 더 빨리 실행할 수 있습니다.

오랫동안 프로세서는 대략 병렬로 작동하는 여러 파이프 라인을 사용하므로 동시에 두 개의 독립적 인 명령을 기부 할 수 있습니다. 두 파이프 라인이있는 간단한 프로세서에서 첫 번째는 모든 지침을 지원하는 반면, 두 번째는 하위 집합 만 지원할 수 있습니다. 또한 파이프 라인 사이에는 아직 완료되지 않은 이전 명령의 결과를 기다려야 할 때 파이프 라인 사이에 일부 마구간이 있습니다.

이러한 상황에서 전용 NOP 다음 명령어를 특정 파이프 라인 (첫 번째 또는 첫 번째)으로 강제하고 다음 지침의 쌍을 개선하여 NOP 상각 이상입니다.

녀석! No-OP는 굉장합니다! 시간을 소비하는 것 외에는 아무것도하지 않는 지시입니다. 희미한 암흑 시대에는 중요한 루프에서 타이밍에서 마이크로드 조정을 수행하거나 더 중요한 것은 자체 수정 코드의 필러로 사용합니다.

한 프로세서에서 나는 최근 (4 년 동안) NOP를 사용하여 다음 작업이 시작되기 전에 이전 작업이 완료되도록하는 데 사용되었습니다. 예를 들어:

등록 할로드 값 (8 사이클 필요) NOP 8 등록에 1을 추가하십시오.

이로 인해 레지스터가 추가 작업 전에 올바른 값을 갖도록했습니다.

또 다른 용도는 vector0의 주소가 Vector 1 0x20 등의 경우 0이기 때문에 특정 크기 (32 바이트) 여야하는 인터럽트 벡터와 같은 실행 장치를 작성하는 것이 었습니다. 필요합니다.

그들에게 고전적인 용도 중 하나는 디버거가 항상 소스 코드 라인을 IL 명령어와 연결할 수 있도록하는 것입니다.

그들은 그들을 사용하여 지원할 수 있습니다 편집 및 연속 디버깅하는 동안. 디버거에 기존 코드를 교체 할 수있는 공간을 제공합니다.

NOP는 버퍼 오버 플로우 익스플로잇의 페이로드에 필수적입니다.

DDAA가 말했듯이, NOPS는 스택의 차이를 설명 할 수있게 해주므로 리턴 주소를 덮어 쓰면 NOP 썰매 (연속으로 많은 NOPS)로 점프 한 다음 일부로 점프하지 않고 실행 가능한 코드를 올바르게 누릅니다. 시작이 아닌 지시의 바이트.

50 년이 너무 늦었지만 이봐.

NOP는 손으로 어셈블리 코드를 입력하는 경우 유용합니다. 코드를 제거 해야하는 경우 이전 Opcodes를 담을 수 있습니다.

Similary, 일부 Opcode를 덮어 쓰고 다른 곳으로 점프하여 새 코드를 삽입 할 수 있습니다. 그곳에서 덮어 쓰기 된 opcodes를 넣고 새 코드를 삽입하십시오. 준비되면 뒤로 점프합니다.

때로는 사용 가능한 도구를 사용해야했습니다. 경우에 따라 이것은 매우 기본적인 MachineCode 편집기였습니다.

요즘 컴파일러를 사용하는 기술은 더 이상 의미가 없습니다.

소프트웨어 크래킹 장면에서 응용 프로그램을 잠금 해제하는 고전적인 방법은 키나 등록 또는 기간을 확인하는 줄을 NOP로 패치하는 것입니다. .

또한 코드에서 NOPS를 보았습니다. 코드는 자리 표시 자 (Veeery Old Copy Protection)로서 수행하는 일을 난독 화하도록 수정했습니다.

다소 정통적으로 사용됩니다 노프 슬라이드, 버퍼 오버 플로우 익스플로잇에 사용됩니다.

링커가 더 긴 명령 (일반적으로 긴 점프)을 짧은 명령 (짧은 점프)으로 대체 할 수 있습니다. NOP는 추가 공간을 차지합니다. 다른 점프가 작동하는 것을 막기 때문에 코드를 움직일 수 없습니다. 이것은 링크 시간에 발생하므로 컴파일러는 길이 또는 짧은 점프가 적절한 지 알 수 없습니다.

적어도 그것은 전통적인 용도 중 하나입니다.

이것은 특정 질문에 대한 답이 아니지만, 예전에는 NOP를 사용하여 분기 지연 슬롯, 당신이 그것을 사용하지 않는 지시로 그것을 채울 수 없다면.

.NET 컴파일러가 MSIL 출력을 정렬합니까? IL에 대한 액세스 속도를 높이는 데 유용 할 수 있다고 생각합니다. 또한 내 이해는 다른 하드웨어 플랫폼에서 휴대용으로 설계되었으며 정렬 된 액세스가 필요하다는 것입니다.

내가 배운 첫 번째 어셈블리는 SPARC 였으므로 분기 지연 슬롯에 익숙합니다. 다른 명령으로 채울 수 없다면 일반적으로 분기 명령어 위에 올려 놓거나 루프에서 카운터를 증가시킬 수있는 지침을 사용하면 사용합니다. NOP.

나는 균열에 익숙하지 않지만 NOP를 사용하여 스택을 덮어 쓰는 것이 일반적이라고 생각하므로 악의적 인 기능이 시작되는 위치를 정확하게 계산하지 않아도됩니다.

NOP를 사용하여 ISR에 들어간 후 누적 된 대기 시간을 자동으로 조정했습니다. 손톱 타이밍이 죽기에 매우 편리합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top