DWORD MyLoadLibrary(LPBYTE pPEBuff, Environment
*
pEnv, LPBYTE pTableBuf, LPBYTE pMyImpBuf) {
DWORD dwImageBase;
HANDLE hFile;
HANDLE hFileMap;
LPVOID pPEBuf;
IMAGE_DOS_HEADER
*
pDosHdr;
IMAGE_NT_HEADERS
*
pNTHdr;
IMAGE_SECTION_HEADER
*
pSecHdr;
DWORD dwNumOfSecs;
IMAGE_IMPORT_DESCRIPTOR
*
pImpHdr;
DWORD dwSizeOfHeaders;
IMAGE_IMPORT_DESCRIPTOR hdrZeroImp;
HMODULE hDll;
DWORD dwOep;
DWORD dwOldProc;
IMAGE_BASE_RELOCATION
*
pReloc;
DWORD dwOfReloc;
DWORD dwOff;
/
/
RtlZeroMemory(&hdrZeroImp, sizeof(IMAGE_IMPORT_DESCRIPTOR));
pPEBuf
=
pPEBuff;
/
/
解析
/
/
dos 头
pDosHdr
=
(IMAGE_DOS_HEADER
*
)pPEBuf;
/
/
nt头
pNTHdr
=
(IMAGE_NT_HEADERS
*
)(pDosHdr
-
>e_lfanew
+
(DWORD)pPEBuf);
/
/
还原节表
DWORD nSecNum
=
*
(DWORD
*
)pTableBuf;
mymemcpy((void
*
)((DWORD)&pNTHdr
-
>OptionalHeader
+
pNTHdr
-
>FileHeader.SizeOfOptionalHeader),
pTableBuf
+
4
, nSecNum
*
40
);
/
/
还原导入表
mymemcpy(&(pNTHdr
-
>OptionalHeader.DataDirectory[
1
].VirtualAddress),
pTableBuf
+
4
+
nSecNum
*
40
,
4
);
mymemcpy(&(pNTHdr
-
>OptionalHeader.DataDirectory[
1
].Size),
pTableBuf
+
4
+
nSecNum
*
40
+
4
,
4
);
/
/
还原重定位表
mymemcpy(&(pNTHdr
-
>OptionalHeader.DataDirectory[
5
].VirtualAddress),
pTableBuf
+
4
+
nSecNum
*
40
+
4
+
4
,
4
);
mymemcpy(&(pNTHdr
-
>OptionalHeader.DataDirectory[
5
].Size),
pTableBuf
+
4
+
nSecNum
*
40
+
4
+
4
+
4
,
4
);
/
/
选项头信息
dwSizeOfHeaders
=
pNTHdr
-
>OptionalHeader.SizeOfHeaders;
/
/
自己的模块基址
dwImageBase
=
(DWORD)GetModuleBase();
dwOff
=
dwImageBase
-
pNTHdr
-
>OptionalHeader.ImageBase;
/
/
新旧ImageBase的偏移差
dwOep
=
pNTHdr
-
>OptionalHeader.AddressOfEntryPoint
+
dwImageBase;
/
/
节表
dwNumOfSecs
=
pNTHdr
-
>FileHeader.NumberOfSections;
pSecHdr
=
(IMAGE_SECTION_HEADER
*
)((DWORD)&pNTHdr
-
>OptionalHeader
+
pNTHdr
-
>FileHeader.SizeOfOptionalHeader);
/
/
拷贝PE头
VirtualProtect((LPVOID)dwImageBase, pNTHdr
-
>OptionalHeader.SizeOfHeaders, PAGE_EXECUTE_READWRITE, &dwOldProc);
mymemcpy((void
*
)dwImageBase, pPEBuf, dwSizeOfHeaders);
VirtualProtect((LPVOID)dwImageBase, pNTHdr
-
>OptionalHeader.SizeOfHeaders, dwOldProc, &dwOldProc);
/
/
按照节表,拷贝节区数据
int
i
=
0
;
IMAGE_SECTION_HEADER
*
dwSecTmp
=
pSecHdr;
while
(i < dwNumOfSecs) {
/
/
目标
DWORD dwDstMem
=
dwImageBase;
dwDstMem
+
=
dwSecTmp
-
>VirtualAddress;
/
/
源
DWORD dwSrcFile
=
(DWORD)pPEBuf
+
dwSecTmp
-
>PointerToRawData;
/
/
拷贝
VirtualProtect((LPVOID)dwDstMem, dwSecTmp
-
>SizeOfRawData, PAGE_EXECUTE_READWRITE, &dwOldProc);
mymemcpy((void
*
)dwDstMem, (void
*
)dwSrcFile, dwSecTmp
-
>SizeOfRawData);
VirtualProtect((LPVOID)dwImageBase, pNTHdr
-
>OptionalHeader.SizeOfHeaders, dwOldProc, &dwOldProc);
i
+
+
;
dwSecTmp
=
(IMAGE_SECTION_HEADER
*
)((char
*
)dwSecTmp
+
sizeof(IMAGE_SECTION_HEADER));
}
/
/
获取导入表
if
(pNTHdr
-
>OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress !
=
0
) {
pImpHdr
=
(IMAGE_IMPORT_DESCRIPTOR
*
)(dwImageBase
+
pNTHdr
-
>OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
/
/
处理导入表
IMAGE_IMPORT_DESCRIPTOR
*
pImpHdrTmp
=
pImpHdr;
DWORD dwNum
=
0
;
int
nImpNum
=
0
;
while
(true) {
/
/
判断结束,全
0
项结束
if
(memcmp(pImpHdrTmp, &hdrZeroImp, sizeof(IMAGE_IMPORT_DESCRIPTOR))
=
=
0
) {
break
;
}
/
/
判断字段, 为空则结束
if
(pImpHdrTmp
-
>Name
=
=
NULL || pImpHdrTmp
-
>FirstThunk
=
=
NULL) {
break
;
}
/
/
加载dll
hDll
=
pEnv
-
>pfnLoadLibraryA((LPCSTR)(dwImageBase
+
pImpHdrTmp
-
>Name));
/
/
获取导入地址表, IAT
DWORD dwIAT
=
pImpHdrTmp
-
>FirstThunk
+
dwImageBase;
DWORD dwINT
=
dwIAT;
/
/
获取导入名称表,
INT
if
(pImpHdrTmp
-
>OriginalFirstThunk !
=
NULL) {
dwINT
=
pImpHdrTmp
-
>OriginalFirstThunk
+
dwImageBase;
}
/
/
遍历导入名称表
while
(
*
(DWORD
*
)(dwINT) !
=
0
) {
if
((
*
(DWORD
*
)pImpHdrTmp) >>
31
) {
/
/
序号导入, 获取序号
dwNum
=
*
(DWORD
*
)pImpHdrTmp;
dwNum
=
(dwNum <<
16
) >>
16
;
}
else
{
/
/
名称导入
dwNum
=
*
(DWORD
*
)pImpHdrTmp;
dwNum
+
=
dwImageBase;
dwNum
+
=
2
;
}
/
/
获取函数地址后,先不要把地址直接写入IAT
/
/
而是先将.imp节地址写入IAT(每
16
个字节写一次)
/
/
在.imp节里写代码指令push 函数地址 retn
/
/
如果函数名是_acmdln,那么这里就不要混淆导入表
if
(((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
0
]
=
=
'_'
&& ((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
1
]
=
=
'a'
&&
((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
2
]
=
=
'c'
&& ((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
3
]
=
=
'm'
&&
((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
4
]
=
=
'd'
&& ((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
5
]
=
=
'l'
&&
((LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
))[
6
]
=
=
'n'
) {
*
(DWORD
*
)dwIAT
=
(DWORD)pEnv
-
>pfnGetProcAddress(hDll, (LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
));
}
else
{
DWORD dwMyAddr
=
(DWORD)pMyImpBuf
+
nImpNum
*
0x10
;
DWORD dwFuncAddr
=
(DWORD)pEnv
-
>pfnGetProcAddress(hDll, (LPCSTR)((
*
(DWORD
*
)(dwINT))
+
dwImageBase
+
2
));
*
(DWORD
*
)dwIAT
=
dwMyAddr;
*
(BYTE
*
)dwMyAddr
=
0x68
;
/
/
push
*
(DWORD
*
)(dwMyAddr
+
1
)
=
dwFuncAddr;
/
/
真实函数地址
*
(BYTE
*
)(dwMyAddr
+
5
)
=
0xC3
;
/
/
retn
}
dwIAT
+
=
4
;
dwINT
+
=
4
;
nImpNum
+
+
;
}
pImpHdrTmp
=
(IMAGE_IMPORT_DESCRIPTOR
*
)((char
*
)pImpHdrTmp
+
sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
}
if
(pNTHdr
-
>OptionalHeader.DataDirectory[
5
].VirtualAddress !
=
0
) {
/
/
定位重定位表
pReloc
=
(IMAGE_BASE_RELOCATION
*
)(pNTHdr
-
>OptionalHeader.DataDirectory[
5
].VirtualAddress
+
dwImageBase);
dwOfReloc
=
pNTHdr
-
>OptionalHeader.DataDirectory[
5
].Size;
int
nSize
=
0
;
while
(nSize < dwOfReloc) {
/
/
数组首地址
int
nOff
=
(DWORD)pReloc
+
8
;
/
/
数组元素个数
int
nCnt
=
(pReloc
-
>SizeOfBlock
-
8
) >>
1
;
/
/
遍历数组
int
j
=
0
;
while
(j < nCnt) {
/
/
取出一项
int
nDataOff
=
*
(WORD
*
)(nOff
+
j
*
2
);
/
/
判断是否是有效重定位项
if
(nDataOff &
0x00003000
) {
/
/
修正
nDataOff
=
nDataOff &
0x0fff
;
/
/
页偏移
nDataOff
=
nDataOff
+
pReloc
-
>VirtualAddress;
nDataOff
=
nDataOff
+
dwImageBase;
*
(
int
*
)nDataOff
=
*
(
int
*
)nDataOff
+
dwOff;
}
j
+
+
;
}
/
/
处理下一个分页
nSize
+
=
pReloc
-
>SizeOfBlock;
pReloc
=
(IMAGE_BASE_RELOCATION
*
)((char
*
)pReloc
+
pReloc
-
>SizeOfBlock);
}
}
return
dwOep;
}