2013-10-02 2 views
2

내가 함께로드 된 DLL에서 기호와 섹션을 덤프하는 루틴을 작성했습니다 LoadLibrary하지만 예를 들어 이상 IMAGE_SIZEOF_SHORT_NAMEWindows DLL의 문자열 테이블은 어디에 있습니까?

있는 섹션 이름을 가지고는 MinGW DLL을 디코딩하는 방법을 잘하는는 MinGW DLL은 follwing을 섹션을 출력 내가 문자열로 인쇄하는 경우 :

[".text", ".data", ".rdata", ".pdata", ".xdata", ".bss", ".edata", ".idata", 
".CRT", ".tls", ".reloc", "/4", "/19", "/31", "/45", "/57", "/70", "/81", 
"/92"] 

objdump.exe 등의 다른 섹션을 가져옵니다 모든 이상입니다

.debug_aranges 
.debug_info 
.debug_abbrev 
.debug_line 
.debug_frame 
.debug_str 
.debug_loc 
.debug_ranges 

IMAGE_SIZEOF_SHORT_NAME. MSDN 설명이 : 그래서

For longer names, this member contains a forward slash (/) followed by an ASCII representation of a decimal number that is an offset into the string table.

나는 다음과 같은 코드가 있습니다 그것이 있어야하므로

Char buffer[IMAGE_SIZEOF_SHORT_NAME + 1]; 
    std::strncpy(buffer, reinterpret_cast<const Char * const>(section_header_ptr[i].Name), IMAGE_SIZEOF_SHORT_NAME); 
    buffer[IMAGE_SIZEOF_SHORT_NAME] = '\0'; 
    const Char * name = buffer; 
    if (name[0] == '/') { 
    const Long rva = std::strtol(name + 1, NULL, 10); 
    if ((LONG_MAX == rva) || (LONG_MIN == rva) || ((0 == rva) && (name[0] != '0'))) { 
     static const Char * const failure = "failed to convert offset"; 
     name = failure; 
    } 
    // -- How do I get the string table here? and use the offset? -- 
    } 

내가 문자열 테이블 기호 항목 후 것을 볼 수있는 COFF 사양을 읽기를

HMODULE handle = LoadLibrary("some_mingw_library.dll"); 
PIMAGE_DOS_HEADER idh = (PIMAGE_DOS_HEADER)(handle); 
PIMAGE_NT_HEADERS inh = (PIMAGE_NT_HEADERS)(((const uint8_t*)(idh)) + idh->e_lfanew) 
PIMAGE_FILE_HEADER ifh = &inh->FileHeader; 
PIMAGE_SYMBOL is = (PIMAGE_SYMBOL)(((const uint8_t*)(idh)) + ifh->PointerToSymbolTable) 
const char * const string_table = &is[ifh->NumberOfSymbols]; 

하지만 나는 확실히 문자열 테이블이 아닌 것을 얻습니다. 내 16 진수 편집기에서 문자열 테이블을 볼 수 있습니다. 휴대용 테이블의 문자열 테이블은 어디에 있습니까?

+0

MSDN도 (연결 한 링크) ... "실행 가능한 이미지는 문자열 테이블을 사용하지 않으며 8 자 이상의 섹션 이름을 지원하지 않습니다." – mox

+0

@mox Microsoft의 세계에서 확실히. MSDN은 Microsoft의 설명서이지만 PE 및 COFF 사양은 공개되어 있으며 UNIX에서도 사용됩니다. GNU binutils를보고 PE 사양이'-Windows.h'가 아닌 헤더를 통해 작성된 것을 볼 수 있습니다. Microsoft가 '더 이상 사용하지 않음'은 더 이상 사용하지 않는다는 것을 의미합니다. 야생에서 이미지를 채울 수없는 이유는 없습니다. 사양에서 완전히 지원됩니다. –

답변

3

실행 파일이 메모리에 매핑되면 하나의 인접한 덩어리로로드되지 않습니다. 섹션 헤더에 설명 된대로 섹션이 흩어져 있습니다.

기호가 메모리에 매핑되지 않아도됩니다.

PointerToSymbolTable은 오프셋 파일이 아니라 메모리 오프셋 (위에서 설명한대로 같은 것은 아닙니다)입니다.

EXE와 DLL에는 COFF 기호가 없어야합니다.

대부분의 질문에 대한 답변은 PEDUMP에서 찾을 수 있습니다.

+0

PointerToSymbolTable은 더 이상 사용되지 않으며 사용되지 않습니다. – mox

+0

필자는'PEDUMP' 소스 코드를 가지고 있으며'PointerToSymbolTable'을 파일 오프셋으로 사용합니다 (당신이 옳습니다). 파일을 가상 메모리로 매핑하여 DLL을 읽지 만'LoadLibrary'의 결과를 사용하고 있습니다. 섹션은 주변에 흩어져 있으며 일반적으로 대부분의 정보를 찾을 수 있습니다. 또한 심볼이 메모리에 매핑되지 않는다는 것이 맞다고 생각합니다. –

+0

파일에서 심볼 테이블을 직접 읽어야 할 것 같습니다. 당신은 이미 오프셋을 가지고 있습니다. – arx

-1

실행 파일 (DLL)에서는 문자열 테이블을 사용할 수 없으며 OBJ 파일에서만 사용할 수 있습니다. 이것이 PE 파일을 분석 할 때 이들을 열거 할 수없는 이유입니다. PE 파일의 섹션 이름은 8자를 넘지 않습니다.

+0

원본 포스터에는 이름이 8 자 이상인 DLL이 있으며 objdump가 올바르게 디코딩합니다. '사용되지 않음'과 '사용하지 않음'은 동의어가 아닙니다. – arx

+0

PE 이미지의 섹션 이름에는 8 자보다 긴 이름이 없어야합니다. – mox

+1

포스터에는 "/ 19"와 같은 섹션 이름을 가진 MinGW에서 제작 한 DLL이 있으며 objdump가 ".debug_info"와 같은 더 긴 이름으로 디코딩한다고합니다. 이 세부 사항을 그가 발명했다고 생각하니? – arx