2016-10-12 4 views
1

, 나는 다음과 같은 수출 순서 표 참조 : 검증 수 있듯이'kernel32.dll`은'OrdinalBase` 필드가 1로 설정된 경우 서수 0을 어떻게 내 보냅니 까? 이 메모리에로드 될 때 kernel32.dll에서 보면

(gdb) x /400hd $eax 

0x776334b0 <Wow64Transition+71576>:  3  4  5  6  7  8  9  10 
0x776334c0 <Wow64Transition+71592>:  11  12  13  14  15  16  17  18 
0x776334d0 <Wow64Transition+71608>:  19  20  21  22  23  24  25  26 
0x776334e0 <Wow64Transition+71624>:  27  28  29  30  31  32  33  34 
0x776334f0 <Wow64Transition+71640>:  35  36  37  38  39  40  41  42 
0x77633500 <Wow64Transition+71656>:  43  44  45  46  47  48  49  50 
0x77633510 <Wow64Transition+71672>:  51  52  53  54  55  56  57  58 
0x77633520 <Wow64Transition+71688>:  59  60  61  62  63  64  65  66 
0x77633530 <Wow64Transition+71704>:  67  68  69  70  0  71  72  73 
0x77633540 <Wow64Transition+71720>:  74  75  76  77  78  79  80  81 
0x77633550 <Wow64Transition+71736>:  82  83  84  85  86  87  88  89 
0x77633560 <Wow64Transition+71752>:  90  91  92  93  94  95  96  97 

는, 0의 순서가 수출된다. 이 이미지의 수출의 시작 서수 :

그러나 수출 디렉토리 테이블의 OrdinalBase 필드가 1로 설정되어 있는지 주어, 어떻게 서수 미만 1 개?

서수 자료가 될 수 있습니다. 이 필드는 내보내기 주소 테이블의 시작 서수를 지정합니다. 그것은 일반적으로 1

문서로 설정이 서수는

수출 순서 표는 수출 주소 테이블에 16 비트 인덱스의 배열입니다 : 즉, 바이어스 것을 말한다. 서수는 의 서수 기본 필드에 따라 바이어스됩니다. 다시 말하면 서수 기본 값은 주소 테이블에서 실제 인덱스를 얻기 위해 서수에서 뺀 이어야합니다.

이제 서수가 0이면 내보내기 주소 테이블에 -1의 인덱스가 생성됩니다. 서수 사전 조정처럼 내 관점에서

는 것 같습니다 (예 : 1 각에서 차감됩니다), 그러나 (또한 PE-문서에 명시) "공식적인"알고리즘이 실패

수출 이름 포인터 테이블을 검색하고 일치하는 문자열이 위치에서 발견되면 따라서

, 난, 심볼의 주소를 찾기위한 알고리즘은 다음과 같습니다

i = Search_ExportNamePointerTable (ExportName); 
ordinal = 
ExportOrdinalTable [i]; 
SymbolRVA = ExportAddressTable [ordinal - OrdinalBase]; 

난을 떠오르는 유일한 아이디어 다음과 같습니다. 로더는 DLL을 메모리에로드 할 때 내보내기 서수 테이블에서 서수를 조정했습니다.

아무도 설명을 줄 수 있습니까?

+0

그러나 기호 RVA를 찾는 PE 문서의 알고리즘은 무엇입니까? 이 알고리즘은 올바르지 않습니까? RVA 조회의 일부로 서수를 사용합니다. 또한 적절한 서수가 아니라면 서수 테이블에있는 숫자는 무엇입니까 (dumpbin을 사용하여 볼 수있는 것과 일치합니까?)? – Shuzheng

+0

또한 항목 0은 서수 4이지만 3을 표시하는 이유는 무엇입니까? – Shuzheng

+0

@HansPassant : 또한 각 서수에서 1 (OrdinalBase)를 뺍니까?이 질문에 답할 수 있다면 올해 크리스마스가 올 것입니다. – Shuzheng

답변

2

이것은 PE/COFF 사양에서 알려진 오류입니다. 지정된 알고리즘은 명백히 잘못이고, 서수 테이블이 실제로 편견 서수를 포함로는

ordinal = ExportOrdinalTable [i] + OrdinalBase; 

하지

ordinal = ExportOrdinalTable [i]; 

해야한다.

+0

감사합니다. 출처가 없습니까 아니면 개인적인 경험이 있습니까? – Shuzheng

+0

이전 프로젝트에 대한 PE 파서 및 로더 작성 경험 : –

+0

다음에 대해 생각해 보았습니다. 알고리즘이 DLL을 정적으로 검사하는 데 사용됩니까? DLL을 메모리에로드하면 ordinals가 변경되는 것처럼 보입니다. 348 (DUMPBIN을 사용하여 검증 됨)에서 347 (런타임에 검증 됨)으로 변경됩니다. 귀하의 신원은 어리석은 것처럼 보입니다 : ordinal = ExportOrdinalTable [i] + OrdinalBase; - OrdinalBase를 나중에 추가하면 왜 즉시 뺄까요? – Shuzheng