당신이 요구하는 것은 할 수 있지만 그리 쉬운 것은 아닙니다.
한 가지 방법은 지침에서 코드 이동을 보완하는 것입니다. RIP 상대 주소 지정 (05h, 0dh, 15h, 1dh, 25h, 2dh, 35h 또는 3dh의 ModRM
바이트)을 사용하는 모든 지침을 찾아야하며 이동량에 따라 disp32
필드를 조정해야합니다 따라서 가상 주소 공간에서 +/- 2GB로 제한되며, 이는 64 비트 주소 공간이 4GB보다 크므로 보장 할 수 없습니다.
또한 대부분 예를 들어, 하나 이상의 함께 모든 원래의 명령을 대체 그 등가물로 그 명령을 대체 할 수
; These replace the original instruction and occupy exactly as many bytes as the original instruction:
JMP Equivalent1
NOP
NOP
Equivalent1End:
; This is the code equivalent to the original instruction:
Equivalent1:
Equivalent subinstruction 1
Equivalent subinstruction 2
...
JMP Equivalent1End
두 가지 방법이 적어도 일부 기초적인 86 분해 루틴이 필요합니다.
전자의 경우 원본 코드의 패치 된 복사본이 포함 된 메모리가 원본 코드의 +/- 2GB 내에 있도록하려면 Windows에서 VirtualAlloc()
(또는 일부 해당 기능의 Linux)을 사용해야 할 수 있습니다. 그리고 특정 주소의 할당은 여전히 실패 할 수 있습니다.
후자는 단순한 기본 디스어셈 외에 전체 명령 디코딩 및 생성을 요구합니다.
해결해야 할 다른 단점이있을 수 있습니다.
RFLAGS
레지스터에 TF
플래그를 설정하여 모든 명령어의 실행이 끝나면 CPU가 single-step
디버그 인터럽트를 생성하도록하여 명령어 경계를 찾을 수도 있습니다. 디버그 예외 핸들러는이를 catch하고 다음 명령어의 RIP 값을 기록해야합니다. Windows에서 Structured Exception Handling (SEH)
을 사용하여이 작업을 수행 할 수 있다고 생각합니다 (디버그 인터럽트를 시도한 적이 없음). Linux에 대해서는 확실하지 않습니다. 이를 위해서는 모든 명령어를 실행해야합니다.
Btw는 64 비트 모드에서 절대 주소 지정을합니다. 예를 들어 0A0h부터 0A3h까지의 opcode를 사용하는 MOV to/accumulator 명령을 참조하십시오.
-mcmodel = large는 솔루션이어야합니다. 나는 왜 gcc osx 컴파일러가 그것을 지원하지 않는지 조사해야만한다. – nux
아마 오래되었다. 작은 (표준) 및 중간 코드 모델이 일찍 추가되었으며 나중에 대형 모델이 추가되었습니다. – hirschhornsalz
정말 고맙게 여기며 정말 고맙게 생각하고 문제를 해결하는 absolut를 해결합니다. – nux