2011-12-04 4 views
4

다음은 함수 포인터가 가리키는 컴퓨터 코드를 읽고 인쇄하는 나의 시도입니다. 현재 인쇄되는 데이터는 생성 된 코드와 다릅니다 ... 생성 된 실행 파일에서 생성 된 포인터의 값을 확인한 후 디스어셈블러 (코드/디버거간에 차이점이 있음)가 표시되지만 돈은 표시되지 않습니다. 문제가있는 것을 보거나 문제를 해결할 수있는 방법을 이해하십시오. 여기함수 포인터를 역 참조하고 MSVC++에서 데이터로 읽는 방법은 무엇입니까?

void dummy(); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int i; 

    printf("\nReading dummy...\n"); 
    for(i = 0; i < 25; i++) 
     printf("%.2X ", ((char *)((void *)dummy))[i]); 
    puts(""); 

    dummy(); 

    getchar(); 
    return 0; 
} 

void __declspec(naked) dummy() 
{ 
    __asm 
    { 
     nop; 
     nop; 
     nop; 
     nop; 

     ret; 
    } 
} 
+2

에 선

printf("%.2X ", ((char *)((void *)dummy))[i]); 

? –

+1

함수 주소에서 메모리 덤프 창을 사용할 때 무엇을 얻고, 무엇을 얻으며, 디버거에 표시되는 내용은 무엇입니까? –

답변

12

두 가지 일반적인 실수는 여기에서해야합니다. 먼저 char * 대신 unsigned char*으로 전송하십시오. 다음으로 중요한 프로젝트 + 속성, 링커, 일반을 선택하고 증분 링크를 해제하십시오.

증분 링크가 활성화되면 함수 주소는 실제로 실제 함수에 JMP 만 포함하는 작은 스텁을 가리 킵니다. 따라서 링커는 전체 실행 가능 이미지를 다시 만들 필요없이 이전 코드를 새 코드로 바꿀 수 있습니다. 증분 링크가 활성화되어 있으면 코드가 실제 함수 대신 해당 스텁을 읽는 것입니다. 적절한 출력 :

Reading dummy... 
90 90 90 90 C3 //... rest is random 
+0

고마워, 정확히 내가 필요로했던. 나는 덤프되는 코드를 더 자세히 살펴야했는데, 나는 그것이 링커 바보 같은 짓이라고 생각했지만, 나는 무엇을 확신하지 못했다. :) –

-2

당신이가는 :

#include <stdio.h> 

void PrintHex(const char* input, const int len) 
{ 
    char * tmp=new char[len*3+1]; 
    for(int i=0;i<len;++i) 
      sprintf(tmp+i*3,"%02x ",*(input+i)&0xFF); 

    printf("%s\n",tmp); 
}; 
+2

'tmp'를 삭제하는 것을 잊었습니다 – Abyx

+0

-1, 이것은 OP의 코드와 같은 결과를 줄 것입니다. 그것은 또한 실제로는 버퍼 오버 플로우를 일으키는 것을 제외하고는 서명 된'char'을 잘못 사용합니다. 그리고 값을 직접 출력 할 수있을 때 버퍼를 할당하는 것은 무엇입니까? – interjay

2

날 어디 보자,이 인쇄 :

 
FFFFFF90 FFFFFF90 FFFFFF90 FFFFFF90 FFFFFFC3 

의 printf로 hh 길이 수정을 사용해보십시오 :

printf("%02hhX ", ((char *)((void *)dummy))[i]); 

출력 :

 
90 90 90 90 C3 

X 지정은 그 자체함으로써, unsigned int 같은 값을 출력하지만 당신은 signed int에 승진 char 전달합니다. hh 수정자는 unsigned int 대신 unsigned char으로 변경합니다.

0

변경 당신의 printf`에 대한 호출은()`인쇄를 결국 무엇을 게시 할 수

printf("%.2X ", ((unsigned char *)dummy)[i]); 
관련 문제