PETOOL开发日记3 - Directory解析

本文最后更新于:2022年4月13日 下午

本节将进一步完善PE TOOL的功能,添加对PE头的Directory解析。

接上文,本节将完成的是目录按钮背后的功能。

image-20220110214822067

点击目录按钮,将会弹出如下对话框:

image-20220110214959698

该对话框的消息处理函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
BOOL CALLBACK DirDialogProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_INITDIALOG :
{
InitDirectoryView(hwndDlg);
return TRUE ;
}
case WM_COMMAND :
{
switch (LOWORD (wParam))
{
case IDC_BUTTON_DIR_CLOSE :
{
EndDialog(hwndDlg, 0);
return TRUE;
}
case IDC_BUTTON_DIR_IMPORT :
{
detailDirNum = IMPORT_DETAIL;
DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_DIALOG_DETAIL),hwndDlg,DirDetailDialogProc);
return TRUE;
}
case IDC_BUTTON_DIR_EXPORT :
{
detailDirNum = EXPORT_DETAIL;
DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_DIALOG_DETAIL),hwndDlg,DirDetailDialogProc);
return TRUE;
}
case IDC_BUTTON_DIR_RESOURCE :
{
detailDirNum = RESOURCE_DETAIL;
DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_DIALOG_DETAIL),hwndDlg,DirDetailDialogProc);
return TRUE;
}
case IDC_BUTTON_DIR_RELOC :
{
detailDirNum = RELOCATION_DETAIL;
DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_DIALOG_DETAIL),hwndDlg,DirDetailDialogProc);
return TRUE;
}

}
return FALSE;
}
case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
return TRUE;
}
}
return FALSE;
}

该对话框的初始函数是InitDirectoryView,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
VOID InitDirectoryView(HWND hwndDlg)
{
ReadPEFile(szFileName, &pFileBuffer);
pDosHeader = (PIMAGE_DOS_HEADER) pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS) ((DWORD) pFileBuffer + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER) (((DWORD) pNTHeader) + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32) ((DWORD) pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_DATA_DIRECTORY dirHeader = pOptionHeader->DataDirectory;

TCHAR strBuffer[0x20];

sprintf(strBuffer, _T("0x%08X"), dirHeader[0].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_EXPORT_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[1].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_IMPORT_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[2].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_RESOURCE_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[3].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_EXCEPTION_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[4].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_SEC_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[5].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_RELOC_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[6].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_DEBUG_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[7].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_COPYRIGHT_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[8].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_GPOINTER_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[9].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_TLS_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[10].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_IMPORTCONF_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[11].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_BINDIMPORT_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[12].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_IAT_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[13].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_POSTIMPORT_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[14].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_COM_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%08X"), dirHeader[15].VirtualAddress);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_RESERVE_RVA, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));
//----------------------------------------------------------//
sprintf(strBuffer, _T("0x%X"), dirHeader[0].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_EXPORT_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[1].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_IMPORT_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[2].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_RESOURCE_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[3].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_EXCEPTION_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[4].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_SEC_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[5].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_RELOC_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[6].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_DEBUG_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[7].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_COPYRIGHT_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[8].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_GPOINTER_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[9].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_TLS_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[10].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_IMPORTCONF_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[11].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_BINDIMPORT_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[12].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_IAT_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[13].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_POSTIMPORT_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[14].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_COM_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));

sprintf(strBuffer, _T("0x%X"), dirHeader[15].Size);
SetDlgItemText(hwndDlg,IDC_EDIT_DIR_RESERVE_SIZE, strBuffer);
memset(strBuffer,0x20 ,sizeof(TCHAR));
}

接下来还需要给处理几个按钮的逻辑,以便查看诸如导入表和导出表之类的重要表的详细信息。六个按钮调出的对话框使用的是同一个消息处理函数DirDetailDialogProc。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
BOOL CALLBACK DirDetailDialogProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_INITDIALOG :
{
switch(detailDirNum)
{

case IMPORT_DETAIL:
{
LPSTR detail = GetImport(szFileName);
SetDlgItemText(hwndDlg,IDC_EDIT_DETAIL, detail);
return TRUE ;
}
case EXPORT_DETAIL:
{
LPSTR detail = GetExport(szFileName);
SetDlgItemText(hwndDlg,IDC_EDIT_DETAIL, detail);
return TRUE ;
}
case RESOURCE_DETAIL:
{
LPSTR detail = GetResource(szFileName);
SetDlgItemText(hwndDlg,IDC_EDIT_DETAIL, detail);
return TRUE ;
}
case RELOCATION_DETAIL:
{
LPSTR detail = GetRelocation(szFileName);
SetDlgItemText(hwndDlg,IDC_EDIT_DETAIL, detail);
return TRUE ;
}

}

}

case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
return TRUE;
}
}
return FALSE;
}

这里用上了之前解析PE文件时的代码。

最终完成的效果如下:

image-20220110215915612

image-20220110215934533

本节难度不高,主要是一个个在Edit Control控件中输入数据耗费了较多时间。


PETOOL开发日记3 - Directory解析
https://m0ck1ng-b1rd.github.io/2022/02/20/二进制/PE Tool 开发日记 3 - Directory解析/
作者
何语灵
发布于
2022年2月20日
许可协议