Programing

nop opcode의 목적은 무엇입니까?

lottogame 2020. 10. 10. 09:28
반응형

nop opcode의 목적은 무엇입니까?


MSIL을 살펴보고 많은 nop 지침 이 있음을 알았습니다 . MSDN 기사는 조치를 취하지 않으며 opcode가 패치되면 공간을 채우는 데 사용됩니다. 릴리스 빌드보다 디버그 빌드에서 더 많이 사용됩니다. 이러한 종류의 문은 opcode가 단어 경계에 맞는지 확인하기 위해 어셈블리 언어에서 사용된다는 것을 알고 있지만 MSIL에서 왜 필요한가요?


NOP는 여러 가지 용도로 사용됩니다.

  • 그들은 생성 된 코드에서 다른 것과 결합 된 경우에도 디버거가 한 줄에 중단 점을 배치 할 수 있도록합니다.
  • 로더는 다른 크기의 타겟 오프셋으로 점프를 패치 할 수 있습니다.
  • 이를 통해 코드 블록을 특정 경계에 정렬 할 수 있으므로 캐싱에 유용 할 수 있습니다.
  • 전체 함수 변경 크기에 대해 걱정할 필요없이 새 섹션에 대한 호출로 코드 청크를 덮어 쓰는 증분 링크를 허용합니다.

디버깅에서 nops를 사용하는 방법은 다음과 같습니다.

Nops는 암시 적 시퀀스 포인트를 정의하기 위해 언어 컴파일러 (C #, VB 등)에서 사용됩니다. 이것들은 기계 명령어가 IL 명령어로 다시 매핑 될 수 있도록 JIT 컴파일러에 알려줍니다.

DebuggingModes.IgnoreSymbolStoreSequencePoints 에 대한 Rick Byer의 블로그 항목 은 몇 가지 세부 정보를 설명합니다.

C #은 또한 호출 명령 뒤에 Nops를 배치하므로 소스의 반환 사이트 위치가 호출 후 라인이 아닌 호출이됩니다.


릴리스 빌드가 아무 것도 방출하지 않는 코드에서 라인 기반 마커 (예 : 중단 점)에 대한 기회를 제공합니다.


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

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

이러한 상황에서 전용 nop 는 다음 명령어를 특정 파이프 라인 (첫 번째 파이프 라인 또는 첫 번째 파이프 라인 아님)으로 강제 적용하고 다음 명령어의 페어링을 개선하여 nop 의 비용 이 상각 된 금액 이상이 되도록합니다 .


친구! No-op은 굉장합니다! 시간 만 소비하는 명령입니다. 희미한 암흑 시대에는 중요한 루프에서 타이밍을 미세 조정하거나 더 중요한 것은 자체 수정 코드의 필러로 사용합니다.


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

등록 할 값로드 (8주기 소요) nop 8 레지스터에 1 추가

이것은 레지스터가 추가 작업 전에 올바른 값을 가지고 있는지 확인했습니다.

또 다른 용도는 특정 크기 (32 바이트) 여야하는 인터럽트 벡터와 같은 실행 단위를 채우는 것입니다. 왜냐하면 vector0의 주소는 벡터 1 0x20 등의 경우 0이므로 컴파일러는 여기에 NOP를 넣습니다. 필요합니다.


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


디버깅하는 동안 편집 및 계속 을 지원하는 데 사용할 수 있습니다 . 디버거에 오프셋 등을 변경하지 않고 이전 코드를 새 코드로 교체 할 수있는 공간을 제공합니다.


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


ddaa가 말했듯이 nops를 사용하면 스택의 분산을 설명 할 수 있으므로 반환 주소를 덮어 쓸 때 nop sled (연속 많은 nops)로 점프 한 다음 일부로 점프하는 대신 실행 가능한 코드를 올바르게 입력합니다. 시작이 아닌 명령어의 바이트.


50 년이 늦었지만 헤이.

Nop는 어셈블리 코드를 직접 입력 할 때 유용합니다. 코드를 제거해야한다면 이전 opcode를 사용할 수 없습니다.

유사하게, 일부 opcode를 덮어 써서 새 코드를 삽입하고 다른 곳으로 이동할 수 있습니다. 거기에 덮어 쓴 opcode를 넣고 새 코드를 삽입합니다. 준비가되면 뒤로 뛰어 오릅니다.

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

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


소프트웨어 크래킹 장면에서 애플리케이션 잠금을 해제하는 고전적인 방법은 키 또는 등록 또는 기간을 확인하는 라인을 NOP로 패치하여 아무것도하지 않고 등록 된 것처럼 애플리케이션을 계속 시작하는 것입니다. .


또한 자리 표시 자 (veeery old copy protection)로 수행되는 작업을 난독 화하기 위해 자체 수정하는 코드에서 NOP를 보았습니다.


다소 비 정통적인 사용은 버퍼 오버플로 익스플로잇에 사용되는 NOP-Slides 입니다.


이를 통해 링커는 긴 명령 (일반적으로 긴 점프)을 짧은 명령 (짧은 점프)으로 대체 할 수 있습니다. NOP는 추가 공간을 차지합니다. 다른 점프가 작동하지 않도록 코드를 이동할 수 없습니다. 이것은 링크 타임에 발생하므로 컴파일러는 길거나 짧은 점프가 적절한 지 알 수 없습니다.

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


이것은 특정 질문에 대한 답변은 아니지만 예전 에는 다른 유용한 지침으로 채울 수 없었던 경우 NOP를 사용하여 분기 지연 슬롯 을 채울 수있었습니다.


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


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

크래킹에 익숙하지 않지만 NOP를 사용하여 스택을 덮어 쓰는 것이 일반적이라고 생각하므로 악성 기능이 시작되는 위치를 정확히 계산할 필요가 없습니다.


ISR에 들어간 후 누적 된 지연 시간을 자동으로 조정하기 위해 NOP를 사용했습니다. 타이밍 데드 온 네일에 매우 편리합니다.

참고 URL : https://stackoverflow.com/questions/234906/whats-the-purpose-of-the-nop-opcode

반응형