一般而言要注入DLL到一个目标进程最简单的方法 就是先获取DLL文件路径,然后在目标进程分配内存空间将路径写入到目标进程,写入到目标进程后再调用CreateRemoteThread()/NtCreateThread()/RtlCreateUserThread()函数来运行LoadLibraryA/W函数调用自己的DLL,这种方法的缺陷也很明显那就是容易被游戏检测到,很容易被游戏拦截,比如CSGO最新版就已经有这个限制了。
想要突破CSGO的限制注入DLL进去,我们可以采用反射式注入的方法(也可以先恢复CSGOhook的api进行远程线程注入),那么什么是反射式注入呢?又有什么有点呢?
反射式dll注入与常规dll注入类似,而不同的地方在于反射式dll注入技术自己实现了一个reflective loader()函数来代替LoadLibaryA()函数去加载dll,示意图如下图所示。蓝色的线表示与用常规dll注入相同的步骤,红框中的是reflective loader()函数行为,也是下面重点描述的地方。
Reflective loader实现思路如下:
1.获得被注入进程未解析的dll的基地址。
2.获得必要的dll句柄和函数为修复导入表做准备。
3.分配一块新内存去取解析dll,并把pe头复制到新内存中和将各节复制到新内存中。
4.修复导入表和重定向表。
5.执行DllMain()函数。
核心代码如下:
ManualMapInject.h
ManualMapInject.cpp
运行效果如下:
using f_LoadLibraryA
=
HINSTANCE(WINAPI
*
)(const char
*
lpLibFilename);
using f_GetProcAddress
=
FARPROC(WINAPI
*
)(HMODULE hModule, LPCSTR lpProcName);
using f_DLL_ENTRY_POINT
=
BOOL
(WINAPI
*
)(void
*
hDll, DWORD dwReason, void
*
pReserved);
using f_RtlAddFunctionTable
=
BOOL
(WINAPIV
*
)(PRUNTIME_FUNCTION FunctionTable, DWORD EntryCount, DWORD64 BaseAddress);
struct MANUAL_MAPPING_DATA
{
f_LoadLibraryA pLoadLibraryA;
f_GetProcAddress pGetProcAddress;
f_RtlAddFunctionTable pRtlAddFunctionTable;
BYTE
*
pbase;
HINSTANCE hMod;
DWORD fdwReasonParam;
LPVOID reservedParam;
BOOL
SEHSupport;
};
/
/
Note: Exception support only x64 with build params
/
EHa
or
/
EHc
bool
ManualMapDll(HANDLE hProc, BYTE
*
pSrcData, SIZE_T FileSize,
bool
ClearHeader
=
true,
bool
ClearNonNeededSections
=
true,
bool
AdjustProtections
=
true,
bool
SEHExceptionSupport
=
true, DWORD fdwReason
=
DLL_PROCESS_ATTACH, LPVOID lpReserved
=
0
);
void __stdcall Shellcode(MANUAL_MAPPING_DATA
*
pData);
class
CManualMapInject :public CInjector
{
public:
CManualMapInject();
virtual ~CManualMapInject();
virtual
bool
InjectorDLL(TCHAR
*
szPath,DWORD dwPid);
};
using f_LoadLibraryA
=
HINSTANCE(WINAPI
*
)(const char
*
lpLibFilename);
using f_GetProcAddress
=
FARPROC(WINAPI
*
)(HMODULE hModule, LPCSTR lpProcName);
using f_DLL_ENTRY_POINT
=
BOOL
(WINAPI
*
)(void
*
hDll, DWORD dwReason, void
*
pReserved);
using f_RtlAddFunctionTable
=
BOOL
(WINAPIV
*
)(PRUNTIME_FUNCTION FunctionTable, DWORD EntryCount, DWORD64 BaseAddress);
struct MANUAL_MAPPING_DATA
{
f_LoadLibraryA pLoadLibraryA;
f_GetProcAddress pGetProcAddress;
f_RtlAddFunctionTable pRtlAddFunctionTable;
BYTE
*
pbase;
HINSTANCE hMod;
DWORD fdwReasonParam;
LPVOID reservedParam;
BOOL
SEHSupport;
};
/
/
Note: Exception support only x64 with build params
/
EHa
or
/
EHc
bool
ManualMapDll(HANDLE hProc, BYTE
*
pSrcData, SIZE_T FileSize,
bool
ClearHeader
=
true,
bool
ClearNonNeededSections
=
true,
bool
AdjustProtections
=
true,
bool
SEHExceptionSupport
=
true, DWORD fdwReason
=
DLL_PROCESS_ATTACH, LPVOID lpReserved
=
0
);
void __stdcall Shellcode(MANUAL_MAPPING_DATA
*
pData);
class
CManualMapInject :public CInjector
{
public:
CManualMapInject();
virtual ~CManualMapInject();
virtual
bool
InjectorDLL(TCHAR
*
szPath,DWORD dwPid);
};
CManualMapInject::CManualMapInject()
{
}
CManualMapInject::~CManualMapInject()
{
}
bool
CManualMapInject::InjectorDLL(TCHAR
*
szPath, DWORD dwPid)
{
HANDLE hProc
=
GetProcessHandle(dwPid);
if
(!hProc || !IsCorrectTargetArchitecture(hProc) || GetFileAttributes(szPath)
=
=
INVALID_FILE_ATTRIBUTES)
{
return
false;
}
/
/
std::ifstream
File
(szPath, std::ios::binary | std::ios::ate);
/
/
/
/
if
(
File
.fail())
/
/
{
/
/
printf(
"Opening the file failed: %X\n"
, (DWORD)
File
.rdstate());
/
/
File
.close();
/
/
CloseHandle(hProc);
/
/
system(
"PAUSE"
);
/
/
return
-
5
;
/
/
}
/
/
/
/
auto FileSize
=
File
.tellg();
/
/
if
(FileSize <
0x1000
)
/
/
{
/
/
printf(
"Filesize invalid.\n"
);
/
/
File
.close();
/
/
CloseHandle(hProc);
/
/
system(
"PAUSE"
);
/
/
return
-
6
;
/
/
}
/
/
/
/
BYTE
*
pSrcData
=
new BYTE[(UINT_PTR)FileSize];
/
/
if
(!pSrcData)
/
/
{
/
/
printf(
"Can't allocate dll file.\n"
);
/
/
File
.close();
/
/
CloseHandle(hProc);
/
/
system(
"PAUSE"
);
/
/
return
-
7
;
/
/
}
/
/
/
/
File
.seekg(
0
, std::ios::beg);
/
/
File
.read((char
*
)(pSrcData), FileSize);
/
/
File
.close();
CFile
file
;
file
.
Open
(szPath, CFile::modeRead);
ULONGLONG nFileSize
=
file
.GetLength();
BYTE
*
pSrcData
=
new BYTE[nFileSize];
ZeroMemory(pSrcData,nFileSize);
file
.SeekToBegin();
file
.Read(pSrcData,nFileSize);
file
.Close();
if
(!ManualMapDll(hProc, pSrcData, nFileSize))
{
delete[] pSrcData;
CloseHandle(hProc);
return
false;
}
delete[] pSrcData;
CloseHandle(hProc);
return
false;
}
bool
ManualMapDll(HANDLE hProc, BYTE
*
pSrcData, SIZE_T FileSize,
bool
ClearHeader,
bool
ClearNonNeededSections,
bool
AdjustProtections,
bool
SEHExceptionSupport, DWORD fdwReason, LPVOID lpReserved)
{
IMAGE_NT_HEADERS
*
pOldNtHeader
=
nullptr;
IMAGE_OPTIONAL_HEADER
*
pOldOptHeader
=
nullptr;
IMAGE_FILE_HEADER
*
pOldFileHeader
=
nullptr;
BYTE
*
pTargetBase
=
nullptr;
if
(reinterpret_cast<IMAGE_DOS_HEADER
*
>(pSrcData)
-
>e_magic !
=
0x5A4D
)
/
/
"MZ"
{
return
false;
}
pOldNtHeader
=
reinterpret_cast<IMAGE_NT_HEADERS
*
>(pSrcData
+
reinterpret_cast<IMAGE_DOS_HEADER
*
>(pSrcData)
-
>e_lfanew);
pOldOptHeader
=
&pOldNtHeader
-
>OptionalHeader;
pOldFileHeader
=
&pOldNtHeader
-
>FileHeader;
if
(pOldFileHeader
-
>Machine !
=
CURRENT_ARCH)
{
return
false;
}
pTargetBase
=
reinterpret_cast<BYTE
*
>(VirtualAllocEx(hProc, nullptr, pOldOptHeader
-
>SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
if
(!pTargetBase)
{
return
false;
}
DWORD oldp
=
0
;
VirtualProtectEx(hProc, pTargetBase, pOldOptHeader
-
>SizeOfImage, PAGE_EXECUTE_READWRITE, &oldp);
MANUAL_MAPPING_DATA data{
0
};
data.pLoadLibraryA
=
LoadLibraryA;
data.pGetProcAddress
=
GetProcAddress;
data.pRtlAddFunctionTable
=
(f_RtlAddFunctionTable)RtlAddFunctionTable;
SEHExceptionSupport
=
false;
data.pbase
=
pTargetBase;
data.fdwReasonParam
=
fdwReason;
data.reservedParam
=
lpReserved;
data.SEHSupport
=
SEHExceptionSupport;
/
/
PE header
if
(!WriteProcessMemory(hProc, pTargetBase, pSrcData,
0x1000
, nullptr))
/
/
only first
0x1000
bytes
for
the header
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
return
false;
}
IMAGE_SECTION_HEADER
*
pSectionHeader
=
IMAGE_FIRST_SECTION(pOldNtHeader);
for
(UINT i
=
0
; i !
=
pOldFileHeader
-
>NumberOfSections;
+
+
i,
+
+
pSectionHeader)
{
if
(pSectionHeader
-
>SizeOfRawData)
{
if
(!WriteProcessMemory(hProc, pTargetBase
+
pSectionHeader
-
>VirtualAddress, pSrcData
+
pSectionHeader
-
>PointerToRawData, pSectionHeader
-
>SizeOfRawData, nullptr))
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
return
false;
}
}
}
/
/
Mapping params
BYTE
*
MappingDataAlloc
=
reinterpret_cast<BYTE
*
>(VirtualAllocEx(hProc, nullptr, sizeof(MANUAL_MAPPING_DATA), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
if
(!MappingDataAlloc)
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
return
false;
}
if
(!WriteProcessMemory(hProc, MappingDataAlloc, &data, sizeof(MANUAL_MAPPING_DATA), nullptr))
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
return
false;
}
/
/
Shell code
void
*
pShellcode
=
VirtualAllocEx(hProc, nullptr,
0x1000
, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if
(!pShellcode)
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
return
false;
}
if
(!WriteProcessMemory(hProc, pShellcode, Shellcode,
0x1000
, nullptr))
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, pShellcode,
0
, MEM_RELEASE);
return
false;
}
HANDLE hThread
=
CreateRemoteThread(hProc, nullptr,
0
, reinterpret_cast<LPTHREAD_START_ROUTINE>(pShellcode), MappingDataAlloc,
0
, nullptr);
if
(!hThread)
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, pShellcode,
0
, MEM_RELEASE);
return
false;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
HINSTANCE hCheck
=
NULL;
while
(!hCheck)
{
DWORD exitcode
=
0
;
GetExitCodeProcess(hProc, &exitcode);
if
(exitcode !
=
STILL_ACTIVE)
{
return
false;
}
MANUAL_MAPPING_DATA data_checked{
0
};
ReadProcessMemory(hProc, MappingDataAlloc, &data_checked, sizeof(data_checked), nullptr);
hCheck
=
data_checked.hMod;
if
(hCheck
=
=
(HINSTANCE)
0x404040
)
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, pShellcode,
0
, MEM_RELEASE);
return
false;
}
else
if
(hCheck
=
=
(HINSTANCE)
0x505050
)
{
/
/
Exception support failed!
}
Sleep(
10
);
}
BYTE
*
emptyBuffer
=
(BYTE
*
)malloc(
1024
*
1024
*
20
);
if
(emptyBuffer
=
=
nullptr)
{
return
false;
}
memset(emptyBuffer,
0
,
1024
*
1024
*
20
);
/
/
CLEAR PE HEAD
if
(ClearHeader)
{
WriteProcessMemory(hProc, pTargetBase, emptyBuffer,
0x1000
, nullptr);
}
/
/
END CLEAR PE HEAD
if
(ClearNonNeededSections)
{
pSectionHeader
=
IMAGE_FIRST_SECTION(pOldNtHeader);
for
(UINT i
=
0
; i !
=
pOldFileHeader
-
>NumberOfSections;
+
+
i,
+
+
pSectionHeader)
{
if
(pSectionHeader
-
>Misc.VirtualSize)
{
if
((SEHExceptionSupport ?
0
: strcmp((char
*
)pSectionHeader
-
>Name,
".pdata"
)
=
=
0
) ||
strcmp((char
*
)pSectionHeader
-
>Name,
".rsrc"
)
=
=
0
||
strcmp((char
*
)pSectionHeader
-
>Name,
".reloc"
)
=
=
0
)
{
WriteProcessMemory(hProc, pTargetBase
+
pSectionHeader
-
>VirtualAddress, emptyBuffer, pSectionHeader
-
>Misc.VirtualSize, nullptr);
}
}
}
}
if
(AdjustProtections)
{
pSectionHeader
=
IMAGE_FIRST_SECTION(pOldNtHeader);
for
(UINT i
=
0
; i !
=
pOldFileHeader
-
>NumberOfSections;
+
+
i,
+
+
pSectionHeader)
{
if
(pSectionHeader
-
>Misc.VirtualSize)
{
DWORD old
=
0
;
DWORD newP
=
PAGE_READONLY;
if
((pSectionHeader
-
>Characteristics & IMAGE_SCN_MEM_WRITE) >
0
)
{
newP
=
PAGE_READWRITE;
}
else
if
((pSectionHeader
-
>Characteristics & IMAGE_SCN_MEM_EXECUTE) >
0
)
{
newP
=
PAGE_EXECUTE_READ;
}
VirtualProtectEx(hProc, pTargetBase
+
pSectionHeader
-
>VirtualAddress, pSectionHeader
-
>Misc.VirtualSize, newP, &old);
}
}
DWORD old
=
0
;
VirtualProtectEx(hProc, pTargetBase, IMAGE_FIRST_SECTION(pOldNtHeader)
-
>VirtualAddress, PAGE_READONLY, &old);
}
WriteProcessMemory(hProc, pShellcode, emptyBuffer,
0x1000
, nullptr);
VirtualFreeEx(hProc, pShellcode,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
return
true;
}
/
/
/
/
void __stdcall Shellcode(MANUAL_MAPPING_DATA
*
pData)
{
if
(!pData)
{
pData
-
>hMod
=
(HINSTANCE)
0x404040
;
return
;
}
BYTE
*
pBase
=
pData
-
>pbase;
auto
*
pOpt
=
&reinterpret_cast<IMAGE_NT_HEADERS
*
>(pBase
+
reinterpret_cast<IMAGE_DOS_HEADER
*
>((uintptr_t)pBase)
-
>e_lfanew)
-
>OptionalHeader;
auto _LoadLibraryA
=
pData
-
>pLoadLibraryA;
auto _GetProcAddress
=
pData
-
>pGetProcAddress;
auto _RtlAddFunctionTable
=
pData
-
>pRtlAddFunctionTable;
auto _DllMain
=
reinterpret_cast<f_DLL_ENTRY_POINT>(pBase
+
pOpt
-
>AddressOfEntryPoint);
BYTE
*
LocationDelta
=
pBase
-
pOpt
-
>ImageBase;
if
(LocationDelta) {
if
(pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
{
auto
*
pRelocData
=
reinterpret_cast<IMAGE_BASE_RELOCATION
*
>(pBase
+
pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
const auto
*
pRelocEnd
=
reinterpret_cast<IMAGE_BASE_RELOCATION
*
>(reinterpret_cast<uintptr_t>(pRelocData)
+
pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
while
(pRelocData < pRelocEnd && pRelocData
-
>SizeOfBlock)
{
UINT AmountOfEntries
=
(pRelocData
-
>SizeOfBlock
-
sizeof(IMAGE_BASE_RELOCATION))
/
sizeof(WORD);
WORD
*
pRelativeInfo
=
reinterpret_cast<WORD
*
>(pRelocData
+
1
);
for
(UINT i
=
0
; i !
=
AmountOfEntries;
+
+
i,
+
+
pRelativeInfo)
{
if
(RELOC_FLAG(
*
pRelativeInfo))
{
UINT_PTR
*
pPatch
=
reinterpret_cast<UINT_PTR
*
>(pBase
+
pRelocData
-
>VirtualAddress
+
((
*
pRelativeInfo) &
0xFFF
));
*
pPatch
+
=
reinterpret_cast<UINT_PTR>(LocationDelta);
}
}
pRelocData
=
reinterpret_cast<IMAGE_BASE_RELOCATION
*
>(reinterpret_cast<BYTE
*
>(pRelocData)
+
pRelocData
-
>SizeOfBlock);
}
}
}
if
(pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
{
auto
*
pImportDescr
=
reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR
*
>(pBase
+
pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while
(pImportDescr
-
>Name)
{
char
*
szMod
=
reinterpret_cast<char
*
>(pBase
+
pImportDescr
-
>Name);
HINSTANCE hDll
=
_LoadLibraryA(szMod);
ULONG_PTR
*
pThunkRef
=
reinterpret_cast<ULONG_PTR
*
>(pBase
+
pImportDescr
-
>OriginalFirstThunk);
ULONG_PTR
*
pFuncRef
=
reinterpret_cast<ULONG_PTR
*
>(pBase
+
pImportDescr
-
>FirstThunk);
if
(!pThunkRef)
pThunkRef
=
pFuncRef;
for
(;
*
pThunkRef;
+
+
pThunkRef,
+
+
pFuncRef)
{
if
(IMAGE_SNAP_BY_ORDINAL(
*
pThunkRef))
{
*
pFuncRef
=
(ULONG_PTR)_GetProcAddress(hDll, reinterpret_cast<char
*
>(
*
pThunkRef &
0xFFFF
));
}
else
{
auto
*
pImport
=
reinterpret_cast<IMAGE_IMPORT_BY_NAME
*
>(pBase
+
(
*
pThunkRef));
*
pFuncRef
=
(ULONG_PTR)_GetProcAddress(hDll, pImport
-
>Name);
}
}
+
+
pImportDescr;
}
}
if
(pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
{
auto
*
pTLS
=
reinterpret_cast<IMAGE_TLS_DIRECTORY
*
>(pBase
+
pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
auto
*
pCallback
=
reinterpret_cast<PIMAGE_TLS_CALLBACK
*
>(pTLS
-
>AddressOfCallBacks);
for
(; pCallback &&
*
pCallback;
+
+
pCallback)
(
*
pCallback)(pBase, DLL_PROCESS_ATTACH, nullptr);
}
bool
ExceptionSupportFailed
=
false;
if
(pData
-
>SEHSupport)
{
auto excep
=
pOpt
-
>DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
if
(excep.Size) {
if
(!_RtlAddFunctionTable(
reinterpret_cast<IMAGE_RUNTIME_FUNCTION_ENTRY
*
>(pBase
+
excep.VirtualAddress),
excep.Size
/
sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY), (DWORD64)pBase))
{
ExceptionSupportFailed
=
true;
}
}
}
_DllMain(pBase, pData
-
>fdwReasonParam, pData
-
>reservedParam);
if
(ExceptionSupportFailed)
pData
-
>hMod
=
reinterpret_cast<HINSTANCE>(
0x505050
);
else
pData
-
>hMod
=
reinterpret_cast<HINSTANCE>(pBase);
}
CManualMapInject::CManualMapInject()
{
}
CManualMapInject::~CManualMapInject()
{
}
bool
CManualMapInject::InjectorDLL(TCHAR
*
szPath, DWORD dwPid)
{
HANDLE hProc
=
GetProcessHandle(dwPid);
if
(!hProc || !IsCorrectTargetArchitecture(hProc) || GetFileAttributes(szPath)
=
=
INVALID_FILE_ATTRIBUTES)
{
return
false;
}
/
/
std::ifstream
File
(szPath, std::ios::binary | std::ios::ate);
/
/
/
/
if
(
File
.fail())
/
/
{
/
/
printf(
"Opening the file failed: %X\n"
, (DWORD)
File
.rdstate());
/
/
File
.close();
/
/
CloseHandle(hProc);
/
/
system(
"PAUSE"
);
/
/
return
-
5
;
/
/
}
/
/
/
/
auto FileSize
=
File
.tellg();
/
/
if
(FileSize <
0x1000
)
/
/
{
/
/
printf(
"Filesize invalid.\n"
);
/
/
File
.close();
/
/
CloseHandle(hProc);
/
/
system(
"PAUSE"
);
/
/
return
-
6
;
/
/
}
/
/
/
/
BYTE
*
pSrcData
=
new BYTE[(UINT_PTR)FileSize];
/
/
if
(!pSrcData)
/
/
{
/
/
printf(
"Can't allocate dll file.\n"
);
/
/
File
.close();
/
/
CloseHandle(hProc);
/
/
system(
"PAUSE"
);
/
/
return
-
7
;
/
/
}
/
/
/
/
File
.seekg(
0
, std::ios::beg);
/
/
File
.read((char
*
)(pSrcData), FileSize);
/
/
File
.close();
CFile
file
;
file
.
Open
(szPath, CFile::modeRead);
ULONGLONG nFileSize
=
file
.GetLength();
BYTE
*
pSrcData
=
new BYTE[nFileSize];
ZeroMemory(pSrcData,nFileSize);
file
.SeekToBegin();
file
.Read(pSrcData,nFileSize);
file
.Close();
if
(!ManualMapDll(hProc, pSrcData, nFileSize))
{
delete[] pSrcData;
CloseHandle(hProc);
return
false;
}
delete[] pSrcData;
CloseHandle(hProc);
return
false;
}
bool
ManualMapDll(HANDLE hProc, BYTE
*
pSrcData, SIZE_T FileSize,
bool
ClearHeader,
bool
ClearNonNeededSections,
bool
AdjustProtections,
bool
SEHExceptionSupport, DWORD fdwReason, LPVOID lpReserved)
{
IMAGE_NT_HEADERS
*
pOldNtHeader
=
nullptr;
IMAGE_OPTIONAL_HEADER
*
pOldOptHeader
=
nullptr;
IMAGE_FILE_HEADER
*
pOldFileHeader
=
nullptr;
BYTE
*
pTargetBase
=
nullptr;
if
(reinterpret_cast<IMAGE_DOS_HEADER
*
>(pSrcData)
-
>e_magic !
=
0x5A4D
)
/
/
"MZ"
{
return
false;
}
pOldNtHeader
=
reinterpret_cast<IMAGE_NT_HEADERS
*
>(pSrcData
+
reinterpret_cast<IMAGE_DOS_HEADER
*
>(pSrcData)
-
>e_lfanew);
pOldOptHeader
=
&pOldNtHeader
-
>OptionalHeader;
pOldFileHeader
=
&pOldNtHeader
-
>FileHeader;
if
(pOldFileHeader
-
>Machine !
=
CURRENT_ARCH)
{
return
false;
}
pTargetBase
=
reinterpret_cast<BYTE
*
>(VirtualAllocEx(hProc, nullptr, pOldOptHeader
-
>SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
if
(!pTargetBase)
{
return
false;
}
DWORD oldp
=
0
;
VirtualProtectEx(hProc, pTargetBase, pOldOptHeader
-
>SizeOfImage, PAGE_EXECUTE_READWRITE, &oldp);
MANUAL_MAPPING_DATA data{
0
};
data.pLoadLibraryA
=
LoadLibraryA;
data.pGetProcAddress
=
GetProcAddress;
data.pRtlAddFunctionTable
=
(f_RtlAddFunctionTable)RtlAddFunctionTable;
SEHExceptionSupport
=
false;
data.pbase
=
pTargetBase;
data.fdwReasonParam
=
fdwReason;
data.reservedParam
=
lpReserved;
data.SEHSupport
=
SEHExceptionSupport;
/
/
PE header
if
(!WriteProcessMemory(hProc, pTargetBase, pSrcData,
0x1000
, nullptr))
/
/
only first
0x1000
bytes
for
the header
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
return
false;
}
IMAGE_SECTION_HEADER
*
pSectionHeader
=
IMAGE_FIRST_SECTION(pOldNtHeader);
for
(UINT i
=
0
; i !
=
pOldFileHeader
-
>NumberOfSections;
+
+
i,
+
+
pSectionHeader)
{
if
(pSectionHeader
-
>SizeOfRawData)
{
if
(!WriteProcessMemory(hProc, pTargetBase
+
pSectionHeader
-
>VirtualAddress, pSrcData
+
pSectionHeader
-
>PointerToRawData, pSectionHeader
-
>SizeOfRawData, nullptr))
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
return
false;
}
}
}
/
/
Mapping params
BYTE
*
MappingDataAlloc
=
reinterpret_cast<BYTE
*
>(VirtualAllocEx(hProc, nullptr, sizeof(MANUAL_MAPPING_DATA), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
if
(!MappingDataAlloc)
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
return
false;
}
if
(!WriteProcessMemory(hProc, MappingDataAlloc, &data, sizeof(MANUAL_MAPPING_DATA), nullptr))
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
return
false;
}
/
/
Shell code
void
*
pShellcode
=
VirtualAllocEx(hProc, nullptr,
0x1000
, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if
(!pShellcode)
{
VirtualFreeEx(hProc, pTargetBase,
0
, MEM_RELEASE);
VirtualFreeEx(hProc, MappingDataAlloc,
0
, MEM_RELEASE);
return
false;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-5-6 22:05
被_DriverEntry编辑
,原因: 之前图片没显示出来