DWORD CPEedit::shiftReloc(LPBYTE pPeBuf, size_t oldImageBase, size_t newImageBase, DWORD offset,
bool
bMemAlign)
{
/
/
修复重定位,其实此处pShellBuf为hShell副本
DWORD all_num
=
0
;
DWORD sumsize
=
0
;
auto pRelocEntry
=
&getImageDataDirectory(pPeBuf)[IMAGE_DIRECTORY_ENTRY_BASERELOC];
while
(sumsize < pRelocEntry
-
>Size)
{
auto pBaseRelocation
=
(PIMAGE_BASE_RELOCATION)(pPeBuf
+
sumsize
+
(bMemAlign ? pRelocEntry
-
>VirtualAddress :
rva2faddr(pPeBuf, pRelocEntry
-
>VirtualAddress)));
auto pRelocOffset
=
(PRELOCOFFSET)
((LPBYTE)pBaseRelocation
+
sizeof(IMAGE_BASE_RELOCATION));
DWORD item_num
=
(pBaseRelocation
-
>SizeOfBlock
-
sizeof(IMAGE_BASE_RELOCATION))
/
sizeof(RELOCOFFSET);
for
(
int
i
=
0
; i < item_num; i
+
+
)
{
if
(pRelocOffset[i].offset
=
=
0
)
continue
;
DWORD toffset
=
pRelocOffset[i].offset
+
pBaseRelocation
-
>VirtualAddress;
if
(!bMemAlign) toffset
=
rva2faddr(pPeBuf, toffset);
/
/
新的重定位地址
=
重定位后的地址(VA)
-
加载时的镜像基址(hModule VA)
+
新的镜像基址(VA)
+
新代码基址RVA(前面用于存放压缩的代码)
/
/
由于讲dll附加在后面,需要在dll shell中的重定位加上偏移修正
*
(PULONGLONG)(pPeBuf
+
toffset)
+
=
newImageBase
-
oldImageBase
+
offset;
/
/
重定向每一项地址
/
/
printf(
"%08lX -> "
,
*
(PDWORD)(pPeBuf
+
toffset));
*
(PDWORD)(pPeBuf
+
toffset)
+
=
newImageBase
-
oldImageBase
+
offset;
/
/
重定向每一项地址
/
/
printf(
"%08lX\n"
,
*
(PDWORD)(pPeBuf
+
toffset));
}
pBaseRelocation
-
>VirtualAddress
+
=
offset;
/
/
重定向页表基址
sumsize
+
=
sizeof(RELOCOFFSET)
*
item_num
+
sizeof(IMAGE_BASE_RELOCATION);
all_num
+
=
item_num;
}
return
all_num;
}
DWORD CPEedit::shiftOft(LPBYTE pPeBuf, DWORD offset,
bool
bMemAlign,
bool
bResetFt)
{
auto pImportEntry
=
&getImageDataDirectory(pPeBuf)[IMAGE_DIRECTORY_ENTRY_IMPORT];
DWORD dll_num
=
pImportEntry
-
>Size
/
sizeof(IMAGE_IMPORT_DESCRIPTOR);
/
/
导入dll的个数,含最后全为空的一项
DWORD func_num
=
0
;
/
/
所有导入函数个数,不包括全
0
的项
auto pImportDescriptor
=
(PIMAGE_IMPORT_DESCRIPTOR) (pPeBuf
+
(bMemAlign ? pImportEntry
-
>VirtualAddress :
rva2faddr(pPeBuf, pImportEntry
-
>VirtualAddress)));
/
/
指向第一个dll
for
(
int
i
=
0
; i < dll_num; i
+
+
)
{
if
(pImportDescriptor[i].OriginalFirstThunk
=
=
0
)
continue
;
auto pOFT
=
(PIMAGE_THUNK_DATA)(pPeBuf
+
(bMemAlign ?
pImportDescriptor[i].OriginalFirstThunk:
rva2faddr(pPeBuf, pImportDescriptor[i].OriginalFirstThunk)));
auto pFT
=
(PIMAGE_THUNK_DATA)(pPeBuf
+
(bMemAlign ?
pImportDescriptor[i].FirstThunk :
rva2faddr(pPeBuf, pImportDescriptor[i].FirstThunk)));
DWORD item_num
=
0
;
for
(
int
j
=
0
; pOFT[j].u1.AddressOfData !
=
0
; j
+
+
)
{
item_num
+
+
;
/
/
一个dll中导入函数的个数,不包括全
0
的项
if
((pOFT[j].u1.Ordinal >>
31
) !
=
0x1
)
/
/
不是用序号
{
pOFT[j].u1.AddressOfData
+
=
offset;
if
(bResetFt) pFT[j].u1.AddressOfData
=
pOFT[j].u1.AddressOfData;
}
}
pImportDescriptor[i].OriginalFirstThunk
+
=
offset;
pImportDescriptor[i].FirstThunk
+
=
offset;
pImportDescriptr[i].Name
+
=
offset;
func_num
+
=
item_num;
}
return
func_num;
}