2011-08-19 2 views
1

그래서 최근에 어셈블리에서 win32 호출을 호출하고 싶었고 NASM을 외부 어셈블러로 사용했습니다. [dword addr] 근처에서 호출 즉시 호출 대 dword

call [email protected] 

상대 점프 (0xE8 연산 코드)에 조립 한 결과는 액세스 위반했다 : 나는 다음과 같은 방법으로 내 코드에 SendMessage를 호출했다. 디버거에서 계산 된 점프 오프셋이 올바른 것으로 보였습니다. ( [email protected]이 실제로 거기에 있었던 것 같습니다) 그럼에도 불구하고 작동하지 않았습니다. 내가 C++에서 함수를 호출했을 때 Visual Studio에서 생성 된 어셈블리를 조사한 결과, 상대적으로 즉각적인 점프가 아닌 (MASM 언어로) call dword ptr [[email protected]] (0xFF15 opcode에 해당) 대신에 나타났습니다. 주위에 몇 가지 futzing 후 나는 NASM 구문이 call dword near [dword [email protected]]로 인코딩이 알아 냈어, 그리고 내 코드를 변경 갑자기 일했다.

제 질문은, 왜 하나가 작동하고 다른 하나는 작동하지 않는 것입니까? 코드의 재배치가 진행되어 상대적으로 즉각적인 호출이 불친절하게 어딘가로 점프하게됩니까? 필자는 결코 어셈블리 프로그래머가 아니었지만 필자의 인상은 항상 두 가지 호출이 똑같은 것을 수행해야한다는 것과 주된 차이점은 하나는 위치 독립적이고 다른 하나는 그렇지 않다는 것이다. (그들은 IP를 같은 장소로 이동한다고 가정한다.)). 코드 이론의 재배치는 의미가 있지만, 올바른 주소를 보여주는 디버거에 대해 어떻게 설명합니까?

또한이 호출에서 [] 구문의 논리는 무엇입니까? 오프셋은 여전히 ​​즉시 (단지 0xFF15 바로 뒤에 인코딩 된 리틀 엔디안입니다.) 여기에는 명령어 페치를 넘어선 메모리 액세스가 없습니다 (lea의 컨텍스트 외부에서 참조로 생각하는 경향이 있습니다). 16 @

답변

1
call dword[[email protected]] 

_ 꼬마 도깨비 _SendMessageW는 API 함수의 주소를 포함하여 수입 섹션에 주소입니다. 이 대괄호를 사용하여 (이 주소로 저장 한 주소로 전화)

+0

아, 잠시만 기다려주세요. '__imp__SendMessageW @ 16'은 함수 포인터입니까? 따라서 문제는 아마도이 데이터가 실행되지 않는 페이지에 있기 때문에 액세스 위반이 발생하는 것입니다. 맞습니까? – 808140

+0

예, 본질적으로 읽기 전용 데이터를 코드로 실행하려고합니다. –

+0

그럼, 다음과 같은 질문 :이 종류의 간접 지정을 생성하는이면의 논리는 무엇입니까? 약간의 실험은 VS 디버거가'[dword __imp__SendMessageW @ 16]'의 값을'SendMessageW'로 인식 할지라도'_SendMessageW' 또는'SendMessageW'를 직접 호출 할 수 없음을 확인합니다. Linux 시스템에서 테이블을 통해 공유 라이브러리 인덱스 함수를 알고 있지만 Windows에서 실제 재배치를 수행한다는 것을 기억하고 있다고 생각했습니다. 즉, 코드에서 오프셋 목록을 유지 관리하고로드시 패치합니다. 내가 오해하고 있니? – 808140