2013-06-06 4 views
3

최근에 나는 (c/C++로 작성된) DLL을 디스 어셈블하여 코드 세그먼트 안에 많은 "점프 스텁"이 있음을 발견했습니다. 이러한 스텁은 DLL 내부의 함수로 이동합니다.PE 파일의 스텁 스텁

예 :

jmp foo() 
jmp foo2() 
... 

왜 컴파일러 (비주얼 스튜디오 2012) 이진 내부 이러한 기능 스텁을 포함하고 있습니까?

감사합니다.

답변

4

모든 스텁 뒤에 0xCC 바이트가 많이 있습니까? 그렇다면 점진적 연결을 사용하도록 컴파일 된 코드 (디버그 빌드의 경우 기본값)를보고있는 것입니다.

증분 링크 용으로 컴파일 할 때 컴파일러는 모든 함수에 대해 스텁을 만들고 모든 호출이 스텁을 통과하는지 확인합니다. 함수를 업데이트 된 코드로 대체해야하는 경우 새 코드를 끝에 추가하고 점프 썽크 만 패치해야합니다. 기존의 모든 호출이 새 코드로 리디렉션됩니다. 여분의 CC는 새로운 기능이 추가 될 경우를 대비하여 더 많은 스텁을 위해 예약되어 있습니다.

자세한 배경 정보는 see MSDN을 참조하십시오.

+0

예 이러한 썽크 뒤에 0xcc 바이트의 buch가 있습니다. 그리고이 썽크는 릴리스 빌드에만 나타납니다. – user2458855

2

그런 식으로 링커와 DLL의 심볼이 "결합됩니다". DLL을로드하고 DLL의 함수 주소를 업데이트하는 로더가 해결할 수있는 올바른 유형의 오프셋이 심볼 테이블에 사용되며 컴파일 된 코드는 예를 들어 여전히 처리 할 수 ​​있습니다 함수 포인터 :

void (*fptr)() = foo; 

foo이 주소는 로더에 의존 될 것입니다 해결 방법 DLL에있는 장소에 그냥 참조 인 경우. 이 문제를 해결하는 것이 훨씬 더 복잡합니다. "여기 foo() 진입 점이있어 실제 foo로 연결됩니다."라는 문제를 해결하는 것입니다.

+0

DLL = 공유 라이브러리. 예, 우리는'foo'가'myprog.exe'보다는'mydll.dll'의 일부라고 이야기하고 있습니다. –

0

DLL의 위치를 ​​변경할 수 있습니다. 즉, 메모리의 어느 위치에서나 끝날 수 있습니다. 즉, 모든 통화를 다시 작성해야합니다. 모든 호출을 작은 jumptable에 유지하면 재배치시 한 페이지 만 다시 작성해야합니다. 변경되지 않은 코드 페이지가 프로세스간에 공유 될 수 있기 때문에 문제가 발생하지만 각 프로세스에는 수정 된 페이지의 자체 복사본이 있습니다.