2012-01-08 1 views
-3

해당 주소를 기반으로 하나의 함수를 호출하려고합니다. 하지만 그 일을하려고하면 몇 가지 문제가 내 눈에 들어옵니다. 나는 그 문제를 다룰 수 없다. 나는 무엇이 잘못되고 있는지 모른다. 누군가 제게 전화하는 행동을 끝내시기 바랍니다. image link어셈블리의 주소를 기반으로 printf 함수를 호출하는 방법

#include <stdio.h> 

void main() 
{ 
    char* mat = "%s\n"; 
    char* str = "abc"; 
    //printf(mat,str); 

    _asm 
    { 
     mov   eax,dword ptr [ebp-8] 
     push  eax 
     mov   ecx,dword ptr [ebp-4] 
     push  ecx 
     mov   eax,00401090h //function 'printf' address 
     call  [eax] 
     //call  printf //dont call like this, we shall call based on its address. 
    } 

    getchar(); 
} 
+11

왜 코드가 별도의 파일에 대한 링크입니까? ** 그리고 왜 사진입니까? ** –

+2

사람들이 자신의 환경에서 테스트 할 수 있도록 코드를 복사하여 붙여 넣으십시오. 코드를 포맷팅하기 위해 선택된 코드와 함께'{}'버튼을 사용하십시오. – bdonlan

+1

'printf'가'00401090'에 있다고 어떻게 결정 했습니까? 항상 거기에 있기를 기대하십니까? –

답변

4

당신은 하드 코딩 된 주소에있는 printf에 의존 할 수 없다.

은 교체 :

mov eax,00401090h 
call [eax] 

으로 :

call printf 
+0

은 기능 이름을 기반으로하지 않고 주소를 기반으로합니다. – user859974

+5

함수 이름은 주소입니다. –

+1

그리고 여기서 명백한 call-and-adress 접근 방식이 있습니다 :'mov eax, printf; call [eax];'. –

2

수의 printf가 포함 된 DLL의로드 주소는 (! 및 수행)에 따라 다릅니다. 이것은 printf의 주소가 변경된다는 것을 의미합니다. 동일한 응용 프로그램을 두 번 실행해도 변경 될 수 있습니다!

Drew가 제안한 바대로 리터럴 printf으로 바꿀 수 있습니다. 링커가 trampoline 루틴의 적절한 주소로 바꿉니다 (차례대로 컴파일에서 다른 컴파일로 이동할 수도 있고 런타임에 옮길 수도 있음). 재배치 가능 실행 파일이있는 경우) 런타임시 실제 printf을 가리킬 것입니다.

또는 OS 특정 루틴을 사용하여 런타임에 직접 printf의 주소를 찾은 다음 해당 주소를 사용하여 호출 할 수 있습니다 (세부 정보는 독자를위한 연습 과제로 남겨 둡니다. 먼저 C에서 프로토 타입을 작성한 다음 번역하는 것이 좋습니다. 한 번에 조금씩). 창문에서는 GetProcAddress을 찾으십시오. Unixen에서 dlsym을 찾으십시오.

+0

질문이 OS를 지정하지 않으면 서 OS가 너무 많습니다. – m0skit0

+2

@ m0skit0, 그는 Visual C++ 인라인 어셈블러 구문을 사용하고 있으므로 Windows는 좋은 추측이지만 어쨌든 OS를 조금 적게 만들었습니다 – bdonlan

관련 문제