解析数据目录表
- 导出表
void AnalyzeExportsTabel(char* lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);
PIMAGE_DATA_DIRECTORY pExportDir = &pNt->OptionalHeader.DataDirectory[0];
DWORD dwExportFOA = RvaToFoa(lpImage, pExportDir->VirtualAddress);
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)(lpImage + dwExportFOA);
DWORD dwBase = pExport->Base;
DWORD EatFoa = RvaToFoa(lpImage,pExport->AddressOfFunctions);
DWORD EntFoa = RvaToFoa(lpImage, pExport->AddressOfNames);
DWORD EotFoa = RvaToFoa(lpImage, pExport->AddressOfNameOrdinals);
PDWORD pEat= (PDWORD)(lpImage + EatFoa);
PDWORD pEnt = (PDWORD)(lpImage + EntFoa);
PWORD pEot = (PWORD)(lpImage + EotFoa);
for (int i = 0; i < pExport->NumberOfFunctions; i++)
{
if (pEat[i] == 0)
{
continue;
}
int j = 0;
int nSign = FALSE;
for (; j < pExport->NumberOfNames; j++)
{
if (i == pEot[j])
{
nSign = TRUE;
break;
}
}
if (nSign== TRUE)
{
DWORD dwFunNameFOA = RvaToFoa(lpImage, pEnt[j]);
char* pFunName = lpImage + dwFunNameFOA;
printf("序号:%4x 地址:%x 名称:%s\n", i+ dwBase, pEat[i], pFunName);
}
else
{
printf("序号:%4x 地址:%x 名称:NULL\n", i + dwBase, pEat[i]);
}
}
}
- 导入表
void AnalyzeImportTabel(char* lpImage,bool bAnalyzeInt)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);
PIMAGE_DATA_DIRECTORY dwImportDir = &pNt->OptionalHeader.DataDirectory[1];
DWORD dwImportFOA = RvaToFoa(lpImage, dwImportDir->VirtualAddress);
PIMAGE_IMPORT_DESCRIPTOR pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)(lpImage + dwImportFOA);
while (pImportTable->Name!=0)
{
DWORD dwNameFoa = RvaToFoa(lpImage,pImportTable->Name);
char* pDllName = (char*)(dwNameFoa + lpImage);
printf("DllName:%s\n", pDllName);
PIMAGE_THUNK_DATA32 pNameTable = NULL;
if (bAnalyzeInt == true)
{
DWORD Foa = RvaToFoa(lpImage, pImportTable->OriginalFirstThunk);
pNameTable = (PIMAGE_THUNK_DATA32)(lpImage + Foa);
}
else
{
DWORD Foa = RvaToFoa(lpImage, pImportTable->FirstThunk);
pNameTable = (PIMAGE_THUNK_DATA32)(lpImage + Foa);
}
while (pNameTable->u1.Ordinal!=0)
{
if (IMAGE_SNAP_BY_ORDINAL32(pNameTable->u1.Ordinal)==1)
{
printf(" 序号:%x,名称:NULL\n", pNameTable->u1.Ordinal&0x7FFFFFFF);
}
else
{
DWORD dwNameFoa = RvaToFoa(lpImage, pNameTable->u1.AddressOfData);
PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(dwNameFoa + lpImage);
printf(" 序号:%x,名称:%s\n", pName->Hint,pName->Name);
}
pNameTable++;
}
printf("----------------------------\n");
pImportTable++;
}
}
- 资源表
map<int, const char*> g_mapResourceInfo;
map<const char*, const char*> abc;
void InitResourceInfo()
{
g_mapResourceInfo[0x1] = "Cursor";
g_mapResourceInfo[0x2] = "BitMap";
g_mapResourceInfo[0x3] = "Icon";
g_mapResourceInfo[0x4] = "Menu";
g_mapResourceInfo[0x5] = "Dialog";
g_mapResourceInfo[0x6] = "String Table";
g_mapResourceInfo[0x7] = "Font Directory";
g_mapResourceInfo[0x8] = "Font";
g_mapResourceInfo[0x9] = "Accelerators";
g_mapResourceInfo[0xA] = "UnFormatted";
g_mapResourceInfo[0xB] = "Message Table";
g_mapResourceInfo[0xC] = "Group Cursor";
g_mapResourceInfo[0xE] = "Group Icon";
g_mapResourceInfo[0x10] = "Version Information";
}
void AnalyzeResource(char* lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);
PIMAGE_OPTIONAL_HEADER pOption = &pNt->OptionalHeader;
PIMAGE_DATA_DIRECTORY pResourceDir= &pOption->DataDirectory[2];
DWORD dwResourceFOA = RvaToFoa(lpImage, pResourceDir->VirtualAddress);
PIMAGE_RESOURCE_DIRECTORY pFirstDir =(PIMAGE_RESOURCE_DIRECTORY)(dwResourceFOA + lpImage);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pFirstRes = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pFirstDir + 1);
DWORD dwFirstCount = pFirstDir->NumberOfIdEntries + pFirstDir->NumberOfNamedEntries;
for (int i = 0; i < dwFirstCount; i++)
{
if (pFirstRes[i].NameIsString == TRUE)
{
PIMAGE_RESOURCE_DIR_STRING_U pNameInfo =
(PIMAGE_RESOURCE_DIR_STRING_U)(pFirstRes[i].NameOffset + (DWORD)pFirstDir);
WCHAR* pName = new WCHAR[pNameInfo->Length + 1]{0};
for (int m = 0; m < pNameInfo->Length; m++)
{
pName[m] = pNameInfo->NameString[m];
}
wprintf(L"资源种类标识:%s\n", pName);
}
else
{
if (g_mapResourceInfo.count(pFirstRes[i].Id) == 1)
{
printf("资源种类标识%s\n", g_mapResourceInfo[pFirstRes[i].Id]);
}
else
{
printf("资源种类标识%d\n", pFirstRes[i].Id);
}
}
if (pFirstRes[i].DataIsDirectory == 1)
{
PIMAGE_RESOURCE_DIRECTORY pSecondDir =
(PIMAGE_RESOURCE_DIRECTORY)(pFirstRes[i].OffsetToDirectory + (DWORD)pFirstDir);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pSecondRes =
PIMAGE_RESOURCE_DIRECTORY_ENTRY(pSecondDir + 1);
DWORD dwSecondCount =
pSecondDir->NumberOfIdEntries + pSecondDir->NumberOfNamedEntries;
for (int j = 0; j < dwSecondCount; j++)
{
if (pSecondRes[j].NameIsString == TRUE)
{
PIMAGE_RESOURCE_DIR_STRING_U pNameInfo =
(PIMAGE_RESOURCE_DIR_STRING_U)(pSecondRes[j].NameOffset + (DWORD)pFirstDir);
WCHAR* pName = new WCHAR[pNameInfo->Length + 1]{ 0 };
for (int m = 0; m < pNameInfo->Length; m++)
{
pName[m] = pNameInfo->NameString[m];
}
wprintf(L" 资源标识:%s\n", pName);
}
else
{
wprintf(L" 资源标识:%d\n", pSecondRes[j].Id);
}
if (pSecondRes[j].DataIsDirectory == TRUE)
{
PIMAGE_RESOURCE_DIRECTORY pThirdDir =
(PIMAGE_RESOURCE_DIRECTORY)
(pSecondRes[j].OffsetToDirectory+ (DWORD)pFirstDir);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pThirdRes =
(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pThirdDir + 1);
PIMAGE_RESOURCE_DATA_ENTRY pData =
(PIMAGE_RESOURCE_DATA_ENTRY)(pThirdRes->OffsetToData + (DWORD)pFirstDir);
printf(" 资源的起始RVA:%x 资源的大小:%x\n", pData->OffsetToData, pData->Size);
unsigned char* pRes = (unsigned char *)
(RvaToFoa(lpImage, pData->OffsetToData) + lpImage);
printf(" ");
for (size_t m= 0; m < 10; m++)
{
printf("%x ", pRes[m]);
}
printf("\n");
}
}
}
}
}
- 重定位表
void AnalyzeReloc(char* lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);
PIMAGE_OPTIONAL_HEADER pOption = &pNt->OptionalHeader;
PIMAGE_DATA_DIRECTORY pRelocDir = &pOption->DataDirectory[5];
PIMAGE_BASE_RELOCATION pReloc =
(PIMAGE_BASE_RELOCATION)
(RvaToFoa(lpImage, pRelocDir->VirtualAddress)+ lpImage);
while (pReloc->SizeOfBlock!=0)
{
TYPEOFFSET* typeoffset = (TYPEOFFSET*)(pReloc + 1);
DWORD dwCount = (pReloc->SizeOfBlock - 8) / 2;
DWORD dwBeginRva = pReloc->VirtualAddress;
printf("----------------------------------\n");
for (int i = 0; i < dwCount; i++)
{
if (typeoffset[i].TYPE==3)
{
DWORD dwRelocRva = (dwBeginRva + typeoffset[i].OFFSET);
printf("要重定位的位置RVA:%p\n", dwRelocRva);
PDWORD pRelocData = (PDWORD)(RvaToFoa(lpImage, dwRelocRva) + lpImage);
printf("要重定位的数据:%p\n", *pRelocData);
}
else
{
printf("类型是%d", typeoffset[i].TYPE);
}
}
printf("----------------------------------\n");
pReloc = (PIMAGE_BASE_RELOCATION)((char*)pReloc + pReloc->SizeOfBlock);
}
}
- TLS
#include <iostream>
#include <Windows.h>
#pragma comment(linker, "/INCLUDE:__tls_used")
int g_nNum1 = 100;
_declspec(thread) int g_nNum2 = 200;
void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Red) {
if (DLL_PROCESS_ATTACH == Reason)
{
printf("i am a mimidaima!\r\n");
}
if (DLL_THREAD_DETACH == Reason)
printf("t_TlsCallBack_A -> ThreadDetach!\r\n");
return;
}
void NTAPI t_TlsCallBack_B(PVOID DllHandle, DWORD Reason, PVOID Red) {
if (DLL_THREAD_DETACH == Reason)
printf("t_TlsCallBack_B -> ThreadDetach!\r\n");
return;
}
#pragma data_seg(".CRT$XLB")
PIMAGE_TLS_CALLBACK p_thread_callback[] = {
t_TlsCallBack_A,
t_TlsCallBack_B,
NULL };
#pragma data_seg()
DWORD WINAPI t_ThreadFun(PVOID pParam) {
printf("%p ", &g_nNum1);
printf("%p\n", &g_nNum2);
return 0;
}
int main()
{
printf("%p ", &g_nNum1);
printf("%p\n", &g_nNum2);
HANDLE hThread = CreateThread(NULL, 0, t_ThreadFun, NULL, 0, 0);
WaitForSingleObject(hThread, -1);
return 0;
}
- 延迟载入
#include <iostream>
#include <windows.h>
#include <delayimp.h>
#pragma comment(lib, "Delayimp.lib")
int main()
{
std::cout << "Hello World!\n";
}
- 读取PE
HANDLE hFile = CreateFile(
PATH,
GENERIC_ALL,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
DWORD dwFileSize = GetFileSize(hFile, NULL);
char* buf = new char[dwFileSize] {0};
DWORD dwRealSize = 0;
ReadFile(hFile, buf, dwFileSize, &dwRealSize, NULL);
- 判断PE
BOOL IsPE_File(char* lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);
if (pNt->Signature != IMAGE_NT_SIGNATURE)
{
return FALSE;
}
return TRUE;
}
- RvaToFoa
DWORD RvaToFoa(char* lpImage, DWORD dwRva)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);
PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt);
if (dwRva < pNt->OptionalHeader.SizeOfHeaders)
{
return dwRva;
}
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
DWORD dwSectionRva = pHeader[i].VirtualAddress;
DWORD dwSectionEndRva = dwSectionRva + pHeader[i].SizeOfRawData;
DWORD dwSectionFOA = pHeader[i].PointerToRawData;
if (dwRva >= dwSectionRva && dwRva <= dwSectionEndRva)
{
pHeader[i].VirtualAddress;
DWORD dwFOA = dwRva - dwSectionRva + dwSectionFOA;
return dwFOA;
}
}
return -1;
}