能力值:
( LV4,RANK:50 )
2 楼
莫非, 这些地址只与低位有关?
似乎是这样了.明白了.
能力值:
( LV4,RANK:50 )
3 楼
如果用这个奇怪的SecionHeadedr, 在获得SectionHeader[i].Name的时候
能正确运行, 反而是我象下面处理了的不能访问:
UINT32 Mask = 0xffff;
SectionHeader =(PIMAGE_SECTION_HEADER)((UINT32)
(SectionHeader) & Mask);
更郁闷的问题是, 继续用这个奇怪的SectionHeader搞ImportTable时出错了:
int Offset = (int) (SectionHeader->VirtualAddress -
SectionHeader->PointerToRawData);
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)(NtHeader->
OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress-
Offset + NtHeader->OptionalHeader.ImageBase);
ThunkData = (PIMAGE_THUNK_DATA)(pImportDesc->
OriginalFirstThunk - Offset +
NtHeader->OptionalHeader.ImageBase);
ImportBN = (PIMAGE_IMPORT_BY_NAME)(ThunkData - Offset +
NtHeader->OptionalHeader.ImageBase);
wsprintf(szError,"%s",ImportBN->Name);
MessageBox(hwnd,szError,"ERROR",MB_OK);
这段程序在wsprintf(szError,"%s",ImportBN->Name); 时出错
跟踪时发现, 那个Offset = 0 .
这是为什么?
能力值:
(RANK:410 )
4 楼
最初由 Casimodo 发布 代码如下: HANDLE hFile; HANDLE hMapFile; LPVOID pMapping; OPENFILENAME ofn; ........
不明白,如果你用CreateFileMapping和MapViewOfFile成功的话,pMapping的指针怎么会是0呢?只有创建失败才会是0。你得出的0f00000h地址,正是MapViewOfFile成功后返回的映像地址。
能力值:
( LV4,RANK:50 )
5 楼
完了, 是我把pMapping的含义理解错了.
那么哪个Offset为什么会是0?
我的RVA转化错了么?
能力值:
( LV9,RANK:780 )
6 楼
假设我们要列出某个PE文件的所有引入函数,可以照着下面步骤走:
1.校验文件是否是有效的PE。
2.从 DOS header 定位到 PE header。
3.获取位于 OptionalHeader 数据目录地址。
4.转至数据目录的第二个成员提取其VirtualAddress值。
5.利用上值定位第一个 IMAGE_IMPORT_DESCRIPTOR 结构。
6.检查 OriginalFirstThunk值。若不为0,顺着 OriginalFirstThunk 里的RVA值转入那个RVA数组。若 OriginalFirstThunk 为0,就改用 FirstThunk值。有些连接器生成PE文件时会置OriginalFirstThunk值为0,这应该算是个bug。不过为了安全起见,我们还是检查 OriginalFirstThunk值先。
7.对于每个数组元素,我们比对元素值是否等于IMAGE_ORDINAL_FLAG32。如果该元素值的最高二进位为1, 那么函数是由序数引入的,可以从该值的低字节提取序数。
8.如果元素值的最高二进位为0,就可将该值作为RVA转入 IMAGE_IMPORT_BY_NAME 数组,跳过 Hint 就是函数名字了。
再跳至下一个数组元素提取函数名一直到数组底部(它以null结尾)。现在我们已遍历完一个DLL的引入函数,接下去处理下一个DLL。
即跳转到下一个 IMAGE_IMPORT_DESCRIPTOR 并处理之,如此这般循环直到数组见底。(IMAGE_IMPORT_DESCRIPTOR 数组以一个全0域元素结尾)
能力值:
( LV8,RANK:130 )
7 楼
关键在于你再写程序的时候牢记PE Header里的地址都是RVA,相对ImageBase的,不是你的process里的VA---实际地址。
IMAGE_NT_HEADERS32 PEHeader = pMapping + dosHeader->e_lfanew;
// your code to check the validity of PE header ...
// do not handle x64 PE files at this moment
if( IMAGE_NT_SIGNATURE != PEHeader->Signature ||
IMAGE_FILE_MACHINE_I386 != (PEHeader->FileHeader).Machine ||
IMAGE_NT_OPTIONAL_HDR32_MAGIC != (PEHeader->OptionalHeader).Magic ||
200 >= (PEHeader->FileHeader).NumberOfSections )
{
// do something as it's corrupted PE,... return E_INVALIDARG;
}
PIMAGE_SECTION_HEADER pSectionHeader = PEHeader + sizeof(IMAGE_NT_HEADERS32);
// your code to browse IAT/EAT ...