2012-03-06 5 views
6

gcc에서는 잘 작동합니다.Visual C++에서 함수 포인터로 캐스팅하여 쉘 코드를 실행하십시오.

unsigned char b[50] = "\xda\xd1 ... \x0"; //some shellcode with terminating \x0 
((void(*)())b)(); //cast b to function pointer from void to void, then run it 

그러나 이것은 비주얼 C++에 넣어 때,이 오류 메시지가 뱉어 : 왜 이렇게되는지

1>..\test.cpp(132): error C2440: 'type cast' : cannot convert from 'unsigned char [50]' to 'void (__cdecl *)(void)' 
1>   There is no context in which this conversion is possible 

아는 사람을 코드는 무언가 같이 간다? 다른 형식으로 데이터를 재 해석

+1

'(* (void (*)()) & b [0])()'을 시도해보십시오. –

+0

어떻게 든이 일을하게 되더라도, 그것은 아주 나쁜 생각입니다. –

+0

또는'reinterpret_cast (static_cast (b))()'. –

답변

10

올바른 디버거가 무엇이 잘못되었는지 알려줍니다. 이동하려는 버퍼가 실행 가능하지 않기 때문에 코드가 액세스 위반을 일으키는 것으로 추측 할 수 있습니다.

아마도 Vista 또는 7과 같이 DEP 사용 가능 시스템을 사용하고 있으므로 쉘 코드가 실행 가능해야합니다. 그렇게하려면 먼저 사용 VirtualAlloc는 새로운 실행 버퍼를 할당하고 그것으로 당신의 쉘 코드를 복사하려면 다음을 실행합니다

void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
memcpy(exec, b, sizeof b); 
((void(*)())exec)(); 

을 그건 그렇고, 당신은 ++ (C를 쉘 코드를 NULL로 종료 할 필요가 없습니다 자동으로 문자열 리터럴을 종료하지만 이것은 필요하지 않습니다. 또한 크기를 지정할 필요가 없습니다.

unsigned char b[] = "\xcc"; 
+0

감사합니다 - 이것은 올바르게 작동합니다. 물건을 실행하기위한 특별한 할당 기능이 있다는 것을 몰랐습니다. – Arcinde

+1

@ user49164 : 스택 및 힙 기반 버퍼 오버플로를 악용하는 데 어려움이 많아 지도록 DEP는 메모리 페이지에 대한 실행 권한 순종을 시행합니다. 이렇게하면 스택이나 힙에서 데이터가 즉시 실행되지 않습니다. 'VirtualAlloc'은 물건을 실행하기위한 특별한 할당 함수가 아니며 일반적인 할당 함수입니다. 할당 된 메모리의 원하는 액세스 권한을 인자로 취합니다. –

0

일반적인 방법은 이진 표현을 복사이다

void (*fp)(); 
unsigned char buf[50]; 
char const * p = reinterpret_cast<char const *>(&buf); 

std::copy(p, p + sizeof(char const *), reinterpret_cast<char*>(&fp)); 

// now fp contains the same value as &buf 

fp(); // call 

앨리어싱이 얼라인먼트 위반 의한 정의되지 않은 동작을 회피한다.

+0

OP는 버퍼에 대한 포인터를 함수 포인터로 재 해석하여 내용을 코드로 실행하려고합니다. 귀하의 버전은 일부 버퍼 내용으로 함수 포인터를 덮어 씁니다. 결과는 유효한 포인터가 아닙니다. 'buf'에 대한 포인터를 정의한 다음 그 값을 복사해야합니다. –

+0

이 확인되었습니다. 런타임에 충돌이 발생합니다. – Arcinde

+0

@ user49164 : 네, 마이크 말이 맞습니다. 미안합니다. 결정된. –