से फ़ाइल में ऑफ़सेट हो रहा है मैं एक पीई फ़ाइल पढ़ने की कोशिश कर रहा हूं।
समस्या यह है कि डेटा आरवीए पॉइंटर्स का उपयोग करता है, जबकि मुझे फ़ाइल की आवश्यकता होती है, मुझे फ़ाइल
में ऑफसेट की आवश्यकता होती है। मैं आरवीए को फ़ाइल में ऑफ़सेट करने के लिए कैसे परिवर्तित कर सकता हूं?आरवीए
आरवीए
उत्तर
फ़ाइल RVA की भरपाई का निर्धारण करने के लिए, आप की जरूरत:
- जिसमें खंड अंक RVA निर्धारित करने के लिए। अनुभाग
- का अपना पता रिश्तेदार वर्चुअल ऐड्रेस से
- घटाना फ़ाइल अनुभाग
आप एक फ़ाइल ऑफसेट कि आप की आवश्यकता प्राप्त होगा की भरपाई परिणाम में जोड़ें।
file Offset = RVAOfData - Virtual Offset + Raw Offset
उदाहरण:
हमारे संसाधन अनुभाग (".rsrc") का विवरण:
वर्चुअल ऑफसेट: F000
कच्चे ऑफसेट: C600
चलें संसाधन में से एक पर देखो हमारे पास है:
नाम: बीआईएन
डेटा का आरवीए: F0B0
फाइल ऑफ़सेट:?
fileOffset = RVAOfData - Virtual Offset + Raw Offset
=> C6B0 = F0B0 - F000 + C600
फ़ाइल ऑफ़सेट: C6B0
संदर्भ:
Understanding RVAs and Import Tables - by Sunshine
सी # में फंक्शन:
// Example:
// RVA: F0B0
// Virtual offset: F000 ("RVA" in PEview)
// Raw offset: C600 ("Pointer to Raw Data" in PEview)
// fileOffset = F0B0 - F000 + C600 = C6B0
private static uint rvaToFileOffset(uint i_Rva, uint i_VirtualOffset, uint i_RawOffset)
{
return (i_Rva - i_VirtualOffset + i_RawOffset);
}
उदाहरण के नीचे आरवीए से प्रवेश बिंदु के पते की फ़ाइल ऑफ़सेट देता है। आरवीए से डिस्क डिस्क ऑफसेट प्राप्त करने के लिए कोई भी पॉइंटर पास कर सकता है।
असल में हमें यह पता लगाने की आवश्यकता है कि पता किस अनुभाग से संबंधित है। एक बार सही अनुभाग की पहचान हो जाने के बाद ऑफ़सेट प्राप्त करने के लिए सूत्र का उपयोग करें।
DWORD retAddr = ptr - (sectionHeader-> VirtualAddress) +
(sectionHeader-> PointerToRawData);
तो भौतिक पता
retAddr + (PBYTE) प्राप्त करने के लिए फ़ाइल आधार पता जोड़ने lpFileBase
LPCSTR fileName="exe_file_to_parse";
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
PIMAGE_NT_HEADERS peHeader;
PIMAGE_SECTION_HEADER sectionHeader;
hFile = CreateFileA(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile==INVALID_HANDLE_VALUE)
{
printf("\n CreateFile failed in read mode \n");
return 1;
}
hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(hFileMapping==0)
{
printf("\n CreateFileMapping failed \n");
CloseHandle(hFile);
return 1;
}
lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0); // Base pointer to file
if(lpFileBase==0)
{
printf("\n MapViewOfFile failed \n");
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 1;
}
dosHeader = (PIMAGE_DOS_HEADER) lpFileBase; //pointer to dos headers
if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE)
{
//if it is executable file print different fileds of structure
//dosHeader->e_lfanew : RVA for PE Header
printf("\n DOS Signature (MZ) Matched");
//pointer to PE/NT header
peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew);
if(peHeader->Signature==IMAGE_NT_SIGNATURE)
{
printf("\n PE Signature (PE) Matched \n");
// valid executable so we can proceed
//address of entry point
DWORD ptr = peHeader->OptionalHeader.AddressOfEntryPoint;
//instead of AEP send any pointer to get actual disk offset of it
printf("\n RVA : %x \n",ptr); // this is in memory address i.e. RVA
//suppose any one wants to know actual disk offset of "address of entry point" (AEP)
sectionHeader = IMAGE_FIRST_SECTION(peHeader); //first section address
UINT nSectionCount = peHeader->FileHeader.NumberOfSections;
UINT i=0;
//check in which section the address belongs
for(i=0; i<=nSectionCount; ++i, ++sectionHeader)
{
if((sectionHeader->VirtualAddress) > ptr)
{
sectionHeader--;
break;
}
}
if(i>nSectionCount)
{
sectionHeader = IMAGE_FIRST_SECTION(peHeader);
UINT nSectionCount = peHeader->FileHeader.NumberOfSections;
for(i=0; i<nSectionCount-1; ++i,++sectionHeader);
}
//once the correct section is found below formula gives the actual disk offset
DWORD retAddr = ptr - (sectionHeader->VirtualAddress) +
(sectionHeader->PointerToRawData);
printf("\n Disk Offset : %x \n",retAddr+(PBYTE)lpFileBase);
// retAddr+(PBYTE)lpFileBase contains the actual disk offset of address of entry point
}
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
//getchar();
return 0;
}
else
{
printf("\n DOS Signature (MZ) Not Matched \n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return 1;
}
क्या आप अपने कोड में कुछ टिप्पणियां जोड़ सकते हैं? –
ने कुछ विवरण और साथ ही टिप्पणी भी जोड़े। –
मान लीजिए आप फ़ाइल से इसे पढ़ा नहीं कर सकता है, कैसे पीई लोडर करता है काम? – harold
मुझे नहीं पता ... क्या यह अनचाहे जानकारी दिखाता है? और अगर मैं इसे फाइल से पढ़ सकता हूं, तो पता ऑफसेट से क्या पता चला है? – Idov
मेरी जानकारी के अनुसार, वे छविबेस (शीर्षलेख में) – harold