최근에 나는 (c/C++로 작성된) DLL을 디스 어셈블하여 코드 세그먼트 안에 많은 "점프 스텁"이 있음을 발견했습니다. 이러한 스텁은 DLL 내부의 함수로 이동합니다.PE 파일의 스텁 스텁
예 :
jmp foo()
jmp foo2()
...
왜 컴파일러 (비주얼 스튜디오 2012) 이진 내부 이러한 기능 스텁을 포함하고 있습니까?
감사합니다.
최근에 나는 (c/C++로 작성된) DLL을 디스 어셈블하여 코드 세그먼트 안에 많은 "점프 스텁"이 있음을 발견했습니다. 이러한 스텁은 DLL 내부의 함수로 이동합니다.PE 파일의 스텁 스텁
예 :
jmp foo()
jmp foo2()
...
왜 컴파일러 (비주얼 스튜디오 2012) 이진 내부 이러한 기능 스텁을 포함하고 있습니까?
감사합니다.
모든 스텁 뒤에 0xCC 바이트가 많이 있습니까? 그렇다면 점진적 연결을 사용하도록 컴파일 된 코드 (디버그 빌드의 경우 기본값)를보고있는 것입니다.
증분 링크 용으로 컴파일 할 때 컴파일러는 모든 함수에 대해 스텁을 만들고 모든 호출이 스텁을 통과하는지 확인합니다. 함수를 업데이트 된 코드로 대체해야하는 경우 새 코드를 끝에 추가하고 점프 썽크 만 패치해야합니다. 기존의 모든 호출이 새 코드로 리디렉션됩니다. 여분의 CC는 새로운 기능이 추가 될 경우를 대비하여 더 많은 스텁을 위해 예약되어 있습니다.
자세한 배경 정보는 see MSDN을 참조하십시오.
그런 식으로 링커와 DLL의 심볼이 "결합됩니다". DLL을로드하고 DLL의 함수 주소를 업데이트하는 로더가 해결할 수있는 올바른 유형의 오프셋이 심볼 테이블에 사용되며 컴파일 된 코드는 예를 들어 여전히 처리 할 수 있습니다 함수 포인터 :
void (*fptr)() = foo;
foo
이 주소는 로더에 의존 될 것입니다 해결 방법 DLL에있는 장소에 그냥 참조 인 경우. 이 문제를 해결하는 것이 훨씬 더 복잡합니다. "여기 foo() 진입 점이있어 실제 foo로 연결됩니다."라는 문제를 해결하는 것입니다.
DLL = 공유 라이브러리. 예, 우리는'foo'가'myprog.exe'보다는'mydll.dll'의 일부라고 이야기하고 있습니다. –
DLL의 위치를 변경할 수 있습니다. 즉, 메모리의 어느 위치에서나 끝날 수 있습니다. 즉, 모든 통화를 다시 작성해야합니다. 모든 호출을 작은 jumptable에 유지하면 재배치시 한 페이지 만 다시 작성해야합니다. 변경되지 않은 코드 페이지가 프로세스간에 공유 될 수 있기 때문에 문제가 발생하지만 각 프로세스에는 수정 된 페이지의 자체 복사본이 있습니다.
예 이러한 썽크 뒤에 0xcc 바이트의 buch가 있습니다. 그리고이 썽크는 릴리스 빌드에만 나타납니다. – user2458855