2013-04-25 4 views
3

디버깅 목적으로 주소를 기호에 매핑하는 데 어려움을 겪고 있습니다 (콜 스택 가져 오기). MS dbghelp.dll은 주소에서 기호를 알 수 있습니다 (SymFromAddr, MSDN 참조). 그러나, 그것은 작동하지 않고 주소가 프로그램의 모든 실행으로 변경하는 것 때문에 나는이 이제까지 일할 수있는 방법을 궁금해 :함수가 실행될 때마다 주소가 변경되는 이유는 무엇입니까?

#include <iostream> 
void Foo() {} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    const long unsigned int addr = reinterpret_cast<long unsigned int>(&Foo); 
    std::cout << "Address: " << std::hex << addr << std::endl; 
    return 0; 
} 

출력 :

D:\dev\Sandbox\Debug>Sandbox.exe 
Address: 901320 
D:\dev\Sandbox\Debug>Sandbox.exe 
Address: ce1320 
D:\dev\Sandbox\Debug>Sandbox.exe 
Address: 3a1320 
D:\dev\Sandbox\Debug>Sandbox.exe 
Address: 3f1320 

어떻게 할 수있는 다른 프로그램 이제까지 stacktrace 에서처럼 주소를 읽고 함수에 매핑 하시겠습니까? 이것은 나에게 마술처럼 들린다. 나는 링크 된 문서에서 주소에서 무엇인가를 뺄 필요가 있다고 말한 것을 찾지 못했습니다.

리얼 모드를 극복 한 이후 모든 프로세스에는 가상 메모리 공간이 있으므로 어쨌든로드 주소에 대해 주사위를 굴릴 필요가 없습니다. DLL의 경우 절대 주소의 불확실성을 이해할 수 있지만 주 실행 파일은 이해할 수 없습니다.

VS2008로 Win7에서 시도했습니다.

+0

이 무작위 화에 대한 여러 답변, 감사합니다! 나는 WTF와 같았다! !!! 어떻게이 슈퍼 MS "무명을 통한 보안"과 함께 스택 덤프가 유용할까요?! – Borph

+0

모든 디버거는 임의의 오프셋으로로드 된 모듈을 처리 할 수 ​​있기 때문에. DLL은 항상 움직입니다. – MSalters

답변

3

코드가 "StackOverflows"에서 공격에 덜 취약 코드를 만들어 주소 공간 레이아웃 임의 화를 사용하도록 컴파일되어 있기 때문에.

정말로 변경하고 싶다면 linker option이 있습니다.

2

다른 사람들이 이미 언급 한 것처럼 실제로는 ASLR입니다.

SymLoadModuleEx()을 호출 할 때 실행 파일의 이미지 기반을 지정하는 것 같습니다. 그것은 BaseOfDll 매개 변수입니다.

크래시 덤프에 정확히 어디에 저장되어 있는지 알 수는 없지만 (실행중인 프로그램이 GetModuleHandle() (논의 된 내용은 here)) 자체 이미지베이스 주소를 얻을 수 있습니다.

EXE 자체의 DLL뿐만 아니라 프로세스에로드 된 모든 DLL의 이름과 기본 주소도 저장하려고합니다.

+0

네, 고마워요! 이제 실행중인 코드에서 기본 주소를 빼서 로그 파일에 상대 주소가 있으므로 작동했습니다. GetModuleHandle()이 트릭을 수행했습니다. 앞으로는 모든 DLL을 사용할 수 있지만 나중에. – Borph

관련 문제